Multipass shaders
This commit is contained in:
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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() };
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user