[ATOM-15978] ShaderVariantAssetBuilder needs to fill up ShaderPlatformInterface::m_srgLayouts for Metal (#2156)
ShaderVariantAssetBuilder builds SRG Layout data only for Metal. Signed-off-by: garrieta <garrieta@amazon.com>
This commit is contained in:
@@ -95,7 +95,7 @@ namespace AZ
|
||||
shaderVariantAssetBuilderDescriptor.m_name = "Shader Variant Asset Builder";
|
||||
// Both "Shader Variant Asset Builder" and "Shader Asset Builder" produce ShaderVariantAsset products. If you update
|
||||
// ShaderVariantAsset you will need to update BOTH version numbers, not just "Shader Variant Asset Builder".
|
||||
shaderVariantAssetBuilderDescriptor.m_version = 23; // ATOM-15472
|
||||
shaderVariantAssetBuilderDescriptor.m_version = 24; // ATOM-15978
|
||||
shaderVariantAssetBuilderDescriptor.m_patterns.push_back(AssetBuilderSDK::AssetBuilderPattern(AZStd::string::format("*.%s", RPI::ShaderVariantListSourceData::Extension), AssetBuilderSDK::AssetBuilderPattern::PatternType::Wildcard));
|
||||
shaderVariantAssetBuilderDescriptor.m_busId = azrtti_typeid<ShaderVariantAssetBuilder>();
|
||||
shaderVariantAssetBuilderDescriptor.m_createJobFunction = AZStd::bind(&ShaderVariantAssetBuilder::CreateJobs, &m_shaderVariantAssetBuilder, AZStd::placeholders::_1, AZStd::placeholders::_2);
|
||||
|
||||
@@ -48,6 +48,7 @@
|
||||
|
||||
#include "ShaderAssetBuilder.h"
|
||||
#include "ShaderBuilderUtility.h"
|
||||
#include "SrgLayoutUtility.h"
|
||||
#include "AzslData.h"
|
||||
#include "AzslCompiler.h"
|
||||
#include <CommonFiles/Preprocessor.h>
|
||||
@@ -520,6 +521,96 @@ namespace AZ
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static bool LoadSrgLayoutListFromShaderAssetBuilder(
|
||||
const RHI::ShaderPlatformInterface* shaderPlatformInterface,
|
||||
const AssetBuilderSDK::PlatformInfo& platformInfo,
|
||||
const AzslCompiler& azslCompiler, const AZStd::string& shaderSourceFileFullPath,
|
||||
const RPI::SupervariantIndex supervariantIndex,
|
||||
const bool platformUsesRegisterSpaces,
|
||||
RPI::ShaderResourceGroupLayoutList& srgLayoutList,
|
||||
RootConstantData& rootConstantData)
|
||||
{
|
||||
auto srgJsonPathOutcome = ShaderBuilderUtility::ObtainBuildArtifactPathFromShaderAssetBuilder(
|
||||
shaderPlatformInterface->GetAPIUniqueIndex(), platformInfo.m_identifier, shaderSourceFileFullPath, supervariantIndex.GetIndex(), AZ::RPI::ShaderAssetSubId::SrgJson);
|
||||
if (!srgJsonPathOutcome.IsSuccess())
|
||||
{
|
||||
AZ_Error(ShaderVariantAssetBuilderName, false, "%s", srgJsonPathOutcome.GetError().c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
auto srgJsonPath = srgJsonPathOutcome.TakeValue();
|
||||
auto jsonOutcome = JsonSerializationUtils::ReadJsonFile(srgJsonPath);
|
||||
if (!jsonOutcome.IsSuccess())
|
||||
{
|
||||
AZ_Error(ShaderVariantAssetBuilderName, false, "%s", jsonOutcome.GetError().c_str());
|
||||
return false;
|
||||
}
|
||||
SrgDataContainer srgData;
|
||||
if (!azslCompiler.ParseSrgPopulateSrgData(jsonOutcome.GetValue(), srgData))
|
||||
{
|
||||
AZ_Error(ShaderVariantAssetBuilderName, false, "Failed to parse srg data");
|
||||
return false;
|
||||
}
|
||||
// Add all Shader Resource Group Assets that were defined in the shader code to the shader asset
|
||||
if (!SrgLayoutUtility::LoadShaderResourceGroupLayouts(ShaderVariantAssetBuilderName, srgData, platformUsesRegisterSpaces, srgLayoutList))
|
||||
{
|
||||
AZ_Error(ShaderVariantAssetBuilderName, false, "Failed to load ShaderResourceGroupLayouts");
|
||||
return false;
|
||||
}
|
||||
|
||||
for (auto srgLayout : srgLayoutList)
|
||||
{
|
||||
if (!srgLayout->Finalize())
|
||||
{
|
||||
AZ_Error(ShaderVariantAssetBuilderName, false,
|
||||
"Failed to finalize SrgLayout %s", srgLayout->GetName().GetCStr());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Access the root constants reflection
|
||||
if (!azslCompiler.ParseSrgPopulateRootConstantData(
|
||||
jsonOutcome.GetValue(),
|
||||
rootConstantData)) // consuming data from --srg ("InlineConstantBuffer" subjson section)
|
||||
{
|
||||
AZ_Error(ShaderVariantAssetBuilderName, false, "Failed to obtain root constant data reflection");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool LoadBindingDependenciesFromShaderAssetBuilder(
|
||||
const RHI::ShaderPlatformInterface* shaderPlatformInterface,
|
||||
const AssetBuilderSDK::PlatformInfo& platformInfo,
|
||||
const AzslCompiler& azslCompiler, const AZStd::string& shaderSourceFileFullPath,
|
||||
const RPI::SupervariantIndex supervariantIndex,
|
||||
BindingDependencies& bindingDependencies)
|
||||
{
|
||||
auto bindingsJsonPathOutcome = ShaderBuilderUtility::ObtainBuildArtifactPathFromShaderAssetBuilder(
|
||||
shaderPlatformInterface->GetAPIUniqueIndex(), platformInfo.m_identifier, shaderSourceFileFullPath, supervariantIndex.GetIndex(), AZ::RPI::ShaderAssetSubId::BindingdepJson);
|
||||
if (!bindingsJsonPathOutcome.IsSuccess())
|
||||
{
|
||||
AZ_Error(ShaderVariantAssetBuilderName, false, "%s", bindingsJsonPathOutcome.GetError().c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
auto bindingsJsonPath = bindingsJsonPathOutcome.TakeValue();
|
||||
auto jsonOutcome = JsonSerializationUtils::ReadJsonFile(bindingsJsonPath);
|
||||
if (!jsonOutcome.IsSuccess())
|
||||
{
|
||||
AZ_Error(ShaderVariantAssetBuilderName, false, "%s", jsonOutcome.GetError().c_str());
|
||||
return false;
|
||||
}
|
||||
if (!azslCompiler.ParseBindingdepPopulateBindingDependencies(jsonOutcome.GetValue(), bindingDependencies))
|
||||
{
|
||||
AZ_Error(ShaderVariantAssetBuilderName, false, "Failed to parse binding dependencies data");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// Returns the content of the hlsl file for the given supervariant as produced by ShaderAsssetBuilder.
|
||||
@@ -773,6 +864,50 @@ namespace AZ
|
||||
response.m_resultCode = AssetBuilderSDK::ProcessJobResult_Failed;
|
||||
return;
|
||||
}
|
||||
|
||||
//! It is important to keep this refcounted pointer outside of the if block to prevent it from being destroyed.
|
||||
RHI::Ptr<RHI::PipelineLayoutDescriptor> pipelineLayoutDescriptor;
|
||||
if (shaderPlatformInterface->VariantCompilationRequiresSrgLayoutData())
|
||||
{
|
||||
AZStd::string azslcCompilerParameters =
|
||||
shaderPlatformInterface->GetAzslCompilerParameters(buildOptions.m_compilerArguments);
|
||||
const bool platformUsesRegisterSpaces =
|
||||
(AzFramework::StringFunc::Find(azslcCompilerParameters, "--use-spaces") != AZStd::string::npos);
|
||||
|
||||
RPI::ShaderResourceGroupLayoutList srgLayoutList;
|
||||
RootConstantData rootConstantData;
|
||||
if (!LoadSrgLayoutListFromShaderAssetBuilder(
|
||||
shaderPlatformInterface, request.m_platformInfo, azslc, shaderSourceFileFullPath, supervariantIndex,
|
||||
platformUsesRegisterSpaces,
|
||||
srgLayoutList,
|
||||
rootConstantData))
|
||||
{
|
||||
response.m_resultCode = AssetBuilderSDK::ProcessJobResult_Failed;
|
||||
return;
|
||||
}
|
||||
|
||||
BindingDependencies bindingDependencies;
|
||||
if (!LoadBindingDependenciesFromShaderAssetBuilder(
|
||||
shaderPlatformInterface, request.m_platformInfo, azslc, shaderSourceFileFullPath, supervariantIndex,
|
||||
bindingDependencies))
|
||||
{
|
||||
response.m_resultCode = AssetBuilderSDK::ProcessJobResult_Failed;
|
||||
return;
|
||||
}
|
||||
|
||||
pipelineLayoutDescriptor =
|
||||
ShaderBuilderUtility::BuildPipelineLayoutDescriptorForApi(
|
||||
ShaderVariantAssetBuilderName, srgLayoutList, shaderEntryPoints, buildOptions.m_compilerArguments, rootConstantData,
|
||||
shaderPlatformInterface, bindingDependencies);
|
||||
if (!pipelineLayoutDescriptor)
|
||||
{
|
||||
AZ_Error(
|
||||
ShaderVariantAssetBuilderName, false, "Failed to build pipeline layout descriptor for api=[%s]",
|
||||
shaderPlatformInterface->GetAPIName().GetCStr());
|
||||
response.m_resultCode = AssetBuilderSDK::ProcessJobResult_Failed;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Setup the shader variant creation context:
|
||||
ShaderVariantCreationContext shaderVariantCreationContext =
|
||||
|
||||
@@ -144,6 +144,12 @@ namespace AZ
|
||||
const ShaderResourceGroupInfoList& srgInfoList,
|
||||
const RootConstantsInfo& rootConstantsInfo,
|
||||
const ShaderCompilerArguments& shaderCompilerArguments) = 0;
|
||||
|
||||
//! In general, shader compilation doesn't require SRG Layout data, but RHIs like
|
||||
//! Metal don't do well if unused resources (descriptors) are not bound. If this function returns TRUE
|
||||
//! the ShaderVariantAssetBuilder will invoke BuildPipelineLayoutDescriptor() so the RHI gets the chance to
|
||||
//! build SRG Layout data which will be useful when compiling MetalISL to Metal byte code.
|
||||
virtual bool VariantCompilationRequiresSrgLayoutData() const { return false; }
|
||||
|
||||
//! See AZ::RHI::Factory::GetAPIUniqueIndex() for details.
|
||||
//! See AZ::RHI::Limits::APIType::PerPlatformApiUniqueIndexMax.
|
||||
|
||||
@@ -159,7 +159,13 @@ namespace AZ
|
||||
arguments += " -Zi"; // Generate debug information
|
||||
arguments += " -Zss"; // Compute Shader Hash considering source information
|
||||
}
|
||||
arguments += " " + m_dxcAdditionalFreeArguments;
|
||||
// strip spaces at both sides
|
||||
AZStd::string dxcAdditionalFreeArguments = m_dxcAdditionalFreeArguments;
|
||||
AzFramework::StringFunc::TrimWhiteSpace(dxcAdditionalFreeArguments, true, true);
|
||||
if (!dxcAdditionalFreeArguments.empty())
|
||||
{
|
||||
arguments += " " + dxcAdditionalFreeArguments;
|
||||
}
|
||||
return arguments;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,6 +40,8 @@ namespace AZ
|
||||
const ShaderResourceGroupInfoList& srgInfoList,
|
||||
const RootConstantsInfo& rootConstantsInfo,
|
||||
const RHI::ShaderCompilerArguments& shaderCompilerArguments) override;
|
||||
|
||||
bool VariantCompilationRequiresSrgLayoutData() const override { return true; }
|
||||
|
||||
bool CompilePlatformInternal(
|
||||
const AssetBuilderSDK::PlatformInfo& platform,
|
||||
|
||||
Reference in New Issue
Block a user