PostProcessing: Add ReShade .fx shader support

This commit is contained in:
Stenzek
2023-08-13 23:23:54 +10:00
parent 288757ca9a
commit 8a40c7bf94
9 changed files with 1522 additions and 34 deletions

View File

@ -52,6 +52,8 @@ add_library(util
postprocessing.h
postprocessing_shader.cpp
postprocessing_shader.h
postprocessing_shader_fx.cpp
postprocessing_shader_fx.h
postprocessing_shader_glsl.cpp
postprocessing_shader_glsl.h
shadergen.cpp
@ -69,7 +71,7 @@ add_library(util
target_include_directories(util PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/..")
target_include_directories(util PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/..")
target_link_libraries(util PUBLIC common simpleini imgui)
target_link_libraries(util PRIVATE stb libchdr zlib soundtouch Zstd::Zstd)
target_link_libraries(util PRIVATE stb libchdr zlib soundtouch Zstd::Zstd reshadefx)
if(ENABLE_CUBEB)
target_sources(util PRIVATE

View File

@ -6,6 +6,7 @@
#include "host.h"
#include "imgui_manager.h"
#include "postprocessing_shader.h"
#include "postprocessing_shader_fx.h"
#include "postprocessing_shader_glsl.h"
// TODO: Remove me
@ -175,6 +176,32 @@ std::vector<std::pair<std::string, std::string>> PostProcessing::GetAvailableSha
}
}
FileSystem::FindFiles(Path::Combine(EmuFolders::Shaders, "reshade" FS_OSPATH_SEPARATOR_STR "Shaders").c_str(), "*.fx",
FILESYSTEM_FIND_FILES | FILESYSTEM_FIND_RELATIVE_PATHS, &results);
FileSystem::FindFiles(
Path::Combine(EmuFolders::Resources, "shaders" FS_OSPATH_SEPARATOR_STR "reshade" FS_OSPATH_SEPARATOR_STR "Shaders")
.c_str(),
"*.fx", FILESYSTEM_FIND_FILES | FILESYSTEM_FIND_RELATIVE_PATHS | FILESYSTEM_FIND_KEEP_ARRAY, &results);
for (FILESYSTEM_FIND_DATA& fd : results)
{
size_t pos = fd.FileName.rfind('.');
if (pos != std::string::npos && pos > 0)
fd.FileName.erase(pos);
// swap any backslashes for forward slashes so the config is cross-platform
for (size_t i = 0; i < fd.FileName.size(); i++)
{
if (fd.FileName[i] == '\\')
fd.FileName[i] = '/';
}
if (std::none_of(names.begin(), names.end(), [&fd](const auto& other) { return fd.FileName == other.second; }))
{
std::string display_name = fmt::format(TRANSLATE_FS("PostProcessing", "{} [ReShade]"), fd.FileName);
names.emplace_back(std::move(display_name), std::move(fd.FileName));
}
}
return names;
}
@ -333,7 +360,31 @@ void PostProcessing::SetEnabled(bool enabled)
std::unique_ptr<PostProcessing::Shader> PostProcessing::TryLoadingShader(const std::string& shader_name,
bool only_config, Error* error)
{
std::string filename(Path::Combine(EmuFolders::Shaders, fmt::format("{}.glsl", shader_name)));
std::string filename;
std::optional<std::string> resource_str;
// Try reshade first.
filename = Path::Combine(
EmuFolders::Shaders,
fmt::format("reshade" FS_OSPATH_SEPARATOR_STR "Shaders" FS_OSPATH_SEPARATOR_STR "{}.fx", shader_name));
// TODO: Won't work on Android. Who cares? All the homies are tired of demanding Android users.
if (!FileSystem::FileExists(filename.c_str()))
{
filename = Path::Combine(EmuFolders::Resources,
fmt::format("shaders" FS_OSPATH_SEPARATOR_STR "reshade" FS_OSPATH_SEPARATOR_STR
"Shaders" FS_OSPATH_SEPARATOR_STR "{}.fx",
shader_name));
}
if (FileSystem::FileExists(filename.c_str()))
{
std::unique_ptr<ReShadeFXShader> shader = std::make_unique<ReShadeFXShader>();
if (shader->LoadFromFile(std::string(shader_name), filename.c_str(), only_config, error))
return shader;
}
filename = Path::Combine(EmuFolders::Shaders, fmt::format("{}.glsl", shader_name));
if (FileSystem::FileExists(filename.c_str()))
{
std::unique_ptr<GLSLShader> shader = std::make_unique<GLSLShader>();
@ -341,8 +392,8 @@ std::unique_ptr<PostProcessing::Shader> PostProcessing::TryLoadingShader(const s
return shader;
}
std::optional<std::string> resource_str(
Host::ReadResourceFileToString(fmt::format("shaders" FS_OSPATH_SEPARATOR_STR "{}.glsl", shader_name).c_str()));
resource_str =
Host::ReadResourceFileToString(fmt::format("shaders" FS_OSPATH_SEPARATOR_STR "{}.glsl", shader_name).c_str());
if (resource_str.has_value())
{
std::unique_ptr<GLSLShader> shader = std::make_unique<GLSLShader>();

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,122 @@
// SPDX-FileCopyrightText: 2019-2023 Connor McLaughlin <stenzek@gmail.com>
// SPDX-License-Identifier: (GPL-3.0 OR CC-BY-NC-ND-4.0)
#pragma once
#include "postprocessing_shader.h"
#include "common/timer.h"
// reshadefx
#include "effect_module.hpp"
class Error;
namespace PostProcessing {
class ReShadeFXShader final : public Shader
{
public:
ReShadeFXShader();
~ReShadeFXShader();
bool IsValid() const override;
bool LoadFromFile(std::string name, const char* filename, bool only_config, Error* error);
bool ResizeOutput(GPUTexture::Format format, u32 width, u32 height) override;
bool CompilePipeline(GPUTexture::Format format, u32 width, u32 height) override;
bool Apply(GPUTexture* input, GPUFramebuffer* final_target, s32 final_left, s32 final_top, s32 final_width,
s32 final_height, s32 orig_width, s32 orig_height, u32 target_width, u32 target_height) override;
private:
using TextureID = s32;
static constexpr TextureID INPUT_COLOR_TEXTURE = -1;
static constexpr TextureID INPUT_DEPTH_TEXTURE = -2;
static constexpr TextureID OUTPUT_COLOR_TEXTURE = -3;
enum class SourceOptionType
{
None,
Zero,
Timer,
FrameTime,
FrameCount,
FrameCountF,
PingPong,
MousePoint,
BufferWidth,
BufferHeight,
BufferWidthF,
BufferHeightF,
InternalWidth,
InternalHeight,
InternalWidthF,
InternalHeightF,
MaxCount
};
struct SourceOption
{
SourceOptionType source;
u32 offset;
float min;
float max;
float smoothing;
std::array<float, 2> step;
ShaderOption::ValueVector value;
};
bool CreateModule(s32 buffer_width, s32 buffer_height, reshadefx::module* mod, Error* error);
bool CreateOptions(const reshadefx::module& mod, Error* error);
bool GetSourceOption(const reshadefx::uniform_info& ui, SourceOptionType* si, Error* error);
bool CreatePasses(GPUTexture::Format backbuffer_format, reshadefx::module& mod, Error* error);
const char* GetTextureNameForID(TextureID id) const;
GPUTexture* GetTextureByID(TextureID id, GPUTexture* input, GPUFramebuffer* final_target) const;
GPUFramebuffer* GetFramebufferByID(TextureID id, GPUTexture* input, GPUFramebuffer* final_target) const;
std::string m_filename;
struct Texture
{
std::unique_ptr<GPUTexture> texture;
std::unique_ptr<GPUFramebuffer> framebuffer;
std::string reshade_name; // TODO: we might be able to drop this
GPUTexture::Format format;
float rt_scale;
};
struct Sampler
{
u32 slot;
TextureID texture_id;
std::string reshade_name;
GPUSampler* sampler;
};
struct Pass
{
std::unique_ptr<GPUPipeline> pipeline;
TextureID render_target;
std::vector<Sampler> samplers;
u32 num_vertices;
#ifdef _DEBUG
std::string name;
#endif
};
std::vector<Pass> m_passes;
std::vector<Texture> m_textures;
std::vector<SourceOption> m_source_options;
u32 m_uniforms_size = 0;
bool m_valid = false;
Common::Timer m_frame_timer;
u32 m_frame_count = 0;
};
} // namespace PostProcessing

View File

@ -64,6 +64,7 @@
<ClInclude Include="platform_misc.h" />
<ClInclude Include="postprocessing.h" />
<ClInclude Include="postprocessing_shader.h" />
<ClInclude Include="postprocessing_shader_fx.h" />
<ClInclude Include="postprocessing_shader_glsl.h" />
<ClInclude Include="sdl_input_source.h" />
<ClInclude Include="shadergen.h" />
@ -164,6 +165,7 @@
<ClCompile Include="platform_misc_win32.cpp" />
<ClCompile Include="postprocessing.cpp" />
<ClCompile Include="postprocessing_shader.cpp" />
<ClCompile Include="postprocessing_shader_fx.cpp" />
<ClCompile Include="postprocessing_shader_glsl.cpp" />
<ClCompile Include="sdl_input_source.cpp" />
<ClCompile Include="shadergen.cpp" />
@ -215,6 +217,9 @@
<ProjectReference Include="..\..\dep\libchdr\libchdr.vcxproj">
<Project>{425d6c99-d1c8-43c2-b8ac-4d7b1d941017}</Project>
</ProjectReference>
<ProjectReference Include="..\..\dep\reshadefx\reshadefx.vcxproj">
<Project>{27b8d4bb-4f01-4432-bc14-9bf6ca458eee}</Project>
</ProjectReference>
<ProjectReference Include="..\..\dep\soundtouch\soundtouch.vcxproj">
<Project>{751d9f62-881c-454e-bce8-cb9cf5f1d22f}</Project>
</ProjectReference>
@ -238,8 +243,9 @@
<Import Project="util.props" />
<ItemDefinitionGroup>
<ClCompile>
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(SolutionDir)dep\reshadefx\include</AdditionalIncludeDirectories>
<ObjectFileName>$(IntDir)/%(RelativeDir)/</ObjectFileName>
</ClCompile>
</ItemDefinitionGroup>
<Import Project="..\..\dep\msvc\vsprops\Targets.props" />
</Project>
</Project>

View File

@ -69,6 +69,7 @@
<ClInclude Include="d3d11_stream_buffer.h" />
<ClInclude Include="d3d11_texture.h" />
<ClInclude Include="host.h" />
<ClInclude Include="postprocessing_shader_fx.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="jit_code_buffer.cpp" />
@ -144,10 +145,11 @@
<ClCompile Include="d3d11_stream_buffer.cpp" />
<ClCompile Include="d3d11_texture.cpp" />
<ClCompile Include="host.cpp" />
<ClCompile Include="postprocessing_shader_fx.cpp" />
</ItemGroup>
<ItemGroup>
<Filter Include="gl">
<UniqueIdentifier>{e637fc5b-2483-4a31-abc3-89a16d45c223}</UniqueIdentifier>
</Filter>
</ItemGroup>
</Project>
</Project>