From 920ac6695f1540be957ba807a20e1a1a7dcca617 Mon Sep 17 00:00:00 2001 From: Gregory Hainaut Date: Sun, 9 Nov 2014 15:27:24 +0100 Subject: [PATCH] gsdx-ogl: add preliminary support of external shader fx --- plugins/GSdx/GSDeviceOGL.cpp | 69 +++++++++++++++++++++++++++++------- plugins/GSdx/GSDeviceOGL.h | 6 ++++ plugins/GSdx/GSRenderer.cpp | 4 +++ plugins/GSdx/GSShaderOGL.cpp | 6 ++-- 4 files changed, 69 insertions(+), 16 deletions(-) diff --git a/plugins/GSdx/GSDeviceOGL.cpp b/plugins/GSdx/GSDeviceOGL.cpp index 71e438ccca..3791e825a3 100644 --- a/plugins/GSdx/GSDeviceOGL.cpp +++ b/plugins/GSdx/GSDeviceOGL.cpp @@ -22,6 +22,7 @@ #include "stdafx.h" #include "GSDeviceOGL.h" #include "GLState.h" +#include #include "res/glsl_source.h" @@ -40,6 +41,7 @@ static const uint32 g_merge_cb_index = 10; static const uint32 g_interlace_cb_index = 11; static const uint32 g_shadeboost_cb_index = 12; static const uint32 g_fxaa_cb_index = 13; +static const uint32 g_fx_cb_index = 14; GSDeviceOGL::GSDeviceOGL() : m_free_window(false) @@ -52,6 +54,8 @@ GSDeviceOGL::GSDeviceOGL() memset(&m_merge_obj, 0, sizeof(m_merge_obj)); memset(&m_interlace, 0, sizeof(m_interlace)); memset(&m_convert, 0, sizeof(m_convert)); + memset(&m_fxaa, 0, sizeof(m_fxaa)); + memset(&m_shaderfx, 0, sizeof(m_shaderfx)); memset(&m_date, 0, sizeof(m_date)); memset(&m_state, 0, sizeof(m_state)); GLState::Clear(); @@ -94,6 +98,10 @@ GSDeviceOGL::~GSDeviceOGL() delete m_fxaa.cb; m_shader->Delete(m_fxaa.ps); + // Clean m_shaderfx + delete m_shaderfx.cb; + m_shader->Delete(m_shaderfx.ps); + // Clean m_date delete m_date.dss; delete m_date.bs; @@ -296,18 +304,6 @@ bool GSDeviceOGL::Create(GSWnd* wnd) rd.AntialiasedLineEnable = false; #endif - // **************************************************************** - // fxaa - // **************************************************************** - std::string fxaa_macro = "#define FXAA_GLSL_130 1\n"; - if (GLLoader::found_GL_ARB_gpu_shader5) { - // This extension become core on openGL4 - fxaa_macro += "#extension GL_ARB_gpu_shader5 : enable\n"; - fxaa_macro += "#define FXAA_GATHER4_ALPHA 1\n"; - } - m_fxaa.cb = new GSUniformBufferOGL(g_fxaa_cb_index, sizeof(FXAAConstantBuffer)); - m_fxaa.ps = m_shader->Compile("fxaa.fx", "ps_main", GL_FRAGMENT_SHADER, old_fxaa_fx, fxaa_macro); - // **************************************************************** // DATE // **************************************************************** @@ -920,6 +916,18 @@ void GSDeviceOGL::DoInterlace(GSTexture* st, GSTexture* dt, int shader, bool lin void GSDeviceOGL::DoFXAA(GSTexture* st, GSTexture* dt) { + // Lazy compile + if (!m_fxaa.ps) { + std::string fxaa_macro = "#define FXAA_GLSL_130 1\n"; + if (GLLoader::found_GL_ARB_gpu_shader5) { + // This extension become core on openGL4 + fxaa_macro += "#extension GL_ARB_gpu_shader5 : enable\n"; + fxaa_macro += "#define FXAA_GATHER4_ALPHA 1\n"; + } + m_fxaa.cb = new GSUniformBufferOGL(g_fxaa_cb_index, sizeof(FXAAConstantBuffer)); + m_fxaa.ps = m_shader->Compile("fxaa.fx", "ps_main", GL_FRAGMENT_SHADER, old_fxaa_fx, fxaa_macro); + } + GSVector2i s = dt->GetSize(); GSVector4 sr(0, 0, 1, 1); @@ -927,7 +935,6 @@ void GSDeviceOGL::DoFXAA(GSTexture* st, GSTexture* dt) FXAAConstantBuffer cb; - // FIXME optimize: remove rcpFrameOpt. And reduce rcpFrame to vec2 cb.rcpFrame = GSVector4(1.0f / s.x, 1.0f / s.y, 0.0f, 0.0f); cb.rcpFrameOpt = GSVector4::zero(); @@ -936,6 +943,42 @@ void GSDeviceOGL::DoFXAA(GSTexture* st, GSTexture* dt) StretchRect(st, sr, dt, dr, m_fxaa.ps, true); } +void GSDeviceOGL::DoExternalFX(GSTexture* st, GSTexture* dt) +{ + // Lazy compile + if (!m_shaderfx.ps) { + std::ifstream fconfig("bin/GSdx_FX_Settings.ini"); + std::stringstream config; + if (fconfig.good()) + config << fconfig.rdbuf(); + + std::ifstream fshader("bin/shader.fx"); + std::stringstream shader; + if (!fshader.good()) + return; + shader << fshader.rdbuf(); + + + m_shaderfx.cb = new GSUniformBufferOGL(g_fx_cb_index, sizeof(ExternalFXConstantBuffer)); + m_shaderfx.ps = m_shader->Compile("Extra", "ps_main", GL_FRAGMENT_SHADER, shader.str().c_str(), config.str()); + } + + GSVector2i s = dt->GetSize(); + + GSVector4 sr(0, 0, 1, 1); + GSVector4 dr(0, 0, s.x, s.y); + + ExternalFXConstantBuffer cb; + + cb.xyFrame = GSVector2(s.x, s.y); + cb.rcpFrame = GSVector4(1.0f / s.x, 1.0f / s.y, 0.0f, 0.0f); + cb.rcpFrameOpt = GSVector4::zero(); + + m_shaderfx.cb->upload(&cb); + + StretchRect(st, sr, dt, dr, m_shaderfx.ps, true); +} + void GSDeviceOGL::DoShadeBoost(GSTexture* st, GSTexture* dt) { GSVector2i s = dt->GetSize(); diff --git a/plugins/GSdx/GSDeviceOGL.h b/plugins/GSdx/GSDeviceOGL.h index 20fcdbb58a..a0c726ffb1 100644 --- a/plugins/GSdx/GSDeviceOGL.h +++ b/plugins/GSdx/GSDeviceOGL.h @@ -494,6 +494,11 @@ class GSDeviceOGL : public GSDevice GSUniformBufferOGL *cb; } m_fxaa; + struct { + GLuint ps; + GSUniformBufferOGL* cb; + } m_shaderfx; + struct { GSDepthStencilOGL* dss; GSBlendStateOGL* bs; @@ -535,6 +540,7 @@ class GSDeviceOGL : public GSDevice void DoInterlace(GSTexture* st, GSTexture* dt, int shader, bool linear, float yoffset = 0); void DoFXAA(GSTexture* st, GSTexture* dt); void DoShadeBoost(GSTexture* st, GSTexture* dt); + void DoExternalFX(GSTexture* st, GSTexture* dt); void OMAttachRt(GLuint rt); void OMAttachDs(GLuint ds); diff --git a/plugins/GSdx/GSRenderer.cpp b/plugins/GSdx/GSRenderer.cpp index 845adf3df7..d38744d5a1 100644 --- a/plugins/GSdx/GSRenderer.cpp +++ b/plugins/GSdx/GSRenderer.cpp @@ -615,6 +615,10 @@ void GSRenderer::KeyEvent(GSKeyEventData* e) m_fxaa = !m_fxaa; fprintf(stderr,"GSdx: fxaa is now %s.\n", m_fxaa ? "enabled" : "disabled"); return; + case XK_Home: + m_shaderfx = !m_shaderfx; + printf("GSdx: External post-processing is now %s.\n", m_shaderfx ? "enabled" : "disabled"); + return; case XK_Shift_L: case XK_Shift_R: m_shift_key = true; diff --git a/plugins/GSdx/GSShaderOGL.cpp b/plugins/GSdx/GSShaderOGL.cpp index 2a7b171bc8..4451739dae 100644 --- a/plugins/GSdx/GSShaderOGL.cpp +++ b/plugins/GSdx/GSShaderOGL.cpp @@ -170,7 +170,7 @@ bool GSShaderOGL::ValidateShader(GLuint s) { if (!m_debug_shader) return true; - GLint status; + GLint status = 0; gl_GetShaderiv(s, GL_COMPILE_STATUS, &status); if (status) return true; @@ -191,7 +191,7 @@ bool GSShaderOGL::ValidateProgram(GLuint p) { if (!m_debug_shader) return true; - GLint status; + GLint status = 0; gl_GetProgramiv(p, GL_LINK_STATUS, &status); if (status) return true; @@ -216,7 +216,7 @@ bool GSShaderOGL::ValidatePipeline(GLuint p) // FIXME: might be mandatory to validate the pipeline gl_ValidateProgramPipeline(p); - GLint status; + GLint status = 0; gl_GetProgramPipelineiv(p, GL_VALIDATE_STATUS, &status); if (status) return true;