VideoCommon: add support to graphics mod manager to load in assets and pass it to graphics actions

This commit is contained in:
iwubcode 2023-07-10 22:23:32 -05:00
parent 6ea0d17802
commit 5506121685
10 changed files with 136 additions and 11 deletions

View File

@ -663,6 +663,7 @@
<ClInclude Include="VideoCommon\GeometryShaderGen.h" />
<ClInclude Include="VideoCommon\GeometryShaderManager.h" />
<ClInclude Include="VideoCommon\GraphicsModSystem\Config\GraphicsMod.h" />
<ClInclude Include="VideoCommon\GraphicsModSystem\Config\GraphicsModAsset.h" />
<ClInclude Include="VideoCommon\GraphicsModSystem\Config\GraphicsModFeature.h" />
<ClInclude Include="VideoCommon\GraphicsModSystem\Config\GraphicsModGroup.h" />
<ClInclude Include="VideoCommon\GraphicsModSystem\Config\GraphicsTarget.h" />
@ -1278,6 +1279,7 @@
<ClCompile Include="VideoCommon\GeometryShaderGen.cpp" />
<ClCompile Include="VideoCommon\GeometryShaderManager.cpp" />
<ClCompile Include="VideoCommon\GraphicsModSystem\Config\GraphicsMod.cpp" />
<ClCompile Include="VideoCommon\GraphicsModSystem\Config\GraphicsModAsset.cpp" />
<ClCompile Include="VideoCommon\GraphicsModSystem\Config\GraphicsModFeature.cpp" />
<ClCompile Include="VideoCommon\GraphicsModSystem\Config\GraphicsModGroup.cpp" />
<ClCompile Include="VideoCommon\GraphicsModSystem\Config\GraphicsTarget.cpp" />

View File

@ -64,6 +64,8 @@ add_library(videocommon
GeometryShaderManager.h
GraphicsModSystem/Config/GraphicsMod.cpp
GraphicsModSystem/Config/GraphicsMod.h
GraphicsModSystem/Config/GraphicsModAsset.cpp
GraphicsModSystem/Config/GraphicsModAsset.h
GraphicsModSystem/Config/GraphicsModFeature.cpp
GraphicsModSystem/Config/GraphicsModFeature.h
GraphicsModSystem/Config/GraphicsModGroup.cpp

View File

@ -178,6 +178,27 @@ bool GraphicsModConfig::DeserializeFromConfig(const picojson::value& value)
}
}
const auto& assets = value.get("assets");
if (assets.is<picojson::array>())
{
for (const auto& asset_val : assets.get<picojson::array>())
{
if (!asset_val.is<picojson::object>())
{
ERROR_LOG_FMT(
VIDEO, "Failed to load mod configuration file, specified asset is not a json object");
return false;
}
GraphicsModAssetConfig asset;
if (!asset.DeserializeFromConfig(asset_val.get<picojson::object>()))
{
return false;
}
m_assets.push_back(std::move(asset));
}
}
return true;
}

View File

@ -9,6 +9,7 @@
#include <picojson.h>
#include "VideoCommon/GraphicsModSystem/Config/GraphicsModAsset.h"
#include "VideoCommon/GraphicsModSystem/Config/GraphicsModFeature.h"
#include "VideoCommon/GraphicsModSystem/Config/GraphicsTargetGroup.h"
@ -30,6 +31,7 @@ struct GraphicsModConfig
std::vector<GraphicsTargetGroupConfig> m_groups;
std::vector<GraphicsModFeatureConfig> m_features;
std::vector<GraphicsModAssetConfig> m_assets;
static std::optional<GraphicsModConfig> Create(const std::string& file, Source source);
static std::optional<GraphicsModConfig> Create(const picojson::object* obj);

View File

@ -0,0 +1,52 @@
// Copyright 2023 Dolphin Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include "VideoCommon/GraphicsModSystem/Config/GraphicsModAsset.h"
#include "Common/Logging/Log.h"
bool GraphicsModAssetConfig::DeserializeFromConfig(const picojson::object& obj)
{
auto name_iter = obj.find("name");
if (name_iter == obj.end())
{
ERROR_LOG_FMT(VIDEO, "Failed to load mod configuration file, specified asset has no name");
return false;
}
if (!name_iter->second.is<std::string>())
{
ERROR_LOG_FMT(VIDEO, "Failed to load mod configuration file, specified asset has a name "
"that is not a string");
return false;
}
m_name = name_iter->second.to_str();
auto data_iter = obj.find("data");
if (data_iter == obj.end())
{
ERROR_LOG_FMT(VIDEO, "Failed to load mod configuration file, specified asset '{}' has no data",
m_name);
return false;
}
if (!data_iter->second.is<picojson::object>())
{
ERROR_LOG_FMT(VIDEO,
"Failed to load mod configuration file, specified asset '{}' has data "
"that is not an object",
m_name);
return false;
}
for (const auto& [key, value] : data_iter->second.get<picojson::object>())
{
if (!value.is<std::string>())
{
ERROR_LOG_FMT(VIDEO,
"Failed to load mod configuration file, specified asset '{}' has data "
"with a value for key '{}' that is not a string",
m_name, key);
}
m_map[key] = value.to_str();
}
return true;
}

