dep/reshadefx: Update to 7bdfb03

This commit is contained in:
Stenzek
2024-09-08 19:19:58 +10:00
parent 3078339f64
commit 86bff869bc
25 changed files with 6041 additions and 3244 deletions

View File

@ -83,15 +83,16 @@ static std::unique_ptr<reshadefx::codegen> CreateRFXCodegen()
case RenderAPI::Metal:
{
return std::unique_ptr<reshadefx::codegen>(reshadefx::create_codegen_glsl(
false, true, debug_info, uniforms_to_spec_constants, false, (rapi == RenderAPI::Vulkan)));
460, false, 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(
(rapi == RenderAPI::OpenGLES), false, debug_info, uniforms_to_spec_constants, false, true));
return std::unique_ptr<reshadefx::codegen>(
reshadefx::create_codegen_glsl(ShaderGen::GetGLSLVersion(rapi), (rapi == RenderAPI::OpenGLES), false,
debug_info, uniforms_to_spec_constants, false, true));
}
}
}
@ -120,7 +121,7 @@ static GPUTexture::Format MapTextureFormat(reshadefx::texture_format format)
return s_mapping[static_cast<u32>(format)];
}
static GPUSampler::Config MapSampler(const reshadefx::sampler_info& si)
static GPUSampler::Config MapSampler(const reshadefx::sampler_desc& si)
{
GPUSampler::Config config = GPUSampler::GetNearestConfig();
@ -200,44 +201,44 @@ static GPUSampler::Config MapSampler(const reshadefx::sampler_info& si)
return config;
}
static GPUPipeline::BlendState MapBlendState(const reshadefx::pass_info& pi)
static GPUPipeline::BlendState MapBlendState(const reshadefx::pass& pi)
{
static constexpr auto map_blend_op = [](const reshadefx::pass_blend_op o) {
static constexpr auto map_blend_op = [](const reshadefx::blend_op o) {
switch (o)
{
case reshadefx::pass_blend_op::add:
case reshadefx::blend_op::add:
return GPUPipeline::BlendOp::Add;
case reshadefx::pass_blend_op::subtract:
case reshadefx::blend_op::subtract:
return GPUPipeline::BlendOp::Subtract;
case reshadefx::pass_blend_op::reverse_subtract:
case reshadefx::blend_op::reverse_subtract:
return GPUPipeline::BlendOp::ReverseSubtract;
case reshadefx::pass_blend_op::min:
case reshadefx::blend_op::min:
return GPUPipeline::BlendOp::Min;
case reshadefx::pass_blend_op::max:
case reshadefx::blend_op::max:
default:
return GPUPipeline::BlendOp::Max;
}
};
static constexpr auto map_blend_factor = [](const reshadefx::pass_blend_factor f) {
static constexpr auto map_blend_factor = [](const reshadefx::blend_factor f) {
switch (f)
{
case reshadefx::pass_blend_factor::zero:
case reshadefx::blend_factor::zero:
return GPUPipeline::BlendFunc::Zero;
case reshadefx::pass_blend_factor::one:
case reshadefx::blend_factor::one:
return GPUPipeline::BlendFunc::One;
case reshadefx::pass_blend_factor::source_color:
case reshadefx::blend_factor::source_color:
return GPUPipeline::BlendFunc::SrcColor;
case reshadefx::pass_blend_factor::one_minus_source_color:
case reshadefx::blend_factor::one_minus_source_color:
return GPUPipeline::BlendFunc::InvSrcColor;
case reshadefx::pass_blend_factor::dest_color:
case reshadefx::blend_factor::dest_color:
return GPUPipeline::BlendFunc::DstColor;
case reshadefx::pass_blend_factor::one_minus_dest_color:
case reshadefx::blend_factor::one_minus_dest_color:
return GPUPipeline::BlendFunc::InvDstColor;
case reshadefx::pass_blend_factor::source_alpha:
case reshadefx::blend_factor::source_alpha:
return GPUPipeline::BlendFunc::SrcAlpha;
case reshadefx::pass_blend_factor::one_minus_source_alpha:
case reshadefx::blend_factor::one_minus_source_alpha:
return GPUPipeline::BlendFunc::InvSrcAlpha;
case reshadefx::pass_blend_factor::dest_alpha:
case reshadefx::blend_factor::dest_alpha:
default:
return GPUPipeline::BlendFunc::DstAlpha;
}
@ -245,13 +246,13 @@ static GPUPipeline::BlendState MapBlendState(const reshadefx::pass_info& pi)
GPUPipeline::BlendState bs = GPUPipeline::BlendState::GetNoBlendingState();
bs.enable = (pi.blend_enable[0] != 0);
bs.blend_op = map_blend_op(pi.blend_op[0]);
bs.src_blend = map_blend_factor(pi.src_blend[0]);
bs.dst_blend = map_blend_factor(pi.dest_blend[0]);
bs.alpha_blend_op = map_blend_op(pi.blend_op_alpha[0]);
bs.src_alpha_blend = map_blend_factor(pi.src_blend_alpha[0]);
bs.dst_alpha_blend = map_blend_factor(pi.dest_blend_alpha[0]);
bs.write_mask = pi.color_write_mask[0];
bs.blend_op = map_blend_op(pi.color_blend_op[0]);
bs.src_blend = map_blend_factor(pi.source_color_blend_factor[0]);
bs.dst_blend = map_blend_factor(pi.dest_color_blend_factor[0]);
bs.alpha_blend_op = map_blend_op(pi.alpha_blend_op[0]);
bs.src_alpha_blend = map_blend_factor(pi.source_alpha_blend_factor[0]);
bs.dst_alpha_blend = map_blend_factor(pi.dest_alpha_blend_factor[0]);
bs.write_mask = pi.render_target_write_mask[0];
return bs;
}
@ -306,14 +307,19 @@ bool PostProcessing::ReShadeFXShader::LoadFromString(std::string name, std::stri
if (code.empty() || code.back() != '\n')
code.push_back('\n');
reshadefx::module temp_module;
// TODO: This could use spv, it's probably fastest.
std::unique_ptr<reshadefx::codegen> cg = CreateRFXCodegen();
if (!cg)
return false;
if (!CreateModule(only_config ? DEFAULT_BUFFER_WIDTH : g_gpu_device->GetWindowWidth(),
only_config ? DEFAULT_BUFFER_HEIGHT : g_gpu_device->GetWindowHeight(), &temp_module,
std::move(code), error))
only_config ? DEFAULT_BUFFER_HEIGHT : g_gpu_device->GetWindowHeight(), cg.get(), std::move(code),
error))
{
return false;
}
const reshadefx::effect_module& temp_module = cg->module();
if (!CreateOptions(temp_module, error))
return false;
@ -321,9 +327,9 @@ bool PostProcessing::ReShadeFXShader::LoadFromString(std::string name, std::stri
if (!temp_module.techniques.empty())
{
bool has_passes = false;
for (const reshadefx::technique_info& tech : temp_module.techniques)
for (const reshadefx::technique& tech : temp_module.techniques)
{
for (const reshadefx::pass_info& pi : tech.passes)
for (const reshadefx::pass& pi : tech.passes)
{
has_passes = true;
@ -338,15 +344,15 @@ bool PostProcessing::ReShadeFXShader::LoadFromString(std::string name, std::stri
if (max_rt > GPUDevice::MAX_RENDER_TARGETS)
{
Error::SetString(error, fmt::format("Too many render targets ({}) in pass {}, only {} are supported.", max_rt,
pi.name, GPUDevice::MAX_RENDER_TARGETS));
Error::SetStringFmt(error, "Too many render targets ({}) in pass {}, only {} are supported.", max_rt, pi.name,
GPUDevice::MAX_RENDER_TARGETS);
return false;
}
if (pi.samplers.size() > GPUDevice::MAX_TEXTURE_SAMPLERS)
if (pi.sampler_bindings.size() > GPUDevice::MAX_TEXTURE_SAMPLERS)
{
Error::SetString(error, fmt::format("Too many samplers ({}) in pass {}, only {} are supported.",
pi.samplers.size(), pi.name, GPUDevice::MAX_TEXTURE_SAMPLERS));
Error::SetStringFmt(error, "Too many samplers ({}) in pass {}, only {} are supported.",
pi.sampler_bindings.size(), pi.name, GPUDevice::MAX_TEXTURE_SAMPLERS);
return false;
}
}
@ -373,7 +379,7 @@ bool PostProcessing::ReShadeFXShader::WantsDepthBuffer() const
return m_wants_depth_buffer;
}
bool PostProcessing::ReShadeFXShader::CreateModule(s32 buffer_width, s32 buffer_height, reshadefx::module* mod,
bool PostProcessing::ReShadeFXShader::CreateModule(s32 buffer_width, s32 buffer_height, reshadefx::codegen* cg,
std::string code, Error* error)
{
reshadefx::preprocessor pp;
@ -427,26 +433,21 @@ bool PostProcessing::ReShadeFXShader::CreateModule(s32 buffer_width, s32 buffer_
if (!pp.append_string(std::move(code), m_filename))
{
Error::SetString(error, fmt::format("Failed to preprocess:\n{}", pp.errors()));
Error::SetStringFmt(error, "Failed to preprocess:\n{}", pp.errors());
return false;
}
std::unique_ptr<reshadefx::codegen> cg = CreateRFXCodegen();
if (!cg)
return false;
reshadefx::parser parser;
if (!parser.parse(pp.output(), cg.get()))
if (!parser.parse(pp.output(), cg))
{
Error::SetString(error, fmt::format("Failed to parse:\n{}", parser.errors()));
Error::SetStringFmt(error, "Failed to parse:\n{}", parser.errors());
return false;
}
cg->write_result(*mod);
return true;
}
static bool HasAnnotationWithName(const reshadefx::uniform_info& uniform, const std::string_view annotation_name)
static bool HasAnnotationWithName(const reshadefx::uniform& uniform, const std::string_view annotation_name)
{
for (const reshadefx::annotation& an : uniform.annotations)
{
@ -493,7 +494,7 @@ static bool GetBooleanAnnotationValue(const std::vector<reshadefx::annotation>&
}
static PostProcessing::ShaderOption::ValueVector
GetVectorAnnotationValue(const reshadefx::uniform_info& uniform, const std::string_view annotation_name,
GetVectorAnnotationValue(const reshadefx::uniform& uniform, const std::string_view annotation_name,
const PostProcessing::ShaderOption::ValueVector& default_value)
{
PostProcessing::ShaderOption::ValueVector vv = default_value;
@ -575,9 +576,9 @@ GetVectorAnnotationValue(const reshadefx::uniform_info& uniform, const std::stri
return vv;
}
bool PostProcessing::ReShadeFXShader::CreateOptions(const reshadefx::module& mod, Error* error)
bool PostProcessing::ReShadeFXShader::CreateOptions(const reshadefx::effect_module& mod, Error* error)
{
for (const reshadefx::uniform_info& ui : mod.uniforms)
for (const reshadefx::uniform& ui : mod.uniforms)
{
SourceOptionType so;
if (!GetSourceOption(ui, &so, error))
@ -639,7 +640,7 @@ bool PostProcessing::ReShadeFXShader::CreateOptions(const reshadefx::module& mod
break;
default:
Error::SetString(error, fmt::format("Unhandled uniform type {} ({})", static_cast<u32>(ui.type.base), ui.name));
Error::SetStringFmt(error, "Unhandled uniform type {} ({})", static_cast<u32>(ui.type.base), ui.name);
return false;
}
@ -648,8 +649,7 @@ bool PostProcessing::ReShadeFXShader::CreateOptions(const reshadefx::module& mod
opt.vector_size = ui.type.components();
if (opt.vector_size == 0 || opt.vector_size > ShaderOption::MAX_VECTOR_COMPONENTS)
{
Error::SetString(error,
fmt::format("Unhandled vector size {} ({})", static_cast<u32>(ui.type.components()), ui.name));
Error::SetStringFmt(error, "Unhandled vector size {} ({})", static_cast<u32>(ui.type.components()), ui.name);
return false;
}
@ -762,8 +762,7 @@ bool PostProcessing::ReShadeFXShader::CreateOptions(const reshadefx::module& mod
return true;
}
bool PostProcessing::ReShadeFXShader::GetSourceOption(const reshadefx::uniform_info& ui, SourceOptionType* si,
Error* error)
bool PostProcessing::ReShadeFXShader::GetSourceOption(const reshadefx::uniform& ui, SourceOptionType* si, Error* error)
{
// TODO: Rewrite these to a lookup table instead, this if chain is terrible.
const std::string_view source = GetStringAnnotationValue(ui.annotations, "source", {});
@ -773,8 +772,8 @@ bool PostProcessing::ReShadeFXShader::GetSourceOption(const reshadefx::uniform_i
{
if (ui.type.base != reshadefx::type::t_float || ui.type.components() > 1)
{
Error::SetString(
error, fmt::format("Unexpected type '{}' for timer source in uniform '{}'", ui.type.description(), ui.name));
Error::SetStringFmt(error, "Unexpected type '{}' for timer source in uniform '{}'", ui.type.description(),
ui.name);
return false;
}
@ -785,8 +784,8 @@ bool PostProcessing::ReShadeFXShader::GetSourceOption(const reshadefx::uniform_i
{
if ((!ui.type.is_integral() && !ui.type.is_floating_point()) || ui.type.components() > 1)
{
Error::SetString(
error, fmt::format("Unexpected type '{}' for timer source in uniform '{}'", ui.type.description(), ui.name));
Error::SetStringFmt(error, "Unexpected type '{}' for timer source in uniform '{}'", ui.type.description(),
ui.name);
return false;
}
@ -797,8 +796,8 @@ bool PostProcessing::ReShadeFXShader::GetSourceOption(const reshadefx::uniform_i
{
if (ui.type.base != reshadefx::type::t_float || ui.type.components() > 1)
{
Error::SetString(
error, fmt::format("Unexpected type '{}' for timer source in uniform '{}'", ui.type.description(), ui.name));
Error::SetStringFmt(error, "Unexpected type '{}' for timer source in uniform '{}'", ui.type.description(),
ui.name);
return false;
}
@ -809,8 +808,8 @@ bool PostProcessing::ReShadeFXShader::GetSourceOption(const reshadefx::uniform_i
{
if (!ui.type.is_floating_point() || ui.type.components() < 2)
{
Error::SetString(error, fmt::format("Unexpected type '{}' for pingpong source in uniform '{}'",
ui.type.description(), ui.name));
Error::SetStringFmt(error, "Unexpected type '{}' for pingpong source in uniform '{}'", ui.type.description(),
ui.name);
return false;
}
@ -821,8 +820,8 @@ bool PostProcessing::ReShadeFXShader::GetSourceOption(const reshadefx::uniform_i
{
if (!ui.type.is_floating_point() || ui.type.components() < 2)
{
Error::SetString(error, fmt::format("Unexpected type '{}' for mousepoint source in uniform '{}'",
ui.type.description(), ui.name));
Error::SetStringFmt(error, "Unexpected type '{}' for mousepoint source in uniform '{}'", ui.type.description(),
ui.name);
return false;
}
@ -839,8 +838,8 @@ bool PostProcessing::ReShadeFXShader::GetSourceOption(const reshadefx::uniform_i
{
if ((!ui.type.is_floating_point() && !ui.type.is_integral()) || ui.type.components() != 1)
{
Error::SetString(error, fmt::format("Unexpected type '{}' ({} components) for random source in uniform '{}'",
ui.type.description(), ui.type.components(), ui.name));
Error::SetStringFmt(error, "Unexpected type '{}' ({} components) for random source in uniform '{}'",
ui.type.description(), ui.type.components(), ui.name);
return false;
}
@ -896,8 +895,8 @@ bool PostProcessing::ReShadeFXShader::GetSourceOption(const reshadefx::uniform_i
{
if (!ui.type.is_floating_point() || ui.type.components() != 1)
{
Error::SetString(error, fmt::format("Unexpected type '{}' for {} source in uniform '{}'", ui.type.description(),
source, ui.name));
Error::SetStringFmt(error, "Unexpected type '{}' for {} source in uniform '{}'", ui.type.description(), source,
ui.name);
return false;
}
@ -908,8 +907,8 @@ bool PostProcessing::ReShadeFXShader::GetSourceOption(const reshadefx::uniform_i
{
if (!ui.type.is_floating_point() || ui.type.components() != 1)
{
Error::SetString(error, fmt::format("Unexpected type '{}' for {} source in uniform '{}'", ui.type.description(),
source, ui.name));
Error::SetStringFmt(error, "Unexpected type '{}' for {} source in uniform '{}'", ui.type.description(), source,
ui.name);
return false;
}
@ -920,8 +919,8 @@ bool PostProcessing::ReShadeFXShader::GetSourceOption(const reshadefx::uniform_i
{
if (!ui.type.is_floating_point() || ui.type.components() != 1)
{
Error::SetString(error, fmt::format("Unexpected type '{}' for {} source in uniform '{}'", ui.type.description(),
source, ui.name));
Error::SetStringFmt(error, "Unexpected type '{}' for {} source in uniform '{}'", ui.type.description(), source,
ui.name);
return false;
}
@ -932,8 +931,8 @@ bool PostProcessing::ReShadeFXShader::GetSourceOption(const reshadefx::uniform_i
{
if (!ui.type.is_floating_point() || ui.type.components() != 1)
{
Error::SetString(error, fmt::format("Unexpected type '{}' for {} source in uniform '{}'", ui.type.description(),
source, ui.name));
Error::SetStringFmt(error, "Unexpected type '{}' for {} source in uniform '{}'", ui.type.description(), source,
ui.name);
return false;
}
@ -944,8 +943,8 @@ bool PostProcessing::ReShadeFXShader::GetSourceOption(const reshadefx::uniform_i
{
if (!ui.type.is_floating_point() || ui.type.components() != 1)
{
Error::SetString(error, fmt::format("Unexpected type '{}' for {} source in uniform '{}'", ui.type.description(),
source, ui.name));
Error::SetStringFmt(error, "Unexpected type '{}' for {} source in uniform '{}'", ui.type.description(), source,
ui.name);
return false;
}
@ -956,8 +955,8 @@ bool PostProcessing::ReShadeFXShader::GetSourceOption(const reshadefx::uniform_i
{
if (!ui.type.is_floating_point() || ui.type.components() != 2)
{
Error::SetString(error, fmt::format("Unexpected type '{}' for {} source in uniform '{}'", ui.type.description(),
source, ui.name));
Error::SetStringFmt(error, "Unexpected type '{}' for {} source in uniform '{}'", ui.type.description(), source,
ui.name);
return false;
}
@ -968,8 +967,8 @@ bool PostProcessing::ReShadeFXShader::GetSourceOption(const reshadefx::uniform_i
{
if (!ui.type.is_floating_point() || ui.type.components() != 2)
{
Error::SetString(error, fmt::format("Unexpected type '{}' for {} source in uniform '{}'", ui.type.description(),
source, ui.name));
Error::SetStringFmt(error, "Unexpected type '{}' for {} source in uniform '{}'", ui.type.description(), source,
ui.name);
return false;
}
@ -980,8 +979,8 @@ bool PostProcessing::ReShadeFXShader::GetSourceOption(const reshadefx::uniform_i
{
if (!ui.type.is_floating_point() || ui.type.components() != 2)
{
Error::SetString(error, fmt::format("Unexpected type '{}' for {} source in uniform '{}'", ui.type.description(),
source, ui.name));
Error::SetStringFmt(error, "Unexpected type '{}' for {} source in uniform '{}'", ui.type.description(), source,
ui.name);
return false;
}
@ -992,8 +991,8 @@ bool PostProcessing::ReShadeFXShader::GetSourceOption(const reshadefx::uniform_i
{
if (!ui.type.is_floating_point() || ui.type.components() != 2)
{
Error::SetString(error, fmt::format("Unexpected type '{}' for {} source in uniform '{}'", ui.type.description(),
source, ui.name));
Error::SetStringFmt(error, "Unexpected type '{}' for {} source in uniform '{}'", ui.type.description(), source,
ui.name);
return false;
}
@ -1004,8 +1003,8 @@ bool PostProcessing::ReShadeFXShader::GetSourceOption(const reshadefx::uniform_i
{
if (!ui.type.is_floating_point() || ui.type.components() != 2)
{
Error::SetString(error, fmt::format("Unexpected type '{}' for {} source in uniform '{}'", ui.type.description(),
source, ui.name));
Error::SetStringFmt(error, "Unexpected type '{}' for {} source in uniform '{}'", ui.type.description(), source,
ui.name);
return false;
}
@ -1016,8 +1015,8 @@ bool PostProcessing::ReShadeFXShader::GetSourceOption(const reshadefx::uniform_i
{
if (!ui.type.is_floating_point() || ui.type.components() != 2)
{
Error::SetString(error, fmt::format("Unexpected type '{}' for {} source in uniform '{}'", ui.type.description(),
source, ui.name));
Error::SetStringFmt(error, "Unexpected type '{}' for {} source in uniform '{}'", ui.type.description(), source,
ui.name);
return false;
}
@ -1028,8 +1027,8 @@ bool PostProcessing::ReShadeFXShader::GetSourceOption(const reshadefx::uniform_i
{
if (!ui.type.is_floating_point() || ui.type.components() != 2)
{
Error::SetString(error, fmt::format("Unexpected type '{}' for {} source in uniform '{}'", ui.type.description(),
source, ui.name));
Error::SetStringFmt(error, "Unexpected type '{}' for {} source in uniform '{}'", ui.type.description(), source,
ui.name);
return false;
}
@ -1038,7 +1037,7 @@ bool PostProcessing::ReShadeFXShader::GetSourceOption(const reshadefx::uniform_i
}
else
{
Error::SetString(error, fmt::format("Unknown source '{}' in uniform '{}'", source, ui.name));
Error::SetStringFmt(error, "Unknown source '{}' in uniform '{}'", source, ui.name);
return false;
}
}
@ -1062,11 +1061,11 @@ bool PostProcessing::ReShadeFXShader::GetSourceOption(const reshadefx::uniform_i
return true;
}
bool PostProcessing::ReShadeFXShader::CreatePasses(GPUTexture::Format backbuffer_format, reshadefx::module& mod,
Error* error)
bool PostProcessing::ReShadeFXShader::CreatePasses(GPUTexture::Format backbuffer_format,
const reshadefx::effect_module& mod, Error* error)
{
u32 total_passes = 0;
for (const reshadefx::technique_info& tech : mod.techniques)
for (const reshadefx::technique& tech : mod.techniques)
total_passes += static_cast<u32>(tech.passes.size());
if (total_passes == 0)
{
@ -1077,7 +1076,7 @@ bool PostProcessing::ReShadeFXShader::CreatePasses(GPUTexture::Format backbuffer
m_passes.reserve(total_passes);
// Named render targets.
for (const reshadefx::texture_info& ti : mod.textures)
for (const reshadefx::texture& ti : mod.textures)
{
Texture tex;
@ -1097,7 +1096,7 @@ bool PostProcessing::ReShadeFXShader::CreatePasses(GPUTexture::Format backbuffer
const std::string_view source = GetStringAnnotationValue(ti.annotations, "source", {});
if (source.empty())
{
Error::SetString(error, fmt::format("Non-render target texture '{}' is missing source.", ti.unique_name));
Error::SetStringFmt(error, "Non-render target texture '{}' is missing source.", ti.unique_name);
return false;
}
@ -1111,7 +1110,7 @@ bool PostProcessing::ReShadeFXShader::CreatePasses(GPUTexture::Format backbuffer
if (std::optional<DynamicHeapArray<u8>> resdata = Host::ReadResourceFile(resource_name.c_str(), true);
!resdata.has_value() || !image.LoadFromBuffer(resource_name.c_str(), resdata->data(), resdata->size()))
{
Error::SetString(error, fmt::format("Failed to load image '{}' (from '{}')", source, image_path).c_str());
Error::SetStringFmt(error, "Failed to load image '{}' (from '{}')", source, image_path);
return false;
}
}
@ -1121,8 +1120,7 @@ bool PostProcessing::ReShadeFXShader::CreatePasses(GPUTexture::Format backbuffer
GPUTexture::Format::RGBA8, image.GetPixels(), image.GetPitch());
if (!tex.texture)
{
Error::SetString(
error, fmt::format("Failed to create {}x{} texture ({})", image.GetWidth(), image.GetHeight(), source));
Error::SetStringFmt(error, "Failed to create {}x{} texture ({})", image.GetWidth(), image.GetHeight(), source);
return false;
}
@ -1133,9 +1131,9 @@ bool PostProcessing::ReShadeFXShader::CreatePasses(GPUTexture::Format backbuffer
m_textures.push_back(std::move(tex));
}
for (reshadefx::technique_info& tech : mod.techniques)
for (const reshadefx::technique& tech : mod.techniques)
{
for (reshadefx::pass_info& pi : tech.passes)
for (const reshadefx::pass& pi : tech.passes)
{
const bool is_final = (&tech == &mod.techniques.back() && &pi == &tech.passes.back());
@ -1164,8 +1162,7 @@ bool PostProcessing::ReShadeFXShader::CreatePasses(GPUTexture::Format backbuffer
}
if (rt == static_cast<TextureID>(m_textures.size()))
{
Error::SetString(error,
fmt::format("Unknown texture '{}' used as render target in pass '{}'", rtname, pi.name));
Error::SetStringFmt(error, "Unknown texture '{}' used as render target in pass '{}'", rtname, pi.name);
return false;
}
@ -1182,17 +1179,22 @@ bool PostProcessing::ReShadeFXShader::CreatePasses(GPUTexture::Format backbuffer
}
u32 texture_slot = 0;
for (const reshadefx::sampler_info& si : pi.samplers)
Assert(pi.texture_bindings.size() == pi.sampler_bindings.size());
for (size_t tb_index = 0; tb_index < pi.texture_bindings.size(); tb_index++)
{
const reshadefx::texture_binding& tb = pi.texture_bindings[tb_index];
const reshadefx::sampler_binding& sb = pi.sampler_bindings[tb_index];
Sampler sampler;
sampler.slot = texture_slot++;
sampler.reshade_name = si.unique_name;
sampler.texture_id = static_cast<TextureID>(m_textures.size());
for (const reshadefx::texture_info& ti : mod.textures)
for (const reshadefx::texture& ti : mod.textures)
{
if (ti.unique_name == si.texture_name)
if (ti.unique_name == tb.texture_name)
{
sampler.reshade_name = ti.unique_name; // TODO: REMOVE THIS
// found the texture, now look for our side of it
if (ti.semantic == "COLOR")
{
@ -1207,14 +1209,14 @@ bool PostProcessing::ReShadeFXShader::CreatePasses(GPUTexture::Format backbuffer
}
else if (!ti.semantic.empty())
{
Error::SetString(error, fmt::format("Unknown semantic {} in texture {}", ti.semantic, ti.name));
Error::SetStringFmt(error, "Unknown semantic {} in texture {}", ti.semantic, ti.name);
return false;
}
// must be a render target, or another texture
for (u32 i = 0; i < static_cast<u32>(m_textures.size()); i++)
{
if (m_textures[i].reshade_name == si.texture_name)
if (m_textures[i].reshade_name == ti.unique_name)
{
// hook it up
sampler.texture_id = static_cast<TextureID>(i);
@ -1225,16 +1227,16 @@ bool PostProcessing::ReShadeFXShader::CreatePasses(GPUTexture::Format backbuffer
break;
}
}
if (sampler.texture_id == static_cast<TextureID>(m_textures.size()))
{
Error::SetString(
error, fmt::format("Unknown texture {} (sampler {}) in pass {}", si.texture_name, si.name, pi.name));
Error::SetStringFmt(error, "Unknown texture {} in pass {}", tb.texture_name, pi.name);
return false;
}
DEV_LOG("Pass {} Texture {} => {}", pi.name, si.texture_name, sampler.texture_id);
DEV_LOG("Pass {} Texture {} => {}", pi.name, tb.texture_name, sampler.texture_id);
sampler.sampler = GetSampler(MapSampler(si));
sampler.sampler = GetSampler(MapSampler(sb));
if (!sampler.sampler)
{
Error::SetString(error, "Failed to create sampler.");
@ -1320,14 +1322,18 @@ bool PostProcessing::ReShadeFXShader::CompilePipeline(GPUTexture::Format format,
if (fxcode.empty() || fxcode.back() != '\n')
fxcode.push_back('\n');
std::unique_ptr<reshadefx::codegen> cg = CreateRFXCodegen();
if (!cg)
return false;
Error error;
reshadefx::module mod;
if (!CreateModule(width, height, &mod, std::move(fxcode), &error))
if (!CreateModule(width, height, cg.get(), std::move(fxcode), &error))
{
ERROR_LOG("Failed to create module for '{}': {}", m_name, error.GetDescription());
return false;
}
const reshadefx::effect_module& mod = cg->module();
DebugAssert(!mod.techniques.empty());
if (!CreatePasses(format, mod, &error))
@ -1336,53 +1342,16 @@ bool PostProcessing::ReShadeFXShader::CompilePipeline(GPUTexture::Format format,
return false;
}
const std::string_view code(mod.code.data(), mod.code.size());
// TODO: If using spv, this will be populated.
// const std::string effect_code = cg->finalize_code();
auto get_shader = [api, needs_main_defn, &code](const std::string& name, const std::span<Sampler> samplers,
GPUShaderStage stage) {
std::string real_code;
if (needs_main_defn)
{
// 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#define discard\n" : "";
const char* precision = (api == RenderAPI::OpenGLES) ?
"precision highp float;\nprecision highp int;\nprecision highp sampler2D;\n" :
"";
auto get_shader = [api, needs_main_defn, &cg](const std::string& name, const std::span<Sampler> samplers,
GPUShaderStage stage) {
const std::string real_code = cg->finalize_code_for_entry_point(name);
TinyString version_string = "#version 460 core\n";
#ifdef ENABLE_OPENGL
if (api == RenderAPI::OpenGL || api == RenderAPI::OpenGLES)
version_string = ShaderGen::GetGLSLVersionString(api, ShaderGen::GetGLSLVersion(api));
#if 0
FileSystem::WriteStringToFile(fmt::format("D:\\reshade_{}.txt", Path::SanitizeFileName(name)).c_str(), real_code);
#endif
real_code = fmt::format("{}\n#define ENTRY_POINT_{}\n{}\n{}\n{}", version_string, name, defns, precision, 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);
}
}
// FileSystem::WriteStringToFile("D:\\foo.txt", real_code);
Error error;
std::unique_ptr<GPUShader> sshader = g_gpu_device->CreateShader(
@ -1407,15 +1376,15 @@ bool PostProcessing::ReShadeFXShader::CompilePipeline(GPUTexture::Format format,
progress->PushState();
size_t total_passes = 0;
for (const reshadefx::technique_info& tech : mod.techniques)
for (const reshadefx::technique& tech : mod.techniques)
total_passes += tech.passes.size();
progress->SetProgressRange(static_cast<u32>(total_passes));
progress->SetProgressValue(0);
u32 passnum = 0;
for (const reshadefx::technique_info& tech : mod.techniques)
for (const reshadefx::technique& tech : mod.techniques)
{
for (const reshadefx::pass_info& info : tech.passes)
for (const reshadefx::pass& info : tech.passes)
{
DebugAssert(passnum < m_passes.size());
Pass& pass = m_passes[passnum++];

View File

@ -13,6 +13,10 @@
#include <random>
namespace reshadefx {
class codegen;
}
class Error;
namespace PostProcessing {
@ -94,10 +98,10 @@ private:
ShaderOption::ValueVector value;
};
bool CreateModule(s32 buffer_width, s32 buffer_height, reshadefx::module* mod, std::string code, 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);
bool CreateModule(s32 buffer_width, s32 buffer_height, reshadefx::codegen* cg, std::string code, Error* error);
bool CreateOptions(const reshadefx::effect_module& mod, Error* error);
bool GetSourceOption(const reshadefx::uniform& ui, SourceOptionType* si, Error* error);
bool CreatePasses(GPUTexture::Format backbuffer_format, const reshadefx::effect_module& mod, Error* error);
const char* GetTextureNameForID(TextureID id) const;
GPUTexture* GetTextureByID(TextureID id, GPUTexture* input_color, GPUTexture* input_depth,

View File

@ -98,9 +98,9 @@ void ShaderGen::DefineMacro(std::stringstream& ss, const char* name, s32 value)
ss << "#define " << name << " " << value << "\n";
}
#ifdef ENABLE_OPENGL
u32 ShaderGen::GetGLSLVersion(RenderAPI render_api)
{
#ifdef ENABLE_OPENGL
const char* glsl_version = reinterpret_cast<const char*>(glGetString(GL_SHADING_LANGUAGE_VERSION));
const bool glsl_es = (render_api == RenderAPI::OpenGLES);
Assert(glsl_version != nullptr);
@ -136,6 +136,9 @@ u32 ShaderGen::GetGLSLVersion(RenderAPI render_api)
}
return (static_cast<u32>(major_version) * 100) + static_cast<u32>(minor_version);
#else
return 460;
#endif
}
TinyString ShaderGen::GetGLSLVersionString(RenderAPI render_api, u32 version)
@ -147,7 +150,6 @@ TinyString ShaderGen::GetGLSLVersionString(RenderAPI render_api, u32 version)
return TinyString::from_format("#version {}{:02d}{}", major_version, minor_version,
(glsl_es && major_version >= 3) ? " es" : "");
}
#endif
void ShaderGen::WriteHeader(std::stringstream& ss, bool enable_rov /* = false */)
{

View File

@ -20,10 +20,8 @@ public:
static GPUShaderLanguage GetShaderLanguageForAPI(RenderAPI api);
static bool UseGLSLBindingLayout();
#ifdef ENABLE_OPENGL
static u32 GetGLSLVersion(RenderAPI render_api);
static TinyString GetGLSLVersionString(RenderAPI render_api, u32 version);
#endif
ALWAYS_INLINE GPUShaderLanguage GetLanguage() const { return m_shader_language; }