Skip to content

Commit

Permalink
PostProcessing: Add ReShade .fx shader support
Browse files Browse the repository at this point in the history
  • Loading branch information
stenzek committed Aug 29, 2023
1 parent 288757c commit 8a40c7b
Show file tree
Hide file tree
Showing 9 changed files with 1,522 additions and 34 deletions.
52 changes: 26 additions & 26 deletions README.md
Expand Up @@ -22,37 +22,37 @@ DuckStation features a fully-featured frontend built using Qt, as well as a full

Other features include:

- CPU Recompiler/JIT (x86-64, armv7/AArch32 and AArch64)
- Hardware (D3D11, D3D12, OpenGL, Vulkan, Metal) and software rendering
- Upscaling, texture filtering, and true colour (24-bit) in hardware renderers
- PGXP for geometry precision, texture correction, and depth buffer emulation
- Adaptive downsampling filter
- Post processing shader chains
- "Fast boot" for skipping BIOS splash/intro
- Save state support
- Windows, Linux, macOS support
- CPU Recompiler/JIT (x86-64, armv7/AArch32 and AArch64).
- Hardware (D3D11, D3D12, OpenGL, Vulkan, Metal) and software rendering.
- Upscaling, texture filtering, and true colour (24-bit) in hardware renderers.
- PGXP for geometry precision, texture correction, and depth buffer emulation.
- Adaptive downsampling filter.
- Post processing shader chains (GLSL and experimental Reshade FX).
- "Fast boot" for skipping BIOS splash/intro.
- Save state support.
- Windows, Linux, macOS support.
- Supports bin/cue images, raw bin/img files, MAME CHD, single-track ECM, MDS/MDF, and unencrypted PBP formats.
- Direct booting of homebrew executables
- Direct loading of Portable Sound Format (psf) files
- Digital and analog controllers for input (rumble is forwarded to host)
- Namco GunCon lightgun support (simulated with mouse)
- NeGcon support
- Qt and "Big Picture" UI
- Automatic updates for Windows builds
- Automatic content scanning - game titles/hashes are provided by redump.org
- Optional automatic switching of memory cards for each game
- Supports loading cheats from existing lists
- Memory card editor and save importer
- Emulated CPU overclocking
- Integrated and remote debugging
- Multitap controllers (up to 8 devices)
- RetroAchievements
- Automatic loading/applying of PPF patches
- Direct booting of homebrew executables.
- Direct loading of Portable Sound Format (psf) files.
- Digital and analog controllers for input (rumble is forwarded to host).
- Namco GunCon lightgun support (simulated with mouse).
- NeGcon support.
- Qt and "Big Picture" UI.
- Automatic updates for Windows builds.
- Automatic content scanning - game titles/hashes are provided by redump.org.
- Optional automatic switching of memory cards for each game.
- Supports loading cheats from existing lists.
- Memory card editor and save importer.
- Emulated CPU overclocking.
- Integrated and remote debugging.
- Multitap controllers (up to 8 devices).
- RetroAchievements.
- Automatic loading/applying of PPF patches.

## System Requirements
- A CPU faster than a potato. But it needs to be x86_64, AArch32/armv7, or AArch64/ARMv8, otherwise you won't get a recompiler and it'll be slow.
- For the hardware renderers, a GPU capable of OpenGL 3.1/OpenGL ES 3.1/Direct3D 11 Feature Level 10.0 (or Vulkan 1.0) and above. So, basically anything made in the last 10 years or so.
- SDL, XInput or DInput compatible game controller (e.g. XB360/XBOne). DualShock 3 users on Windows will need to install the official DualShock 3 drivers included as part of PlayStation Now.
- SDL, XInput or DInput compatible game controller (e.g. XB360/XBOne/XBSeries). DualShock 3 users on Windows will need to install the official DualShock 3 drivers included as part of PlayStation Now.

## Downloading and running
Binaries of DuckStation for Windows x64/ARM64, Linux x86_64 (in AppImage format), and Android ARMv7/ARMv8 are available via GitHub Releases and are automatically built with every commit/push. Binaries or packages distributed through other sources may be out of date and are not supported by the developer, please speak to them for support, not us.
Expand Down
1 change: 1 addition & 0 deletions dep/CMakeLists.txt
Expand Up @@ -16,6 +16,7 @@ add_subdirectory(soundtouch)
add_subdirectory(googletest)
add_subdirectory(cpuinfo)
add_subdirectory(fast_float)
add_subdirectory(reshadefx)

if(ENABLE_CUBEB)
add_subdirectory(cubeb)
Expand Down
4 changes: 2 additions & 2 deletions dep/reshadefx/src/effect_codegen_hlsl.cpp
Expand Up @@ -632,9 +632,9 @@ class codegen_hlsl final : public codegen
const unsigned int texture_dimension = info.type.texture_dimension();
code += "Texture" + std::to_string(texture_dimension) + "D<";
write_texture_format(code, tex_info.format);
code += "> __" + info.unique_name + "_t : register(t" + std::to_string(info.binding) + "); \n";
code += "> __" + info.unique_name + "_t : register( t0); \n";

code += "SamplerState __" + info.unique_name + "_s : register(s" + std::to_string(info.binding) + ");\n";
code += "SamplerState __" + info.unique_name + "_s : register( s0);\n";

code += "static const ";
write_type(code, info.type);
Expand Down
4 changes: 3 additions & 1 deletion src/util/CMakeLists.txt
Expand Up @@ -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
Expand All @@ -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
Expand Down
57 changes: 54 additions & 3 deletions src/util/postprocessing.cpp
Expand Up @@ -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
Expand Down Expand Up @@ -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;
}

Expand Down Expand Up @@ -333,16 +360,40 @@ 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>();
if (shader->LoadFromFile(std::string(shader_name), filename.c_str(), error))
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>();
Expand Down

0 comments on commit 8a40c7b

Please sign in to comment.