mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-03-01 10:13:38 +00:00
VideoCommon: add logic to handle a GraphicsMod while Dolphin is running
This commit is contained in:
parent
254246b814
commit
f416b71925
@ -637,6 +637,15 @@
|
|||||||
<ClInclude Include="VideoCommon\GraphicsModSystem\Config\GraphicsTarget.h" />
|
<ClInclude Include="VideoCommon\GraphicsModSystem\Config\GraphicsTarget.h" />
|
||||||
<ClInclude Include="VideoCommon\GraphicsModSystem\Config\GraphicsTargetGroup.h" />
|
<ClInclude Include="VideoCommon\GraphicsModSystem\Config\GraphicsTargetGroup.h" />
|
||||||
<ClInclude Include="VideoCommon\GraphicsModSystem\Constants.h" />
|
<ClInclude Include="VideoCommon\GraphicsModSystem\Constants.h" />
|
||||||
|
<ClInclude Include="VideoCommon\GraphicsModSystem\Runtime\Actions\MoveAction.h" />
|
||||||
|
<ClInclude Include="VideoCommon\GraphicsModSystem\Runtime\Actions\PrintAction.h" />
|
||||||
|
<ClInclude Include="VideoCommon\GraphicsModSystem\Runtime\Actions\ScaleAction.h" />
|
||||||
|
<ClInclude Include="VideoCommon\GraphicsModSystem\Runtime\Actions\SkipAction.h" />
|
||||||
|
<ClInclude Include="VideoCommon\GraphicsModSystem\Runtime\FBInfo.h" />
|
||||||
|
<ClInclude Include="VideoCommon\GraphicsModSystem\Runtime\GraphicsModAction.h" />
|
||||||
|
<ClInclude Include="VideoCommon\GraphicsModSystem\Runtime\GraphicsModActionFactory.h" />
|
||||||
|
<ClInclude Include="VideoCommon\GraphicsModSystem\Runtime\GraphicsModGroup.h" />
|
||||||
|
<ClInclude Include="VideoCommon\GraphicsModSystem\Runtime\GraphicsModManager.h" />
|
||||||
<ClInclude Include="VideoCommon\GXPipelineTypes.h" />
|
<ClInclude Include="VideoCommon\GXPipelineTypes.h" />
|
||||||
<ClInclude Include="VideoCommon\HiresTextures.h" />
|
<ClInclude Include="VideoCommon\HiresTextures.h" />
|
||||||
<ClInclude Include="VideoCommon\ImageWrite.h" />
|
<ClInclude Include="VideoCommon\ImageWrite.h" />
|
||||||
@ -1220,6 +1229,13 @@
|
|||||||
<ClCompile Include="VideoCommon\GraphicsModSystem\Config\GraphicsModGroup.cpp" />
|
<ClCompile Include="VideoCommon\GraphicsModSystem\Config\GraphicsModGroup.cpp" />
|
||||||
<ClCompile Include="VideoCommon\GraphicsModSystem\Config\GraphicsTarget.cpp" />
|
<ClCompile Include="VideoCommon\GraphicsModSystem\Config\GraphicsTarget.cpp" />
|
||||||
<ClCompile Include="VideoCommon\GraphicsModSystem\Config\GraphicsTargetGroup.cpp" />
|
<ClCompile Include="VideoCommon\GraphicsModSystem\Config\GraphicsTargetGroup.cpp" />
|
||||||
|
<ClCompile Include="VideoCommon\GraphicsModSystem\Runtime\Actions\MoveAction.cpp" />
|
||||||
|
<ClCompile Include="VideoCommon\GraphicsModSystem\Runtime\Actions\PrintAction.cpp" />
|
||||||
|
<ClCompile Include="VideoCommon\GraphicsModSystem\Runtime\Actions\ScaleAction.cpp" />
|
||||||
|
<ClCompile Include="VideoCommon\GraphicsModSystem\Runtime\Actions\SkipAction.cpp" />
|
||||||
|
<ClCompile Include="VideoCommon\GraphicsModSystem\Runtime\FBInfo.cpp" />
|
||||||
|
<ClCompile Include="VideoCommon\GraphicsModSystem\Runtime\GraphicsModActionFactory.cpp" />
|
||||||
|
<ClCompile Include="VideoCommon\GraphicsModSystem\Runtime\GraphicsModManager.cpp" />
|
||||||
<ClCompile Include="VideoCommon\HiresTextures_DDSLoader.cpp" />
|
<ClCompile Include="VideoCommon\HiresTextures_DDSLoader.cpp" />
|
||||||
<ClCompile Include="VideoCommon\HiresTextures.cpp" />
|
<ClCompile Include="VideoCommon\HiresTextures.cpp" />
|
||||||
<ClCompile Include="VideoCommon\IndexGenerator.cpp" />
|
<ClCompile Include="VideoCommon\IndexGenerator.cpp" />
|
||||||
|
@ -50,6 +50,21 @@ add_library(videocommon
|
|||||||
GraphicsModSystem/Config/GraphicsTargetGroup.cpp
|
GraphicsModSystem/Config/GraphicsTargetGroup.cpp
|
||||||
GraphicsModSystem/Config/GraphicsTargetGroup.h
|
GraphicsModSystem/Config/GraphicsTargetGroup.h
|
||||||
GraphicsModSystem/Constants.h
|
GraphicsModSystem/Constants.h
|
||||||
|
GraphicsModSystem/Runtime/Actions/MoveAction.cpp
|
||||||
|
GraphicsModSystem/Runtime/Actions/MoveAction.h
|
||||||
|
GraphicsModSystem/Runtime/Actions/PrintAction.cpp
|
||||||
|
GraphicsModSystem/Runtime/Actions/PrintAction.h
|
||||||
|
GraphicsModSystem/Runtime/Actions/ScaleAction.cpp
|
||||||
|
GraphicsModSystem/Runtime/Actions/ScaleAction.h
|
||||||
|
GraphicsModSystem/Runtime/Actions/SkipAction.cpp
|
||||||
|
GraphicsModSystem/Runtime/Actions/SkipAction.h
|
||||||
|
GraphicsModSystem/Runtime/FBInfo.cpp
|
||||||
|
GraphicsModSystem/Runtime/FBInfo.h
|
||||||
|
GraphicsModSystem/Runtime/GraphicsModAction.h
|
||||||
|
GraphicsModSystem/Runtime/GraphicsModActionFactory.cpp
|
||||||
|
GraphicsModSystem/Runtime/GraphicsModActionFactory.h
|
||||||
|
GraphicsModSystem/Runtime/GraphicsModManager.cpp
|
||||||
|
GraphicsModSystem/Runtime/GraphicsModManager.h
|
||||||
HiresTextures.cpp
|
HiresTextures.cpp
|
||||||
HiresTextures.h
|
HiresTextures.h
|
||||||
HiresTextures_DDSLoader.cpp
|
HiresTextures_DDSLoader.cpp
|
||||||
|
@ -0,0 +1,47 @@
|
|||||||
|
// Copyright 2022 Dolphin Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#include "VideoCommon/GraphicsModSystem/Runtime/Actions/MoveAction.h"
|
||||||
|
|
||||||
|
std::unique_ptr<MoveAction> MoveAction::Create(const picojson::value& json_data)
|
||||||
|
{
|
||||||
|
Common::Vec3 position_offset;
|
||||||
|
const auto& x = json_data.get("X");
|
||||||
|
if (x.is<double>())
|
||||||
|
{
|
||||||
|
position_offset.x = static_cast<float>(x.get<double>());
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto& y = json_data.get("Y");
|
||||||
|
if (y.is<double>())
|
||||||
|
{
|
||||||
|
position_offset.y = static_cast<float>(y.get<double>());
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto& z = json_data.get("Z");
|
||||||
|
if (z.is<double>())
|
||||||
|
{
|
||||||
|
position_offset.z = static_cast<float>(z.get<double>());
|
||||||
|
}
|
||||||
|
return std::make_unique<MoveAction>(position_offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
MoveAction::MoveAction(Common::Vec3 position_offset) : m_position_offset(position_offset)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void MoveAction::OnProjection(Common::Matrix44* matrix)
|
||||||
|
{
|
||||||
|
if (!matrix)
|
||||||
|
return;
|
||||||
|
|
||||||
|
*matrix *= Common::Matrix44::Translate(m_position_offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MoveAction::OnProjectionAndTexture(Common::Matrix44* matrix)
|
||||||
|
{
|
||||||
|
if (!matrix)
|
||||||
|
return;
|
||||||
|
|
||||||
|
*matrix *= Common::Matrix44::Translate(m_position_offset);
|
||||||
|
}
|
@ -0,0 +1,22 @@
|
|||||||
|
// Copyright 2022 Dolphin Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
#include <picojson.h>
|
||||||
|
|
||||||
|
#include "VideoCommon/GraphicsModSystem/Runtime/GraphicsModAction.h"
|
||||||
|
|
||||||
|
class MoveAction final : public GraphicsModAction
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static std::unique_ptr<MoveAction> Create(const picojson::value& json_data);
|
||||||
|
explicit MoveAction(Common::Vec3 position_offset);
|
||||||
|
void OnProjection(Common::Matrix44* matrix) override;
|
||||||
|
void OnProjectionAndTexture(Common::Matrix44* matrix) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
Common::Vec3 m_position_offset;
|
||||||
|
};
|
@ -0,0 +1,36 @@
|
|||||||
|
// Copyright 2022 Dolphin Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#include "VideoCommon/GraphicsModSystem/Runtime/Actions/PrintAction.h"
|
||||||
|
|
||||||
|
#include "Common/Logging/Log.h"
|
||||||
|
|
||||||
|
void PrintAction::OnDrawStarted(bool*)
|
||||||
|
{
|
||||||
|
INFO_LOG_FMT(VIDEO, "OnDrawStarted Called");
|
||||||
|
}
|
||||||
|
|
||||||
|
void PrintAction::OnEFB(bool*, u32 texture_width, u32 texture_height, u32* scaled_width,
|
||||||
|
u32* scaled_height)
|
||||||
|
{
|
||||||
|
if (!scaled_width || !scaled_height)
|
||||||
|
return;
|
||||||
|
|
||||||
|
INFO_LOG_FMT(VIDEO, "OnEFB Called. Original [{}, {}], Scaled [{}, {}]", texture_width,
|
||||||
|
texture_height, *scaled_width, *scaled_height);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PrintAction::OnProjection(Common::Matrix44*)
|
||||||
|
{
|
||||||
|
INFO_LOG_FMT(VIDEO, "OnProjection Called");
|
||||||
|
}
|
||||||
|
|
||||||
|
void PrintAction::OnProjectionAndTexture(Common::Matrix44*)
|
||||||
|
{
|
||||||
|
INFO_LOG_FMT(VIDEO, "OnProjectionAndTexture Called");
|
||||||
|
}
|
||||||
|
|
||||||
|
void PrintAction::OnTextureLoad()
|
||||||
|
{
|
||||||
|
INFO_LOG_FMT(VIDEO, "OnTextureLoad Called");
|
||||||
|
}
|
@ -0,0 +1,17 @@
|
|||||||
|
// Copyright 2022 Dolphin Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "VideoCommon/GraphicsModSystem/Runtime/GraphicsModAction.h"
|
||||||
|
|
||||||
|
class PrintAction final : public GraphicsModAction
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
void OnDrawStarted(bool* skip) override;
|
||||||
|
void OnEFB(bool* skip, u32 texture_width, u32 texture_height, u32* scaled_width,
|
||||||
|
u32* scaled_height) override;
|
||||||
|
void OnProjection(Common::Matrix44* matrix) override;
|
||||||
|
void OnProjectionAndTexture(Common::Matrix44* matrix) override;
|
||||||
|
void OnTextureLoad() override;
|
||||||
|
};
|
@ -0,0 +1,59 @@
|
|||||||
|
// Copyright 2022 Dolphin Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#include "VideoCommon/GraphicsModSystem/Runtime/Actions/ScaleAction.h"
|
||||||
|
|
||||||
|
std::unique_ptr<ScaleAction> ScaleAction::Create(const picojson::value& json_data)
|
||||||
|
{
|
||||||
|
Common::Vec3 scale;
|
||||||
|
const auto& x = json_data.get("X");
|
||||||
|
if (x.is<double>())
|
||||||
|
{
|
||||||
|
scale.x = static_cast<float>(x.get<double>());
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto& y = json_data.get("Y");
|
||||||
|
if (y.is<double>())
|
||||||
|
{
|
||||||
|
scale.y = static_cast<float>(y.get<double>());
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto& z = json_data.get("Z");
|
||||||
|
if (z.is<double>())
|
||||||
|
{
|
||||||
|
scale.z = static_cast<float>(z.get<double>());
|
||||||
|
}
|
||||||
|
return std::make_unique<ScaleAction>(scale);
|
||||||
|
}
|
||||||
|
|
||||||
|
ScaleAction::ScaleAction(Common::Vec3 scale) : m_scale(scale)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScaleAction::OnEFB(bool*, u32 texture_width, u32 texture_height, u32* scaled_width,
|
||||||
|
u32* scaled_height)
|
||||||
|
{
|
||||||
|
if (scaled_width && m_scale.x > 0)
|
||||||
|
*scaled_width = texture_width * m_scale.x;
|
||||||
|
|
||||||
|
if (scaled_height && m_scale.y > 0)
|
||||||
|
*scaled_height = texture_height * m_scale.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScaleAction::OnProjection(Common::Matrix44* matrix)
|
||||||
|
{
|
||||||
|
if (!matrix)
|
||||||
|
return;
|
||||||
|
auto& the_matrix = *matrix;
|
||||||
|
the_matrix.data[0] = the_matrix.data[0] * m_scale.x;
|
||||||
|
the_matrix.data[5] = the_matrix.data[5] * m_scale.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScaleAction::OnProjectionAndTexture(Common::Matrix44* matrix)
|
||||||
|
{
|
||||||
|
if (!matrix)
|
||||||
|
return;
|
||||||
|
auto& the_matrix = *matrix;
|
||||||
|
the_matrix.data[0] = the_matrix.data[0] * m_scale.x;
|
||||||
|
the_matrix.data[5] = the_matrix.data[5] * m_scale.y;
|
||||||
|
}
|
@ -0,0 +1,24 @@
|
|||||||
|
// Copyright 2022 Dolphin Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
#include <picojson.h>
|
||||||
|
|
||||||
|
#include "VideoCommon/GraphicsModSystem/Runtime/GraphicsModAction.h"
|
||||||
|
|
||||||
|
class ScaleAction final : public GraphicsModAction
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static std::unique_ptr<ScaleAction> Create(const picojson::value& json_data);
|
||||||
|
explicit ScaleAction(Common::Vec3 scale);
|
||||||
|
void OnEFB(bool* skip, u32 texture_width, u32 texture_height, u32* scaled_width,
|
||||||
|
u32* scaled_height) override;
|
||||||
|
void OnProjection(Common::Matrix44* matrix) override;
|
||||||
|
void OnProjectionAndTexture(Common::Matrix44* matrix) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
Common::Vec3 m_scale;
|
||||||
|
};
|
@ -0,0 +1,20 @@
|
|||||||
|
// Copyright 2022 Dolphin Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#include "VideoCommon/GraphicsModSystem/Runtime/Actions/SkipAction.h"
|
||||||
|
|
||||||
|
void SkipAction::OnDrawStarted(bool* skip)
|
||||||
|
{
|
||||||
|
if (!skip)
|
||||||
|
return;
|
||||||
|
|
||||||
|
*skip = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SkipAction::OnEFB(bool* skip, u32, u32, u32*, u32*)
|
||||||
|
{
|
||||||
|
if (!skip)
|
||||||
|
return;
|
||||||
|
|
||||||
|
*skip = true;
|
||||||
|
}
|
@ -0,0 +1,14 @@
|
|||||||
|
// Copyright 2022 Dolphin Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "VideoCommon/GraphicsModSystem/Runtime/GraphicsModAction.h"
|
||||||
|
|
||||||
|
class SkipAction final : public GraphicsModAction
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
void OnDrawStarted(bool* skip) override;
|
||||||
|
void OnEFB(bool* skip, u32 texture_width, u32 texture_height, u32* scaled_width,
|
||||||
|
u32* scaled_height) override;
|
||||||
|
};
|
22
Source/Core/VideoCommon/GraphicsModSystem/Runtime/FBInfo.cpp
Normal file
22
Source/Core/VideoCommon/GraphicsModSystem/Runtime/FBInfo.cpp
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
// Copyright 2022 Dolphin Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#include "VideoCommon/GraphicsModSystem/Runtime/FBInfo.h"
|
||||||
|
|
||||||
|
#include "Common/Hash.h"
|
||||||
|
|
||||||
|
u32 FBInfo::CalculateHash() const
|
||||||
|
{
|
||||||
|
return Common::HashAdler32(reinterpret_cast<const u8*>(this), sizeof(FBInfo));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FBInfo::operator==(const FBInfo& other) const
|
||||||
|
{
|
||||||
|
return m_height == other.m_height && m_width == other.m_width &&
|
||||||
|
m_texture_format == other.m_texture_format;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FBInfo::operator!=(const FBInfo& other) const
|
||||||
|
{
|
||||||
|
return !(*this == other);
|
||||||
|
}
|
25
Source/Core/VideoCommon/GraphicsModSystem/Runtime/FBInfo.h
Normal file
25
Source/Core/VideoCommon/GraphicsModSystem/Runtime/FBInfo.h
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
// Copyright 2022 Dolphin Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "Common/CommonTypes.h"
|
||||||
|
#include "VideoCommon/TextureDecoder.h"
|
||||||
|
|
||||||
|
struct FBInfo
|
||||||
|
{
|
||||||
|
u32 m_height = 0;
|
||||||
|
u32 m_width = 0;
|
||||||
|
TextureFormat m_texture_format = TextureFormat::I4;
|
||||||
|
u32 CalculateHash() const;
|
||||||
|
bool operator==(const FBInfo& other) const;
|
||||||
|
bool operator!=(const FBInfo& other) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct FBInfoHasher
|
||||||
|
{
|
||||||
|
std::size_t operator()(const FBInfo& fb_info) const noexcept
|
||||||
|
{
|
||||||
|
return static_cast<std::size_t>(fb_info.CalculateHash());
|
||||||
|
}
|
||||||
|
};
|
@ -0,0 +1,29 @@
|
|||||||
|
// Copyright 2022 Dolphin Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "Common/CommonTypes.h"
|
||||||
|
#include "Common/Matrix.h"
|
||||||
|
|
||||||
|
class GraphicsModAction
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
GraphicsModAction() = default;
|
||||||
|
virtual ~GraphicsModAction() = default;
|
||||||
|
GraphicsModAction(const GraphicsModAction&) = default;
|
||||||
|
GraphicsModAction(GraphicsModAction&&) = default;
|
||||||
|
GraphicsModAction& operator=(const GraphicsModAction&) = default;
|
||||||
|
GraphicsModAction& operator=(GraphicsModAction&&) = default;
|
||||||
|
|
||||||
|
virtual void OnDrawStarted(bool* skip) {}
|
||||||
|
virtual void OnEFB(bool* skip, u32 texture_width, u32 texture_height, u32* scaled_width,
|
||||||
|
u32* scaled_height)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
virtual void OnXFB() {}
|
||||||
|
virtual void OnProjection(Common::Matrix44* matrix) {}
|
||||||
|
virtual void OnProjectionAndTexture(Common::Matrix44* matrix) {}
|
||||||
|
virtual void OnTextureLoad() {}
|
||||||
|
virtual void OnFrameEnd() {}
|
||||||
|
};
|
@ -0,0 +1,34 @@
|
|||||||
|
// Copyright 2022 Dolphin Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#include "VideoCommon/GraphicsModSystem/Runtime/GraphicsModActionFactory.h"
|
||||||
|
|
||||||
|
#include "VideoCommon/GraphicsModSystem/Runtime/Actions/MoveAction.h"
|
||||||
|
#include "VideoCommon/GraphicsModSystem/Runtime/Actions/PrintAction.h"
|
||||||
|
#include "VideoCommon/GraphicsModSystem/Runtime/Actions/ScaleAction.h"
|
||||||
|
#include "VideoCommon/GraphicsModSystem/Runtime/Actions/SkipAction.h"
|
||||||
|
|
||||||
|
namespace GraphicsModActionFactory
|
||||||
|
{
|
||||||
|
std::unique_ptr<GraphicsModAction> Create(std::string_view name, const picojson::value& json_data)
|
||||||
|
{
|
||||||
|
if (name == "print")
|
||||||
|
{
|
||||||
|
return std::make_unique<PrintAction>();
|
||||||
|
}
|
||||||
|
else if (name == "skip")
|
||||||
|
{
|
||||||
|
return std::make_unique<SkipAction>();
|
||||||
|
}
|
||||||
|
else if (name == "move")
|
||||||
|
{
|
||||||
|
return MoveAction::Create(json_data);
|
||||||
|
}
|
||||||
|
else if (name == "scale")
|
||||||
|
{
|
||||||
|
return ScaleAction::Create(json_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
} // namespace GraphicsModActionFactory
|
@ -0,0 +1,16 @@
|
|||||||
|
// Copyright 2022 Dolphin Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include <string_view>
|
||||||
|
|
||||||
|
#include <picojson.h>
|
||||||
|
|
||||||
|
#include "VideoCommon/GraphicsModSystem/Runtime/GraphicsModAction.h"
|
||||||
|
|
||||||
|
namespace GraphicsModActionFactory
|
||||||
|
{
|
||||||
|
std::unique_ptr<GraphicsModAction> Create(std::string_view name, const picojson::value& json_data);
|
||||||
|
}
|
@ -0,0 +1,279 @@
|
|||||||
|
// Copyright 2022 Dolphin Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#include "VideoCommon/GraphicsModSystem/Runtime/GraphicsModManager.h"
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <string_view>
|
||||||
|
#include <variant>
|
||||||
|
|
||||||
|
#include "Common/Logging/Log.h"
|
||||||
|
#include "Common/VariantUtil.h"
|
||||||
|
|
||||||
|
#include "VideoCommon/GraphicsModSystem/Config/GraphicsMod.h"
|
||||||
|
#include "VideoCommon/GraphicsModSystem/Config/GraphicsModGroup.h"
|
||||||
|
#include "VideoCommon/GraphicsModSystem/Runtime/GraphicsModActionFactory.h"
|
||||||
|
#include "VideoCommon/TextureInfo.h"
|
||||||
|
|
||||||
|
class GraphicsModManager::DecoratedAction final : public GraphicsModAction
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
DecoratedAction(std::unique_ptr<GraphicsModAction> action, GraphicsModConfig mod)
|
||||||
|
: m_action_impl(std::move(action)), m_mod(std::move(mod))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
void OnDrawStarted(bool* skip) override
|
||||||
|
{
|
||||||
|
if (!m_mod.m_enabled)
|
||||||
|
return;
|
||||||
|
m_action_impl->OnDrawStarted(skip);
|
||||||
|
}
|
||||||
|
void OnEFB(bool* skip, u32 texture_width, u32 texture_height, u32* scaled_width,
|
||||||
|
u32* scaled_height) override
|
||||||
|
{
|
||||||
|
if (!m_mod.m_enabled)
|
||||||
|
return;
|
||||||
|
m_action_impl->OnEFB(skip, texture_width, texture_height, scaled_width, scaled_height);
|
||||||
|
}
|
||||||
|
void OnProjection(Common::Matrix44* matrix) override
|
||||||
|
{
|
||||||
|
if (!m_mod.m_enabled)
|
||||||
|
return;
|
||||||
|
m_action_impl->OnProjection(matrix);
|
||||||
|
}
|
||||||
|
void OnProjectionAndTexture(Common::Matrix44* matrix) override
|
||||||
|
{
|
||||||
|
if (!m_mod.m_enabled)
|
||||||
|
return;
|
||||||
|
m_action_impl->OnProjectionAndTexture(matrix);
|
||||||
|
}
|
||||||
|
void OnTextureLoad() override
|
||||||
|
{
|
||||||
|
if (!m_mod.m_enabled)
|
||||||
|
return;
|
||||||
|
m_action_impl->OnTextureLoad();
|
||||||
|
}
|
||||||
|
void OnFrameEnd() override
|
||||||
|
{
|
||||||
|
if (!m_mod.m_enabled)
|
||||||
|
return;
|
||||||
|
m_action_impl->OnFrameEnd();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
GraphicsModConfig m_mod;
|
||||||
|
std::unique_ptr<GraphicsModAction> m_action_impl;
|
||||||
|
};
|
||||||
|
|
||||||
|
const std::vector<GraphicsModAction*>&
|
||||||
|
GraphicsModManager::GetProjectionActions(ProjectionType projection_type) const
|
||||||
|
{
|
||||||
|
if (const auto it = m_projection_target_to_actions.find(projection_type);
|
||||||
|
it != m_projection_target_to_actions.end())
|
||||||
|
{
|
||||||
|
return it->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
return m_default;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::vector<GraphicsModAction*>&
|
||||||
|
GraphicsModManager::GetProjectionTextureActions(ProjectionType projection_type,
|
||||||
|
const std::string& texture_name) const
|
||||||
|
{
|
||||||
|
const auto lookup = fmt::format("{}_{}", texture_name, static_cast<int>(projection_type));
|
||||||
|
if (const auto it = m_projection_texture_target_to_actions.find(lookup);
|
||||||
|
it != m_projection_texture_target_to_actions.end())
|
||||||
|
{
|
||||||
|
return it->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
return m_default;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::vector<GraphicsModAction*>&
|
||||||
|
GraphicsModManager::GetDrawStartedActions(const std::string& texture_name) const
|
||||||
|
{
|
||||||
|
if (const auto it = m_draw_started_target_to_actions.find(texture_name);
|
||||||
|
it != m_draw_started_target_to_actions.end())
|
||||||
|
{
|
||||||
|
return it->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
return m_default;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::vector<GraphicsModAction*>&
|
||||||
|
GraphicsModManager::GetTextureLoadActions(const std::string& texture_name) const
|
||||||
|
{
|
||||||
|
if (const auto it = m_load_target_to_actions.find(texture_name);
|
||||||
|
it != m_load_target_to_actions.end())
|
||||||
|
{
|
||||||
|
return it->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
return m_default;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::vector<GraphicsModAction*>& GraphicsModManager::GetEFBActions(const FBInfo& efb) const
|
||||||
|
{
|
||||||
|
if (const auto it = m_efb_target_to_actions.find(efb); it != m_efb_target_to_actions.end())
|
||||||
|
{
|
||||||
|
return it->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
return m_default;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::vector<GraphicsModAction*>& GraphicsModManager::GetXFBActions(const FBInfo& xfb) const
|
||||||
|
{
|
||||||
|
if (const auto it = m_efb_target_to_actions.find(xfb); it != m_efb_target_to_actions.end())
|
||||||
|
{
|
||||||
|
return it->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
return m_default;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GraphicsModManager::Load(const GraphicsModGroupConfig& config)
|
||||||
|
{
|
||||||
|
Reset();
|
||||||
|
|
||||||
|
const auto& mods = config.GetMods();
|
||||||
|
|
||||||
|
std::map<std::string, std::vector<GraphicsTargetConfig>> group_to_targets;
|
||||||
|
for (const auto& mod : mods)
|
||||||
|
{
|
||||||
|
for (const GraphicsTargetGroupConfig& group : mod.m_groups)
|
||||||
|
{
|
||||||
|
if (m_groups.find(group.m_name) != m_groups.end())
|
||||||
|
{
|
||||||
|
WARN_LOG_FMT(
|
||||||
|
VIDEO,
|
||||||
|
"Specified graphics mod group '{}' for mod '{}' is already specified by another mod.",
|
||||||
|
group.m_name, mod.m_title);
|
||||||
|
}
|
||||||
|
m_groups.insert(group.m_name);
|
||||||
|
|
||||||
|
const auto internal_group = fmt::format("{}.{}", mod.m_title, group.m_name);
|
||||||
|
for (const GraphicsTargetConfig& target : group.m_targets)
|
||||||
|
{
|
||||||
|
group_to_targets[group.m_name].push_back(target);
|
||||||
|
group_to_targets[internal_group].push_back(target);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const auto& mod : mods)
|
||||||
|
{
|
||||||
|
for (const GraphicsModFeatureConfig& feature : mod.m_features)
|
||||||
|
{
|
||||||
|
const auto create_action = [](const std::string_view& action_name,
|
||||||
|
const picojson::value& json_data,
|
||||||
|
GraphicsModConfig mod) -> std::unique_ptr<GraphicsModAction> {
|
||||||
|
auto action = GraphicsModActionFactory::Create(action_name, json_data);
|
||||||
|
if (action == nullptr)
|
||||||
|
{
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
return std::make_unique<DecoratedAction>(std::move(action), std::move(mod));
|
||||||
|
};
|
||||||
|
|
||||||
|
const auto internal_group = fmt::format("{}.{}", mod.m_title, feature.m_group);
|
||||||
|
|
||||||
|
const auto add_target = [&](const GraphicsTargetConfig& target, GraphicsModConfig mod) {
|
||||||
|
auto action = create_action(feature.m_action, feature.m_action_data, std::move(mod));
|
||||||
|
if (action == nullptr)
|
||||||
|
{
|
||||||
|
WARN_LOG_FMT(VIDEO, "Failed to create action '{}' for group '{}'.", feature.m_action,
|
||||||
|
feature.m_group);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
m_actions.push_back(std::move(action));
|
||||||
|
std::visit(
|
||||||
|
overloaded{
|
||||||
|
[&](const DrawStartedTextureTarget& the_target) {
|
||||||
|
m_draw_started_target_to_actions[the_target.m_texture_info_string].push_back(
|
||||||
|
m_actions.back().get());
|
||||||
|
},
|
||||||
|
[&](const LoadTextureTarget& the_target) {
|
||||||
|
m_load_target_to_actions[the_target.m_texture_info_string].push_back(
|
||||||
|
m_actions.back().get());
|
||||||
|
},
|
||||||
|
[&](const EFBTarget& the_target) {
|
||||||
|
FBInfo info;
|
||||||
|
info.m_height = the_target.m_height;
|
||||||
|
info.m_width = the_target.m_width;
|
||||||
|
info.m_texture_format = the_target.m_texture_format;
|
||||||
|
m_efb_target_to_actions[info].push_back(m_actions.back().get());
|
||||||
|
},
|
||||||
|
[&](const XFBTarget& the_target) {
|
||||||
|
FBInfo info;
|
||||||
|
info.m_height = the_target.m_height;
|
||||||
|
info.m_width = the_target.m_width;
|
||||||
|
info.m_texture_format = the_target.m_texture_format;
|
||||||
|
m_xfb_target_to_actions[info].push_back(m_actions.back().get());
|
||||||
|
},
|
||||||
|
[&](const ProjectionTarget& the_target) {
|
||||||
|
if (the_target.m_texture_info_string)
|
||||||
|
{
|
||||||
|
const auto lookup = fmt::format("{}_{}", *the_target.m_texture_info_string,
|
||||||
|
static_cast<int>(the_target.m_projection_type));
|
||||||
|
m_projection_texture_target_to_actions[lookup].push_back(
|
||||||
|
m_actions.back().get());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_projection_target_to_actions[the_target.m_projection_type].push_back(
|
||||||
|
m_actions.back().get());
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
target);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Prefer groups in the pack over groups from another pack
|
||||||
|
if (const auto local_it = group_to_targets.find(internal_group);
|
||||||
|
local_it != group_to_targets.end())
|
||||||
|
{
|
||||||
|
for (const GraphicsTargetConfig& target : local_it->second)
|
||||||
|
{
|
||||||
|
add_target(target, mod);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (const auto global_it = group_to_targets.find(feature.m_group);
|
||||||
|
global_it != group_to_targets.end())
|
||||||
|
{
|
||||||
|
for (const GraphicsTargetConfig& target : global_it->second)
|
||||||
|
{
|
||||||
|
add_target(target, mod);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
WARN_LOG_FMT(VIDEO, "Specified graphics mod group '{}' was not found for mod '{}'",
|
||||||
|
feature.m_group, mod.m_title);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void GraphicsModManager::EndOfFrame()
|
||||||
|
{
|
||||||
|
for (auto&& action : m_actions)
|
||||||
|
{
|
||||||
|
action->OnFrameEnd();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void GraphicsModManager::Reset()
|
||||||
|
{
|
||||||
|
m_actions.clear();
|
||||||
|
m_groups.clear();
|
||||||
|
m_projection_target_to_actions.clear();
|
||||||
|
m_projection_texture_target_to_actions.clear();
|
||||||
|
m_draw_started_target_to_actions.clear();
|
||||||
|
m_load_target_to_actions.clear();
|
||||||
|
m_efb_target_to_actions.clear();
|
||||||
|
m_xfb_target_to_actions.clear();
|
||||||
|
}
|
@ -0,0 +1,54 @@
|
|||||||
|
// Copyright 2022 Dolphin Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <list>
|
||||||
|
#include <memory>
|
||||||
|
#include <string>
|
||||||
|
#include <unordered_map>
|
||||||
|
#include <unordered_set>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "VideoCommon/GraphicsModSystem/Runtime/FBInfo.h"
|
||||||
|
#include "VideoCommon/GraphicsModSystem/Runtime/GraphicsModAction.h"
|
||||||
|
#include "VideoCommon/TextureInfo.h"
|
||||||
|
#include "VideoCommon/XFMemory.h"
|
||||||
|
|
||||||
|
class GraphicsModGroupConfig;
|
||||||
|
class GraphicsModManager
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
const std::vector<GraphicsModAction*>& GetProjectionActions(ProjectionType projection_type) const;
|
||||||
|
const std::vector<GraphicsModAction*>&
|
||||||
|
GetProjectionTextureActions(ProjectionType projection_type,
|
||||||
|
const std::string& texture_name) const;
|
||||||
|
const std::vector<GraphicsModAction*>&
|
||||||
|
GetDrawStartedActions(const std::string& texture_name) const;
|
||||||
|
const std::vector<GraphicsModAction*>&
|
||||||
|
GetTextureLoadActions(const std::string& texture_name) const;
|
||||||
|
const std::vector<GraphicsModAction*>& GetEFBActions(const FBInfo& efb) const;
|
||||||
|
const std::vector<GraphicsModAction*>& GetXFBActions(const FBInfo& xfb) const;
|
||||||
|
|
||||||
|
void Load(const GraphicsModGroupConfig& config);
|
||||||
|
|
||||||
|
void EndOfFrame();
|
||||||
|
|
||||||
|
private:
|
||||||
|
void Reset();
|
||||||
|
|
||||||
|
class DecoratedAction;
|
||||||
|
|
||||||
|
static inline const std::vector<GraphicsModAction*> m_default = {};
|
||||||
|
std::list<std::unique_ptr<GraphicsModAction>> m_actions;
|
||||||
|
std::unordered_map<ProjectionType, std::vector<GraphicsModAction*>>
|
||||||
|
m_projection_target_to_actions;
|
||||||
|
std::unordered_map<std::string, std::vector<GraphicsModAction*>>
|
||||||
|
m_projection_texture_target_to_actions;
|
||||||
|
std::unordered_map<std::string, std::vector<GraphicsModAction*>> m_draw_started_target_to_actions;
|
||||||
|
std::unordered_map<std::string, std::vector<GraphicsModAction*>> m_load_target_to_actions;
|
||||||
|
std::unordered_map<FBInfo, std::vector<GraphicsModAction*>, FBInfoHasher> m_efb_target_to_actions;
|
||||||
|
std::unordered_map<FBInfo, std::vector<GraphicsModAction*>, FBInfoHasher> m_xfb_target_to_actions;
|
||||||
|
|
||||||
|
std::unordered_set<std::string> m_groups;
|
||||||
|
};
|
Loading…
x
Reference in New Issue
Block a user