gsdx-ogl: add preliminary support of external shader fx

This commit is contained in:
Gregory Hainaut 2014-11-09 15:27:24 +01:00
parent ec1da2805c
commit 920ac6695f
4 changed files with 69 additions and 16 deletions

View File

@ -22,6 +22,7 @@
#include "stdafx.h"
#include "GSDeviceOGL.h"
#include "GLState.h"
#include <fstream>
#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();

View File

@ -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);

View File

@ -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;

View File

@ -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;