From ec2410222c248365e6d3ab74ead6156880fc3f9f Mon Sep 17 00:00:00 2001 From: Samuliak Date: Thu, 16 Jan 2025 18:31:09 +0100 Subject: [PATCH] support metal shaders in graphics packs --- src/Cafe/GraphicPack/GraphicPack2.cpp | 21 ++++++++++++------- src/Cafe/GraphicPack/GraphicPack2.h | 29 +++++++++++++------------- src/Cafe/HW/Latte/Core/LatteShader.cpp | 2 +- 3 files changed, 30 insertions(+), 22 deletions(-) diff --git a/src/Cafe/GraphicPack/GraphicPack2.cpp b/src/Cafe/GraphicPack/GraphicPack2.cpp index edb4c9e1..f2e6d487 100644 --- a/src/Cafe/GraphicPack/GraphicPack2.cpp +++ b/src/Cafe/GraphicPack/GraphicPack2.cpp @@ -428,7 +428,7 @@ GraphicPack2::GraphicPack2(fs::path rulesPath, IniParser& rules) for (const auto& presetEntry : m_presets) { tmp_map[presetEntry->category].emplace_back(presetEntry); - + for (auto& presetVar : presetEntry->variables) { const auto it = m_preset_vars.find(presetVar.first); @@ -683,12 +683,15 @@ void GraphicPack2::LoadShaders() wchar_t shader_type[256]{}; if (filename.size() < 256 && swscanf(filename.c_str(), L"%" SCNx64 "_%" SCNx64 "_%ls", &shader_base_hash, &shader_aux_hash, shader_type) == 3) { + bool isMetalShader = (shader_type[2] == '_' && shader_type[3] == 'm' && shader_type[4] == 's' && shader_type[5] == 'l'); + printf("IS METAL SHADER: %u\n", isMetalShader); + if (shader_type[0] == 'p' && shader_type[1] == 's') - m_custom_shaders.emplace_back(LoadShader(p, shader_base_hash, shader_aux_hash, GP_SHADER_TYPE::PIXEL)); + m_custom_shaders.emplace_back(LoadShader(p, shader_base_hash, shader_aux_hash, GP_SHADER_TYPE::PIXEL, isMetalShader)); else if (shader_type[0] == 'v' && shader_type[1] == 's') - m_custom_shaders.emplace_back(LoadShader(p, shader_base_hash, shader_aux_hash, GP_SHADER_TYPE::VERTEX)); + m_custom_shaders.emplace_back(LoadShader(p, shader_base_hash, shader_aux_hash, GP_SHADER_TYPE::VERTEX, isMetalShader)); else if (shader_type[0] == 'g' && shader_type[1] == 's') - m_custom_shaders.emplace_back(LoadShader(p, shader_base_hash, shader_aux_hash, GP_SHADER_TYPE::GEOMETRY)); + m_custom_shaders.emplace_back(LoadShader(p, shader_base_hash, shader_aux_hash, GP_SHADER_TYPE::GEOMETRY, isMetalShader)); } else if (filename == L"output.glsl") { @@ -1047,7 +1050,7 @@ bool GraphicPack2::Deactivate() return true; } -const std::string* GraphicPack2::FindCustomShaderSource(uint64 shaderBaseHash, uint64 shaderAuxHash, GP_SHADER_TYPE type, bool isVulkanRenderer) +const std::string* GraphicPack2::FindCustomShaderSource(uint64 shaderBaseHash, uint64 shaderAuxHash, GP_SHADER_TYPE type, bool isVulkanRenderer, bool isMetalRenderer) { for (const auto& gp : GraphicPack2::GetActiveGraphicPacks()) { @@ -1057,9 +1060,12 @@ const std::string* GraphicPack2::FindCustomShaderSource(uint64 shaderBaseHash, u if (it == gp->m_custom_shaders.end()) continue; - if(isVulkanRenderer && (*it).isPreVulkanShader) + if (isVulkanRenderer && (*it).isPreVulkanShader) continue; + if (isMetalRenderer != (*it).isMetalShader) + continue; + return &it->source; } return nullptr; @@ -1217,7 +1223,7 @@ void GraphicPack2::ApplyShaderPresets(std::string& shader_source) const } } -GraphicPack2::CustomShader GraphicPack2::LoadShader(const fs::path& path, uint64 shader_base_hash, uint64 shader_aux_hash, GP_SHADER_TYPE shader_type) const +GraphicPack2::CustomShader GraphicPack2::LoadShader(const fs::path& path, uint64 shader_base_hash, uint64 shader_aux_hash, GP_SHADER_TYPE shader_type, bool isMetalShader) const { CustomShader shader; @@ -1236,6 +1242,7 @@ GraphicPack2::CustomShader GraphicPack2::LoadShader(const fs::path& path, uint64 shader.shader_aux_hash = shader_aux_hash; shader.type = shader_type; shader.isPreVulkanShader = this->m_version <= 3; + shader.isMetalShader = isMetalShader; return shader; } diff --git a/src/Cafe/GraphicPack/GraphicPack2.h b/src/Cafe/GraphicPack/GraphicPack2.h index 9b6a86d4..5fca2f44 100644 --- a/src/Cafe/GraphicPack/GraphicPack2.h +++ b/src/Cafe/GraphicPack/GraphicPack2.h @@ -57,7 +57,7 @@ public: sint32 lod_bias = -1; // in 1/64th steps sint32 relative_lod_bias = -1; // in 1/64th steps sint32 anistropic_value = -1; // 1< vars) : name(name), variables(std::move(vars)) {} Preset(std::string_view category, std::string_view name, std::unordered_map vars) : category(category), name(name), variables(std::move(vars)) {} - + Preset(std::string_view category, std::string_view name, std::string_view condition, std::unordered_map vars) : category(category), name(name), condition(condition), variables(std::move(vars)) {} }; @@ -136,19 +137,19 @@ public: bool SetActivePreset(std::string_view category, std::string_view name, bool update_visibility = true); bool SetActivePreset(std::string_view name); void UpdatePresetVisibility(); - + void AddConstantsForCurrentPreset(ExpressionParser& ep); bool ResolvePresetConstant(const std::string& varname, double& value) const; [[nodiscard]] const std::vector& GetPresets() const { return m_presets; } [[nodiscard]] std::unordered_map> GetCategorizedPresets(std::vector& order) const; - + // shaders void LoadShaders(); bool HasShaders() const; const std::vector& GetCustomShaders() const { return m_custom_shaders; } - static const std::string* FindCustomShaderSource(uint64 shaderBaseHash, uint64 shaderAuxHash, GP_SHADER_TYPE type, bool isVulkanRenderer); + static const std::string* FindCustomShaderSource(uint64 shaderBaseHash, uint64 shaderAuxHash, GP_SHADER_TYPE type, bool isVulkanRenderer, bool isMetalRenderer); const std::string& GetOutputShaderSource() const { return m_output_shader_source; } const std::string& GetDownscalingShaderSource() const { return m_downscaling_shader_source; } @@ -194,7 +195,7 @@ private: { for (auto& var : preset->variables) parser.AddConstant(var.first, (TType)var.second.second); - } + } } for(const auto& preset : active_presets) { @@ -202,7 +203,7 @@ private: { for (auto& var : preset->variables) parser.TryAddConstant(var.first, (TType)var.second.second); - } + } } for (auto& var : m_preset_vars) @@ -228,7 +229,7 @@ private: bool m_activated = false; // set if the graphic pack is currently used by the running game std::vector m_title_ids; bool m_patchedFilesLoaded = false; // set to true once patched files are loaded - + sint32 m_vsync_frequency = -1; sint32 m_fs_priority = 100; @@ -241,12 +242,12 @@ private: std::vector m_presets; // default preset vars std::unordered_map m_preset_vars; - + std::vector m_custom_shaders; std::vector m_texture_rules; std::string m_output_shader_source, m_upscaling_shader_source, m_downscaling_shader_source; std::unique_ptr m_output_shader, m_upscaling_shader, m_downscaling_shader, m_output_shader_ud, m_upscaling_shader_ud, m_downscaling_shader_ud; - + template bool ParseRule(const ExpressionParser& parser, IniParser& iniParser, const char* option_name, T* value_out) const; @@ -257,7 +258,7 @@ private: std::vector ParseTitleIds(IniParser& rules, const char* option_name) const; - CustomShader LoadShader(const fs::path& path, uint64 shader_base_hash, uint64 shader_aux_hash, GP_SHADER_TYPE shader_type) const; + CustomShader LoadShader(const fs::path& path, uint64 shader_base_hash, uint64 shader_aux_hash, GP_SHADER_TYPE shader_type, bool isMetalShader) const; void ApplyShaderPresets(std::string& shader_source) const; void LoadReplacedFiles(); void _iterateReplacedFiles(const fs::path& currentPath, bool isAOC); @@ -330,6 +331,6 @@ std::vector GraphicPack2::ParseList(const ExpressionParser& parser, IniParser } catch (const std::invalid_argument&) {} } - + return result; -} \ No newline at end of file +} diff --git a/src/Cafe/HW/Latte/Core/LatteShader.cpp b/src/Cafe/HW/Latte/Core/LatteShader.cpp index 7ad25884..0ad42da6 100644 --- a/src/Cafe/HW/Latte/Core/LatteShader.cpp +++ b/src/Cafe/HW/Latte/Core/LatteShader.cpp @@ -339,7 +339,7 @@ void LatteShader_CreateRendererShader(LatteDecompilerShader* shader, bool compil // check if a custom shader is present std::string shaderSrc; - const std::string* customShaderSrc = GraphicPack2::FindCustomShaderSource(shader->baseHash, shader->auxHash, gpShaderType, g_renderer->GetType() == RendererAPI::Vulkan); + const std::string* customShaderSrc = GraphicPack2::FindCustomShaderSource(shader->baseHash, shader->auxHash, gpShaderType, g_renderer->GetType() == RendererAPI::Vulkan, g_renderer->GetType() == RendererAPI::Metal); if (customShaderSrc) { shaderSrc.assign(*customShaderSrc);