gsdx-debug: extend ogl debug capabilities

Group opengl calls into a nice name.

Apitrace shows them in a tree format that support folding. Previously it
was a long flat list (10K-40K of lines by frame)

I align the call number with the internal s_n variable. This way it is
easy to map GSdx dump output with the GL debugger :)
This commit is contained in:
Gregory Hainaut 2015-05-06 18:52:51 +02:00
parent 530e4ce776
commit cc4713d379
10 changed files with 121 additions and 8 deletions

View File

@ -100,6 +100,8 @@ PFNGLPROGRAMUNIFORM1IPROC gl_ProgramUniform1i = NU
// GL4.3
PFNGLCOPYIMAGESUBDATAPROC gl_CopyImageSubData = NULL;
PFNGLINVALIDATETEXIMAGEPROC gl_InvalidateTexImage = NULL;
PFNGLPUSHDEBUGGROUPPROC gl_PushDebugGroup = NULL;
PFNGLPOPDEBUGGROUPPROC gl_PopDebugGroup = NULL;
// GL4.2
PFNGLBINDIMAGETEXTUREPROC gl_BindImageTexture = NULL;
PFNGLMEMORYBARRIERPROC gl_MemoryBarrier = NULL;

View File

@ -285,9 +285,11 @@ extern PFNGLPROGRAMUNIFORM1IPROC gl_ProgramUniform1i;
extern PFNGLBINDIMAGETEXTUREPROC gl_BindImageTexture;
extern PFNGLMEMORYBARRIERPROC gl_MemoryBarrier;
extern PFNGLTEXSTORAGE2DPROC gl_TexStorage2D;
extern PFNGLPOPDEBUGGROUPPROC gl_PopDebugGroup;
// GL4.3
extern PFNGLCOPYIMAGESUBDATAPROC gl_CopyImageSubData;
extern PFNGLINVALIDATETEXIMAGEPROC gl_InvalidateTexImage;
extern PFNGLPUSHDEBUGGROUPPROC gl_PushDebugGroup;
// GL4.4
extern PFNGLBUFFERSTORAGEPROC gl_BufferStorage;
// GL_ARB_bindless_texture (GL5?)

View File

