Skip to content

Commit

Permalink
Add generic "PostShader" functionality, replacing FXAA (it's one of t…
Browse files Browse the repository at this point in the history
…hem).

Replaces #4018, sorry DanyalZia :)
  • Loading branch information
hrydgard committed Oct 12, 2013
1 parent 1375b72 commit e0b19de
Show file tree
Hide file tree
Showing 23 changed files with 342 additions and 33 deletions.
2 changes: 2 additions & 0 deletions CMakeLists.txt
Expand Up @@ -1001,6 +1001,8 @@ add_library(GPU OBJECT
GPU/Common/IndexGenerator.h GPU/Common/IndexGenerator.h
GPU/Common/TextureDecoder.cpp GPU/Common/TextureDecoder.cpp
GPU/Common/TextureDecoder.h GPU/Common/TextureDecoder.h
GPU/Common/PostShader.cpp
GPU/Common/PostShader.h
GPU/Common/SplineCommon.h GPU/Common/SplineCommon.h
GPU/GLES/GLES_GPU.cpp GPU/GLES/GLES_GPU.cpp
GPU/GLES/GLES_GPU.h GPU/GLES/GLES_GPU.h
Expand Down
4 changes: 2 additions & 2 deletions Core/Config.cpp
Expand Up @@ -179,7 +179,7 @@ void Config::Load(const char *iniFileName, const char *controllerIniFilename)
graphics->Get("DisableStencilTest", &bDisableStencilTest, false); graphics->Get("DisableStencilTest", &bDisableStencilTest, false);
graphics->Get("AlwaysDepthWrite", &bAlwaysDepthWrite, false); graphics->Get("AlwaysDepthWrite", &bAlwaysDepthWrite, false);
graphics->Get("LowQualitySplineBezier", &bLowQualitySplineBezier, false); graphics->Get("LowQualitySplineBezier", &bLowQualitySplineBezier, false);
graphics->Get("FXAA", &bFXAA, false); graphics->Get("PostShader", &sPostShaderName, "Off");


IniFile::Section *sound = iniFile.GetOrCreateSection("Sound"); IniFile::Section *sound = iniFile.GetOrCreateSection("Sound");
sound->Get("Enable", &bEnableSound, true); sound->Get("Enable", &bEnableSound, true);
Expand Down Expand Up @@ -349,7 +349,7 @@ void Config::Save() {
graphics->Set("DisableStencilTest", bDisableStencilTest); graphics->Set("DisableStencilTest", bDisableStencilTest);
graphics->Set("AlwaysDepthWrite", bAlwaysDepthWrite); graphics->Set("AlwaysDepthWrite", bAlwaysDepthWrite);
graphics->Set("LowQualitySplineBezier", bLowQualitySplineBezier); graphics->Set("LowQualitySplineBezier", bLowQualitySplineBezier);
graphics->Set("FXAA", bFXAA); graphics->Set("PostShader", sPostShaderName);


IniFile::Section *sound = iniFile.GetOrCreateSection("Sound"); IniFile::Section *sound = iniFile.GetOrCreateSection("Sound");
sound->Set("Enable", bEnableSound); sound->Set("Enable", bEnableSound);
Expand Down
2 changes: 1 addition & 1 deletion Core/Config.h
Expand Up @@ -94,7 +94,7 @@ struct Config {
bool bDisableStencilTest; bool bDisableStencilTest;
bool bAlwaysDepthWrite; bool bAlwaysDepthWrite;
bool bLowQualitySplineBezier; bool bLowQualitySplineBezier;
bool bFXAA; std::string sPostShaderName; // Off for off.


// Sound // Sound
bool bEnableSound; bool bEnableSound;
Expand Down
109 changes: 109 additions & 0 deletions GPU/Common/PostShader.cpp
@@ -0,0 +1,109 @@
// Copyright (c) 2013- PPSSPP Project.

// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0 or later versions.

// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details.

// A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/

// Official git repository and contact information can be found at
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.


// Postprocessing shader manager

#include <string>
#include <vector>

#include "base/logging.h"
#include "file/ini_file.h"
#include "file/file_util.h"
#include "file/vfs.h"

#include "GPU/Common/PostShader.h"

static std::vector<ShaderInfo> shaderInfo;

// Scans the directories for shader ini files and collects info about all the shaders found.
// Additionally, scan the VFS assets. (TODO)

void LoadPostShaderInfo(std::vector<std::string> directories) {
shaderInfo.clear();
ShaderInfo off;
off.name = "Off";
off.section = "Off";
shaderInfo.push_back(off);

for (size_t d = 0; d < directories.size(); d++) {
std::vector<FileInfo> fileInfo;
getFilesInDir(directories[d].c_str(), &fileInfo, "ini:");
if (fileInfo.size() == 0) {
// TODO: Really gotta fix the filter, now it's gonna open shaders as ini files..
VFSGetFileListing(directories[d].c_str(), &fileInfo, "ini:");
}

for (size_t f = 0; f < fileInfo.size(); f++) {
IniFile ini;
bool success = false;
std::string name = fileInfo[f].fullName;
std::string path = directories[d];
// Hack around Android VFS path bug. really need to redesign this.
if (name.substr(0, 7) == "assets/")
name = name.substr(7);
if (path.substr(0, 7) == "assets/")
path = path.substr(7);
if (!ini.LoadFromVFS(name)) {
// vsh load. meh.
} else {
success = true;
}
if (!success)
continue;

// Alright, let's loop through the sections and see if any is a shader.
// Ignore the first section (which only consists of the comments before the first real one).
for (size_t i = 1; i < ini.Sections().size(); i++) {
IniFile::Section &section = ini.Sections()[i];

This comment has been minimized.

Copy link
@thedax

thedax Oct 12, 2013

Collaborator

This seems to break Windows compilation, at least for me, in 2010 mode:

Error   9   error C2440: 'initializing' : cannot convert from 'const IniFile::Section' to 'IniFile::Section &'  \GPU\Common\PostShader.cpp  71  1   GPU

Edit: 2013 doesn't like it either.

This comment has been minimized.

Copy link
@hrydgard

hrydgard Oct 12, 2013

Author Owner

Hm, did you update native?

This comment has been minimized.

Copy link
@thedax

thedax Oct 12, 2013

Collaborator

That fixed it. Sorry for the false alarm.

if (section.Exists("Fragment") && section.Exists("Vertex")) {
// Valid shader!
ShaderInfo info;
std::string temp;
info.section = section.name();
section.Get("Name", &info.name, section.name().c_str());
section.Get("Fragment", &temp, "");
info.fragmentShaderFile = path + "/" + temp;
section.Get("Vertex", &temp, "");
info.vertexShaderFile = path + "/" + temp;
shaderInfo.push_back(info);
}
}
}
}
}

// Scans the directories for shader ini files and collects info about all the shaders found.
void LoadAllPostShaderInfo() {
std::vector<std::string> directories;
directories.push_back("assets/shaders");
LoadPostShaderInfo(directories);
}

const ShaderInfo *GetPostShaderInfo(std::string name) {
LoadAllPostShaderInfo();
for (size_t i = 0; i < shaderInfo.size(); i++) {
if (shaderInfo[i].section == name)
return &shaderInfo[i];
}
return 0;
}

const std::vector<ShaderInfo> &GetAllPostShaderInfo() {
LoadAllPostShaderInfo();
return shaderInfo;
}
41 changes: 41 additions & 0 deletions GPU/Common/PostShader.h
@@ -0,0 +1,41 @@
// Copyright (c) 2013- PPSSPP Project.

// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0 or later versions.

// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details.

// A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/

// Official git repository and contact information can be found at
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.


// Postprocessing shader manager
// For FXAA, "Natural", bloom, B&W, cross processing and whatnot.

#include <string>
#include <vector>

#include "file/ini_file.h"

struct ShaderInfo {
std::string iniFile; // which ini file was this definition in? So we can write settings back later
std::string section; // ini file section. This is saved.
std::string name; // Fancy display name. TODO: Not using yet.

std::string fragmentShaderFile;
std::string vertexShaderFile;

// TODO: Add support for all kinds of fun options like mapping the depth buffer,
// SRGB texture reads, multiple shaders chained, etc.
};

const ShaderInfo *GetPostShaderInfo(std::string name);

const std::vector<ShaderInfo> &GetAllPostShaderInfo();
45 changes: 27 additions & 18 deletions GPU/GLES/Framebuffer.cpp
Expand Up @@ -29,6 +29,7 @@
#include "GPU/ge_constants.h" #include "GPU/ge_constants.h"
#include "GPU/GPUState.h" #include "GPU/GPUState.h"


#include "GPU/Common/PostShader.h"
#include "GPU/GLES/Framebuffer.h" #include "GPU/GLES/Framebuffer.h"
#include "GPU/GLES/TextureCache.h" #include "GPU/GLES/TextureCache.h"
#include "GPU/GLES/ShaderManager.h" #include "GPU/GLES/ShaderManager.h"
Expand Down Expand Up @@ -172,23 +173,31 @@ void FramebufferManager::CompileDraw2DProgram() {
glUniform1i(draw2dprogram_->sampler0, 0); glUniform1i(draw2dprogram_->sampler0, 0);


SetNumExtraFBOs(0); SetNumExtraFBOs(0);
if (g_Config.bFXAA) {
useFXAA_ = true; const ShaderInfo *shaderInfo = 0;
fxaaProgram_ = glsl_create("shaders/fxaa.vsh", "shaders/fxaa.fsh"); if (g_Config.sPostShaderName != "Off") {
if (!fxaaProgram_) { shaderInfo = GetPostShaderInfo(g_Config.sPostShaderName);
ERROR_LOG(G3D, "Failed to build FXAA program"); }
useFXAA_ = false;
if (shaderInfo) {
postShaderProgram_ = glsl_create(shaderInfo->vertexShaderFile.c_str(), shaderInfo->fragmentShaderFile.c_str());
if (!postShaderProgram_) {
ERROR_LOG(G3D, "Failed to build post-processing program");
usePostShader_ = false;
} else { } else {
glsl_bind(fxaaProgram_); glsl_bind(postShaderProgram_);
glUniform1i(fxaaProgram_->sampler0, 0); glUniform1i(postShaderProgram_->sampler0, 0);
SetNumExtraFBOs(1); SetNumExtraFBOs(1);
float u_delta = 1.0f / PSP_CoreParameter().renderWidth; float u_delta = 1.0f / PSP_CoreParameter().renderWidth;
float v_delta = 1.0f / PSP_CoreParameter().renderHeight; float v_delta = 1.0f / PSP_CoreParameter().renderHeight;
glUniform2f(glsl_uniform_loc(fxaaProgram_, "u_texcoordDelta"), u_delta, v_delta); int deltaLoc = glsl_uniform_loc(postShaderProgram_, "u_texcoordDelta");
if (deltaLoc != -1)
glUniform2f(deltaLoc, u_delta, v_delta);
usePostShader_ = true;
} }
} else { } else {
fxaaProgram_ = 0; postShaderProgram_ = 0;
useFXAA_ = false; usePostShader_ = false;
} }


glsl_unbind(); glsl_unbind();
Expand All @@ -200,9 +209,9 @@ void FramebufferManager::DestroyDraw2DProgram() {
glsl_destroy(draw2dprogram_); glsl_destroy(draw2dprogram_);
draw2dprogram_ = 0; draw2dprogram_ = 0;
} }
if (fxaaProgram_) { if (postShaderProgram_) {
glsl_destroy(fxaaProgram_); glsl_destroy(postShaderProgram_);
fxaaProgram_ = 0; postShaderProgram_ = 0;
} }
} }


Expand All @@ -219,10 +228,10 @@ FramebufferManager::FramebufferManager() :
drawPixelsTexFormat_(GE_FORMAT_INVALID), drawPixelsTexFormat_(GE_FORMAT_INVALID),
convBuf(0), convBuf(0),
draw2dprogram_(0), draw2dprogram_(0),
fxaaProgram_(0), postShaderProgram_(0),
textureCache_(0), textureCache_(0),
shaderManager_(0), shaderManager_(0),
useFXAA_(false) usePostShader_(false)
#ifndef USING_GLES2 #ifndef USING_GLES2
, ,
pixelBufObj_(0), pixelBufObj_(0),
Expand Down Expand Up @@ -812,15 +821,15 @@ void FramebufferManager::CopyDisplayToOutput() {
// TODO ES3: Use glInvalidateFramebuffer to discard depth/stencil data at the end of frame. // TODO ES3: Use glInvalidateFramebuffer to discard depth/stencil data at the end of frame.
// and to discard extraFBOs_ after using them. // and to discard extraFBOs_ after using them.


if (useFXAA_ && extraFBOs_.size() == 1) { if (usePostShader_ && extraFBOs_.size() == 1) {
glBindTexture(GL_TEXTURE_2D, colorTexture); glBindTexture(GL_TEXTURE_2D, colorTexture);


// An additional pass, FXAA to the extra FBO. // An additional pass, FXAA to the extra FBO.
fbo_bind_as_render_target(extraFBOs_[0]); fbo_bind_as_render_target(extraFBOs_[0]);
int fbo_w, fbo_h; int fbo_w, fbo_h;
fbo_get_dimensions(extraFBOs_[0], &fbo_w, &fbo_h); fbo_get_dimensions(extraFBOs_[0], &fbo_w, &fbo_h);
glstate.viewport.set(0, 0, fbo_w, fbo_h); glstate.viewport.set(0, 0, fbo_w, fbo_h);
DrawActiveTexture(0, 0, fbo_w, fbo_h, fbo_w, fbo_h, true, 1.0f, 1.0f, fxaaProgram_); DrawActiveTexture(0, 0, fbo_w, fbo_h, fbo_w, fbo_h, true, 1.0f, 1.0f, postShaderProgram_);


fbo_unbind(); fbo_unbind();


Expand Down
4 changes: 2 additions & 2 deletions GPU/GLES/Framebuffer.h
Expand Up @@ -216,11 +216,11 @@ class FramebufferManager {


u8 *convBuf; u8 *convBuf;
GLSLProgram *draw2dprogram_; GLSLProgram *draw2dprogram_;
GLSLProgram *fxaaProgram_; GLSLProgram *postShaderProgram_;


TextureCache *textureCache_; TextureCache *textureCache_;
ShaderManager *shaderManager_; ShaderManager *shaderManager_;
bool useFXAA_; bool usePostShader_;


// Used by antialiasing // Used by antialiasing
std::vector<FBO *> extraFBOs_; std::vector<FBO *> extraFBOs_;
Expand Down
2 changes: 2 additions & 0 deletions GPU/GPU.vcxproj
Expand Up @@ -157,6 +157,7 @@
<ClInclude Include="..\ext\xbrz\xbrz.h" /> <ClInclude Include="..\ext\xbrz\xbrz.h" />
<ClInclude Include="Common\GPUDebugInterface.h" /> <ClInclude Include="Common\GPUDebugInterface.h" />
<ClInclude Include="Common\IndexGenerator.h" /> <ClInclude Include="Common\IndexGenerator.h" />
<ClInclude Include="Common\PostShader.h" />
<ClInclude Include="Common\SplineCommon.h" /> <ClInclude Include="Common\SplineCommon.h" />
<ClInclude Include="Common\VertexDecoderCommon.h" /> <ClInclude Include="Common\VertexDecoderCommon.h" />
<ClInclude Include="Directx9\GPU_DX9.h" /> <ClInclude Include="Directx9\GPU_DX9.h" />
Expand Down Expand Up @@ -200,6 +201,7 @@
<ItemGroup> <ItemGroup>
<ClCompile Include="..\ext\xbrz\xbrz.cpp" /> <ClCompile Include="..\ext\xbrz\xbrz.cpp" />
<ClCompile Include="Common\IndexGenerator.cpp" /> <ClCompile Include="Common\IndexGenerator.cpp" />
<ClCompile Include="Common\PostShader.cpp" />
<ClCompile Include="Common\VertexDecoderCommon.cpp" /> <ClCompile Include="Common\VertexDecoderCommon.cpp" />
<ClCompile Include="Directx9\GPU_DX9.cpp" /> <ClCompile Include="Directx9\GPU_DX9.cpp" />
<ClCompile Include="Directx9\helper\dx_state.cpp" /> <ClCompile Include="Directx9\helper\dx_state.cpp" />
Expand Down
2 changes: 2 additions & 0 deletions GPU/GPU.vcxproj.filters
Expand Up @@ -147,6 +147,7 @@
<ClInclude Include="Common\SplineCommon.h"> <ClInclude Include="Common\SplineCommon.h">
<Filter>Common</Filter> <Filter>Common</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="Common\PostShader.h" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="Math3D.cpp"> <ClCompile Include="Math3D.cpp">
Expand Down Expand Up @@ -266,6 +267,7 @@
<ClCompile Include="Common\TextureDecoder.cpp"> <ClCompile Include="Common\TextureDecoder.cpp">
<Filter>Common</Filter> <Filter>Common</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="Common\PostShader.cpp" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="CMakeLists.txt" /> <None Include="CMakeLists.txt" />
Expand Down
21 changes: 19 additions & 2 deletions UI/GameSettingsScreen.cpp
Expand Up @@ -138,9 +138,12 @@ void GameSettingsScreen::CreateViews() {
graphicsSettings->Add(new CheckBox(&g_Config.bVSync, gs->T("VSync"))); graphicsSettings->Add(new CheckBox(&g_Config.bVSync, gs->T("VSync")));
graphicsSettings->Add(new CheckBox(&g_Config.bFullScreen, gs->T("FullScreen"))); graphicsSettings->Add(new CheckBox(&g_Config.bFullScreen, gs->T("FullScreen")));
#endif #endif
graphicsSettings->Add(new ItemHeader(gs->T("Antialiasing")));
graphicsSettings->Add(new ItemHeader(gs->T("Antialiasing and postprocessing")));
graphicsSettings->Add(new Choice(gs->T("Postprocessing shader")))->OnClick.Handle(this, &GameSettingsScreen::OnPostProcShader);

// In case we're going to add few other antialiasing option like MSAA in the future. // In case we're going to add few other antialiasing option like MSAA in the future.
graphicsSettings->Add(new CheckBox(&g_Config.bFXAA, gs->T("FXAA"))); // graphicsSettings->Add(new CheckBox(&g_Config.bFXAA, gs->T("FXAA")));
graphicsSettings->Add(new ItemHeader(gs->T("Overlay Information"))); graphicsSettings->Add(new ItemHeader(gs->T("Overlay Information")));
graphicsSettings->Add(new PopupMultiChoice(&g_Config.iShowFPSCounter, gs->T("Show FPS Counter"), fpsChoices, 0, ARRAY_SIZE(fpsChoices), gs, screenManager())); graphicsSettings->Add(new PopupMultiChoice(&g_Config.iShowFPSCounter, gs->T("Show FPS Counter"), fpsChoices, 0, ARRAY_SIZE(fpsChoices), gs, screenManager()));
graphicsSettings->Add(new CheckBox(&g_Config.bShowDebugStats, gs->T("Show Debug Statistics"))); graphicsSettings->Add(new CheckBox(&g_Config.bShowDebugStats, gs->T("Show Debug Statistics")));
Expand Down Expand Up @@ -443,6 +446,20 @@ UI::EventReturn GameSettingsScreen::OnLanguageChange(UI::EventParams &e) {
return UI::EVENT_DONE; return UI::EVENT_DONE;
} }


UI::EventReturn GameSettingsScreen::OnPostProcShader(UI::EventParams &e) {
I18NCategory *g = GetI18NCategory("Graphics");
auto procScreen = new PostProcScreen(g->T("Postprocessing Shader"));
procScreen->OnChoice.Handle(this, &GameSettingsScreen::OnPostProcShaderChange);
screenManager()->push(procScreen);
return UI::EVENT_DONE;
}

UI::EventReturn GameSettingsScreen::OnPostProcShaderChange(UI::EventParams &e) {
if (gpu) {
gpu->Resized();
}
return UI::EVENT_DONE;
}
UI::EventReturn GameSettingsScreen::OnDeveloperTools(UI::EventParams &e) { UI::EventReturn GameSettingsScreen::OnDeveloperTools(UI::EventParams &e) {
screenManager()->push(new DeveloperToolsScreen()); screenManager()->push(new DeveloperToolsScreen());
return UI::EVENT_DONE; return UI::EVENT_DONE;
Expand Down
2 changes: 2 additions & 0 deletions UI/GameSettingsScreen.h
Expand Up @@ -56,6 +56,8 @@ class GameSettingsScreen : public UIDialogScreenWithBackground {
// Global settings handlers // Global settings handlers
UI::EventReturn OnLanguage(UI::EventParams &e); UI::EventReturn OnLanguage(UI::EventParams &e);
UI::EventReturn OnLanguageChange(UI::EventParams &e); UI::EventReturn OnLanguageChange(UI::EventParams &e);
UI::EventReturn OnPostProcShader(UI::EventParams &e);
UI::EventReturn OnPostProcShaderChange(UI::EventParams &e);
UI::EventReturn OnFactoryReset(UI::EventParams &e); UI::EventReturn OnFactoryReset(UI::EventParams &e);
UI::EventReturn OnDeveloperTools(UI::EventParams &e); UI::EventReturn OnDeveloperTools(UI::EventParams &e);
UI::EventReturn OnChangeNickname(UI::EventParams &e); UI::EventReturn OnChangeNickname(UI::EventParams &e);
Expand Down

0 comments on commit e0b19de

Please sign in to comment.