View File

@ -0,0 +1,18 @@
// Copyright 2023 Dolphin Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include <string>
#include <picojson.h>
#include "VideoCommon/Assets/DirectFilesystemAssetLibrary.h"
struct GraphicsModAssetConfig
{
std::string m_name;
VideoCommon::DirectFilesystemAssetLibrary::AssetMap m_map;
bool DeserializeFromConfig(const picojson::object& obj);
};

View File

@ -26,8 +26,9 @@ public:
std::string m_pixel_material_asset;
};
static std::unique_ptr<CustomPipelineAction> Create(const picojson::value& json_data,
std::string_view path);
static std::unique_ptr<CustomPipelineAction>
Create(const picojson::value& json_data,
std::shared_ptr<VideoCommon::CustomAssetLibrary> library);
CustomPipelineAction(std::shared_ptr<VideoCommon::CustomAssetLibrary> library,
std::vector<PipelinePassPassDescription> pass_descriptions);
~CustomPipelineAction();

View File

@ -12,7 +12,7 @@
namespace GraphicsModActionFactory
{
std::unique_ptr<GraphicsModAction> Create(std::string_view name, const picojson::value& json_data,
std::string_view path)
std::shared_ptr<VideoCommon::CustomAssetLibrary> library)
{
if (name == "print")
{
@ -32,7 +32,7 @@ std::unique_ptr<GraphicsModAction> Create(std::string_view name, const picojson:
}
else if (name == "custom_pipeline")
{
return CustomPipelineAction::Create(json_data, path);
return CustomPipelineAction::Create(json_data, std::move(library));
}
return nullptr;

View File

@ -8,10 +8,11 @@
#include <picojson.h>
#include "VideoCommon/Assets/CustomAssetLibrary.h"
#include "VideoCommon/GraphicsModSystem/Runtime/GraphicsModAction.h"
namespace GraphicsModActionFactory
{
std::unique_ptr<GraphicsModAction> Create(std::string_view name, const picojson::value& json_data,
std::string_view path);
std::shared_ptr<VideoCommon::CustomAssetLibrary> library);
}

View File

@ -13,7 +13,9 @@
#include "Core/ConfigManager.h"
#include "VideoCommon/Assets/DirectFilesystemAssetLibrary.h"
#include "VideoCommon/GraphicsModSystem/Config/GraphicsMod.h"
#include "VideoCommon/GraphicsModSystem/Config/GraphicsModAsset.h"
#include "VideoCommon/GraphicsModSystem/Config/GraphicsModGroup.h"
#include "VideoCommon/GraphicsModSystem/Runtime/GraphicsModActionFactory.h"
#include "VideoCommon/TextureInfo.h"
@ -187,6 +189,8 @@ void GraphicsModManager::Load(const GraphicsModGroupConfig& config)
const auto& mods = config.GetMods();
auto filesystem_library = std::make_shared<VideoCommon::DirectFilesystemAssetLibrary>();
std::map<std::string, std::vector<GraphicsTargetConfig>> group_to_targets;
for (const auto& mod : mods)
{
@ -208,6 +212,29 @@ void GraphicsModManager::Load(const GraphicsModGroupConfig& config)
group_to_targets[internal_group].push_back(target);
}
}
std::string base_path;
SplitPath(mod.GetAbsolutePath(), &base_path, nullptr, nullptr);
for (const GraphicsModAssetConfig& asset : mod.m_assets)
{
auto asset_map = asset.m_map;
for (auto& [k, v] : asset_map)
{
if (v.is_absolute())
{
WARN_LOG_FMT(VIDEO,
"Specified graphics mod asset '{}' for mod '{}' has an absolute path, you "
"shouldn't release this to users.",
asset.m_name, mod.m_title);
}
else
{
v = std::filesystem::path{base_path} / v;
}
}
filesystem_library->SetAssetIDMapData(asset.m_name, std::move(asset_map));
}
}
for (const auto& mod : mods)
@ -215,12 +242,11 @@ void GraphicsModManager::Load(const GraphicsModGroupConfig& config)
for (const GraphicsModFeatureConfig& feature : mod.m_features)
{
const auto create_action =
[](const std::string_view& action_name, const picojson::value& json_data,
[filesystem_library](const std::string_view& action_name,
const picojson::value& json_data,
GraphicsModConfig mod_config) -> std::unique_ptr<GraphicsModAction> {
std::string base_path;
SplitPath(mod_config.GetAbsolutePath(), &base_path, nullptr, nullptr);
auto action = GraphicsModActionFactory::Create(action_name, json_data, base_path);
auto action =
GraphicsModActionFactory::Create(action_name, json_data, std::move(filesystem_library));
if (action == nullptr)
{
return nullptr;