Add manifest support for pass declarations
This commit is contained in:
@@ -250,6 +250,103 @@ bool ParseShaderMetadata(const JsonValue& manifestJson, ShaderPackage& shaderPac
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ParsePassDefinitions(const JsonValue& manifestJson, ShaderPackage& shaderPackage, const std::filesystem::path& manifestPath, std::string& error)
|
||||
{
|
||||
const JsonValue* passesValue = nullptr;
|
||||
if (!OptionalArrayField(manifestJson, "passes", passesValue, manifestPath, error))
|
||||
return false;
|
||||
|
||||
if (!passesValue)
|
||||
{
|
||||
ShaderPassDefinition pass;
|
||||
pass.id = "main";
|
||||
pass.entryPoint = shaderPackage.entryPoint;
|
||||
pass.sourcePath = shaderPackage.shaderPath;
|
||||
pass.outputName = "layerOutput";
|
||||
if (!std::filesystem::exists(pass.sourcePath))
|
||||
{
|
||||
error = "Shader source not found for package " + shaderPackage.id + ": " + pass.sourcePath.string();
|
||||
return false;
|
||||
}
|
||||
pass.sourceWriteTime = std::filesystem::last_write_time(pass.sourcePath);
|
||||
shaderPackage.passes.push_back(pass);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (passesValue->asArray().empty())
|
||||
{
|
||||
error = "Shader manifest 'passes' field must not be empty in: " + ManifestPathMessage(manifestPath);
|
||||
return false;
|
||||
}
|
||||
|
||||
for (const JsonValue& passJson : passesValue->asArray())
|
||||
{
|
||||
if (!passJson.isObject())
|
||||
{
|
||||
error = "Shader pass entry must be an object in: " + ManifestPathMessage(manifestPath);
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string passId;
|
||||
std::string sourcePath;
|
||||
if (!RequireNonEmptyStringField(passJson, "id", passId, manifestPath, error) ||
|
||||
!RequireNonEmptyStringField(passJson, "source", sourcePath, manifestPath, error))
|
||||
{
|
||||
error = "Shader pass is missing required 'id' or 'source' in: " + ManifestPathMessage(manifestPath);
|
||||
return false;
|
||||
}
|
||||
if (!ValidateShaderIdentifier(passId, "passes[].id", manifestPath, error))
|
||||
return false;
|
||||
|
||||
for (const ShaderPassDefinition& existingPass : shaderPackage.passes)
|
||||
{
|
||||
if (existingPass.id == passId)
|
||||
{
|
||||
error = "Duplicate shader pass id '" + passId + "' in: " + ManifestPathMessage(manifestPath);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
ShaderPassDefinition pass;
|
||||
pass.id = passId;
|
||||
pass.sourcePath = shaderPackage.directoryPath / sourcePath;
|
||||
if (!OptionalStringField(passJson, "entryPoint", pass.entryPoint, shaderPackage.entryPoint, manifestPath, error) ||
|
||||
!OptionalStringField(passJson, "output", pass.outputName, passId, manifestPath, error))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (!ValidateShaderIdentifier(pass.entryPoint, "passes[].entryPoint", manifestPath, error))
|
||||
return false;
|
||||
|
||||
const JsonValue* inputsValue = nullptr;
|
||||
if (!OptionalArrayField(passJson, "inputs", inputsValue, manifestPath, error))
|
||||
return false;
|
||||
if (inputsValue)
|
||||
{
|
||||
for (const JsonValue& inputValue : inputsValue->asArray())
|
||||
{
|
||||
if (!inputValue.isString())
|
||||
{
|
||||
error = "Shader pass inputs must be strings in: " + ManifestPathMessage(manifestPath);
|
||||
return false;
|
||||
}
|
||||
pass.inputNames.push_back(inputValue.asString());
|
||||
}
|
||||
}
|
||||
|
||||
if (!std::filesystem::exists(pass.sourcePath))
|
||||
{
|
||||
error = "Shader pass source not found for package " + shaderPackage.id + ": " + pass.sourcePath.string();
|
||||
return false;
|
||||
}
|
||||
pass.sourceWriteTime = std::filesystem::last_write_time(pass.sourcePath);
|
||||
shaderPackage.passes.push_back(pass);
|
||||
}
|
||||
|
||||
shaderPackage.shaderPath = shaderPackage.passes.front().sourcePath;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ParseTextureAssets(const JsonValue& manifestJson, ShaderPackage& shaderPackage, const std::filesystem::path& manifestPath, std::string& error)
|
||||
{
|
||||
const JsonValue* texturesValue = nullptr;
|
||||
@@ -666,13 +763,15 @@ bool ShaderPackageRegistry::ParseManifest(const std::filesystem::path& manifestP
|
||||
if (!ParseShaderMetadata(manifestJson, shaderPackage, manifestPath, error))
|
||||
return false;
|
||||
|
||||
if (!std::filesystem::exists(shaderPackage.shaderPath))
|
||||
{
|
||||
error = "Shader source not found for package " + shaderPackage.id + ": " + shaderPackage.shaderPath.string();
|
||||
if (!ParsePassDefinitions(manifestJson, shaderPackage, manifestPath, error))
|
||||
return false;
|
||||
}
|
||||
|
||||
shaderPackage.shaderWriteTime = std::filesystem::last_write_time(shaderPackage.shaderPath);
|
||||
shaderPackage.shaderWriteTime = shaderPackage.passes.front().sourceWriteTime;
|
||||
for (const ShaderPassDefinition& pass : shaderPackage.passes)
|
||||
{
|
||||
if (pass.sourceWriteTime > shaderPackage.shaderWriteTime)
|
||||
shaderPackage.shaderWriteTime = pass.sourceWriteTime;
|
||||
}
|
||||
shaderPackage.manifestWriteTime = std::filesystem::last_write_time(shaderPackage.manifestPath);
|
||||
|
||||
return ParseTextureAssets(manifestJson, shaderPackage, manifestPath, error) &&
|
||||
|
||||
Reference in New Issue
Block a user