// 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 #include #include #include "file/ini_file.h" #include "file/file_util.h" #include "file/vfs.h" #include "gfx_es2/gpu_features.h" #include "Core/Config.h" #include "GPU/Common/PostShader.h" static std::vector 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 directories) { shaderInfo.clear(); ShaderInfo off; off.name = "Off"; off.section = "Off"; off.outputResolution = false; off.isUpscalingFilter = false; off.SSAAFilterLevel = 0; off.requires60fps = false; off.settingName1 = ""; off.settingValue1 = 0.0f; off.minSettingValue1 = -1.0f; off.maxSettingValue1 = 1.0f; off.settingStep1 = 0.01f; off.settingName2 = ""; off.settingValue2 = 0.0f; off.minSettingValue2 = -1.0f; off.maxSettingValue2 = 1.0f; off.settingStep2 = 0.01f; off.settingName3 = ""; off.settingValue3 = 0.0f; off.minSettingValue3 = -1.0f; off.maxSettingValue3 = 1.0f; off.settingStep3 = 0.01f; off.settingName4 = ""; off.settingValue4 = 0.0f; off.minSettingValue4 = -1.0f; off.maxSettingValue4 = 1.0f; off.settingStep4 = 0.01f; shaderInfo.push_back(off); 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:"); } 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) || ini.Load(fileInfo[f].fullName)) { success = true; // vsh load. meh. } if (!success) continue; // 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")) { // 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; section.Get("OutputResolution", &info.outputResolution, false); section.Get("Upscaling", &info.isUpscalingFilter, false); section.Get("SSAA", &info.SSAAFilterLevel, 0); section.Get("60fps", &info.requires60fps, false); section.Get("SettingName1", &info.settingName1, ""); section.Get("SettingDefaultValue1", &info.settingValue1, 0.0f); section.Get("SettingMinValue1", &info.minSettingValue1, -1.0f); section.Get("SettingMaxValue1", &info.maxSettingValue1, 1.0f); section.Get("SettingStep1", &info.settingStep1, 0.01f); section.Get("SettingName2", &info.settingName2, ""); section.Get("SettingDefaultValue2", &info.settingValue2, 0.0f); section.Get("SettingMinValue2", &info.minSettingValue2, -1.0f); section.Get("SettingMaxValue2", &info.maxSettingValue2, 1.0f); section.Get("SettingStep2", &info.settingStep2, 0.01f); section.Get("SettingName3", &info.settingName3, ""); section.Get("SettingDefaultValue3", &info.settingValue3, 0.0f); section.Get("SettingMinValue3", &info.minSettingValue3, -1.0f); section.Get("SettingMaxValue3", &info.maxSettingValue3, 1.0f); section.Get("SettingStep3", &info.settingStep3, 0.01f); section.Get("SettingName4", &info.settingName4, ""); section.Get("SettingDefaultValue4", &info.settingValue4, 0.0f); section.Get("SettingMinValue4", &info.minSettingValue4, -1.0f); section.Get("SettingMaxValue4", &info.maxSettingValue4, 1.0f); section.Get("SettingStep4", &info.settingStep4, 0.01f); if (g_Config.mPostShaderSetting.find(info.section + "SettingValue1") == g_Config.mPostShaderSetting.end()) g_Config.mPostShaderSetting.insert(std::pair(info.section + "SettingValue1", info.settingValue1)); if (g_Config.mPostShaderSetting.find(info.section + "SettingValue2") == g_Config.mPostShaderSetting.end()) g_Config.mPostShaderSetting.insert(std::pair(info.section + "SettingValue2", info.settingValue2)); if (g_Config.mPostShaderSetting.find(info.section + "SettingValue3") == g_Config.mPostShaderSetting.end()) g_Config.mPostShaderSetting.insert(std::pair(info.section + "SettingValue3", info.settingValue3)); if (g_Config.mPostShaderSetting.find(info.section + "SettingValue4") == g_Config.mPostShaderSetting.end()) g_Config.mPostShaderSetting.insert(std::pair(info.section + "SettingValue4", info.settingValue4)); // Let's ignore shaders we can't support. TODO: Not a very good check if (gl_extensions.IsGLES && !gl_extensions.GLES3) { bool requiresIntegerSupport; section.Get("RequiresIntSupport", &requiresIntegerSupport, false); if (requiresIntegerSupport) continue; } auto beginErase = std::find(shaderInfo.begin(), shaderInfo.end(), info.name); if (beginErase != shaderInfo.end()) { shaderInfo.erase(beginErase, shaderInfo.end()); } shaderInfo.push_back(info); } } } } } // Scans the directories for shader ini files and collects info about all the shaders found. void ReloadAllPostShaderInfo() { std::vector directories; directories.push_back("shaders"); directories.push_back(g_Config.memStickDirectory + "PSP/shaders"); LoadPostShaderInfo(directories); } const ShaderInfo *GetPostShaderInfo(std::string name) { for (size_t i = 0; i < shaderInfo.size(); i++) { if (shaderInfo[i].section == name) return &shaderInfo[i]; } return nullptr; } const std::vector &GetAllPostShaderInfo() { return shaderInfo; }