Merge remote-tracking branch 'upstream/stabilization/2106' into nvsickle/MergeStabilizationJun18
This commit is contained in:
@@ -112,6 +112,7 @@ namespace AZ
|
||||
{
|
||||
Data::AssetBus::Handler::BusDisconnect();
|
||||
ShaderVariantFinderNotificationBus::Handler::BusDisconnect();
|
||||
AssetInitBus::Handler::BusDisconnect();
|
||||
}
|
||||
|
||||
const Name& ShaderAsset::GetName() const
|
||||
@@ -467,7 +468,7 @@ namespace AZ
|
||||
return &supervariants[index];
|
||||
}
|
||||
|
||||
bool ShaderAsset::FinalizeAfterLoad()
|
||||
bool ShaderAsset::SelectShaderApiData()
|
||||
{
|
||||
// Use the current RHI that is active to select which shader data to use.
|
||||
// We don't assert if the Factory is not available because this method could be called during build time,
|
||||
@@ -509,18 +510,47 @@ namespace AZ
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ShaderAsset::PostLoadInit()
|
||||
{
|
||||
// Once the ShaderAsset is loaded, it is necessary to listen for changes in the Root Variant Asset.
|
||||
Data::AssetBus::Handler::BusConnect(GetRootVariant().GetId());
|
||||
ShaderVariantFinderNotificationBus::Handler::BusConnect(GetId());
|
||||
|
||||
AssetInitBus::Handler::BusDisconnect();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ShaderAsset::ReinitializeRootShaderVariant(Data::Asset<Data::AssetData> asset)
|
||||
{
|
||||
Data::Asset<ShaderVariantAsset> shaderVariantAsset = { asset.GetAs<ShaderVariantAsset>(), AZ::Data::AssetLoadBehavior::PreLoad };
|
||||
AZ_Assert(shaderVariantAsset->GetStableId() == RootShaderVariantStableId, "Was expecting to update the root variant");
|
||||
GetCurrentShaderApiData().m_rootShaderVariantAsset = asset;
|
||||
ShaderReloadNotificationBus::Event(GetId(), &ShaderReloadNotificationBus::Events::OnShaderAssetReinitialized, Data::Asset<ShaderAsset>{ this, AZ::Data::AssetLoadBehavior::PreLoad } );
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// AssetBus overrides...
|
||||
void ShaderAsset::OnAssetReloaded(Data::Asset<Data::AssetData> asset)
|
||||
{
|
||||
ShaderReloadDebugTracker::ScopedSection reloadSection("{%p}->ShaderAsset::OnAssetReloaded %s", this, asset.GetHint().c_str());
|
||||
ReinitializeRootShaderVariant(asset);
|
||||
}
|
||||
void ShaderAsset::OnAssetReady(Data::Asset<Data::AssetData> asset)
|
||||
{
|
||||
// We have to listen to OnAssetReady, OnAssetReloaded isn't enough, because of the following scenario:
|
||||
// The user changes a .shader file, which causes the AP to rebuild the ShaderAsset and root ShaderVariantAsset.
|
||||
// 1) Thread A creates the new ShaderAsset, loads it, and gets the old ShaderVariantAsset.
|
||||
// 2) Thread B creates the new ShaderVariantAsset, loads it, and calls OnAssetReloaded.
|
||||
// 3) Main thread calls ShaderAsset::PostLoadInit which connects to the AssetBus but it's too late to receive OnAssetReloaded,
|
||||
// so it continues using the old ShaderVariantAsset instead of the new one.
|
||||
// The OnAssetReady bus function is called automatically whenever a connection to AssetBus is made, so listening to this gives
|
||||
// us the opportunity to assign the appropriate ShaderVariantAsset.
|
||||
|
||||
ShaderReloadNotificationBus::Event(GetId(), &ShaderReloadNotificationBus::Events::OnShaderAssetReinitialized, Data::Asset<ShaderAsset>{ this, AZ::Data::AssetLoadBehavior::PreLoad } );
|
||||
|
||||
Data::Asset<ShaderVariantAsset> shaderVariantAsset = { asset.GetAs<ShaderVariantAsset>(), AZ::Data::AssetLoadBehavior::PreLoad };
|
||||
AZ_Assert(shaderVariantAsset->GetStableId() == RootShaderVariantStableId,
|
||||
@@ -529,9 +559,12 @@ namespace AZ
|
||||
GetCurrentShaderApiData().m_supervariants[supervariantIndex.GetIndex()].m_rootShaderVariantAsset = asset;
|
||||
|
||||
ShaderReloadNotificationBus::Event(GetId(), &ShaderReloadNotificationBus::Events::OnShaderAssetReinitialized, Data::Asset<ShaderAsset>{ this, AZ::Data::AssetLoadBehavior::PreLoad } );
|
||||
|
||||
ShaderReloadDebugTracker::ScopedSection reloadSection("{%p}->ShaderAsset::OnAssetReady %s", this, asset.GetHint().c_str());
|
||||
ReinitializeRootShaderVariant(asset);
|
||||
}
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
/// ShaderVariantFinderNotificationBus overrides
|
||||
void ShaderAsset::OnShaderVariantTreeAssetReady(Data::Asset<ShaderVariantTreeAsset> shaderVariantTreeAsset, bool isError)
|
||||
@@ -565,25 +598,25 @@ namespace AZ
|
||||
{
|
||||
if (Base::LoadAssetData(asset, stream, assetLoadFilterCB) == Data::AssetHandler::LoadResult::LoadComplete)
|
||||
{
|
||||
return PostLoadInit(asset);
|
||||
}
|
||||
return Data::AssetHandler::LoadResult::Error;
|
||||
}
|
||||
ShaderAsset* shaderAsset = asset.GetAs<ShaderAsset>();
|
||||
|
||||
Data::AssetHandler::LoadResult ShaderAssetHandler::PostLoadInit(const Data::Asset<Data::AssetData>& asset)
|
||||
{
|
||||
if (ShaderAsset* shaderAsset = asset.GetAs<ShaderAsset>())
|
||||
{
|
||||
if (!shaderAsset->FinalizeAfterLoad())
|
||||
// The shader API selection must occur immediately ofter loading, on the same thread, rather than
|
||||
// deferring to AssetInitBus::PostLoadInit. Many functions in the ShaderAsset class are invalid
|
||||
// until after SelectShaderApiData() is called and some client code may need to access data in
|
||||
// the ShaderAsset before then.
|
||||
if (!shaderAsset->SelectShaderApiData())
|
||||
{
|
||||
AZ_Error("ShaderAssetHandler", false, "Shader asset failed to finalize.");
|
||||
return Data::AssetHandler::LoadResult::Error;
|
||||
}
|
||||
|
||||
shaderAsset->AssetInitBus::Handler::BusConnect();
|
||||
|
||||
return Data::AssetHandler::LoadResult::LoadComplete;
|
||||
}
|
||||
|
||||
return Data::AssetHandler::LoadResult::Error;
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
|
||||
} // namespace RPI
|
||||
|
||||
Reference in New Issue
Block a user