Multipass shaders

This commit is contained in:
Aiden
2026-05-12 17:08:35 +10:00
parent 1429b2e660
commit dfd49fd0e3
12 changed files with 392 additions and 72 deletions

View File

@@ -5,12 +5,21 @@
#include <string>
#include <vector>
struct RuntimeShaderPassArtifact
{
std::string passId;
std::string fragmentShaderSource;
std::vector<std::string> inputNames;
std::string outputName;
};
struct RuntimeShaderArtifact
{
std::string layerId;
std::string shaderId;
std::string displayName;
std::string fragmentShaderSource;
std::vector<RuntimeShaderPassArtifact> passes;
std::string message;
std::vector<ShaderParameterDefinition> parameterDefinitions;
};

View File

@@ -112,8 +112,6 @@ RuntimeSlangShaderBuild RuntimeSlangShaderCompiler::BuildShader(const std::strin
return build;
}
const ShaderPassDefinition& pass = shaderPackage.passes.front();
ShaderCompiler compiler(
repoRoot,
runtimeBuildDir / (shaderId + ".wrapper.slang"),
@@ -122,11 +120,22 @@ RuntimeSlangShaderBuild RuntimeSlangShaderCompiler::BuildShader(const std::strin
0);
const auto start = std::chrono::steady_clock::now();
if (!compiler.BuildPassFragmentShaderSource(shaderPackage, pass, build.artifact.fragmentShaderSource, error))
for (const ShaderPassDefinition& pass : shaderPackage.passes)
{
build.succeeded = false;
build.message = error.empty() ? "Slang compile failed." : error;
return build;
std::string fragmentShaderSource;
if (!compiler.BuildPassFragmentShaderSource(shaderPackage, pass, fragmentShaderSource, error))
{
build.succeeded = false;
build.message = error.empty() ? "Slang compile failed." : error;
return build;
}
RuntimeShaderPassArtifact passArtifact;
passArtifact.passId = pass.id;
passArtifact.fragmentShaderSource = std::move(fragmentShaderSource);
passArtifact.inputNames = pass.inputNames;
passArtifact.outputName = pass.outputName;
build.artifact.passes.push_back(std::move(passArtifact));
}
const auto end = std::chrono::steady_clock::now();
@@ -135,6 +144,8 @@ RuntimeSlangShaderBuild RuntimeSlangShaderCompiler::BuildShader(const std::strin
build.artifact.shaderId = shaderPackage.id;
build.artifact.displayName = shaderPackage.displayName;
build.artifact.parameterDefinitions = shaderPackage.parameters;
if (!build.artifact.passes.empty())
build.artifact.fragmentShaderSource = build.artifact.passes.front().fragmentShaderSource;
build.artifact.message = shaderPackage.displayName + " Slang compile completed in " + std::to_string(milliseconds) + " ms.";
build.message = build.artifact.message;
return build;

View File

@@ -9,8 +9,8 @@ namespace RenderCadenceCompositor
{
ShaderSupportResult CheckStatelessSinglePassShaderSupport(const ShaderPackage& shaderPackage)
{
if (shaderPackage.passes.size() != 1)
return { false, "RenderCadenceCompositor currently supports only single-pass runtime shaders." };
if (shaderPackage.passes.empty())
return { false, "Shader package has no render passes." };
if (shaderPackage.temporal.enabled)
return { false, "RenderCadenceCompositor currently supports only stateless shaders; temporal history is not enabled in this app." };
@@ -30,6 +30,35 @@ ShaderSupportResult CheckStatelessSinglePassShaderSupport(const ShaderPackage& s
return { false, "RenderCadenceCompositor currently skips text parameters because they require per-shader text texture storage." };
}
bool writesLayerOutput = false;
for (const ShaderPassDefinition& pass : shaderPackage.passes)
{
if (pass.sourcePath.empty())
{
return { false, "Shader pass '" + pass.id + "' has no source." };
}
if (pass.outputName == "layerOutput")
writesLayerOutput = true;
for (const std::string& inputName : pass.inputNames)
{
if (inputName == "videoInput" || inputName == "layerInput")
continue;
bool matchesNamedOutput = false;
for (const ShaderPassDefinition& outputPass : shaderPackage.passes)
{
if (outputPass.outputName == inputName)
{
matchesNamedOutput = true;
break;
}
}
if (!matchesNamedOutput)
return { false, "Shader pass '" + pass.id + "' references unknown input '" + inputName + "'." };
}
}
if (!writesLayerOutput)
return { false, "Shader package must write a pass output named 'layerOutput'." };
return { true, std::string() };
}