From 16a1fded965254b8addb674d62f78550e4c49854 Mon Sep 17 00:00:00 2001 From: "gregory.hainaut" Date: Fri, 30 Mar 2012 19:02:37 +0000 Subject: [PATCH] gsdx-ogl: LINUX ONLY * Keep the state of the draw buffer (save few opengl call) * AMD fix the shader unloading (12.2 and above). So disable the workaround git-svn-id: http://pcsx2.googlecode.com/svn/branches/gsdx-ogl@5137 96395faa-99c1-11dd-bbfe-3dabce05a288 --- plugins/GSdx/CMakeLists.txt | 3 +- plugins/GSdx/GS.cpp | 7 +++ plugins/GSdx/GSDeviceOGL.cpp | 92 ++++++++++++++++++++++++----------- plugins/GSdx/GSDeviceOGL.h | 4 +- plugins/GSdx/GSTextureOGL.cpp | 7 ++- plugins/GSdx/linux_replay.cpp | 2 +- 6 files changed, 82 insertions(+), 33 deletions(-) diff --git a/plugins/GSdx/CMakeLists.txt b/plugins/GSdx/CMakeLists.txt index 5fa1f3b991..51cf2e5b49 100644 --- a/plugins/GSdx/CMakeLists.txt +++ b/plugins/GSdx/CMakeLists.txt @@ -19,7 +19,8 @@ set(CommonFlags -std=c++0x -fno-strict-aliasing -DOGL_DEBUG # FIXME remove me when code is ready - -DAMD_DRIVER_WORKAROUND + # Unload of Geometry shader was fixed in Cat 12.3 (ie OpenGL version string: 4.2.11554) + #-DAMD_DRIVER_WORKAROUND ) set(OptimizationFlags diff --git a/plugins/GSdx/GS.cpp b/plugins/GSdx/GS.cpp index 8c448348fc..df1a20fdc5 100644 --- a/plugins/GSdx/GS.cpp +++ b/plugins/GSdx/GS.cpp @@ -1269,6 +1269,13 @@ EXPORT_C GSReplay(char* lpszCmdLine, int renderer) ::SetPriorityClass(::GetCurrentProcess(), HIGH_PRIORITY_CLASS); #endif + // Allow to easyly switch between SW/HW renderer + renderer = theApp.GetConfig("renderer", 12); + if (renderer != 12 && renderer != 13) + { + fprintf(stderr, "wrong renderer selected %d\n", renderer); + return; + } if(FILE* fp = fopen(lpszCmdLine, "rb")) { diff --git a/plugins/GSdx/GSDeviceOGL.cpp b/plugins/GSdx/GSDeviceOGL.cpp index 40ecf105ca..914cebd66f 100644 --- a/plugins/GSdx/GSDeviceOGL.cpp +++ b/plugins/GSdx/GSDeviceOGL.cpp @@ -488,7 +488,9 @@ void GSDeviceOGL::Flip() { // FIXME: disable it when code is working CheckDebugLog(); + m_wnd->Flip(); + #ifdef PRINT_FRAME_NUMBER fprintf(stderr, "Draw %d (Frame %d)\n", g_draw_count, g_frame_count); #endif @@ -498,6 +500,33 @@ void GSDeviceOGL::Flip() #endif } +void GSDeviceOGL::DebugBB() +{ + bool dump_me = false; + uint32 start = theApp.GetConfig("debug_ogl_dump", 0); + uint32 length = theApp.GetConfig("debug_ogl_dump_length", 5); + if ( (start != 0 && g_frame_count >= start && g_frame_count < (start + length)) ) dump_me = true; + + if (!dump_me) return; + + GLuint fbo_old = m_state.fbo; + OMSetFBO(m_fbo); + + GSVector2i size = m_backbuffer->GetSize(); + GSTexture* rt = CreateRenderTarget(size.x, size.y, false); + + static_cast(rt)->Attach(GL_COLOR_ATTACHMENT0); + + glBlitFramebuffer(0, 0, size.x, size.y, + 0, 0, size.x, size.y, + GL_COLOR_BUFFER_BIT, GL_NEAREST); + + rt->Save(format("/tmp/out_f%d__d%d__bb.bmp", g_frame_count, g_draw_count)); + + delete rt; + OMSetFBO(fbo_old); +} + void GSDeviceOGL::DebugInput() { bool dump_me = false; @@ -505,21 +534,21 @@ void GSDeviceOGL::DebugInput() uint32 length = theApp.GetConfig("debug_ogl_dump_length", 5); if ( (start != 0 && g_frame_count >= start && g_frame_count < (start + length)) ) dump_me = true; - if ( dump_me ) { - for (auto i = 0 ; i < 3 ; i++) { - if (m_state.ps_srv[i] != NULL) { - m_state.ps_srv[i]->Save(format("/tmp/in_f%d__d%d__%d.bmp", g_frame_count, g_draw_count, i)); - } - } - //if (m_state.rtv != NULL) m_state.rtv->Save(format("/tmp/target_f%d__d%d__tex.bmp", g_frame_count, g_draw_count)); - //if (m_state.dsv != NULL) m_state.dsv->Save(format("/tmp/ds_in_%d.bmp", g_draw_count)); + if (!dump_me) return; - fprintf(stderr, "Draw %d (Frame %d)\n", g_draw_count, g_frame_count); - fprintf(stderr, "vs: %d ; gs: %d ; ps: %d\n", m_state.vs, m_state.gs, m_state.ps); - m_state.vb->debug(); - m_state.bs->debug(); - m_state.dss->debug(); + for (auto i = 0 ; i < 3 ; i++) { + if (m_state.ps_srv[i] != NULL) { + m_state.ps_srv[i]->Save(format("/tmp/in_f%d__d%d__%d.bmp", g_frame_count, g_draw_count, i)); + } } + //if (m_state.rtv != NULL) m_state.rtv->Save(format("/tmp/target_f%d__d%d__tex.bmp", g_frame_count, g_draw_count)); + //if (m_state.dsv != NULL) m_state.dsv->Save(format("/tmp/ds_in_%d.bmp", g_draw_count)); + + fprintf(stderr, "Draw %d (Frame %d)\n", g_draw_count, g_frame_count); + fprintf(stderr, "vs: %d ; gs: %d ; ps: %d\n", m_state.vs, m_state.gs, m_state.ps); + m_state.vb->debug(); + m_state.bs->debug(); + m_state.dss->debug(); } void GSDeviceOGL::DebugOutput() @@ -531,17 +560,17 @@ void GSDeviceOGL::DebugOutput() uint32 length = theApp.GetConfig("debug_ogl_dump_length", 5); if ( (start != 0 && g_frame_count >= start && g_frame_count < (start + length)) ) dump_me = true; - if ( dump_me ) { - if (m_state.rtv == m_backbuffer) { - if (m_state.rtv != NULL) m_state.rtv->Save(format("/tmp/out_f%d__d%d__back.bmp", g_frame_count, g_draw_count)); - } else { - if (m_state.rtv != NULL) m_state.rtv->Save(format("/tmp/out_f%d__d%d__tex.bmp", g_frame_count, g_draw_count)); - } - //if (m_state.dsv != NULL) m_state.dsv->Save(format("/tmp/ds_out_%d.bmp", g_draw_count)); - - fprintf(stderr, "\n"); + if (!dump_me) return; + if (m_state.rtv == m_backbuffer) { + m_state.rtv->Save(format("/tmp/out_f%d__d%d__back.bmp", g_frame_count, g_draw_count)); + } else { + if (m_state.rtv != NULL) m_state.rtv->Save(format("/tmp/out_f%d__d%d__tex.bmp", g_frame_count, g_draw_count)); } + //if (m_state.dsv != NULL) m_state.dsv->Save(format("/tmp/ds_out_%d.bmp", g_draw_count)); + + fprintf(stderr, "\n"); + //DebugBB(); } void GSDeviceOGL::DrawPrimitive() @@ -580,6 +609,7 @@ void GSDeviceOGL::DrawIndexedPrimitive(int offset, int count) #endif m_state.vb->DrawIndexedPrimitive(offset, count); + #ifdef OGL_DEBUG DebugOutput(); g_draw_count++; @@ -601,7 +631,6 @@ void GSDeviceOGL::ClearRenderTarget(GSTexture* t, const GSVector4& c) // FIXME1 I need to clarify this FBO attachment stuff // I would like to avoid FBO for a basic clean operation OMSetFBO(m_fbo); - glDrawBuffer(GL_COLOR_ATTACHMENT0); static_cast(t)->Attach(GL_COLOR_ATTACHMENT0); glClearBufferfv(GL_COLOR, 0, c.v); } @@ -1088,7 +1117,7 @@ void GSDeviceOGL::PSSetShader(GLuint ps) } } -void GSDeviceOGL::OMSetFBO(GLuint fbo) +void GSDeviceOGL::OMSetFBO(GLuint fbo, GLenum buffer) { if (m_state.fbo != fbo) { m_state.fbo = fbo; @@ -1096,6 +1125,12 @@ void GSDeviceOGL::OMSetFBO(GLuint fbo) // FIXME DEBUG //if (fbo) fprintf(stderr, "FB status %x\n", glCheckFramebufferStatus(GL_FRAMEBUFFER)); } + + if (m_state.draw != buffer) { + m_state.draw = buffer; + glDrawBuffer(buffer); + } + } void GSDeviceOGL::OMSetDepthStencilState(GSDepthStencilOGL* dss, uint8 sref) @@ -1135,20 +1170,19 @@ void GSDeviceOGL::OMSetRenderTargets(GSTexture* rt, GSTexture* ds, const GSVecto m_state.dsv = static_cast(ds); if (static_cast(rt)->IsBackbuffer()) { + assert(ds == NULL); // no depth-stencil without FBO + OMSetFBO(0); - assert(ds == NULL); // no depth-stencil without FBO } else { - OMSetFBO(m_fbo); - assert(rt != NULL); // a render target must exists // FIXME DEBUG special case for GL_R16UI if (rt->GetFormat() == GL_R16UI) { - glDrawBuffer(GL_COLOR_ATTACHMENT1); + OMSetFBO(m_fbo, GL_COLOR_ATTACHMENT1); static_cast(rt)->Attach(GL_COLOR_ATTACHMENT1); } else { - glDrawBuffer(GL_COLOR_ATTACHMENT0); + OMSetFBO(m_fbo, GL_COLOR_ATTACHMENT0); static_cast(rt)->Attach(GL_COLOR_ATTACHMENT0); } diff --git a/plugins/GSdx/GSDeviceOGL.h b/plugins/GSdx/GSDeviceOGL.h index fc574a5229..0ab52b8853 100644 --- a/plugins/GSdx/GSDeviceOGL.h +++ b/plugins/GSdx/GSDeviceOGL.h @@ -805,6 +805,7 @@ class GSDeviceOGL : public GSDevice GSTextureOGL* rtv; GSTextureOGL* dsv; GLuint fbo; ++ GLenum draw; } m_state; bool m_srv_changed; @@ -840,6 +841,7 @@ class GSDeviceOGL : public GSDevice static void DebugOutputToFile(unsigned int source, unsigned int type, unsigned int id, unsigned int severity, const char* message); void DebugOutput(); void DebugInput(); + void DebugBB(); bool HasStencil() { return true; } bool HasDepth32() { return true; } @@ -894,7 +896,7 @@ class GSDeviceOGL : public GSDevice void PSSetSamplerState(GLuint ss0, GLuint ss1, GLuint ss2 = 0); void PSSetShader(GLuint ps); - void OMSetFBO(GLuint fbo); + void OMSetFBO(GLuint fbo, GLenum buffer = GL_COLOR_ATTACHMENT0); void OMSetDepthStencilState(GSDepthStencilOGL* dss, uint8 sref); void OMSetBlendState(GSBlendStateOGL* bs, float bf); void OMSetRenderTargets(GSTexture* rt, GSTexture* ds, const GSVector4i* scissor = NULL); diff --git a/plugins/GSdx/GSTextureOGL.cpp b/plugins/GSdx/GSTextureOGL.cpp index 00f4cffd37..73aef4a5d9 100644 --- a/plugins/GSdx/GSTextureOGL.cpp +++ b/plugins/GSdx/GSTextureOGL.cpp @@ -120,6 +120,11 @@ GSTextureOGL::GSTextureOGL(int type, int w, int h, bool msaa, int format, GLuint // In worst case the HW renderer seems to use 3 texture unit // For the moment SW renderer only use 1 so don't bother EnableUnit(0); + // Did we need to setup a default sampler of the texture now? + // glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + // glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + // glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + // glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); if (m_format == GL_RGBA8) glTexImage2D(m_texture_target, 0, m_format, m_size.x, m_size.y, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); else if (m_format == GL_R16UI) @@ -144,7 +149,7 @@ GSTextureOGL::~GSTextureOGL() void GSTextureOGL::Attach(GLenum attachment) { //fprintf(stderr, "format %d,%x\n", m_type, m_format); - glFramebufferTexture2D(GL_FRAMEBUFFER, attachment, m_texture_target, m_texture_id, 0); + glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, attachment, m_texture_target, m_texture_id, 0); // FIXME DEBUG //fprintf(stderr, "FB status %x\n", glCheckFramebufferStatus(GL_FRAMEBUFFER)); } diff --git a/plugins/GSdx/linux_replay.cpp b/plugins/GSdx/linux_replay.cpp index 0de8a06825..f2d25ab8c9 100644 --- a/plugins/GSdx/linux_replay.cpp +++ b/plugins/GSdx/linux_replay.cpp @@ -37,5 +37,5 @@ int main ( int argc, char *argv[] ) if ( argc != 3 ) help(); GSsetSettingsDir(argv[1]); - GSReplay(argv[2], 15); + GSReplay(argv[2], 12); }