Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
Merge pull request #12009 from iwubcode/shader_asset
VideoCommon: add a pixel shader asset
- Loading branch information
Showing
9 changed files
with
310 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,147 @@ | ||
| // Copyright 2023 Dolphin Emulator Project | ||
| // SPDX-License-Identifier: GPL-2.0-or-later | ||
|
|
||
| #include "VideoCommon/Assets/ShaderAsset.h" | ||
|
|
||
| #include "Common/Logging/Log.h" | ||
| #include "VideoCommon/Assets/CustomAssetLibrary.h" | ||
|
|
||
| namespace VideoCommon | ||
| { | ||
| bool ParseShaderProperties(const VideoCommon::CustomAssetLibrary::AssetID& asset_id, | ||
| const picojson::array& properties_data, | ||
| std::map<std::string, VideoCommon::ShaderProperty>* shader_properties) | ||
| { | ||
| if (!shader_properties) [[unlikely]] | ||
| return false; | ||
|
|
||
| for (const auto& property_data : properties_data) | ||
| { | ||
| VideoCommon::ShaderProperty property; | ||
| if (!property_data.is<picojson::object>()) | ||
| { | ||
| ERROR_LOG_FMT(VIDEO, "Asset '{}' failed to parse json, property is not the right json type", | ||
| asset_id); | ||
| return false; | ||
| } | ||
| const auto& property_data_obj = property_data.get<picojson::object>(); | ||
|
|
||
| const auto type_iter = property_data_obj.find("type"); | ||
| if (type_iter == property_data_obj.end()) | ||
| { | ||
| ERROR_LOG_FMT(VIDEO, "Asset '{}' failed to parse json, property entry 'type' not found", | ||
| asset_id); | ||
| return false; | ||
| } | ||
| if (!type_iter->second.is<std::string>()) | ||
| { | ||
| ERROR_LOG_FMT(VIDEO, | ||
| "Asset '{}' failed to parse json, property entry 'type' is not " | ||
| "the right json type", | ||
| asset_id); | ||
| return false; | ||
| } | ||
| std::string type = type_iter->second.to_str(); | ||
| std::transform(type.begin(), type.end(), type.begin(), | ||
| [](unsigned char c) { return std::tolower(c); }); | ||
|
|
||
| if (type == "sampler2d") | ||
| { | ||
| property.m_type = ShaderProperty::Type::Type_Sampler2D; | ||
| } | ||
| else | ||
| { | ||
| ERROR_LOG_FMT(VIDEO, | ||
| "Asset '{}' failed to parse json, property entry 'description' is " | ||
| "an invalid option", | ||
| asset_id); | ||
| return false; | ||
| } | ||
|
|
||
| const auto description_iter = property_data_obj.find("description"); | ||
| if (description_iter == property_data_obj.end()) | ||
| { | ||
| ERROR_LOG_FMT(VIDEO, | ||
| "Asset '{}' failed to parse json, property entry 'description' not found", | ||
| asset_id); | ||
| return false; | ||
| } | ||
| if (!description_iter->second.is<std::string>()) | ||
| { | ||
| ERROR_LOG_FMT(VIDEO, | ||
| "Asset '{}' failed to parse json, property entry 'description' is not " | ||
| "the right json type", | ||
| asset_id); | ||
| return false; | ||
| } | ||
| property.m_description = description_iter->second.to_str(); | ||
|
|
||
| const auto code_name_iter = property_data_obj.find("code_name"); | ||
| if (code_name_iter == property_data_obj.end()) | ||
| { | ||
| ERROR_LOG_FMT(VIDEO, "Asset '{}' failed to parse json, property entry 'code_name' not found", | ||
| asset_id); | ||
| return false; | ||
| } | ||
| if (!code_name_iter->second.is<std::string>()) | ||
| { | ||
| ERROR_LOG_FMT(VIDEO, | ||
| "Asset '{}' failed to parse json, property entry 'code_name' is not " | ||
| "the right json type", | ||
| asset_id); | ||
| return false; | ||
| } | ||
| shader_properties->try_emplace(code_name_iter->second.to_str(), std::move(property)); | ||
| } | ||
|
|
||
| return true; | ||
| } | ||
|
|
||
| bool PixelShaderData::FromJson(const VideoCommon::CustomAssetLibrary::AssetID& asset_id, | ||
| const picojson::object& json, PixelShaderData* data) | ||
| { | ||
| const auto properties_iter = json.find("properties"); | ||
| if (properties_iter == json.end()) | ||
| { | ||
| ERROR_LOG_FMT(VIDEO, "Asset '{}' failed to parse json, 'properties' not found", asset_id); | ||
| return false; | ||
| } | ||
| if (!properties_iter->second.is<picojson::array>()) | ||
| { | ||
| ERROR_LOG_FMT(VIDEO, "Asset '{}' failed to parse json, 'properties' is not the right json type", | ||
| asset_id); | ||
| return false; | ||
| } | ||
| const auto& properties_array = properties_iter->second.get<picojson::array>(); | ||
| if (!ParseShaderProperties(asset_id, properties_array, &data->m_properties)) | ||
| return false; | ||
|
|
||
| for (const auto& [name, property] : data->m_properties) | ||
| { | ||
| if (data->m_shader_source.find(name) == std::string::npos) | ||
| { | ||
| ERROR_LOG_FMT( | ||
| VIDEO, | ||
| "Asset '{}' failed to parse json, the code name '{}' defined in the metadata was not " | ||
| "found in the shader source", | ||
| asset_id, name); | ||
| return false; | ||
| } | ||
| } | ||
|
|
||
| return true; | ||
| } | ||
| CustomAssetLibrary::LoadInfo PixelShaderAsset::LoadImpl(const CustomAssetLibrary::AssetID& asset_id) | ||
| { | ||
| auto potential_data = std::make_shared<PixelShaderData>(); | ||
| const auto loaded_info = m_owning_library->LoadPixelShader(asset_id, potential_data.get()); | ||
| if (loaded_info.m_bytes_loaded == 0) | ||
| return {}; | ||
| { | ||
| std::lock_guard lk(m_data_lock); | ||
| m_loaded = true; | ||
| m_data = std::move(potential_data); | ||
| } | ||
| return loaded_info; | ||
| } | ||
| } // namespace VideoCommon |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,47 @@ | ||
| // Copyright 2023 Dolphin Emulator Project | ||
| // SPDX-License-Identifier: GPL-2.0-or-later | ||
|
|
||
| #pragma once | ||
|
|
||
| #include <map> | ||
| #include <string> | ||
|
|
||
| #include <picojson.h> | ||
|
|
||
| #include "VideoCommon/Assets/CustomAsset.h" | ||
|
|
||
| namespace VideoCommon | ||
| { | ||
| struct ShaderProperty | ||
| { | ||
| enum class Type | ||
| { | ||
| Type_Undefined, | ||
| Type_Sampler2D, | ||
| Type_Max = Type_Sampler2D | ||
| }; | ||
| Type m_type; | ||
| std::string m_description; | ||
| }; | ||
| struct PixelShaderData | ||
| { | ||
| static bool FromJson(const CustomAssetLibrary::AssetID& asset_id, const picojson::object& json, | ||
| PixelShaderData* data); | ||
|
|
||
| // These shader properties describe the input that the | ||
| // shader expects to expose. The key is text | ||
| // expected to be in the shader code and the propery | ||
| // describes various details about the input | ||
| std::map<std::string, ShaderProperty> m_properties; | ||
| std::string m_shader_source; | ||
| }; | ||
|
|
||
| class PixelShaderAsset final : public CustomLoadableAsset<PixelShaderData> | ||
| { | ||
| public: | ||
| using CustomLoadableAsset::CustomLoadableAsset; | ||
|
|
||
| private: | ||
| CustomAssetLibrary::LoadInfo LoadImpl(const CustomAssetLibrary::AssetID& asset_id) override; | ||
| }; | ||
| } // namespace VideoCommon |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters