Skip to content

Commit

Permalink
PostProcessing/ReShade: Fix up for GL/Vulkan
Browse files Browse the repository at this point in the history
  • Loading branch information
stenzek committed Aug 29, 2023
1 parent 22eecc2 commit 358f87a
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 26 deletions.
22 changes: 18 additions & 4 deletions dep/reshadefx/src/effect_codegen_glsl.cpp
Expand Up @@ -99,9 +99,16 @@ class codegen_glsl final : public codegen
"uvec4 compCond(bvec4 cond, uvec4 a, uvec4 b) { return uvec4(cond.x ? a.x : b.x, cond.y ? a.y : b.y, cond.z ? a.z : b.z, cond.w ? a.w : b.w); }\n";

if (!_ubo_block.empty())
// Read matrices in column major layout, even though they are actually row major, to avoid transposing them on every access (since GLSL uses column matrices)
// TODO: This technically only works with square matrices
preamble += "layout(std140, column_major, binding = 0) uniform _Globals {\n" + _ubo_block + "};\n";
{
if (_vulkan_semantics)
{
preamble += "layout(std140, set = 0, binding = 0) uniform _Globals {\n" + _ubo_block + "};\n";
}
else
{
preamble += "layout(std140, binding = 1) uniform _Globals {\n" + _ubo_block + "};\n";
}
}

module.code.assign(preamble.begin(), preamble.end());

Expand Down Expand Up @@ -620,7 +627,14 @@ class codegen_glsl final : public codegen

write_location(code, loc);

code += "layout(binding = " + std::to_string(info.binding);
code += "layout(";
if (_vulkan_semantics)
code += "set = 1, ";
#if 0
code += "binding = " + std::to_string(info.binding);
#else
code += "binding = /*SAMPLER:" + info.unique_name + "*/0";
#endif
code += ") uniform ";
write_type(code, info.type);
code += ' ' + id_to_name(info.id) + ";\n";
Expand Down
73 changes: 51 additions & 22 deletions src/util/postprocessing_shader_fx.cpp
Expand Up @@ -22,6 +22,7 @@

#include "fmt/format.h"

#include <bitset>
#include <cctype>
#include <cmath>
#include <cstring>
Expand All @@ -41,25 +42,32 @@ static std::unique_ptr<reshadefx::codegen> CreateRFXCodegen()
{
const bool debug_info = g_gpu_device ? g_gpu_device->IsDebugDevice() : false;
const bool uniforms_to_spec_constants = false;
const RenderAPI rapi = GetRenderAPI();

switch (GetRenderAPI())
switch (rapi)
{
case RenderAPI::None:
case RenderAPI::D3D11:
case RenderAPI::D3D12:
{
return std::unique_ptr<reshadefx::codegen>(
reshadefx::create_codegen_hlsl(50, debug_info, uniforms_to_spec_constants));
}

case RenderAPI::Vulkan:
case RenderAPI::Metal:
return std::unique_ptr<reshadefx::codegen>(
reshadefx::create_codegen_glsl(true, debug_info, uniforms_to_spec_constants));
{
return std::unique_ptr<reshadefx::codegen>(reshadefx::create_codegen_glsl(
true, debug_info, uniforms_to_spec_constants, false, (rapi == RenderAPI::Vulkan)));
}

case RenderAPI::OpenGL:
case RenderAPI::OpenGLES:
default:
{
return std::unique_ptr<reshadefx::codegen>(
reshadefx::create_codegen_glsl(false, debug_info, uniforms_to_spec_constants));
reshadefx::create_codegen_glsl(false, debug_info, uniforms_to_spec_constants, false, true));
}
}
}

