GPU: Allow postshaders to have parents.

This commit is contained in:
Unknown W. Brackets 2020-05-16 00:03:39 -07:00
parent b79ecc159f
commit 477e988a68
5 changed files with 62 additions and 15 deletions

View File

@ -36,8 +36,11 @@ static std::vector<ShaderInfo> shaderInfo;
// Additionally, scan the VFS assets. (TODO)
void LoadPostShaderInfo(std::vector<std::string> directories) {
std::vector<ShaderInfo> notVisible;
shaderInfo.clear();
ShaderInfo off;
ShaderInfo off{};
off.visible = true;
off.name = "Off";
off.section = "Off";
off.outputResolution = false;
@ -66,6 +69,14 @@ void LoadPostShaderInfo(std::vector<std::string> directories) {
off.settingStep4 = 0.01f;
shaderInfo.push_back(off);
auto appendShader = [&](const ShaderInfo &info) {
auto beginErase = std::remove(shaderInfo.begin(), shaderInfo.end(), info.name);
if (beginErase != shaderInfo.end()) {
shaderInfo.erase(beginErase, shaderInfo.end());
}
shaderInfo.push_back(info);
};
for (size_t d = 0; d < directories.size(); d++) {
std::vector<FileInfo> fileInfo;
getFilesInDir(directories[d].c_str(), &fileInfo, "ini:");
@ -102,6 +113,8 @@ void LoadPostShaderInfo(std::vector<std::string> directories) {
std::string temp;
info.section = section.name();
section.Get("Name", &info.name, section.name().c_str());
section.Get("Parent", &info.parent, "");
section.Get("Visible", &info.visible, true);
section.Get("Fragment", &temp, "");
info.fragmentShaderFile = path + "/" + temp;
section.Get("Vertex", &temp, "");
@ -148,15 +161,20 @@ void LoadPostShaderInfo(std::vector<std::string> directories) {
continue;
}
auto beginErase = std::find(shaderInfo.begin(), shaderInfo.end(), info.name);
if (beginErase != shaderInfo.end()) {
shaderInfo.erase(beginErase, shaderInfo.end());
if (info.visible) {
appendShader(info);
} else {
notVisible.push_back(info);
}
shaderInfo.push_back(info);
}
}
}
}
// We always want the not visible ones at the end. Makes menus easier.
for (const auto &info : notVisible) {
appendShader(info);
}
}
// Scans the directories for shader ini files and collects info about all the shaders found.
@ -167,7 +185,7 @@ void ReloadAllPostShaderInfo() {
LoadPostShaderInfo(directories);
}
const ShaderInfo *GetPostShaderInfo(std::string name) {
const ShaderInfo *GetPostShaderInfo(const std::string &name) {
for (size_t i = 0; i < shaderInfo.size(); i++) {
if (shaderInfo[i].section == name)
return &shaderInfo[i];
@ -175,6 +193,25 @@ const ShaderInfo *GetPostShaderInfo(std::string name) {
return nullptr;
}
std::vector<const ShaderInfo *> GetPostShaderChain(const std::string &name) {
std::vector<const ShaderInfo *> backwards;
const ShaderInfo *shaderInfo = GetPostShaderInfo(name);
while (shaderInfo) {
backwards.push_back(shaderInfo);
if (!shaderInfo->parent.empty() && shaderInfo->parent != "Off") {
shaderInfo = GetPostShaderInfo(shaderInfo->parent);
} else {
shaderInfo = nullptr;
}
}
if (!backwards.empty())
std::reverse(backwards.begin(), backwards.end());
// Not backwards anymore.
return backwards;
}
const std::vector<ShaderInfo> &GetAllPostShaderInfo() {
return shaderInfo;
}

View File

@ -28,10 +28,13 @@ 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.
std::string parent; // Parent shader ini section name.
std::string fragmentShaderFile;
std::string vertexShaderFile;
// Show this shader in lists (i.e. not just for chaining.)
bool visible;
// Run at output instead of input resolution
bool outputResolution;
// Use x1 rendering res + nearest screen scaling filter
@ -63,7 +66,7 @@ struct ShaderInfo {
float settingStep4;
// TODO: Add support for all kinds of fun options like mapping the depth buffer,
// SRGB texture reads, multiple shaders chained, etc.
// SRGB texture reads, etc.
bool operator == (const std::string &other) {
return name == other;
@ -75,5 +78,6 @@ struct ShaderInfo {
void ReloadAllPostShaderInfo();
const ShaderInfo *GetPostShaderInfo(std::string name);
const ShaderInfo *GetPostShaderInfo(const std::string &name);
std::vector<const ShaderInfo *> GetPostShaderChain(const std::string &name);
const std::vector<ShaderInfo> &GetAllPostShaderInfo();

View File

@ -178,20 +178,22 @@ static std::string ReadShaderSrc(const std::string &filename) {
// Note: called on resize and settings changes.
bool PresentationCommon::UpdatePostShader() {
const ShaderInfo *shaderInfo = nullptr;
std::vector<const ShaderInfo *> shaderInfo;
if (g_Config.sPostShaderName != "Off") {
ReloadAllPostShaderInfo();
shaderInfo = GetPostShaderInfo(g_Config.sPostShaderName);
shaderInfo = GetPostShaderChain(g_Config.sPostShaderName);
}
DestroyPostShader();
if (shaderInfo == nullptr)
if (shaderInfo.empty())
return false;
bool pipeline = BuildPostShader(shaderInfo, nullptr);
if (!pipeline) {
DestroyPostShader();
return false;
for (int i = 0; i < shaderInfo.size(); ++i) {
const ShaderInfo *next = i + 1 < shaderInfo.size() ? shaderInfo[i + 1] : nullptr;
if (!BuildPostShader(shaderInfo[i], next)) {
DestroyPostShader();
return false;
}
}
usePostShader_ = true;

View File

@ -306,6 +306,8 @@ PostProcScreen::PostProcScreen(const std::string &title) : ListPopupScreen(title
std::vector<std::string> items;
int selected = -1;
for (int i = 0; i < (int)shaders_.size(); i++) {
if (!shaders_[i].visible)
continue;
if (shaders_[i].section == g_Config.sPostShaderName)
selected = i;
items.push_back(ps->T(shaders_[i].section.c_str(), shaders_[i].name.c_str()));

View File

@ -181,6 +181,8 @@ namespace MainWindow {
availableShaders.clear();
for (auto i = info.begin(); i != info.end(); ++i) {
if (!i->visible)
continue;
int checkedStatus = MF_UNCHECKED;
availableShaders.push_back(i->section);
if (g_Config.sPostShaderName == i->section) {