diff --git a/plugins/GSdx/GLLoader.cpp b/plugins/GSdx/GLLoader.cpp index c6a672a334..8fc5fbbef7 100644 --- a/plugins/GSdx/GLLoader.cpp +++ b/plugins/GSdx/GLLoader.cpp @@ -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; diff --git a/plugins/GSdx/GLLoader.h b/plugins/GSdx/GLLoader.h index 372a486c19..d32b382052 100644 --- a/plugins/GSdx/GLLoader.h +++ b/plugins/GSdx/GLLoader.h @@ -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?) diff --git a/plugins/GSdx/GSDeviceOGL.cpp b/plugins/GSdx/GSDeviceOGL.cpp index 660775d5f9..d04318d2a6 100644 --- a/plugins/GSdx/GSDeviceOGL.cpp +++ b/plugins/GSdx/GSDeviceOGL.cpp @@ -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(t)->GetID()); + GL_PUSH(help.c_str()); +#endif + // TODO: check size of scissor before toggling it glDisable(GL_SCISSOR_TEST); if (static_cast(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(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(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(t)->GetID()); + GL_PUSH(help.c_str()); +#endif + OMSetFBO(m_fbo); OMAttachDs(static_cast(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(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(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) { diff --git a/plugins/GSdx/GSRendererHW.cpp b/plugins/GSdx/GSRendererHW.cpp index 6af8558f39..28cac6574a 100644 --- a/plugins/GSdx/GSRendererHW.cpp +++ b/plugins/GSdx/GSRendererHW.cpp @@ -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 diff --git a/plugins/GSdx/GSRendererOGL.cpp b/plugins/GSdx/GSRendererOGL.cpp index a4f61754d9..e8f4a0e83d 100644 --- a/plugins/GSdx/GSRendererOGL.cpp +++ b/plugins/GSdx/GSRendererOGL.cpp @@ -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) diff --git a/plugins/GSdx/GSRendererSW.cpp b/plugins/GSdx/GSRendererSW.cpp index 5b1f0e92ee..0a2b4ec5b5 100644 --- a/plugins/GSdx/GSRendererSW.cpp +++ b/plugins/GSdx/GSRendererSW.cpp @@ -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); diff --git a/plugins/GSdx/GSTextureCacheOGL.cpp b/plugins/GSdx/GSTextureCacheOGL.cpp index dcf32f4b61..920afba190 100644 --- a/plugins/GSdx/GSTextureCacheOGL.cpp +++ b/plugins/GSdx/GSTextureCacheOGL.cpp @@ -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(); } diff --git a/plugins/GSdx/GSTextureOGL.cpp b/plugins/GSdx/GSTextureOGL.cpp index 78a3de9db3..e7bc418938 100644 --- a/plugins/GSdx/GSTextureOGL.cpp +++ b/plugins/GSdx/GSTextureOGL.cpp @@ -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) diff --git a/plugins/GSdx/GSWnd.cpp b/plugins/GSdx/GSWnd.cpp index 96248a5417..9a1aff0993 100644 --- a/plugins/GSdx/GSWnd.cpp +++ b/plugins/GSdx/GSWnd.cpp @@ -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?) diff --git a/plugins/GSdx/stdafx.h b/plugins/GSdx/stdafx.h index 8670ba92c5..1e3ab9e2eb 100644 --- a/plugins/GSdx/stdafx.h +++ b/plugins/GSdx/stdafx.h @@ -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\\_");