From 5ff75f4ca805d3b72e7934f58f6199b5c1173582 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sat, 1 Aug 2020 21:26:41 -0700 Subject: [PATCH] UI: Add setting for texture upload shader. --- Core/Config.cpp | 1 + Core/Config.h | 1 + GPU/Common/PostShader.cpp | 47 ++++++++++++++++++++++++++++++++---- GPU/Common/PostShader.h | 18 ++++++++++++++ UI/GameSettingsScreen.cpp | 50 ++++++++++++++++++++++++++++++++++++--- UI/GameSettingsScreen.h | 2 ++ UI/MiscScreens.cpp | 20 ++++++++++++++++ UI/MiscScreens.h | 11 +++++++++ 8 files changed, 143 insertions(+), 7 deletions(-) diff --git a/Core/Config.cpp b/Core/Config.cpp index 0a4ada08f4..2a696abaf4 100644 --- a/Core/Config.cpp +++ b/Core/Config.cpp @@ -798,6 +798,7 @@ static ConfigSetting graphicsSettings[] = { ReportedConfigSetting("SplineBezierQuality", &g_Config.iSplineBezierQuality, 2, true, true), ReportedConfigSetting("HardwareTessellation", &g_Config.bHardwareTessellation, false, true, true), ReportedConfigSetting("PostShader", &g_Config.sPostShaderName, "Off", true, true), + ConfigSetting("TextureShader", &g_Config.sTextureShaderName, "Off", true, true), ReportedConfigSetting("MemBlockTransferGPU", &g_Config.bBlockTransferGPU, true, true, true), ReportedConfigSetting("DisableSlowFramebufEffects", &g_Config.bDisableSlowFramebufEffects, false, true, true), diff --git a/Core/Config.h b/Core/Config.h index 497e7eae20..d288f62305 100644 --- a/Core/Config.h +++ b/Core/Config.h @@ -209,6 +209,7 @@ public: int iSplineBezierQuality; // 0 = low , 1 = Intermediate , 2 = High bool bHardwareTessellation; std::string sPostShaderName; // Off for off. + std::string sTextureShaderName; std::map mPostShaderSetting; bool bGfxDebugOutput; bool bGfxDebugSplitSubmit; diff --git a/GPU/Common/PostShader.cpp b/GPU/Common/PostShader.cpp index c8aacbf843..5c24d48ee3 100644 --- a/GPU/Common/PostShader.cpp +++ b/GPU/Common/PostShader.cpp @@ -31,11 +31,12 @@ #include "GPU/Common/PostShader.h" static std::vector shaderInfo; +// Okay, not really "post" shaders, but related. +static std::vector textureShaderInfo; // 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 directories) { +void LoadPostShaderInfo(const std::vector &directories) { std::vector notVisible; shaderInfo.clear(); @@ -52,6 +53,12 @@ void LoadPostShaderInfo(std::vector directories) { } shaderInfo.push_back(off); + textureShaderInfo.clear(); + TextureShaderInfo textureOff{}; + textureOff.name = "Off"; + textureOff.section = "Off"; + textureShaderInfo.push_back(textureOff); + auto appendShader = [&](const ShaderInfo &info) { auto beginErase = std::remove(shaderInfo.begin(), shaderInfo.end(), info.name); if (beginErase != shaderInfo.end()) { @@ -60,12 +67,19 @@ void LoadPostShaderInfo(std::vector directories) { shaderInfo.push_back(info); }; + auto appendTextureShader = [&](const TextureShaderInfo &info) { + auto beginErase = std::remove(textureShaderInfo.begin(), textureShaderInfo.end(), info.name); + if (beginErase != textureShaderInfo.end()) { + textureShaderInfo.erase(beginErase, textureShaderInfo.end()); + } + textureShaderInfo.push_back(info); + }; + for (size_t d = 0; d < directories.size(); d++) { std::vector 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:"); } @@ -90,7 +104,10 @@ void LoadPostShaderInfo(std::vector directories) { // Alright, let's loop through the sections and see if any is a shader. for (size_t i = 0; i < ini.Sections().size(); i++) { IniFile::Section §ion = ini.Sections()[i]; - if (section.Exists("Fragment") && section.Exists("Vertex")) { + std::string shaderType; + section.Get("Type", &shaderType, "render"); + + if (section.Exists("Fragment") && section.Exists("Vertex") && strncasecmp(shaderType.c_str(), "render", shaderType.size()) == 0) { // Valid shader! ShaderInfo info; std::string temp; @@ -135,6 +152,16 @@ void LoadPostShaderInfo(std::vector directories) { } else { notVisible.push_back(info); } + } else if (section.Exists("Compute") && strncasecmp(shaderType.c_str(), "texture", shaderType.size()) == 0) { + // This is a texture shader. + TextureShaderInfo info; + std::string temp; + info.section = section.name(); + section.Get("Name", &info.name, section.name().c_str()); + section.Get("Compute", &temp, ""); + info.computeShaderFile = path + "/" + temp; + + appendTextureShader(info); } } } @@ -189,3 +216,15 @@ std::vector GetPostShaderChain(const std::string &name) { const std::vector &GetAllPostShaderInfo() { return shaderInfo; } + +const TextureShaderInfo *GetTextureShaderInfo(const std::string &name) { + for (auto &info : textureShaderInfo) { + if (info.section == name) { + return &info; + } + } + return nullptr; +} +const std::vector &GetAllTextureShaderInfo() { + return textureShaderInfo; +} diff --git a/GPU/Common/PostShader.h b/GPU/Common/PostShader.h index 86fd7b77da..4f01d728f9 100644 --- a/GPU/Common/PostShader.h +++ b/GPU/Common/PostShader.h @@ -64,8 +64,26 @@ struct ShaderInfo { } }; +struct TextureShaderInfo { + std::string iniFile; + std::string section; + std::string name; + + std::string computeShaderFile; + + bool operator == (const std::string &other) { + return name == other; + } + bool operator == (const TextureShaderInfo &other) { + return name == other.name; + } +}; + void ReloadAllPostShaderInfo(); const ShaderInfo *GetPostShaderInfo(const std::string &name); std::vector GetPostShaderChain(const std::string &name); const std::vector &GetAllPostShaderInfo(); + +const TextureShaderInfo *GetTextureShaderInfo(const std::string &name); +const std::vector &GetAllTextureShaderInfo(); diff --git a/UI/GameSettingsScreen.cpp b/UI/GameSettingsScreen.cpp index a9ae9f891f..d3846ba413 100644 --- a/UI/GameSettingsScreen.cpp +++ b/UI/GameSettingsScreen.cpp @@ -112,6 +112,21 @@ bool DoesBackendSupportHWTess() { } } +static bool UsingHardwareTextureScaling() { + // For now, Vulkan only. + return g_Config.bTexHardwareScaling && GetGPUBackend() == GPUBackend::VULKAN && !g_Config.bSoftwareRendering; +} + +static std::string TextureTranslateName(const char *value) { + auto ps = GetI18NCategory("TextureShaders"); + const TextureShaderInfo *info = GetTextureShaderInfo(value); + if (info) { + return ps->T(value, info ? info->name.c_str() : value); + } else { + return value; + } +} + static std::string PostShaderTranslateName(const char *value) { auto ps = GetI18NCategory("PostShaders"); const ShaderInfo *info = GetPostShaderInfo(value); @@ -450,7 +465,7 @@ void GameSettingsScreen::CreateViews() { texScalingChoice->HideChoice(5); // 5x } texScalingChoice->OnChoice.Add([=](EventParams &e) { - if (g_Config.iTexScalingLevel != 1) { + if (g_Config.iTexScalingLevel != 1 && !UsingHardwareTextureScaling()) { settingInfo_->Show(gr->T("UpscaleLevel Tip", "CPU heavy - some scaling may be delayed to avoid stutter"), e.v); } return UI::EVENT_CONTINUE; @@ -459,7 +474,9 @@ void GameSettingsScreen::CreateViews() { static const char *texScaleAlgos[] = { "xBRZ", "Hybrid", "Bicubic", "Hybrid + Bicubic", }; PopupMultiChoice *texScalingType = graphicsSettings->Add(new PopupMultiChoice(&g_Config.iTexScalingType, gr->T("Upscale Type"), texScaleAlgos, 0, ARRAY_SIZE(texScaleAlgos), gr->GetName(), screenManager())); - texScalingType->SetDisabledPtr(&g_Config.bSoftwareRendering); + texScalingType->SetEnabledFunc([]() { + return !g_Config.bSoftwareRendering && !UsingHardwareTextureScaling(); + }); CheckBox *deposterize = graphicsSettings->Add(new CheckBox(&g_Config.bTexDeposterize, gr->T("Deposterize"))); deposterize->OnClick.Add([=](EventParams &e) { @@ -468,7 +485,18 @@ void GameSettingsScreen::CreateViews() { } return UI::EVENT_CONTINUE; }); - deposterize->SetDisabledPtr(&g_Config.bSoftwareRendering); + deposterize->SetEnabledFunc([]() { + return !g_Config.bSoftwareRendering && !UsingHardwareTextureScaling(); + }); + + CheckBox *texHardwareScaling = graphicsSettings->Add(new CheckBox(&g_Config.bTexHardwareScaling, gr->T("Hardware texture scaling"))); + texHardwareScaling->SetEnabledFunc([]() { + return GetGPUBackend() == GPUBackend::VULKAN && !g_Config.bSoftwareRendering; + }); + + ChoiceWithValueDisplay *textureShaderChoice = graphicsSettings->Add(new ChoiceWithValueDisplay(&g_Config.sTextureShaderName, gr->T("Texture Shader"), &TextureTranslateName)); + textureShaderChoice->OnClick.Handle(this, &GameSettingsScreen::OnTextureShader); + textureShaderChoice->SetEnabledFunc(UsingHardwareTextureScaling); graphicsSettings->Add(new ItemHeader(gr->T("Texture Filtering"))); static const char *anisoLevels[] = { "Off", "2x", "4x", "8x", "16x" }; @@ -1460,6 +1488,22 @@ UI::EventReturn GameSettingsScreen::OnPostProcShaderChange(UI::EventParams &e) { return UI::EVENT_DONE; } +UI::EventReturn GameSettingsScreen::OnTextureShader(UI::EventParams &e) { + auto gr = GetI18NCategory("Graphics"); + auto shaderScreen = new TextureShaderScreen(gr->T("Texture Shader")); + shaderScreen->OnChoice.Handle(this, &GameSettingsScreen::OnTextureShaderChange); + if (e.v) + shaderScreen->SetPopupOrigin(e.v); + screenManager()->push(shaderScreen); + return UI::EVENT_DONE; +} + +UI::EventReturn GameSettingsScreen::OnTextureShaderChange(UI::EventParams &e) { + NativeMessageReceived("gpu_resized", ""); + RecreateViews(); // Update setting name + return UI::EVENT_DONE; +} + UI::EventReturn GameSettingsScreen::OnDeveloperTools(UI::EventParams &e) { screenManager()->push(new DeveloperToolsScreen()); return UI::EVENT_DONE; diff --git a/UI/GameSettingsScreen.h b/UI/GameSettingsScreen.h index f2f27bc206..3b0859e0d0 100644 --- a/UI/GameSettingsScreen.h +++ b/UI/GameSettingsScreen.h @@ -82,6 +82,8 @@ private: UI::EventReturn OnAutoFrameskip(UI::EventParams &e); UI::EventReturn OnPostProcShader(UI::EventParams &e); UI::EventReturn OnPostProcShaderChange(UI::EventParams &e); + UI::EventReturn OnTextureShader(UI::EventParams &e); + UI::EventReturn OnTextureShaderChange(UI::EventParams &e); UI::EventReturn OnDeveloperTools(UI::EventParams &e); UI::EventReturn OnRemoteISO(UI::EventParams &e); UI::EventReturn OnChangeQuickChat0(UI::EventParams &e); diff --git a/UI/MiscScreens.cpp b/UI/MiscScreens.cpp index a6542c65d0..e88e244829 100644 --- a/UI/MiscScreens.cpp +++ b/UI/MiscScreens.cpp @@ -321,6 +321,26 @@ void PostProcScreen::OnCompleted(DialogResult result) { g_Config.sPostShaderName = shaders_[listView_->GetSelected()].section; } +TextureShaderScreen::TextureShaderScreen(const std::string &title) : ListPopupScreen(title) { + auto ps = GetI18NCategory("TextureShaders"); + ReloadAllPostShaderInfo(); + shaders_ = GetAllTextureShaderInfo(); + std::vector items; + int selected = -1; + for (int i = 0; i < (int)shaders_.size(); i++) { + if (shaders_[i].section == g_Config.sTextureShaderName) + selected = i; + items.push_back(ps->T(shaders_[i].section.c_str(), shaders_[i].name.c_str())); + } + adaptor_ = UI::StringVectorListAdaptor(items, selected); +} + +void TextureShaderScreen::OnCompleted(DialogResult result) { + if (result != DR_OK) + return; + g_Config.sTextureShaderName = shaders_[listView_->GetSelected()].section; +} + NewLanguageScreen::NewLanguageScreen(const std::string &title) : ListPopupScreen(title) { // Disable annoying encoding warning #ifdef _MSC_VER diff --git a/UI/MiscScreens.h b/UI/MiscScreens.h index 459974de48..b1c5881bc4 100644 --- a/UI/MiscScreens.h +++ b/UI/MiscScreens.h @@ -26,6 +26,7 @@ #include "ui/ui_screen.h" struct ShaderInfo; +struct TextureShaderInfo; extern std::string boot_filename; void UIBackgroundInit(UIContext &dc); @@ -112,6 +113,16 @@ private: std::vector shaders_; }; +class TextureShaderScreen : public ListPopupScreen { +public: + TextureShaderScreen(const std::string &title); + +private: + void OnCompleted(DialogResult result) override; + bool ShowButtons() const override { return true; } + std::vector shaders_; +}; + class LogoScreen : public UIScreen { public: LogoScreen(bool gotoGameSettings = false)