@ -381,11 +381,15 @@ void GSDeviceOGL::DetachContext()
void GSDeviceOGL::BeforeDraw()
{
GL_PUSH("Before Draw Validation & Setup");
m_shader->UseProgram();
#ifdef _DEBUG
ASSERT(gl_CheckFramebufferStatus(GL_DRAW_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE);
#endif
GL_POP();
}
void GSDeviceOGL::AfterDraw()
@ -420,6 +424,11 @@ void GSDeviceOGL::DrawIndexedPrimitive(int offset, int count)
void GSDeviceOGL::ClearRenderTarget(GSTexture* t, const GSVector4& c)
{
#ifdef ENABLE_OGL_DEBUG
std::string help = format("Clear RT %d", static_cast<GSTextureOGL*>(t)->GetID());
GL_PUSH(help.c_str());
#endif
// TODO: check size of scissor before toggling it
glDisable(GL_SCISSOR_TEST);
if (static_cast<GSTextureOGL*>(t)->IsBackbuffer()) {
@ -435,6 +444,8 @@ void GSDeviceOGL::ClearRenderTarget(GSTexture* t, const GSVector4& c)
gl_ClearBufferfv(GL_COLOR, 0, c.v);
}
glEnable(GL_SCISSOR_TEST);
GL_POP();
}
void GSDeviceOGL::ClearRenderTarget(GSTexture* t, uint32 c)
@ -445,6 +456,11 @@ void GSDeviceOGL::ClearRenderTarget(GSTexture* t, uint32 c)
void GSDeviceOGL::ClearRenderTarget_i(GSTexture* t, int32 c)
{
#ifdef ENABLE_OGL_DEBUG
std::string help = format("Clear RTi %d", static_cast<GSTextureOGL*>(t)->GetID());
GL_PUSH(help.c_str());
#endif
// Keep SCISSOR_TEST enabled on purpose to reduce the size
// of clean in DATE (impact big upscaling)
int32 col[4] = {c, c, c, c};
@ -453,10 +469,17 @@ void GSDeviceOGL::ClearRenderTarget_i(GSTexture* t, int32 c)
OMAttachRt(static_cast<GSTextureOGL*>(t)->GetID());
gl_ClearBufferiv(GL_COLOR, 0, col);
GL_POP();
}
void GSDeviceOGL::ClearDepth(GSTexture* t, float c)
{
#ifdef ENABLE_OGL_DEBUG
std::string help = format("Clear Depth %d", static_cast<GSTextureOGL*>(t)->GetID());
GL_PUSH(help.c_str());
#endif
OMSetFBO(m_fbo);
OMAttachDs(static_cast<GSTextureOGL*>(t)->GetID());
@ -470,10 +493,17 @@ void GSDeviceOGL::ClearDepth(GSTexture* t, float c)
glDepthMask(false);
}
glEnable(GL_SCISSOR_TEST);
GL_POP();
}
void GSDeviceOGL::ClearStencil(GSTexture* t, uint8 c)
{
#ifdef ENABLE_OGL_DEBUG
std::string help = format("Clear Stencil %d", static_cast<GSTextureOGL*>(t)->GetID());
GL_PUSH(help.c_str());
#endif
// Keep SCISSOR_TEST enabled on purpose to reduce the size
// of clean in DATE (impact big upscaling)
OMSetFBO(m_fbo);
@ -481,6 +511,8 @@ void GSDeviceOGL::ClearStencil(GSTexture* t, uint8 c)
GLint color = c;
gl_ClearBufferiv(GL_STENCIL, 0, &color);
GL_POP();
}
GLuint GSDeviceOGL::CreateSampler(PSSamplerSelector sel)
@ -639,6 +671,8 @@ void GSDeviceOGL::CopyRect(GSTexture* st, GSTexture* dt, const GSVector4i& r)
{
ASSERT(st && dt);
GL_PUSH("CopyRect");
if (GLLoader::found_GL_ARB_copy_image) {
gl_CopyImageSubData( static_cast<GSTextureOGL*>(st)->GetID(), GL_TEXTURE_2D,
0, r.x, r.y, 0,
@ -659,6 +693,8 @@ void GSDeviceOGL::CopyRect(GSTexture* st, GSTexture* dt, const GSVector4i& r)
gl_BindFramebuffer(GL_READ_FRAMEBUFFER, 0);
}
GL_POP();
}
void GSDeviceOGL::StretchRect(GSTexture* st, const GSVector4& sr, GSTexture* dt, const GSVector4& dr, int shader, bool linear)
@ -679,6 +715,8 @@ void GSDeviceOGL::StretchRect(GSTexture* st, const GSVector4& sr, GSTexture* dt,
return;
}
GL_PUSH("StretchRect");
// ************************************
// Init
// ************************************
@ -766,10 +804,14 @@ void GSDeviceOGL::StretchRect(GSTexture* st, const GSVector4& sr, GSTexture* dt,
// ************************************
EndScene();
GL_POP();
}
void GSDeviceOGL::DoMerge(GSTexture* st[2], GSVector4* sr, GSTexture* dt, GSVector4* dr, bool slbg, bool mmod, const GSVector4& c)
{
GL_PUSH("DoMerge");
ClearRenderTarget(dt, c);
if(st[1] && !slbg)
@ -783,10 +825,14 @@ void GSDeviceOGL::DoMerge(GSTexture* st[2], GSVector4* sr, GSTexture* dt, GSVect
StretchRect(st[0], sr[0], dt, dr[0], m_merge_obj.ps[mmod ? 1 : 0], m_merge_obj.bs);
}
GL_POP();
}
void GSDeviceOGL::DoInterlace(GSTexture* st, GSTexture* dt, int shader, bool linear, float yoffset)
{
GL_PUSH("DoInterlace");
GSVector4 s = GSVector4(dt->GetSize());
GSVector4 sr(0, 0, 1, 1);
@ -800,6 +846,8 @@ void GSDeviceOGL::DoInterlace(GSTexture* st, GSTexture* dt, int shader, bool lin
m_interlace.cb->upload(&cb);
StretchRect(st, sr, dt, dr, m_interlace.ps[shader], linear);
GL_POP();
}
void GSDeviceOGL::DoFXAA(GSTexture* st, GSTexture* dt)
@ -815,12 +863,16 @@ void GSDeviceOGL::DoFXAA(GSTexture* st, GSTexture* dt)
m_fxaa.ps = m_shader->Compile("fxaa.fx", "ps_main", GL_FRAGMENT_SHADER, fxaa_fx, fxaa_macro);
}
GL_PUSH("DoFxaa");
GSVector2i s = dt->GetSize();
GSVector4 sr(0, 0, 1, 1);
GSVector4 dr(0, 0, s.x, s.y);
StretchRect(st, sr, dt, dr, m_fxaa.ps, true);
GL_POP();
}
void GSDeviceOGL::DoExternalFX(GSTexture* st, GSTexture* dt)
@ -847,6 +899,8 @@ void GSDeviceOGL::DoExternalFX(GSTexture* st, GSTexture* dt)
m_shaderfx.ps = m_shader->Compile("Extra", "ps_main", GL_FRAGMENT_SHADER, shader.str().c_str(), config.str());
}
GL_PUSH("DoExternalFX");
GSVector2i s = dt->GetSize();
GSVector4 sr(0, 0, 1, 1);
@ -861,10 +915,14 @@ void GSDeviceOGL::DoExternalFX(GSTexture* st, GSTexture* dt)
m_shaderfx.cb->upload(&cb);
StretchRect(st, sr, dt, dr, m_shaderfx.ps, true);
GL_POP();
}
void GSDeviceOGL::DoShadeBoost(GSTexture* st, GSTexture* dt)
{
GL_PUSH("DoShadeBoost");
GSVector2i s = dt->GetSize();
GSVector4 sr(0, 0, 1, 1);
@ -878,10 +936,14 @@ void GSDeviceOGL::DoShadeBoost(GSTexture* st, GSTexture* dt)
m_shadeboost.cb->upload(&cb);
StretchRect(st, sr, dt, dr, m_shadeboost.ps, true);
GL_POP();
}
void GSDeviceOGL::SetupDATE(GSTexture* rt, GSTexture* ds, const GSVertexPT1* vertices, bool datm)
{
GL_PUSH("DATE First Pass");
GSTexture* t = NULL;
// sfex3 (after the capcom logo), vf4 (first menu fading in), ffxii shadows, rumble roses shadows, persona4 shadows
@ -926,6 +988,8 @@ void GSDeviceOGL::SetupDATE(GSTexture* rt, GSTexture* ds, const GSVertexPT1* ver
OMSetWriteBuffer();
EndScene();
GL_POP();
}
void GSDeviceOGL::EndScene()
@ -1111,6 +1175,8 @@ void GSDeviceOGL::DebugOutputToFile(GLenum gl_source, GLenum gl_type, GLuint id,
case GL_DEBUG_TYPE_PORTABILITY_ARB : type = "Portability"; break;
case GL_DEBUG_TYPE_PERFORMANCE_ARB : type = "Perf"; break;
case GL_DEBUG_TYPE_OTHER_ARB : type = "Others"; break;
case GL_DEBUG_TYPE_PUSH_GROUP : return; // Don't print message injected by myself
case GL_DEBUG_TYPE_POP_GROUP : return; // Don't print message injected by myself
default : type = "TTT"; break;
}
switch(gl_severity) {

View File

@ -181,6 +181,10 @@ GSTexture* GSRendererHW::GetOutput(int i)
}
s_n++;
#ifdef ENABLE_OGL_DEBUG
} else {
s_n += 2;
#endif
}
}
@ -335,8 +339,8 @@ void GSRendererHW::Draw()
if(m_dev->IsLost() || GSRenderer::IsBadFrame(m_skip, m_userhacks_skipdraw)) {
if (s_dump) {
fprintf(stderr, "Warning skipping a draw call\n");
s_n += 3; // Keep it sync with SW renderer
}
s_n += 3; // Keep it sync with SW renderer
return;
}
@ -382,7 +386,9 @@ void GSRendererHW::Draw()
GetTextureMinMax(r, context->TEX0, context->CLAMP, m_vt.IsLinear());
GL_PUSH("Lookup Source");
tex = m_tc->LookupSource(context->TEX0, env.TEXA, r);
GL_POP();
if(!tex) return;
@ -434,15 +440,17 @@ void GSRendererHW::Draw()
s_n++;
static uint64 draw_call = 0; // Redundant with s_n but easier to map in GL debug tool
if (s_n >= s_saven) {
// Dump Register state
s = format("%05d_context_d%lld.txt", s_n, draw_call);
s = format("%05d_context_d%lld.txt", s_n);
m_env.Dump(root_hw+s);
m_context->Dump(root_hw+s);
}
draw_call++;
#ifdef ENABLE_OGL_DEBUG
} else {
s_n += 2;
#endif
}
if(m_hacks.m_oi && !(this->*m_hacks.m_oi)(rt->m_texture, ds->m_texture, tex))
@ -568,6 +576,10 @@ void GSRendererHW::Draw()
if ((s_n - s_saven) > s_savel) {
s_dump = 0;
}
#ifdef ENABLE_OGL_DEBUG
} else {
s_n += 1;
#endif
}
#ifdef DISABLE_HW_TEXTURE_CACHE

