Software emulate KHR_debug so that applications can use annotations

* Even if the driver doesn't support it (i.e. on macOS) we can still allow
  applications to name objects and add frame markers, they just won't get any
  debug output.
This commit is contained in:
baldurk
2019-05-02 13:30:26 +01:00
parent c515065dcf
commit 06c6b7e8de
7 changed files with 495 additions and 67 deletions
+15 -6
View File
@@ -530,8 +530,6 @@ WrappedOpenGL::WrappedOpenGL(GLPlatform &platform)
m_UsesVRMarkers = false;
m_RealDebugFunc = NULL;
m_RealDebugFuncParam = NULL;
m_SuppressDebugMessages = false;
m_DrawcallStack.push_back(&m_ParentDrawcall);
@@ -1247,8 +1245,18 @@ void WrappedOpenGL::ActivateContext(GLWindowingData winData)
// this extension is something RenderDoc will support even if the impl
// doesn't. https://renderdoc.org/debug_tool.txt
ctxdata.glExts.push_back("GL_EXT_debug_tool");
ctxdata.glExts.push_back("GL_GREMEDY_frame_terminator");
ctxdata.glExts.push_back("GL_GREMEDY_string_marker");
// similarly we report all the debug extensions so that applications can use them freely - we
// don't call into the driver so we don't need to care if the driver supports them
ctxdata.glExts.push_back("GL_KHR_debug");
ctxdata.glExts.push_back("GL_EXT_debug_label");
ctxdata.glExts.push_back("GL_EXT_debug_marker");
if(!IsGLES)
{
ctxdata.glExts.push_back("GL_GREMEDY_frame_terminator");
ctxdata.glExts.push_back("GL_GREMEDY_string_marker");
}
merge(ctxdata.glExts, ctxdata.glExtsString, ' ');
@@ -2641,8 +2649,9 @@ void WrappedOpenGL::DebugSnoop(GLenum source, GLenum type, GLuint id, GLenum sev
}
}
if(m_RealDebugFunc && !RenderDoc::Inst().GetCaptureOptions().debugOutputMute)
m_RealDebugFunc(source, type, id, severity, length, message, m_RealDebugFuncParam);
if(GetCtxData().m_RealDebugFunc && !RenderDoc::Inst().GetCaptureOptions().debugOutputMute)
GetCtxData().m_RealDebugFunc(source, type, id, severity, length, message,
GetCtxData().m_RealDebugFuncParam);
}
void WrappedOpenGL::AddResource(ResourceId id, ResourceType type, const char *defaultNamePrefix)
+6 -2
View File
@@ -86,8 +86,6 @@ private:
void Serialise_DebugMessages(SerialiserType &ser);
vector<DebugMessage> GetDebugMessages();
GLDEBUGPROC m_RealDebugFunc;
const void *m_RealDebugFuncParam;
string m_DebugMsgContext;
bool m_SuppressDebugMessages;
@@ -318,6 +316,9 @@ private:
ctx = NULL;
shareGroup = NULL;
m_RealDebugFunc = NULL;
m_RealDebugFuncParam = NULL;
built = ready = false;
attribsCreate = false;
version = 0;
@@ -341,6 +342,9 @@ private:
void *shareGroup;
GLDEBUGPROC m_RealDebugFunc;
const void *m_RealDebugFuncParam;
bool built;
bool ready;
+24 -2
View File
@@ -153,8 +153,30 @@ DefineUnsupportedHooks();
// implementation.
bool FullyImplementedFunction(const char *funcname)
{
return !strcmp(funcname, "glFrameTerminatorGREMEDY") ||
!strcmp(funcname, "glStringMarkerGREMEDY");
return
// GL_GREMEDY_frame_terminator
!strcmp(funcname, "glFrameTerminatorGREMEDY") ||
// GL_GREMEDY_string_marker
!strcmp(funcname, "glStringMarkerGREMEDY") ||
// GL_EXT_debug_label
!strcmp(funcname, "glLabelObjectEXT") || !strcmp(funcname, "glGetObjectLabelEXT") ||
// GL_EXT_debug_marker
!strcmp(funcname, "glInsertEventMarkerEXT") || !strcmp(funcname, "glPushGroupMarkerEXT") ||
!strcmp(funcname, "glPopGroupMarkerEXT") ||
// GL_KHR_debug (Core variants)
!strcmp(funcname, "DebugMessageControl") || !strcmp(funcname, "DebugMessageInsert") ||
!strcmp(funcname, "DebugMessageCallback") || !strcmp(funcname, "GetDebugMessageLog") ||
!strcmp(funcname, "GetPointerv") || !strcmp(funcname, "PushDebugGroup") ||
!strcmp(funcname, "PopDebugGroup") || !strcmp(funcname, "ObjectLabel") ||
!strcmp(funcname, "GetObjectLabel") || !strcmp(funcname, "ObjectPtrLabel") ||
!strcmp(funcname, "GetObjectPtrLabel") ||
// GL_KHR_debug (KHR variants)
!strcmp(funcname, "DebugMessageControlKHR") || !strcmp(funcname, "DebugMessageInsertKHR") ||
!strcmp(funcname, "DebugMessageCallbackKHR") || !strcmp(funcname, "GetDebugMessageLogKHR") ||
!strcmp(funcname, "GetPointervKHR") || !strcmp(funcname, "PushDebugGroupKHR") ||
!strcmp(funcname, "PopDebugGroupKHR") || !strcmp(funcname, "ObjectLabelKHR") ||
!strcmp(funcname, "GetObjectLabelKHR") || !strcmp(funcname, "ObjectPtrLabelKHR") ||
!strcmp(funcname, "GetObjectPtrLabelKHR");
}
void *HookedGetProcAddress(const char *func, void *realFunc)
+5 -1
View File
@@ -163,6 +163,8 @@ public:
auto it = m_CurrentResourceIds.find(res);
if(it != m_CurrentResourceIds.end())
{
m_Names.erase(it->second);
ReleaseCurrentResource(it->second);
m_CurrentResourceIds.erase(res);
}
@@ -228,9 +230,11 @@ public:
GLsync GetSync(GLuint name) { return m_CurrentSyncs[name]; }
ResourceId GetSyncID(GLsync sync) { return m_SyncIDs[sync]; }
// KHR_debug storage on replay
// KHR_debug storage
const std::string &GetName(ResourceId id) { return m_Names[id]; }
void SetName(ResourceId id, const std::string &name) { m_Names[id] = name; }
void SetName(GLResource res, const std::string &name) { SetName(GetID(res), name); }
std::string GetName(GLResource res) { return GetName(GetID(res)); }
// we need to find all the children bound to VAOs/FBOs and mark them referenced. The reason for
// this is that say a VAO became high traffic and we stopped serialising buffer binds, but then it
// is never modified in a frame and none of the buffers are ever referenced. They would be
+186 -26
View File
@@ -27,6 +27,59 @@
#include "common/common.h"
#include "strings/string_utils.h"
static std::string DecodeObjectLabel(GLsizei length, const GLchar *label)
{
// we share implementations between KHR_debug and EXT_debug_label, however KHR_debug follows the
// pattern elsewhere (e.g. in glShaderSource) of a length of -1 meaning indeterminate
// NULL-terminated length, but EXT_debug_label takes length of 0 to mean that.
GLsizei realLength = length;
if(gl_CurChunk == GLChunk::glLabelObjectEXT && length == 0)
realLength = -1;
// if length is negative (after above twiddling), it's taken from strlen and the label must be
// NULL-terminated
if(realLength < 0)
realLength = label ? (GLsizei)strlen(label) : 0;
if(realLength == 0 || label == NULL)
return "";
return std::string(label, label + realLength);
}
static void ReturnObjectlabel(std::string name, GLsizei bufSize, GLsizei *length, GLchar *label)
{
// If <label> is NULL and <length> is non-NULL then no string will be returned and the length
// of the label will be returned in <length>.
if(length && !label)
{
*length = (GLsizei)name.size();
}
else
{
// The maximum number of characters that may be written into <label>, including the null
// terminator, is specified by <bufSize>.
if(bufSize > 0)
{
name.resize(bufSize - 1);
if(label)
memcpy(label, name.c_str(), name.size() + 1);
// The actual number of characters written into <label>, excluding the null terminator, is
// returned in <length>.
// If <length> is NULL, no length is returned.
if(length)
*length = (GLsizei)name.size();
}
else
{
if(length)
*length = 0;
}
}
}
GLResource WrappedOpenGL::GetResource(GLenum identifier, GLuint name)
{
GLResource Resource;
@@ -65,22 +118,7 @@ bool WrappedOpenGL::Serialise_glObjectLabel(SerialiserType &ser, GLenum identifi
if(ser.IsWriting())
{
// we share implementations between KHR_debug and EXT_debug_label, however KHR_debug follows the
// pattern elsewhere (e.g. in glShaderSource) of a length of -1 meaning indeterminate
// NULL-terminated length, but EXT_debug_label takes length of 0 to mean that.
GLsizei realLength = length;
if(gl_CurChunk == GLChunk::glLabelObjectEXT && length == 0)
realLength = -1;
// if length is negative (after above twiddling), it's taken from strlen and the label must be
// NULL-terminated
if(realLength < 0)
realLength = label ? (GLsizei)strlen(label) : 0;
if(realLength == 0 || label == NULL)
Label = "";
else
Label = std::string(label, label + realLength);
Label = DecodeObjectLabel(length, label);
Resource = GetResource(identifier, name);
}
@@ -108,7 +146,15 @@ bool WrappedOpenGL::Serialise_glObjectLabel(SerialiserType &ser, GLenum identifi
void WrappedOpenGL::glLabelObjectEXT(GLenum identifier, GLuint name, GLsizei length,
const GLchar *label)
{
SERIALISE_TIME_CALL(GL.glLabelObjectEXT(identifier, name, length, label));
if(GL.glLabelObjectEXT)
{
SERIALISE_TIME_CALL(GL.glLabelObjectEXT(identifier, name, length, label));
}
else
{
m_ScratchSerialiser.ChunkMetadata().timestampMicro = RenderDoc::Inst().GetMicrosecondTimestamp();
m_ScratchSerialiser.ChunkMetadata().durationMicro = 0;
}
if(IsCaptureMode(m_State))
{
@@ -123,13 +169,23 @@ void WrappedOpenGL::glLabelObjectEXT(GLenum identifier, GLuint name, GLsizei len
if(GetResourceManager()->HasResourceRecord(res))
record = GetResourceManager()->GetResourceRecord(res);
GetResourceManager()->SetName(res, DecodeObjectLabel(length, label));
record->AddChunk(scope.Get());
}
}
void WrappedOpenGL::glObjectLabel(GLenum identifier, GLuint name, GLsizei length, const GLchar *label)
{
SERIALISE_TIME_CALL(GL.glObjectLabel(identifier, name, length, label));
if(GL.glObjectLabel)
{
SERIALISE_TIME_CALL(GL.glObjectLabel(identifier, name, length, label));
}
else
{
m_ScratchSerialiser.ChunkMetadata().timestampMicro = RenderDoc::Inst().GetMicrosecondTimestamp();
m_ScratchSerialiser.ChunkMetadata().durationMicro = 0;
}
if(IsCaptureMode(m_State))
{
@@ -144,13 +200,23 @@ void WrappedOpenGL::glObjectLabel(GLenum identifier, GLuint name, GLsizei length
if(GetResourceManager()->HasResourceRecord(res))
record = GetResourceManager()->GetResourceRecord(res);
GetResourceManager()->SetName(res, DecodeObjectLabel(length, label));
record->AddChunk(scope.Get());
}
}
void WrappedOpenGL::glObjectPtrLabel(const void *ptr, GLsizei length, const GLchar *label)
{
SERIALISE_TIME_CALL(GL.glObjectPtrLabel(ptr, length, label));
if(GL.glObjectPtrLabel)
{
SERIALISE_TIME_CALL(GL.glObjectPtrLabel(ptr, length, label));
}
else
{
m_ScratchSerialiser.ChunkMetadata().timestampMicro = RenderDoc::Inst().GetMicrosecondTimestamp();
m_ScratchSerialiser.ChunkMetadata().durationMicro = 0;
}
if(IsCaptureMode(m_State))
{
@@ -160,23 +226,31 @@ void WrappedOpenGL::glObjectPtrLabel(const void *ptr, GLsizei length, const GLch
Serialise_glObjectLabel(ser, eGL_SYNC_FENCE, GetResourceManager()->GetCurrentResource(id).name,
length, label);
GetResourceManager()->SetName(id, DecodeObjectLabel(length, label));
GetContextRecord()->AddChunk(scope.Get());
}
}
void WrappedOpenGL::glDebugMessageCallback(GLDEBUGPROC callback, const void *userParam)
{
m_RealDebugFunc = callback;
m_RealDebugFuncParam = userParam;
GetCtxData().m_RealDebugFunc = callback;
GetCtxData().m_RealDebugFuncParam = userParam;
GL.glDebugMessageCallback(&DebugSnoopStatic, this);
if(GL.glDebugMessageCallback)
{
GL.glDebugMessageCallback(&DebugSnoopStatic, this);
}
}
void WrappedOpenGL::glDebugMessageControl(GLenum source, GLenum type, GLenum severity,
GLsizei count, const GLuint *ids, GLboolean enabled)
{
// we could exert control over debug messages here
GL.glDebugMessageControl(source, type, severity, count, ids, enabled);
if(GL.glDebugMessageControl)
{
GL.glDebugMessageControl(source, type, severity, count, ids, enabled);
}
}
template <typename SerialiserType>
@@ -234,7 +308,15 @@ void WrappedOpenGL::HandleVRFrameMarkers(const GLchar *buf, GLsizei length)
void WrappedOpenGL::glDebugMessageInsert(GLenum source, GLenum type, GLuint id, GLenum severity,
GLsizei length, const GLchar *buf)
{
SERIALISE_TIME_CALL(GL.glDebugMessageInsert(source, type, id, severity, length, buf));
if(GL.glDebugMessageInsert)
{
SERIALISE_TIME_CALL(GL.glDebugMessageInsert(source, type, id, severity, length, buf));
}
else
{
m_ScratchSerialiser.ChunkMetadata().timestampMicro = RenderDoc::Inst().GetMicrosecondTimestamp();
m_ScratchSerialiser.ChunkMetadata().durationMicro = 0;
}
HandleVRFrameMarkers(buf, length);
@@ -373,7 +455,15 @@ bool WrappedOpenGL::Serialise_glPushDebugGroup(SerialiserType &ser, GLenum sourc
void WrappedOpenGL::glPushDebugGroup(GLenum source, GLuint id, GLsizei length, const GLchar *message)
{
SERIALISE_TIME_CALL(GL.glPushDebugGroup(source, id, length, message));
if(GL.glPushDebugGroup)
{
SERIALISE_TIME_CALL(GL.glPushDebugGroup(source, id, length, message));
}
else
{
m_ScratchSerialiser.ChunkMetadata().timestampMicro = RenderDoc::Inst().GetMicrosecondTimestamp();
m_ScratchSerialiser.ChunkMetadata().durationMicro = 0;
}
if(IsActiveCapturing(m_State))
{
@@ -409,7 +499,15 @@ bool WrappedOpenGL::Serialise_glPopDebugGroup(SerialiserType &ser)
}
void WrappedOpenGL::glPopDebugGroup()
{
SERIALISE_TIME_CALL(GL.glPopDebugGroup());
if(GL.glPopDebugGroup)
{
SERIALISE_TIME_CALL(GL.glPopDebugGroup());
}
else
{
m_ScratchSerialiser.ChunkMetadata().timestampMicro = RenderDoc::Inst().GetMicrosecondTimestamp();
m_ScratchSerialiser.ChunkMetadata().durationMicro = 0;
}
if(IsActiveCapturing(m_State))
{
@@ -422,6 +520,68 @@ void WrappedOpenGL::glPopDebugGroup()
}
}
// these get functions are here instead of gl_get_funcs.cpp because we have a local implementation
// for in case the driver doesn't support them
void WrappedOpenGL::glGetObjectLabelEXT(GLenum type, GLuint object, GLsizei bufSize,
GLsizei *length, GLchar *label)
{
if(GL.glGetObjectLabelEXT)
{
GL.glGetObjectLabelEXT(type, object, bufSize, length, label);
}
else
{
GLResource res = GetResource(type, object);
ReturnObjectlabel(GetResourceManager()->GetName(res), bufSize, length, label);
}
}
GLuint WrappedOpenGL::glGetDebugMessageLog(GLuint count, GLsizei bufSize, GLenum *sources,
GLenum *types, GLuint *ids, GLenum *severities,
GLsizei *lengths, GLchar *messageLog)
{
if(GL.glGetDebugMessageLog)
{
return GL.glGetDebugMessageLog(count, bufSize, sources, types, ids, severities, lengths,
messageLog);
}
else
{
return 0;
}
}
void WrappedOpenGL::glGetObjectLabel(GLenum identifier, GLuint name, GLsizei bufSize,
GLsizei *length, GLchar *label)
{
if(GL.glGetObjectLabel)
{
GL.glGetObjectLabel(identifier, name, bufSize, length, label);
}
else
{
GLResource res = GetResource(identifier, name);
ReturnObjectlabel(GetResourceManager()->GetName(res), bufSize, length, label);
}
}
void WrappedOpenGL::glGetObjectPtrLabel(const void *ptr, GLsizei bufSize, GLsizei *length,
GLchar *label)
{
if(GL.glGetObjectPtrLabel)
{
GL.glGetObjectPtrLabel(ptr, bufSize, length, label);
}
else
{
ResourceId id = GetResourceManager()->GetSyncID((GLsync)ptr);
ReturnObjectlabel(GetResourceManager()->GetName(id), bufSize, length, label);
}
}
INSTANTIATE_FUNCTION_SERIALISED(void, glObjectLabel, GLenum identifier, GLuint name, GLsizei length,
const GLchar *label);
INSTANTIATE_FUNCTION_SERIALISED(void, glDebugMessageInsert, GLenum source, GLenum type, GLuint id,
+251 -30
View File
@@ -37,19 +37,19 @@ GLenum WrappedOpenGL::glGetGraphicsResetStatus()
return GL.glGetGraphicsResetStatus();
}
GLuint WrappedOpenGL::glGetDebugMessageLog(GLuint count, GLsizei bufSize, GLenum *sources,
GLenum *types, GLuint *ids, GLenum *severities,
GLsizei *lengths, GLchar *messageLog)
{
return GL.glGetDebugMessageLog(count, bufSize, sources, types, ids, severities, lengths,
messageLog);
}
GLboolean WrappedOpenGL::glIsEnabled(GLenum cap)
{
if(cap == eGL_DEBUG_TOOL_EXT)
return true;
if(!HasExt[KHR_debug])
{
if(cap == eGL_DEBUG_OUTPUT)
return false;
if(cap == eGL_DEBUG_OUTPUT_SYNCHRONOUS)
return false;
}
return GL.glIsEnabled(cap);
}
@@ -138,20 +138,68 @@ GLboolean WrappedOpenGL::glIsSemaphoreEXT(GLuint semaphore)
void WrappedOpenGL::glGetFloatv(GLenum pname, GLfloat *params)
{
if(!HasExt[KHR_debug])
{
switch(pname)
{
case eGL_MAX_LABEL_LENGTH:
case eGL_MAX_DEBUG_MESSAGE_LENGTH:
case eGL_MAX_DEBUG_LOGGED_MESSAGES:
case eGL_MAX_DEBUG_GROUP_STACK_DEPTH:
if(params)
*params = GLfloat(1024);
return;
case eGL_DEBUG_LOGGED_MESSAGES:
case eGL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH:
if(params)
*params = GLfloat(0);
return;
case eGL_DEBUG_GROUP_STACK_DEPTH:
if(params)
*params = GLfloat(1);
return;
default: break;
}
}
GL.glGetFloatv(pname, params);
}
void WrappedOpenGL::glGetDoublev(GLenum pname, GLdouble *params)
{
if(!HasExt[KHR_debug])
{
switch(pname)
{
case eGL_MAX_LABEL_LENGTH:
case eGL_MAX_DEBUG_MESSAGE_LENGTH:
case eGL_MAX_DEBUG_LOGGED_MESSAGES:
case eGL_MAX_DEBUG_GROUP_STACK_DEPTH:
if(params)
*params = GLdouble(1024);
return;
case eGL_DEBUG_LOGGED_MESSAGES:
case eGL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH:
if(params)
*params = GLdouble(0);
return;
case eGL_DEBUG_GROUP_STACK_DEPTH:
if(params)
*params = GLdouble(1);
return;
default: break;
}
}
GL.glGetDoublev(pname, params);
}
void WrappedOpenGL::glGetPointerv(GLenum pname, void **params)
{
if(pname == eGL_DEBUG_CALLBACK_FUNCTION)
*params = (void *)m_RealDebugFunc;
*params = (void *)GetCtxData().m_RealDebugFunc;
else if(pname == eGL_DEBUG_CALLBACK_USER_PARAM)
*params = (void *)m_RealDebugFuncParam;
*params = (void *)GetCtxData().m_RealDebugFuncParam;
else
GL.glGetPointerv(pname, params);
}
@@ -176,12 +224,59 @@ void WrappedOpenGL::glGetIntegerv(GLenum pname, GLint *params)
*params = GLint(eGL_DEBUG_TOOL_FRAME_CAPTURE_BIT_EXT);
return;
}
else if(!HasExt[KHR_debug])
{
switch(pname)
{
case eGL_MAX_LABEL_LENGTH:
case eGL_MAX_DEBUG_MESSAGE_LENGTH:
case eGL_MAX_DEBUG_LOGGED_MESSAGES:
case eGL_MAX_DEBUG_GROUP_STACK_DEPTH:
if(params)
*params = GLint(1024);
return;
case eGL_DEBUG_LOGGED_MESSAGES:
case eGL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH:
if(params)
*params = GLint(0);
return;
case eGL_DEBUG_GROUP_STACK_DEPTH:
if(params)
*params = GLint(1);
return;
default: break;
}
}
GL.glGetIntegerv(pname, params);
}
void WrappedOpenGL::glGetBooleanv(GLenum pname, GLboolean *data)
{
if(!HasExt[KHR_debug])
{
switch(pname)
{
case eGL_MAX_LABEL_LENGTH:
case eGL_MAX_DEBUG_MESSAGE_LENGTH:
case eGL_MAX_DEBUG_LOGGED_MESSAGES:
case eGL_MAX_DEBUG_GROUP_STACK_DEPTH:
if(data)
*data = GLboolean(1);
return;
case eGL_DEBUG_LOGGED_MESSAGES:
case eGL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH:
if(data)
*data = GLboolean(0);
return;
case eGL_DEBUG_GROUP_STACK_DEPTH:
if(data)
*data = GLboolean(1);
return;
default: break;
}
}
GL.glGetBooleanv(pname, data);
}
@@ -199,11 +294,59 @@ void WrappedOpenGL::glGetInteger64v(GLenum pname, GLint64 *data)
*data = GLint64(eGL_DEBUG_TOOL_FRAME_CAPTURE_BIT_EXT);
return;
}
else if(!HasExt[KHR_debug])
{
switch(pname)
{
case eGL_MAX_LABEL_LENGTH:
case eGL_MAX_DEBUG_MESSAGE_LENGTH:
case eGL_MAX_DEBUG_LOGGED_MESSAGES:
case eGL_MAX_DEBUG_GROUP_STACK_DEPTH:
if(data)
*data = GLint64(1024);
return;
case eGL_DEBUG_LOGGED_MESSAGES:
case eGL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH:
if(data)
*data = GLint64(0);
return;
case eGL_DEBUG_GROUP_STACK_DEPTH:
if(data)
*data = GLint64(1);
return;
default: break;
}
}
GL.glGetInteger64v(pname, data);
}
void WrappedOpenGL::glGetBooleani_v(GLenum pname, GLuint index, GLboolean *data)
{
if(!HasExt[KHR_debug])
{
switch(pname)
{
case eGL_MAX_LABEL_LENGTH:
case eGL_MAX_DEBUG_MESSAGE_LENGTH:
case eGL_MAX_DEBUG_LOGGED_MESSAGES:
case eGL_MAX_DEBUG_GROUP_STACK_DEPTH:
if(data)
*data = GLboolean(1);
return;
case eGL_DEBUG_LOGGED_MESSAGES:
case eGL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH:
if(data)
*data = GLboolean(0);
return;
case eGL_DEBUG_GROUP_STACK_DEPTH:
if(data)
*data = GLboolean(1);
return;
default: break;
}
}
GL.glGetBooleani_v(pname, index, data);
}
@@ -221,16 +364,88 @@ void WrappedOpenGL::glGetIntegeri_v(GLenum pname, GLuint index, GLint *data)
*data = GLint(eGL_DEBUG_TOOL_FRAME_CAPTURE_BIT_EXT);
return;
}
else if(!HasExt[KHR_debug])
{
switch(pname)
{
case eGL_MAX_LABEL_LENGTH:
case eGL_MAX_DEBUG_MESSAGE_LENGTH:
case eGL_MAX_DEBUG_LOGGED_MESSAGES:
case eGL_MAX_DEBUG_GROUP_STACK_DEPTH:
if(data)
*data = GLint(1024);
return;
case eGL_DEBUG_LOGGED_MESSAGES:
case eGL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH:
if(data)
*data = GLint(0);
return;
case eGL_DEBUG_GROUP_STACK_DEPTH:
if(data)
*data = GLint(1);
return;
default: break;
}
}
GL.glGetIntegeri_v(pname, index, data);
}
void WrappedOpenGL::glGetFloati_v(GLenum pname, GLuint index, GLfloat *data)
{
if(!HasExt[KHR_debug])
{
switch(pname)
{
case eGL_MAX_LABEL_LENGTH:
case eGL_MAX_DEBUG_MESSAGE_LENGTH:
case eGL_MAX_DEBUG_LOGGED_MESSAGES:
case eGL_MAX_DEBUG_GROUP_STACK_DEPTH:
if(data)
*data = GLfloat(1024);
return;
case eGL_DEBUG_LOGGED_MESSAGES:
case eGL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH:
if(data)
*data = GLfloat(0);
return;
case eGL_DEBUG_GROUP_STACK_DEPTH:
if(data)
*data = GLfloat(1);
return;
default: break;
}
}
GL.glGetFloati_v(pname, index, data);
}
void WrappedOpenGL::glGetDoublei_v(GLenum pname, GLuint index, GLdouble *data)
{
if(!HasExt[KHR_debug])
{
switch(pname)
{
case eGL_MAX_LABEL_LENGTH:
case eGL_MAX_DEBUG_MESSAGE_LENGTH:
case eGL_MAX_DEBUG_LOGGED_MESSAGES:
case eGL_MAX_DEBUG_GROUP_STACK_DEPTH:
if(data)
*data = GLdouble(1024);
return;
case eGL_DEBUG_LOGGED_MESSAGES:
case eGL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH:
if(data)
*data = GLdouble(0);
return;
case eGL_DEBUG_GROUP_STACK_DEPTH:
if(data)
*data = GLdouble(1);
return;
default: break;
}
}
GL.glGetDoublei_v(pname, index, data);
}
@@ -248,6 +463,30 @@ void WrappedOpenGL::glGetInteger64i_v(GLenum pname, GLuint index, GLint64 *data)
*data = GLint64(eGL_DEBUG_TOOL_FRAME_CAPTURE_BIT_EXT);
return;
}
else if(!HasExt[KHR_debug])
{
switch(pname)
{
case eGL_MAX_LABEL_LENGTH:
case eGL_MAX_DEBUG_MESSAGE_LENGTH:
case eGL_MAX_DEBUG_LOGGED_MESSAGES:
case eGL_MAX_DEBUG_GROUP_STACK_DEPTH:
if(data)
*data = GLint64(1024);
return;
case eGL_DEBUG_LOGGED_MESSAGES:
case eGL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH:
if(data)
*data = GLint64(0);
return;
case eGL_DEBUG_GROUP_STACK_DEPTH:
if(data)
*data = GLint64(1);
return;
default: break;
}
}
GL.glGetInteger64i_v(pname, index, data);
}
@@ -591,24 +830,6 @@ void WrappedOpenGL::glGetMultisamplefv(GLenum pname, GLuint index, GLfloat *val)
GL.glGetMultisamplefv(pname, index, val);
}
void WrappedOpenGL::glGetObjectLabel(GLenum identifier, GLuint name, GLsizei bufSize,
GLsizei *length, GLchar *label)
{
GL.glGetObjectLabel(identifier, name, bufSize, length, label);
}
void WrappedOpenGL::glGetObjectLabelEXT(GLenum identifier, GLuint name, GLsizei bufSize,
GLsizei *length, GLchar *label)
{
GL.glGetObjectLabelEXT(identifier, name, bufSize, length, label);
}
void WrappedOpenGL::glGetObjectPtrLabel(const void *ptr, GLsizei bufSize, GLsizei *length,
GLchar *label)
{
GL.glGetObjectPtrLabel(ptr, bufSize, length, label);
}
void WrappedOpenGL::glGetShaderiv(GLuint shader, GLenum pname, GLint *params)
{
GL.glGetShaderiv(shader, pname, params);
@@ -1056,9 +1277,9 @@ void WrappedOpenGL::glGetTextureLevelParameterfvEXT(GLuint texture, GLenum targe
void WrappedOpenGL::glGetPointeri_vEXT(GLenum pname, GLuint index, void **params)
{
if(pname == eGL_DEBUG_CALLBACK_FUNCTION)
*params = (void *)m_RealDebugFunc;
*params = (void *)GetCtxData().m_RealDebugFunc;
else if(pname == eGL_DEBUG_CALLBACK_USER_PARAM)
*params = (void *)m_RealDebugFuncParam;
*params = (void *)GetCtxData().m_RealDebugFuncParam;
else
GL.glGetPointeri_vEXT(pname, index, params);
}
@@ -1050,6 +1050,10 @@ bool WrappedOpenGL::Serialise_glDisable(SerialiserType &ser, GLenum cap)
void WrappedOpenGL::glDisable(GLenum cap)
{
// if we're emulating KHR_debug, skip its caps here
if(!HasExt[KHR_debug] && (cap == eGL_DEBUG_OUTPUT || cap == eGL_DEBUG_OUTPUT_SYNCHRONOUS))
return;
SERIALISE_TIME_CALL(GL.glDisable(cap));
if(IsActiveCapturing(m_State))
@@ -1090,6 +1094,10 @@ bool WrappedOpenGL::Serialise_glEnable(SerialiserType &ser, GLenum cap)
void WrappedOpenGL::glEnable(GLenum cap)
{
// if we're emulating KHR_debug, skip its caps here
if(!HasExt[KHR_debug] && (cap == eGL_DEBUG_OUTPUT || cap == eGL_DEBUG_OUTPUT_SYNCHRONOUS))
return;
SERIALISE_TIME_CALL(GL.glEnable(cap));
if(IsActiveCapturing(m_State))