diff --git a/Source/Core/Common/CMakeLists.txt b/Source/Core/Common/CMakeLists.txt index 9f8702659b..61bc9155da 100644 --- a/Source/Core/Common/CMakeLists.txt +++ b/Source/Core/Common/CMakeLists.txt @@ -86,6 +86,7 @@ add_library(common IOFile.h JitRegister.cpp JitRegister.h + JsonUtil.h Lazy.h LinearDiskCache.h Logging/ConsoleListener.h diff --git a/Source/Core/Common/JsonUtil.h b/Source/Core/Common/JsonUtil.h new file mode 100644 index 0000000000..131eb941a8 --- /dev/null +++ b/Source/Core/Common/JsonUtil.h @@ -0,0 +1,26 @@ +// Copyright 2024 Dolphin Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include + +#include + +// Ideally this would use a concept like, 'template ' to constrain it, +// but unfortunately we'd need to require clang 15 for that, since the ranges library isn't +// fully implemented until then, but this should suffice. + +template +picojson::array ToJsonArray(const Range& data) +{ + picojson::array result; + result.reserve(std::size(data)); + + for (const auto& value : data) + { + result.emplace_back(static_cast(value)); + } + + return result; +} diff --git a/Source/Core/DolphinLib.props b/Source/Core/DolphinLib.props index 06b1a88eee..cf0788a8dc 100644 --- a/Source/Core/DolphinLib.props +++ b/Source/Core/DolphinLib.props @@ -125,6 +125,7 @@ + diff --git a/Source/Core/VideoCommon/Assets/ShaderAsset.cpp b/Source/Core/VideoCommon/Assets/ShaderAsset.cpp index 02f2d45a38..b45310dab9 100644 --- a/Source/Core/VideoCommon/Assets/ShaderAsset.cpp +++ b/Source/Core/VideoCommon/Assets/ShaderAsset.cpp @@ -6,6 +6,7 @@ #include #include +#include "Common/JsonUtil.h" #include "Common/Logging/Log.h" #include "Common/StringUtil.h" #include "Common/VariantUtil.h" @@ -291,6 +292,80 @@ bool PixelShaderData::FromJson(const VideoCommon::CustomAssetLibrary::AssetID& a return true; } + +void PixelShaderData::ToJson(picojson::object& obj, const PixelShaderData& data) +{ + picojson::array json_properties; + for (const auto& [name, property] : data.m_properties) + { + picojson::object json_property; + json_property["code_name"] = picojson::value{name}; + json_property["description"] = picojson::value{property.m_description}; + + std::visit( + overloaded{[&](const ShaderProperty::Sampler2D& default_value) { + json_property["type"] = picojson::value{"sampler2d"}; + json_property["default"] = picojson::value{default_value.value}; + }, + [&](const ShaderProperty::Sampler2DArray& default_value) { + json_property["type"] = picojson::value{"sampler2darray"}; + json_property["default"] = picojson::value{default_value.value}; + }, + [&](const ShaderProperty::SamplerCube& default_value) { + json_property["type"] = picojson::value{"samplercube"}; + json_property["default"] = picojson::value{default_value.value}; + }, + [&](s32 default_value) { + json_property["type"] = picojson::value{"int"}; + json_property["default"] = picojson::value{static_cast(default_value)}; + }, + [&](const std::array& default_value) { + json_property["type"] = picojson::value{"int2"}; + json_property["default"] = picojson::value{ToJsonArray(default_value)}; + }, + [&](const std::array& default_value) { + json_property["type"] = picojson::value{"int3"}; + json_property["default"] = picojson::value{ToJsonArray(default_value)}; + }, + [&](const std::array& default_value) { + json_property["type"] = picojson::value{"int4"}; + json_property["default"] = picojson::value{ToJsonArray(default_value)}; + }, + [&](float default_value) { + json_property["type"] = picojson::value{"float"}; + json_property["default"] = picojson::value{static_cast(default_value)}; + }, + [&](const std::array& default_value) { + json_property["type"] = picojson::value{"float2"}; + json_property["default"] = picojson::value{ToJsonArray(default_value)}; + }, + [&](const std::array& default_value) { + json_property["type"] = picojson::value{"float3"}; + json_property["default"] = picojson::value{ToJsonArray(default_value)}; + }, + [&](const std::array& default_value) { + json_property["type"] = picojson::value{"float4"}; + json_property["default"] = picojson::value{ToJsonArray(default_value)}; + }, + [&](const ShaderProperty::RGB& default_value) { + json_property["type"] = picojson::value{"rgb"}; + json_property["default"] = picojson::value{ToJsonArray(default_value.value)}; + }, + [&](const ShaderProperty::RGBA& default_value) { + json_property["type"] = picojson::value{"rgba"}; + json_property["default"] = picojson::value{ToJsonArray(default_value.value)}; + }, + [&](bool default_value) { + json_property["type"] = picojson::value{"bool"}; + json_property["default"] = picojson::value{default_value}; + }}, + property.m_default); + + json_properties.push_back(picojson::value{json_property}); + } + obj["properties"] = picojson::value{json_properties}; +} + CustomAssetLibrary::LoadInfo PixelShaderAsset::LoadImpl(const CustomAssetLibrary::AssetID& asset_id) { auto potential_data = std::make_shared(); diff --git a/Source/Core/VideoCommon/Assets/ShaderAsset.h b/Source/Core/VideoCommon/Assets/ShaderAsset.h index 0cc4255596..8947cf8f5a 100644 --- a/Source/Core/VideoCommon/Assets/ShaderAsset.h +++ b/Source/Core/VideoCommon/Assets/ShaderAsset.h @@ -52,6 +52,7 @@ struct PixelShaderData { static bool FromJson(const CustomAssetLibrary::AssetID& asset_id, const picojson::object& json, PixelShaderData* data); + static void ToJson(picojson::object& obj, const PixelShaderData& data); // These shader properties describe the input that the // shader expects to expose. The key is text