View File

@ -178,6 +178,10 @@ bool GSRendererOGL::PrimitiveOverlap()
void GSRendererOGL::DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Source* tex)
{
#ifdef ENABLE_OGL_DEBUG
std::string help = format("Draw %d", s_n);
GL_PUSH(help.c_str());
#endif
GSDrawingEnvironment& env = m_env;
GSDrawingContext* context = m_context;
@ -514,13 +518,16 @@ void GSRendererOGL::DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Sour
uint8 afix = context->ALPHA.FIX;
GL_PUSH("IA");
SetupIA();
GL_POP();
dev->OMSetColorMaskState(om_csel);
dev->SetupOM(om_dssel, om_bsel, afix);
dev->SetupCB(&vs_cb, &ps_cb);
if (DATE_GL42) {
GL_PUSH("Date GL42");
// It could be good idea to use stencil in the same time.
// Early stencil test will reduce the number of atomic-load operation
@ -546,6 +553,8 @@ void GSRendererOGL::DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Sour
// Be sure that first pass is finished !
if (!UserHacks_DateGL4)
dev->Barrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
GL_POP();
}
dev->OMSetRenderTargets(rt, ds, &scissor);
@ -556,6 +565,7 @@ void GSRendererOGL::DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Sour
if (env.COLCLAMP.CLAMP == 0 && !tex && PRIM->PRIM != GS_POINTLIST)
{
GL_PUSH("COLCLIP");
GSDeviceOGL::OMBlendSelector om_bselneg(om_bsel);
GSDeviceOGL::PSSelector ps_selneg(ps_sel);
@ -567,6 +577,7 @@ void GSRendererOGL::DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Sour
dev->DrawIndexedPrimitive();
dev->SetupOM(om_dssel, om_bsel, afix);
GL_POP();
}
}
@ -610,6 +621,7 @@ void GSRendererOGL::DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Sour
if (env.COLCLAMP.CLAMP == 0 && !tex && PRIM->PRIM != GS_POINTLIST)
{
GL_PUSH("COLCLIP");
GSDeviceOGL::OMBlendSelector om_bselneg(om_bsel);
GSDeviceOGL::PSSelector ps_selneg(ps_sel);
@ -620,6 +632,7 @@ void GSRendererOGL::DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Sour
dev->SetupPS(ps_selneg);
dev->DrawIndexedPrimitive();
GL_POP();
}
}
}
@ -629,6 +642,7 @@ void GSRendererOGL::DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Sour
dev->EndScene();
if(om_dssel.fba) UpdateFBA(rt);
GL_POP();
}
void GSRendererOGL::UpdateFBA(GSTexture* rt)