Expand Down Expand Up @@ -989,12 +997,6 @@ bool PostProcessing::ReShadeFXShader::CompilePipeline(GPUTexture::Format format,
const RenderAPI api = g_gpu_device->GetRenderAPI();
const bool needs_main_defn = (api != RenderAPI::D3D11 && api != RenderAPI::D3D12);

if (api != RenderAPI::D3D11)
{
Log_ErrorPrintf("ReShade is currently only supported on Direct3D 11 (due to bugs)");
return false;
}

m_valid = false;
m_textures.clear();
m_passes.clear();
Expand All @@ -1021,21 +1023,34 @@ bool PostProcessing::ReShadeFXShader::CompilePipeline(GPUTexture::Format format,
GPUShaderStage stage) {
std::string real_code;
if (needs_main_defn)
real_code = fmt::format("#version 460 core\n#define ENTRY_POINT_{}\n{}", name, code);
{
// dFdx/dFdy are not defined in the vertex shader.
const char* defns = (stage == GPUShaderStage::Vertex) ? "#define dFdx(x) x\n#define dFdy(x) x\n" : "";
real_code = fmt::format("#version 460 core\n#define ENTRY_POINT_{}\n{}\n{}", name, defns, code);

for (const Sampler& sampler : samplers)
{
std::string decl = fmt::format("binding = /*SAMPLER:{}*/0", sampler.reshade_name);
std::string replacement = fmt::format("binding = {}", sampler.slot);
StringUtil::ReplaceAll(&real_code, decl, replacement);
}
}
else
{
real_code = std::string(code);

for (const Sampler& sampler : samplers)
{
std::string decl = fmt::format("__{}_t : register( t0);", sampler.reshade_name);
std::string replacement =
fmt::format("__{}_t : register({}t{});", sampler.reshade_name, (sampler.slot < 10) ? " " : "", sampler.slot);
StringUtil::ReplaceAll(&real_code, decl, replacement);

decl = fmt::format("__{}_s : register( s0);", sampler.reshade_name);
replacement =
fmt::format("__{}_s : register({}s{});", sampler.reshade_name, (sampler.slot < 10) ? " " : "", sampler.slot);
StringUtil::ReplaceAll(&real_code, decl, replacement);
for (const Sampler& sampler : samplers)
{
std::string decl = fmt::format("__{}_t : register( t0);", sampler.reshade_name);
std::string replacement =
fmt::format("__{}_t : register({}t{});", sampler.reshade_name, (sampler.slot < 10) ? " " : "", sampler.slot);
StringUtil::ReplaceAll(&real_code, decl, replacement);

decl = fmt::format("__{}_s : register( s0);", sampler.reshade_name);
replacement =
fmt::format("__{}_s : register({}s{});", sampler.reshade_name, (sampler.slot < 10) ? " " : "", sampler.slot);
StringUtil::ReplaceAll(&real_code, decl, replacement);
}
}

// FileSystem::WriteStringToFile("D:\\foo.txt", real_code);
Expand Down Expand Up @@ -1281,24 +1296,38 @@ bool PostProcessing::ReShadeFXShader::Apply(GPUTexture* input, GPUFramebuffer* f
g_gpu_device->SetPipeline(pass.pipeline.get());

// Set all inputs first, before the render pass starts.
std::bitset<GPUDevice::MAX_TEXTURE_SAMPLERS> bound_textures = {};
for (const Sampler& sampler : pass.samplers)
{
GL_INS("Texture Sampler %u: ID %d [%s]", sampler.slot, sampler.texture_id,
GetTextureNameForID(sampler.texture_id));
g_gpu_device->SetTextureSampler(sampler.slot, GetTextureByID(sampler.texture_id, input, final_target),
sampler.sampler);
bound_textures[sampler.slot] = true;
}

// Ensure RT wasn't left bound as a previous output, it breaks VK/DX12.
// TODO: Maybe move this into the backend? Not sure...
for (u32 i = 0; i < GPUDevice::MAX_TEXTURE_SAMPLERS; i++)
{
if (!bound_textures[i])
g_gpu_device->SetTextureSampler(i, nullptr, nullptr);
}

if (!output_fb)
{
// Drawing to final buffer.
if (!g_gpu_device->BeginPresent(false))
{
GL_POP();
return false;
}
}

g_gpu_device->Draw(pass.num_vertices, 0);
}

GL_POP();
m_frame_timer.Reset();
return true;
}

0 comments on commit 358f87a

Please sign in to comment.