View File

@ -541,16 +541,13 @@ void GSRendererSW::Draw()
s_n++;
static uint64 draw_call = 0; // Redundant with s_n but easier to map in GL debug tool
if (s_n >= s_saven) {
// Dump Register state
s = format("%05d_context_d%lld.txt", s_n, draw_call);
s = format("%05d_context_d%lld.txt", s_n);
m_env.Dump(root_sw+s);
m_context->Dump(root_sw+s);
}
draw_call++;
Queue(data);

View File

@ -54,6 +54,8 @@ void GSTextureCacheOGL::Read(Target* t, const GSVector4i& r)
return;
}
GL_PUSH("Texture Cache Read");
// printf("GSRenderTarget::Read %d,%d - %d,%d (%08x)\n", r.left, r.top, r.right, r.bottom, TEX0.TBP0);
int w = r.width();
@ -99,5 +101,7 @@ void GSTextureCacheOGL::Read(Target* t, const GSVector4i& r)
// FIXME invalidate data
m_renderer->m_dev->Recycle(offscreen);
}
GL_POP();
}

View File

@ -255,6 +255,10 @@ bool GSTextureOGL::Update(const GSVector4i& r, const void* data, int pitch)
{
ASSERT(m_type != GSTexture::DepthStencil && m_type != GSTexture::Offscreen);
m_dirty = true;
#ifdef ENABLE_OGL_DEBUG
std::string help = format("Upload Texture %d", m_texture_id);
GL_PUSH(help.c_str());
#endif
// Note: reduce noise for gl retracers
// It might introduce bug after an emulator pause so always set it in standard mode
@ -300,6 +304,7 @@ bool GSTextureOGL::Update(const GSVector4i& r, const void* data, int pitch)
PboPool::EndTransfer();
GL_POP();
return true;
// For reference, standard upload without pbo (Used to crash on FGLRX)

View File

@ -107,6 +107,8 @@ void GSWndGL::PopulateGlFunction()
// GL4.3
*(void**)&(gl_CopyImageSubData) = GetProcAddress("glCopyImageSubData", true);
*(void**)&(gl_InvalidateTexImage) = GetProcAddress("glInvalidateTexImage", true);
*(void**)&(gl_PushDebugGroup) = GetProcAddress("glPushDebugGroup", true);
*(void**)&(gl_PopDebugGroup) = GetProcAddress("glPopDebugGroup", true);
// GL4.4
*(void**)&(gl_BufferStorage) = GetProcAddress("glBufferStorage", true);
// GL_ARB_bindless_texture (GL5?)

View File

@ -493,6 +493,15 @@ extern void vmfree(void* ptr, size_t size);
#endif
// Except apple any sane driver support this extension
#ifdef ENABLE_OGL_DEBUG
#define GL_PUSH(s) gl_PushDebugGroup(GL_DEBUG_SOURCE_APPLICATION, 0xBAD, -1, s);
#define GL_POP(s) gl_PopDebugGroup();
#else
#define GL_PUSH(s) (0);
#define GL_POP() (0);
#endif
// Helper path to dump texture
#ifdef _WINDOWS
const std::string root_sw("c:\\temp1\\_");