Merge branch 'stabilization/2106' into V2Mainline

This commit is contained in:
amzn-mike
2021-06-16 12:05:28 -05:00
275 changed files with 3555 additions and 4137 deletions
@@ -49,7 +49,7 @@ class TestViewMenuOptions(EditorTestHelper):
view_menu_options = [
("Center on Selection",),
("Show Quick Access Bar",),
("Viewport", "Wireframe"),
("Viewport", "Configure Layout"),
("Viewport", "Go to Position"),
("Viewport", "Center on Selection"),
("Viewport", "Go to Location"),
@@ -89,7 +89,7 @@ class TestMenus(object):
expected_lines = [
"Center on Selection Action triggered",
"Show Quick Access Bar Action triggered",
"Wireframe Action triggered",
"Configure Layout Action triggered",
"Go to Position Action triggered",
"Center on Selection Action triggered",
"Go to Location Action triggered",
@@ -406,6 +406,7 @@ namespace AZ
AZStd::vector<AZ::BehaviorParameter> eventParamsTypes{ AZStd::initializer_list<AZ::BehaviorParameter>{
CreateBehaviorEventParameter<decay_array<T>>()... } };
behaviorContext->Class<AZ::Event<T...>>()
->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::ListOnly)
->Attribute(AZ::Script::Attributes::EventHandlerCreationFunction, createHandlerHolder)
->Attribute(AZ::Script::Attributes::EventParameterTypes, eventParamsTypes)
->Method("HasHandlerConnected", &AZ::Event<T...>::HasHandlerConnected)
@@ -413,6 +414,7 @@ namespace AZ
behaviorContext->Class<AZ::EventHandler<T...>>()
->Method("Disconnect", &AZ::EventHandler<T...>::Disconnect)
->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::ListOnly)
;
}
}
@@ -607,10 +607,12 @@ namespace AZ
}
else if (source.Size() > target.Size())
{
rapidjson::SizeType sourceCount = source.Size();
for (rapidjson::SizeType i = count; i < sourceCount; ++i)
// Loop backwards through the removals so that each removal has a valid index when processing in order.
for (rapidjson::SizeType i = source.Size(); i > count; --i)
{
ScopedStackedString entryName(element, i);
// (We use "i - 1" here instead of in the loop to ensure we don't wrap around our unsigned numbers in the case
// where count is 0.)
ScopedStackedString entryName(element, i - 1);
patch.PushBack(CreatePatchInternal_Remove(allocator, element), allocator);
resultCode.Combine(settings.m_reporting("Removed member from array in JSON Patch.",
ResultCode(Tasks::CreatePatch, Outcomes::Success), element));
@@ -303,6 +303,29 @@ namespace JsonSerializationTests
R"( { "foo": [ "bar", "baz" ] })");
}
TEST_F(JsonPatchingSerializationTests, ApplyPatch_UseJsonPatchRemoveArrayMembersInCorrectOrder_ReportsSuccess)
{
CheckApplyPatch(
R"( { "foo": [ "bar", "qux", "baz" ] })",
R"( [
{ "op": "remove", "path": "/foo/2" },
{ "op": "remove", "path": "/foo/1" }
])",
R"( { "foo": [ "bar" ] })");
}
TEST_F(JsonPatchingSerializationTests, ApplyPatch_UseJsonPatchRemoveArrayMembersInWrongOrder_ReportsError)
{
using namespace AZ::JsonSerializationResult;
CheckApplyPatchOutcome(
R"( { "foo": [ "bar", "qux", "baz" ] })",
R"( [
{ "op": "remove", "path": "/foo/1" },
{ "op": "remove", "path": "/foo/2" }
])",
Outcomes::Invalid, Processing::Halted);
}
TEST_F(JsonPatchingSerializationTests, ApplyPatch_UseJsonPatchRemoveOperationInvalidParent_ReportError)
{
using namespace AZ::JsonSerializationResult;
@@ -949,6 +972,27 @@ namespace JsonSerializationTests
);
}
TEST_F(JsonPatchingSerializationTests, CreatePatch_UseJsonPatchRemoveLastArrayEntries_MultipleOperationsInCorrectOrder)
{
CheckCreatePatch(
R"( [ "foo", "hello", "bar" ])", R"( [ "foo" ])",
R"( [
{ "op": "remove", "path": "/2" },
{ "op": "remove", "path": "/1" }
])");
}
TEST_F(JsonPatchingSerializationTests, CreatePatch_UseJsonPatchRemoveAllArrayEntries_MultipleOperationsInCorrectOrder)
{
CheckCreatePatch(
R"( [ "foo", "hello", "bar" ])", R"( [])",
R"( [
{ "op": "remove", "path": "/2" },
{ "op": "remove", "path": "/1" },
{ "op": "remove", "path": "/0" }
])");
}
TEST_F(JsonPatchingSerializationTests, CreatePatch_UseJsonPatchRemoveObjectFromArrayInMiddle_OperationToUpdateMember)
{
CheckCreatePatch(
@@ -159,12 +159,23 @@ namespace AzToolsFramework
void PrefabEditorEntityOwnershipService::GetNonPrefabEntities(EntityList& entities)
{
m_rootInstance->GetEntities(entities, false);
m_rootInstance->GetEntities(
[&entities](const AZStd::unique_ptr<AZ::Entity>& entity)
{
entities.emplace_back(entity.get());
return true;
});
}
bool PrefabEditorEntityOwnershipService::GetAllEntities(EntityList& entities)
{
m_rootInstance->GetEntities(entities, true);
m_rootInstance->GetAllEntitiesInHierarchy(
[&entities](const AZStd::unique_ptr<AZ::Entity>& entity)
{
entities.emplace_back(entity.get());
return true;
});
return true;
}
@@ -551,7 +562,7 @@ namespace AzToolsFramework
return;
}
m_rootInstance->GetNestedEntities([this](AZStd::unique_ptr<AZ::Entity>& entity)
m_rootInstance->GetAllEntitiesInHierarchy([this](AZStd::unique_ptr<AZ::Entity>& entity)
{
AZ_Assert(entity, "Invalid entity found in root instance while starting play in editor.");
if (entity->GetState() == AZ::Entity::State::Active)
@@ -373,17 +373,25 @@ namespace AzToolsFramework
}
}
void Instance::GetConstNestedEntities(const AZStd::function<bool(const AZ::Entity&)>& callback)
bool Instance::GetEntities_Impl(const AZStd::function<bool(AZStd::unique_ptr<AZ::Entity>&)>& callback)
{
GetConstEntities(callback);
for (const auto& [instanceAlias, instance] : m_nestedInstances)
for (auto& [entityAlias, entity] : m_entities)
{
instance->GetConstNestedEntities(callback);
if (!entity)
{
continue;
}
if (!callback(entity))
{
return false;
}
}
return true;
}
void Instance::GetConstEntities(const AZStd::function<bool(const AZ::Entity&)>& callback)
bool Instance::GetConstEntities_Impl(const AZStd::function<bool(const AZ::Entity&)>& callback) const
{
for (const auto& [entityAlias, entity] : m_entities)
{
@@ -394,19 +402,83 @@ namespace AzToolsFramework
if (!callback(*entity))
{
break;
return false;
}
}
return true;
}
void Instance::GetNestedEntities(const AZStd::function<bool(AZStd::unique_ptr<AZ::Entity>&)>& callback)
bool Instance::GetAllEntitiesInHierarchy_Impl(const AZStd::function<bool(AZStd::unique_ptr<AZ::Entity>&)>& callback)
{
GetEntities(callback);
if (HasContainerEntity())
{
if (!callback(m_containerEntity))
{
return false;
}
}
if (!GetEntities_Impl(callback))
{
return false;
}
for (auto& [instanceAlias, instance] : m_nestedInstances)
{
instance->GetNestedEntities(callback);
if (!instance->GetAllEntitiesInHierarchy_Impl(callback))
{
return false;
}
}
return true;
}
bool Instance::GetAllEntitiesInHierarchyConst_Impl(const AZStd::function<bool(const AZ::Entity&)>& callback) const
{
if (HasContainerEntity())
{
if (!callback(*m_containerEntity))
{
return false;
}
}
if (!GetConstEntities_Impl(callback))
{
return false;
}
for (const auto& [instanceAlias, instance] : m_nestedInstances)
{
if (!instance->GetAllEntitiesInHierarchyConst_Impl(callback))
{
return false;
}
}
return true;
}
void Instance::GetEntities(const AZStd::function<bool(AZStd::unique_ptr<AZ::Entity>&)>& callback)
{
GetEntities_Impl(callback);
}
void Instance::GetConstEntities(const AZStd::function<bool(const AZ::Entity&)>& callback) const
{
GetConstEntities_Impl(callback);
}
void Instance::GetAllEntitiesInHierarchy(const AZStd::function<bool(AZStd::unique_ptr<AZ::Entity>&)>& callback)
{
GetAllEntitiesInHierarchy_Impl(callback);
}
void Instance::GetAllEntitiesInHierarchyConst(const AZStd::function<bool(const AZ::Entity&)>& callback) const
{
GetAllEntitiesInHierarchyConst_Impl(callback);
}
void Instance::GetNestedInstances(const AZStd::function<void(AZStd::unique_ptr<Instance>&)>& callback)
@@ -417,44 +489,6 @@ namespace AzToolsFramework
}
}
void Instance::GetEntities(const AZStd::function<bool(AZStd::unique_ptr<AZ::Entity>&)>& callback)
{
for (auto& [entityAlias, entity] : m_entities)
{
if (!callback(entity))
{
break;
}
}
}
void Instance::GetEntities(EntityList& entities, bool includeNestedEntities)
{
// Non-recursive traversal of instances
AZStd::vector<Instance*> instancesToTraverse = { this };
while (!instancesToTraverse.empty())
{
Instance* currentInstance = instancesToTraverse.back();
instancesToTraverse.pop_back();
if (includeNestedEntities)
{
instancesToTraverse.reserve(instancesToTraverse.size() + currentInstance->m_nestedInstances.size());
for (const auto& instanceByAlias : currentInstance->m_nestedInstances)
{
instancesToTraverse.push_back(instanceByAlias.second.get());
}
}
// Size increases by 1 for each instance because we have to count the container entity also.
entities.reserve(entities.size() + currentInstance->m_entities.size() + 1);
entities.push_back(m_containerEntity.get());
for (const auto& entityByAlias : currentInstance->m_entities)
{
entities.push_back(entityByAlias.second.get());
}
}
}
EntityAliasOptionalReference Instance::GetEntityAlias(const AZ::EntityId& id)
{
if (m_instanceToTemplateEntityIdMap.count(id))
@@ -121,10 +121,10 @@ namespace AzToolsFramework
/**
* Gets the entities in the Instance DOM. Can recursively trace all nested instances.
*/
void GetConstNestedEntities(const AZStd::function<bool(const AZ::Entity&)>& callback);
void GetConstEntities(const AZStd::function<bool(const AZ::Entity&)>& callback);
void GetNestedEntities(const AZStd::function<bool(AZStd::unique_ptr<AZ::Entity>&)>& callback);
void GetEntities(const AZStd::function<bool(AZStd::unique_ptr<AZ::Entity>&)>& callback);
void GetConstEntities(const AZStd::function<bool(const AZ::Entity&)>& callback) const;
void GetAllEntitiesInHierarchy(const AZStd::function<bool(AZStd::unique_ptr<AZ::Entity>&)>& callback);
void GetAllEntitiesInHierarchyConst(const AZStd::function<bool(const AZ::Entity&)>& callback) const;
void GetNestedInstances(const AZStd::function<void(AZStd::unique_ptr<Instance>&)>& callback);
/**
@@ -184,12 +184,6 @@ namespace AzToolsFramework
static InstanceAlias GenerateInstanceAlias();
protected:
/**
* Gets the entities owned by this instance
*/
void GetEntities(EntityList& entities, bool includeNestedEntities = false);
private:
static constexpr const char s_aliasPathSeparator = '/';
@@ -197,6 +191,11 @@ namespace AzToolsFramework
void RemoveEntities(const AZStd::function<bool(const AZStd::unique_ptr<AZ::Entity>&)>& filter);
bool GetEntities_Impl(const AZStd::function<bool(AZStd::unique_ptr<AZ::Entity>&)>& callback);
bool GetConstEntities_Impl(const AZStd::function<bool(const AZ::Entity&)>& callback) const;
bool GetAllEntitiesInHierarchy_Impl(const AZStd::function<bool(AZStd::unique_ptr<AZ::Entity>&)>& callback);
bool GetAllEntitiesInHierarchyConst_Impl(const AZStd::function<bool(const AZ::Entity&)>& callback) const;
bool RegisterEntity(const AZ::EntityId& entityId, const EntityAlias& entityAlias);
AZStd::unique_ptr<AZ::Entity> DetachEntity(const EntityAlias& entityAlias);
@@ -62,25 +62,16 @@ namespace AzToolsFramework::Prefab::PrefabConversionUtils
}
}
AZStd::vector<AZ::Entity*> EditorInfoRemover::GetEntitiesFromInstance(AZStd::unique_ptr<Instance>& instance)
void EditorInfoRemover::GetEntitiesFromInstance(
AZStd::unique_ptr<AzToolsFramework::Prefab::Instance>& instance, EntityList& hierarchyEntities)
{
AZStd::vector<AZ::Entity*> result;
instance->GetNestedEntities(
[&result](const AZStd::unique_ptr<AZ::Entity>& entity)
instance->GetAllEntitiesInHierarchy(
[&hierarchyEntities](const AZStd::unique_ptr<AZ::Entity>& entity)
{
result.emplace_back(entity.get());
hierarchyEntities.emplace_back(entity.get());
return true;
}
);
if (instance->HasContainerEntity())
{
auto containerEntityReference = instance->GetContainerEntity();
result.emplace_back(&containerEntityReference->get());
}
return result;
}
void EditorInfoRemover::SetEditorOnlyEntityHandlerFromCandidates(const EntityList& entities)
@@ -543,7 +534,9 @@ exportComponent, prefabProcessorContext);
}
// grab all nested entities from the Instance as source entities.
EntityList sourceEntities = GetEntitiesFromInstance(instance);
EntityList sourceEntities;
GetEntitiesFromInstance(instance, sourceEntities);
EntityList exportEntities;
// prepare for validation of component requirements.
@@ -616,7 +609,7 @@ exportComponent, prefabProcessorContext);
);
// replace entities of instance with exported ones.
instance->GetNestedEntities(
instance->GetAllEntitiesInHierarchy(
[&exportEntitiesMap](AZStd::unique_ptr<AZ::Entity>& entity)
{
auto entityId = entity->GetId();
@@ -625,14 +618,6 @@ exportComponent, prefabProcessorContext);
}
);
if (instance->HasContainerEntity())
{
if (auto found = exportEntitiesMap.find(instance->GetContainerEntityId()); found != exportEntitiesMap.end())
{
instance->SetContainerEntity(*found->second);
}
}
// save the final result in the target Prefab DOM.
PrefabDom filteredPrefab;
if (!PrefabDomUtils::StoreInstanceInPrefabDom(*instance, filteredPrefab))
@@ -55,8 +55,8 @@ namespace AzToolsFramework::Prefab::PrefabConversionUtils
protected:
using EntityList = AZStd::vector<AZ::Entity*>;
static EntityList GetEntitiesFromInstance(
AZStd::unique_ptr<AzToolsFramework::Prefab::Instance>& instance);
static void GetEntitiesFromInstance(
AZStd::unique_ptr<AzToolsFramework::Prefab::Instance>& instance, EntityList& hierarchyEntities);
static bool ReadComponentAttribute(
AZ::Component* component,
@@ -29,15 +29,20 @@ namespace Benchmark
{},
m_pathString));
auto& prefabDom = m_prefabSystemComponent->FindTemplateDom(instance->GetTemplateId());
for (auto _ : state)
{
state.PauseTiming();
AzFramework::Spawnable spawnable;
AzToolsFramework::Prefab::SpawnableUtils::CreateSpawnable(spawnable, prefabDom);
state.ResumeTiming();
// Create a vector to store spawnables so that they don't get destroyed immediately after construction.
AZStd::vector<AZStd::unique_ptr<AzFramework::Spawnable>> spawnables;
spawnables.reserve(numSpawnables);
for (int spwanableCounter = 0; spwanableCounter < numSpawnables; ++spwanableCounter)
{
AZStd::unique_ptr<AzFramework::Spawnable> spawnable = AZStd::make_unique<AzFramework::Spawnable>();
AzToolsFramework::Prefab::SpawnableUtils::CreateSpawnable(*spawnable, prefabDom);
spawnables.push_back(AZStd::move(spawnable));
}
}
state.SetComplexityN(numSpawnables);
@@ -50,3 +55,4 @@ namespace Benchmark
}
#endif
@@ -93,7 +93,7 @@ namespace UnitTest
// Retrieve the entity pointer from the component application bus.
AZ::Entity* wheelEntityUnderAxle = nullptr;
axleInstance->GetNestedEntities([&wheelEntityUnderAxle, wheelEntityIdUnderAxle](AZStd::unique_ptr<AZ::Entity>& entity)
axleInstance->GetAllEntitiesInHierarchy([&wheelEntityUnderAxle, wheelEntityIdUnderAxle](AZStd::unique_ptr<AZ::Entity>& entity)
{
if (entity->GetId() == wheelEntityIdUnderAxle)
{
+15 -5
View File
@@ -514,18 +514,28 @@ void EditorViewportWidget::Update()
// Disable rendering to avoid recursion into Update()
PushDisableRendering();
//get debug display interface for the viewport
AzFramework::DebugDisplayRequestBus::BusPtr debugDisplayBus;
AzFramework::DebugDisplayRequestBus::Bind(debugDisplayBus, GetViewportId());
AZ_Assert(debugDisplayBus, "Invalid DebugDisplayRequestBus.");
AzFramework::DebugDisplayRequests* debugDisplay =
AzFramework::DebugDisplayRequestBus::FindFirstHandler(debugDisplayBus);
// draw debug visualizations
if (m_debugDisplay)
if (debugDisplay)
{
const AZ::u32 prevState = m_debugDisplay->GetState();
m_debugDisplay->SetState(
const AZ::u32 prevState = debugDisplay->GetState();
debugDisplay->SetState(
e_Mode3D | e_AlphaBlended | e_FillModeSolid | e_CullModeBack | e_DepthWriteOn | e_DepthTestOn);
AzFramework::EntityDebugDisplayEventBus::Broadcast(
&AzFramework::EntityDebugDisplayEvents::DisplayEntityViewport,
AzFramework::ViewportInfo{ GetViewportId() }, *m_debugDisplay);
AzFramework::ViewportInfo{ GetViewportId() }, *debugDisplay);
m_debugDisplay->SetState(prevState);
debugDisplay->SetState(prevState);
}
QtViewport::Update();
@@ -154,11 +154,23 @@ SandboxIntegrationManager::SandboxIntegrationManager()
{
// Required to receive events from the Cry Engine undo system
GetIEditor()->GetUndoManager()->AddListener(this);
// Only create the PrefabIntegrationManager if prefabs are enabled
bool prefabSystemEnabled = false;
AzFramework::ApplicationRequests::Bus::BroadcastResult(
prefabSystemEnabled, &AzFramework::ApplicationRequests::IsPrefabSystemEnabled);
if (prefabSystemEnabled)
{
m_prefabIntegrationManager = aznew AzToolsFramework::Prefab::PrefabIntegrationManager();
}
}
SandboxIntegrationManager::~SandboxIntegrationManager()
{
GetIEditor()->GetUndoManager()->RemoveListener(this);
delete m_prefabIntegrationManager;
m_prefabIntegrationManager = nullptr;
}
void SandboxIntegrationManager::Setup()
@@ -187,11 +199,16 @@ void SandboxIntegrationManager::Setup()
AZ_Assert((m_editorEntityUiInterface != nullptr),
"SandboxIntegrationManager requires a EditorEntityUiInterface instance to be present on Setup().");
m_prefabIntegrationInterface = AZ::Interface<AzToolsFramework::Prefab::PrefabIntegrationInterface>::Get();
AZ_Assert(
(m_prefabIntegrationInterface != nullptr),
"SandboxIntegrationManager requires a PrefabIntegrationInterface instance to be present on Setup().");
bool prefabSystemEnabled = false;
AzFramework::ApplicationRequests::Bus::BroadcastResult(
prefabSystemEnabled, &AzFramework::ApplicationRequests::IsPrefabSystemEnabled);
if (prefabSystemEnabled)
{
m_prefabIntegrationInterface = AZ::Interface<AzToolsFramework::Prefab::PrefabIntegrationInterface>::Get();
AZ_Assert(
(m_prefabIntegrationInterface != nullptr),
"SandboxIntegrationManager requires a PrefabIntegrationInterface instance to be present on Setup().");
}
m_editorEntityAPI = AZ::Interface<AzToolsFramework::EditorEntityAPI>::Get();
AZ_Assert(m_editorEntityAPI, "SandboxIntegrationManager requires an EditorEntityAPI instance to be present on Setup().");
@@ -305,7 +305,7 @@ private:
bool m_debugDisplayBusImplementationActive = false;
AzToolsFramework::Prefab::PrefabIntegrationManager m_prefabIntegrationManager;
AzToolsFramework::Prefab::PrefabIntegrationManager* m_prefabIntegrationManager = nullptr;
AzToolsFramework::EditorEntityUiInterface* m_editorEntityUiInterface = nullptr;
AzToolsFramework::Prefab::PrefabIntegrationInterface* m_prefabIntegrationInterface = nullptr;
@@ -12,6 +12,7 @@
#include "BuilderManager.h"
#include <AzCore/std/smart_ptr/make_shared.h>
#include <AzCore/Utils/Utils.h>
#include <AzFramework/API/ApplicationAPI.h>
#include <native/connection/connectionManager.h>
@@ -186,10 +187,9 @@ namespace AssetProcessor
QDir projectCacheRoot;
AssetUtilities::ComputeProjectCacheRoot(projectCacheRoot);
QString gameName = AssetUtilities::ComputeProjectName();
QString projectPath = AssetUtilities::ComputeProjectPath();
QDir engineRoot;
AssetUtilities::ComputeEngineRoot(engineRoot);
AZ::SettingsRegistryInterface::FixedValueString projectName = AZ::Utils::GetProjectName();
AZ::IO::FixedMaxPathString projectPath = AZ::Utils::GetProjectPath();
AZ::IO::FixedMaxPathString enginePath = AZ::Utils::GetEnginePath();
int portNumber = 0;
ApplicationServerBus::BroadcastResult(portNumber, &ApplicationServerBus::Events::GetServerListeningPort);
@@ -197,14 +197,14 @@ namespace AssetProcessor
AZStd::string params;
#if !AZ_TRAIT_OS_PLATFORM_APPLE && !AZ_TRAIT_OS_USE_WINDOWS_FILE_PATHS
params = AZStd::string::format(
R"(-task=%s -id="%s" -project-name="%s" -project-cache-path="%s" -project-path="%s" -engine-path="%s" -port %d)", task,
builderGuid.c_str(), gameName.toUtf8().constData(), projectCacheRoot.absolutePath().toUtf8().constData(),
projectPath.toUtf8().constData(), engineRoot.absolutePath().toUtf8().constData(), portNumber);
R"(-task=%s -id="%s" -project-name="%s" -project-cache-path="%s" -project-path="%s" -engine-path="%s" -port %d)",
task, builderGuid.c_str(), projectName.c_str(), projectCacheRoot.absolutePath().toUtf8().constData(),
projectPath.c_str(), enginePath.c_str(), portNumber);
#else
params = AZStd::string::format(
R"(-task=%s -id="%s" -project-name="\"%s\"" -project-cache-path="\"%s\"" -project-path="\"%s\"" -engine-path="\"%s\"" -port %d)",
task, builderGuid.c_str(), gameName.toUtf8().constData(), projectCacheRoot.absolutePath().toUtf8().constData(),
projectPath.toUtf8().constData(), engineRoot.absolutePath().toUtf8().constData(), portNumber);
task, builderGuid.c_str(), projectName.c_str(), projectCacheRoot.absolutePath().toUtf8().constData(),
projectPath.c_str(), enginePath.c_str(), portNumber);
#endif // !AZ_TRAIT_OS_PLATFORM_APPLE && !AZ_TRAIT_OS_USE_WINDOWS_FILE_PATHS
if (moduleFilePath && moduleFilePath[0])
@@ -77,6 +77,7 @@ namespace AZ
{
AZStd::string extension;
StringFunc::Path::GetExtension(path.c_str(), extension);
AZStd::to_lower(extension.begin(), extension.end());
if (!m_settings.m_supportedFileTypeExtensions.contains(extension))
{
@@ -151,7 +151,7 @@ namespace AZ
SerializeContext* serializeContext = azrtti_cast<SerializeContext*>(context);
if (serializeContext)
{
serializeContext->Class<AssImpAnimationImporter, SceneCore::LoadingComponent>()->Version(4); // [LYN-3971] Bone pruning crash fix in AssImp SDK
serializeContext->Class<AssImpAnimationImporter, SceneCore::LoadingComponent>()->Version(5); // [LYN-4226] Invert PostRotation matrix in animation chains
}
}
@@ -385,24 +385,36 @@ namespace AZ
return false;
}
// Now, convert the nested slice to a prefab.
bool nestedSliceResult = ConvertSliceFile(serializeContext, assetPath, isDryRun);
if (!nestedSliceResult)
{
AZ_Warning("Convert-Slice", nestedSliceResult, " Nested slice '%s' could not be converted.", assetPath.c_str());
return false;
}
// Check to see if we've already converted this slice at a higher level of slice nesting, or if this is our first
// occurrence and we need to convert it now.
// Find the prefab template we created for the newly-created nested prefab.
// To get the template, we need to take our absolute slice path and turn it into a project-relative prefab path.
// First, take our absolute slice path and turn it into a project-relative prefab path.
AZ::IO::Path nestedPrefabPath = assetPath;
nestedPrefabPath.ReplaceExtension("prefab");
auto prefabLoaderInterface = AZ::Interface<AzToolsFramework::Prefab::PrefabLoaderInterface>::Get();
nestedPrefabPath = prefabLoaderInterface->GenerateRelativePath(nestedPrefabPath);
// Now, see if we already have a template ID in memory for it.
AzToolsFramework::Prefab::TemplateId nestedTemplateId =
prefabSystemComponentInterface->GetTemplateIdFromFilePath(nestedPrefabPath);
// If we don't have a template ID yet, convert the nested slice to a prefab and get the template ID.
if (nestedTemplateId == AzToolsFramework::Prefab::InvalidTemplateId)
{
bool nestedSliceResult = ConvertSliceFile(serializeContext, assetPath, isDryRun);
if (!nestedSliceResult)
{
AZ_Warning("Convert-Slice", nestedSliceResult, " Nested slice '%s' could not be converted.", assetPath.c_str());
return false;
}
nestedTemplateId = prefabSystemComponentInterface->GetTemplateIdFromFilePath(nestedPrefabPath);
AZ_Assert(nestedTemplateId != AzToolsFramework::Prefab::InvalidTemplateId,
"Template ID for %s is invalid", nestedPrefabPath.c_str());
}
// Get the nested prefab template.
AzToolsFramework::Prefab::TemplateReference nestedTemplate =
prefabSystemComponentInterface->FindTemplate(nestedTemplateId);
@@ -24,9 +24,9 @@
},
"ImageDescriptor": {
"Format": "R16G16B16A16_FLOAT",
"MipLevels": "8",
"SharedQueueMask": "Graphics"
}
},
"GenerateFullMipChain": true
}
],
"Connections": [
@@ -5,7 +5,7 @@
"ClassData": {
"PassTemplate": {
"Name": "ReflectionScreenSpaceCompositePassTemplate",
"PassClass": "FullScreenTriangle",
"PassClass": "ReflectionScreenSpaceCompositePass",
"Slots": [
{
"Name": "TraceInput",
@@ -15,9 +15,6 @@
#include <Atom/Features/PBR/Lights/LightTypesCommon.azsli>
#include <Atom/Features/Shadow/ProjectedShadow.azsli>
// The order should match m_pointShadowTransforms in PointLightFeatureProcessor.h/.cpp
static const float3 PointLightShadowCubemapDirections[6] = {float3(-1,0,0), float3(1,0,0), float3(0,-1,0), float3(0,1,0), float3(0,0,-1), float3(0,0,1)};
int GetPointLightShadowCubemapFace(const float3 targetPos, const float3 lightPos)
{
const float3 toPoint = targetPos - lightPos;
@@ -83,12 +80,13 @@ void ApplyPointLight(ViewSrg::PointLight light, Surface surface, inout LightingD
{
const int shadowCubemapFace = GetPointLightShadowCubemapFace(surface.position, light.m_position);
const int shadowIndex = UnpackPointLightShadowIndex(light, shadowCubemapFace);
const float3 lightDir = normalize(light.m_position - surface.position);
litRatio *= ProjectedShadow::GetVisibility(
shadowIndex,
light.m_position,
surface.position,
PointLightShadowCubemapDirections[shadowCubemapFace],
lightDir,
surface.normal);
// Use backShadowRatio to carry thickness from shadow map for thick mode
@@ -37,6 +37,9 @@ ShaderResourceGroup PassSrg : SRG_PerPass
AddressV = Clamp;
AddressW = Clamp;
};
// the max roughness mip level for sampling the previous frame image
uint m_maxMipLevel;
}
#include <Atom/RPI/ShaderResourceGroups/DefaultDrawSrg.azsli>
@@ -69,10 +72,6 @@ PSOutput MainPS(VSOutput IN, in uint sampleIndex : SV_SampleIndex)
float4 positionWS = mul(ViewSrg::m_viewProjectionInverseMatrix, projectedPos);
positionWS /= positionWS.w;
//float4 positionVS = mul(ViewSrg::m_projectionMatrixInverse, projectedPos);
//positionVS /= positionVS.w;
//float4 positionWS = mul(ViewSrg::m_viewMatrixInverse, positionVS);
// compute ray from camera to surface position
float3 cameraToPositionWS = normalize(positionWS.xyz - ViewSrg::m_worldPosition);
@@ -103,8 +102,7 @@ PSOutput MainPS(VSOutput IN, in uint sampleIndex : SV_SampleIndex)
// compute the roughness mip to use in the previous frame image
// remap the roughness mip into a lower range to more closely match the material roughness values
const float MaxRoughness = 0.5f;
const float MaxRoughnessMip = 7;
float mip = saturate(roughness / MaxRoughness) * MaxRoughnessMip;
float mip = saturate(roughness / MaxRoughness) * PassSrg::m_maxMipLevel;
// sample reflection value from the roughness mip
float4 reflectionColor = float4(PassSrg::m_previousFrame.SampleLevel(PassSrg::LinearSampler, tracePrevUV, mip).rgb, 1.0f);
@@ -103,6 +103,7 @@
#include <DiffuseGlobalIllumination/DiffuseGlobalIlluminationFeatureProcessor.h>
#include <ReflectionScreenSpace/ReflectionScreenSpaceBlurPass.h>
#include <ReflectionScreenSpace/ReflectionScreenSpaceBlurChildPass.h>
#include <ReflectionScreenSpace/ReflectionScreenSpaceCompositePass.h>
#include <ReflectionScreenSpace/ReflectionCopyFrameBufferPass.h>
#include <OcclusionCullingPlane/OcclusionCullingPlaneFeatureProcessor.h>
@@ -283,6 +284,7 @@ namespace AZ
// Add Reflection passes
passSystem->AddPassCreator(Name("ReflectionScreenSpaceBlurPass"), &Render::ReflectionScreenSpaceBlurPass::Create);
passSystem->AddPassCreator(Name("ReflectionScreenSpaceBlurChildPass"), &Render::ReflectionScreenSpaceBlurChildPass::Create);
passSystem->AddPassCreator(Name("ReflectionScreenSpaceCompositePass"), &Render::ReflectionScreenSpaceCompositePass::Create);
passSystem->AddPassCreator(Name("ReflectionCopyFrameBufferPass"), &Render::ReflectionCopyFrameBufferPass::Create);
// Add RayTracing pas
@@ -37,6 +37,9 @@ namespace AZ
//! to store the previous frame image
Data::Instance<RPI::AttachmentImage>& GetFrameBufferImageAttachment() { return m_frameBufferImageAttachment; }
//! Returns the number of mip levels in the blur
uint32_t GetNumBlurMips() const { return m_numBlurMips; }
private:
explicit ReflectionScreenSpaceBlurPass(const RPI::PassDescriptor& descriptor);
@@ -0,0 +1,58 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include "ReflectionScreenSpaceCompositePass.h"
#include "ReflectionScreenSpaceBlurPass.h"
#include <Atom/RPI.Public/Pass/PassSystemInterface.h>
#include <Atom/RPI.Public/Pass/PassFilter.h>
namespace AZ
{
namespace Render
{
RPI::Ptr<ReflectionScreenSpaceCompositePass> ReflectionScreenSpaceCompositePass::Create(const RPI::PassDescriptor& descriptor)
{
RPI::Ptr<ReflectionScreenSpaceCompositePass> pass = aznew ReflectionScreenSpaceCompositePass(descriptor);
return AZStd::move(pass);
}
ReflectionScreenSpaceCompositePass::ReflectionScreenSpaceCompositePass(const RPI::PassDescriptor& descriptor)
: RPI::FullscreenTrianglePass(descriptor)
{
}
void ReflectionScreenSpaceCompositePass::CompileResources([[maybe_unused]] const RHI::FrameGraphCompileContext& context)
{
if (!m_shaderResourceGroup)
{
return;
}
RPI::PassHierarchyFilter passFilter(AZ::Name("ReflectionScreenSpaceBlurPass"));
const AZStd::vector<RPI::Pass*>& passes = RPI::PassSystemInterface::Get()->FindPasses(passFilter);
if (!passes.empty())
{
Render::ReflectionScreenSpaceBlurPass* blurPass = azrtti_cast<ReflectionScreenSpaceBlurPass*>(passes.front());
// compute the max mip level based on the available mips in the previous frame image, and capping it
// to stay within a range that has reasonable data
const uint32_t MaxNumRoughnessMips = 8;
uint32_t maxMipLevel = AZStd::min(MaxNumRoughnessMips, blurPass->GetNumBlurMips()) - 1;
auto constantIndex = m_shaderResourceGroup->FindShaderInputConstantIndex(Name("m_maxMipLevel"));
m_shaderResourceGroup->SetConstant(constantIndex, maxMipLevel);
}
FullscreenTrianglePass::CompileResources(context);
}
} // namespace RPI
} // namespace AZ
@@ -0,0 +1,43 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
#include <Atom/RPI.Public/Pass/Pass.h>
#include <Atom/RPI.Public/Pass/FullscreenTrianglePass.h>
#include <Atom/RPI.Public/Shader/ShaderResourceGroup.h>
#include <Atom/RPI.Public/Shader/Shader.h>
namespace AZ
{
namespace Render
{
//! This pass composites the screenspace reflection trace onto the reflection buffer.
class ReflectionScreenSpaceCompositePass
: public RPI::FullscreenTrianglePass
{
AZ_RPI_PASS(ReflectionScreenSpaceCompositePass);
public:
AZ_RTTI(Render::ReflectionScreenSpaceCompositePass, "{88739CC9-C3F1-413A-A527-9916C697D93A}", FullscreenTrianglePass);
AZ_CLASS_ALLOCATOR(Render::ReflectionScreenSpaceCompositePass, SystemAllocator, 0);
//! Creates a new pass without a PassTemplate
static RPI::Ptr<ReflectionScreenSpaceCompositePass> Create(const RPI::PassDescriptor& descriptor);
private:
explicit ReflectionScreenSpaceCompositePass(const RPI::PassDescriptor& descriptor);
// Pass Overrides...
void CompileResources(const RHI::FrameGraphCompileContext& context) override;
};
} // namespace RPI
} // namespace AZ
@@ -629,6 +629,11 @@ namespace AZ
Data::Asset<RPI::ModelLodAsset> lodAsset;
modelLodCreator.End(lodAsset);
if (!lodAsset.IsReady())
{
// [GFX TODO] During mesh reload the modelLodCreator could report errors and result in the lodAsset not ready.
return nullptr;
}
modelCreator.AddLodAsset(AZStd::move(lodAsset));
lodIndex++;
@@ -267,6 +267,8 @@ set(FILES
Source/ReflectionScreenSpace/ReflectionScreenSpaceBlurPass.h
Source/ReflectionScreenSpace/ReflectionScreenSpaceBlurChildPass.cpp
Source/ReflectionScreenSpace/ReflectionScreenSpaceBlurChildPass.h
Source/ReflectionScreenSpace/ReflectionScreenSpaceCompositePass.cpp
Source/ReflectionScreenSpace/ReflectionScreenSpaceCompositePass.h
Source/ReflectionScreenSpace/ReflectionCopyFrameBufferPass.cpp
Source/ReflectionScreenSpace/ReflectionCopyFrameBufferPass.h
Source/ScreenSpace/DeferredFogSettings.cpp
@@ -417,7 +417,7 @@ namespace AZ
AZ::IO::FileIOStream sourceMtlfileStream(inputMetalFile.c_str(), AZ::IO::OpenMode::ModeWrite | AZ::IO::OpenMode::ModeBinary);
if (!sourceMtlfileStream.IsOpen())
{
AZ_Error(platformName, false, "Failed because the shader file \"%s\" could not be opened", inputMetalFile);
AZ_Error(platformName, false, "Failed because the shader file \"%s\" could not be opened", inputMetalFile.c_str());
return false;
}
@@ -400,15 +400,13 @@ namespace AZ
id<MTLResource> mtlconstantBufferResource = m_constantBuffer.GetGpuAddress<id<MTLResource>>();
if(RHI::CheckBitsAny(srgResourcesVisInfo.m_constantDataStageMask, RHI::ShaderStageMask::Compute))
{
uint16_t arrayIndex = resourcesToMakeResidentCompute[MTLResourceUsageRead].m_resourceArrayLen++;
resourcesToMakeResidentCompute[MTLResourceUsageRead].m_resourceArray[arrayIndex] = mtlconstantBufferResource;
resourcesToMakeResidentCompute[MTLResourceUsageRead].emplace(mtlconstantBufferResource);
}
else
{
MTLRenderStages mtlRenderStages = GetRenderStages(srgResourcesVisInfo.m_constantDataStageMask);
AZStd::pair <MTLResourceUsage,MTLRenderStages> key = AZStd::make_pair(MTLResourceUsageRead, mtlRenderStages);
uint16_t arrayIndex = resourcesToMakeResidentGraphics[key].m_resourceArrayLen++;
resourcesToMakeResidentGraphics[key].m_resourceArray[arrayIndex] = mtlconstantBufferResource;
AZStd::pair <MTLResourceUsage,MTLRenderStages> key = AZStd::make_pair(MTLResourceUsageRead, mtlRenderStages);
resourcesToMakeResidentGraphics[key].emplace(mtlconstantBufferResource);
}
}
}
@@ -440,16 +438,18 @@ namespace AZ
//Call UseResource on all resources for Compute stage
for (const auto& key : resourcesToMakeResidentCompute)
{
[static_cast<id<MTLComputeCommandEncoder>>(commandEncoder) useResources: key.second.m_resourceArray.data()
count: key.second.m_resourceArrayLen
AZStd::vector<id <MTLResource>> resourcesToProcessVec(key.second.begin(), key.second.end());
[static_cast<id<MTLComputeCommandEncoder>>(commandEncoder) useResources: &resourcesToProcessVec[0]
count: resourcesToProcessVec.size()
usage: key.first];
}
//Call UseResource on all resources for Vertex and Fragment stages
for (const auto& key : resourcesToMakeResidentGraphics)
{
[static_cast<id<MTLRenderCommandEncoder>>(commandEncoder) useResources: key.second.m_resourceArray.data()
count: key.second.m_resourceArrayLen
AZStd::vector<id <MTLResource>> resourcesToProcessVec(key.second.begin(), key.second.end());
[static_cast<id<MTLRenderCommandEncoder>>(commandEncoder) useResources: &resourcesToProcessVec[0]
count: resourcesToProcessVec.size()
usage: key.first.first
stages: key.first.second];
}
@@ -480,9 +480,9 @@ namespace AZ
AZ_Assert(false, "Undefined Resource type");
}
}
uint16_t arrayIndex = resourcesToMakeResidentMap[resourceUsage].m_resourceArrayLen++;
id<MTLResource> mtlResourceToBind = resourceBindingData.m_resourcPtr->GetGpuAddress<id<MTLResource>>();
resourcesToMakeResidentMap[resourceUsage].m_resourceArray[arrayIndex] = mtlResourceToBind;
resourcesToMakeResidentMap[resourceUsage].emplace(mtlResourceToBind);
}
}
@@ -516,9 +516,8 @@ namespace AZ
}
AZStd::pair <MTLResourceUsage, MTLRenderStages> key = AZStd::make_pair(resourceUsage, mtlRenderStages);
uint16_t arrayIndex = resourcesToMakeResidentMap[key].m_resourceArrayLen++;
id<MTLResource> mtlResourceToBind = resourceBindingData.m_resourcPtr->GetGpuAddress<id<MTLResource>>();
resourcesToMakeResidentMap[key].m_resourceArray[arrayIndex] = mtlResourceToBind;
resourcesToMakeResidentMap[key].emplace(mtlResourceToBind);
}
}
}
@@ -120,15 +120,10 @@ namespace AZ
ResourceBindingsMap m_resourceBindings;
static const int MaxEntriesInArgTable = 31;
struct MetalResourceArray
{
AZStd::array<id <MTLResource>, MaxEntriesInArgTable> m_resourceArray;
uint16_t m_resourceArrayLen = 0;
};
//Map to cache all the resources based on the usage as we can batch all the resources for a given usage
using ComputeResourcesToMakeResidentMap = AZStd::unordered_map<MTLResourceUsage, MetalResourceArray>;
//Map to cache all the resources based on the usage and shader stage as we can batch all the resources for a given usage/shader usage
using GraphicsResourcesToMakeResidentMap = AZStd::unordered_map<AZStd::pair<MTLResourceUsage,MTLRenderStages>, MetalResourceArray>;
//Map to cache all the resources based on the usage as we can batch all the resources for a given usage.
using ComputeResourcesToMakeResidentMap = AZStd::unordered_map<MTLResourceUsage, AZStd::unordered_set<id <MTLResource>>>;
//Map to cache all the resources based on the usage and shader stage as we can batch all the resources for a given usage/shader usage.
using GraphicsResourcesToMakeResidentMap = AZStd::unordered_map<AZStd::pair<MTLResourceUsage,MTLRenderStages>, AZStd::unordered_set<id <MTLResource>>>;
void CollectResourcesForCompute(id<MTLCommandEncoder> encoder,
const ResourceBindingsSet& resourceBindingData,
@@ -85,16 +85,36 @@ namespace AZ
uint64_t AsyncUploadQueue::QueueUpload(const RHI::BufferStreamRequest& uploadRequest)
{
uint64_t queueValue = m_uploadFence.Increment();
Buffer& destBuffer = static_cast<Buffer&>(*uploadRequest.m_buffer);
const MemoryView& destMemoryView = destBuffer.GetMemoryView();
MTLStorageMode mtlStorageMode = destBuffer.GetMemoryView().GetStorageMode();
RHI::BufferPool& bufferPool = static_cast<RHI::BufferPool&>(*destBuffer.GetPool());
// No need to use staging buffers since it's host memory.
// We just map, copy and then unmap.
if(mtlStorageMode == MTLStorageModeShared || mtlStorageMode == GetCPUGPUMemoryMode())
{
RHI::BufferMapRequest mapRequest;
mapRequest.m_buffer = uploadRequest.m_buffer;
mapRequest.m_byteCount = uploadRequest.m_byteCount;
mapRequest.m_byteOffset = uploadRequest.m_byteOffset;
RHI::BufferMapResponse mapResponse;
bufferPool.MapBuffer(mapRequest, mapResponse);
::memcpy(mapResponse.m_data, uploadRequest.m_sourceData, uploadRequest.m_byteCount);
bufferPool.UnmapBuffer(*uploadRequest.m_buffer);
if (uploadRequest.m_fenceToSignal)
{
uploadRequest.m_fenceToSignal->SignalOnCpu();
}
return m_uploadFence.GetPendingValue();
}
const MemoryView& memoryView = static_cast<Buffer&>(*uploadRequest.m_buffer).GetMemoryView();
RHI::Ptr<Memory> buffer = memoryView.GetMemory();
Fence* fenceToSignal = nullptr;
uint64_t fenceToSignalValue = 0;
size_t byteCount = uploadRequest.m_byteCount;
size_t byteOffset = memoryView.GetOffset() + uploadRequest.m_byteOffset;
size_t byteOffset = destMemoryView.GetOffset() + uploadRequest.m_byteOffset;
uint64_t queueValue = m_uploadFence.Increment();
const uint8_t* sourceData = reinterpret_cast<const uint8_t*>(uploadRequest.m_sourceData);
if (uploadRequest.m_fenceToSignal)
@@ -125,11 +145,11 @@ namespace AZ
}
id<MTLBlitCommandEncoder> blitEncoder = [framePacket->m_mtlCommandBuffer blitCommandEncoder];
[blitEncoder copyFromBuffer:framePacket->m_stagingResource
sourceOffset:0
toBuffer:buffer->GetGpuAddress<id<MTLBuffer>>()
destinationOffset:byteOffset + pendingByteOffset
size:bytesToCopy];
[blitEncoder copyFromBuffer: framePacket->m_stagingResource
sourceOffset: 0
toBuffer: destMemoryView.GetGpuAddress<id<MTLBuffer>>()
destinationOffset: byteOffset + pendingByteOffset
size: bytesToCopy];
[blitEncoder endEncoding];
blitEncoder = nil;
@@ -40,9 +40,8 @@ namespace AZ
buffer->m_pendingResolves++;
uploadRequest.m_attachmentBuffer = buffer;
uploadRequest.m_byteOffset = request.m_byteOffset;
uploadRequest.m_byteOffset = buffer->GetMemoryView().GetOffset() + request.m_byteOffset;
uploadRequest.m_stagingBuffer = stagingBuffer;
uploadRequest.m_byteSize = request.m_byteCount;
return stagingBuffer->GetMemoryView().GetCpuAddress();
}
@@ -64,12 +63,15 @@ namespace AZ
AZ_Assert(stagingBuffer, "Staging Buffer is null.");
AZ_Assert(destBuffer, "Attachment Buffer is null.");
//Inform the GPU that the CPU has modified the staging buffer.
Platform::SynchronizeBufferOnCPU(stagingBuffer->GetMemoryView().GetGpuAddress<id<MTLBuffer>>(), stagingBuffer->GetMemoryView().GetOffset(), stagingBuffer->GetMemoryView().GetSize());
RHI::CopyBufferDescriptor copyDescriptor;
copyDescriptor.m_sourceBuffer = stagingBuffer;
copyDescriptor.m_sourceOffset = 0;
copyDescriptor.m_sourceOffset = stagingBuffer->GetMemoryView().GetOffset();
copyDescriptor.m_destinationBuffer = destBuffer;
copyDescriptor.m_destinationOffset = static_cast<uint32_t>(packet.m_byteOffset);
copyDescriptor.m_size = static_cast<uint32_t>(packet.m_byteSize);
copyDescriptor.m_size = stagingBuffer->GetMemoryView().GetSize();
commandList.Submit(RHI::CopyItem(copyDescriptor));
device.QueueForRelease(stagingBuffer->GetMemoryView());
@@ -54,7 +54,6 @@ namespace AZ
Buffer* m_attachmentBuffer = nullptr;
RHI::Ptr<Buffer> m_stagingBuffer;
size_t m_byteOffset = 0;
size_t m_byteSize = 0;
};
AZStd::mutex m_uploadPacketsLock;
@@ -44,7 +44,7 @@ namespace AZ
if (memoryView.IsValid())
{
heapMemoryUsage.m_residentInBytes += m_descriptor.m_pageSizeInBytes;
memoryView.SetName("BufferPage");
memoryView.SetName(AZStd::string::format("BufferPage_%s", AZ::Uuid::CreateRandom().ToString<AZStd::string>().c_str()));
}
else
{
@@ -55,7 +55,11 @@ namespace AZ
const auto& image = static_cast<const Image&>(resourceBase);
const RHI::ImageViewDescriptor& descriptor = GetDescriptor();
AZ_Assert(image.GetNativeImage() != VK_NULL_HANDLE, "Image has not been initialized.");
// this can happen when image has been invalidated/released right before re-compiling the image
if (image.GetNativeImage() == VK_NULL_HANDLE)
{
return RHI::ResultCode::Fail;
}
RHI::Format viewFormat = descriptor.m_overrideFormat;
// If an image is not owner of native image, it is a swapchain image.
@@ -0,0 +1,43 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
#include <AzCore/EBus/EBus.h>
namespace AZ
{
namespace RPI
{
//! Bus for post-load initialization of assets.
//! Assets that need to do post-load initialization should connect to this bus in their asset handler's LoadAssetData() function.
//! Be sure to disconnect from this bus as soon as initialization is complete, as it will be called every frame.
//! (Note this bus is needed rather than utilizing TickBus because TickBus is not protected by a mutex which means it can't be
//! connected on an asset load job thread).
class AssetInitEvents
: public EBusTraits
{
public:
// EBus Configuration
static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Multiple;
static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::Single;
typedef AZStd::recursive_mutex MutexType;
//! This function is called every frame on the main thread to perform any necessary post-load initialization.
//! Connect to the bus after loading the asset data, and disconnect when initialization is complete.
//! @return whether initialization was successful
virtual bool PostLoadInit() = 0;
};
using AssetInitBus = AZ::EBus<AssetInitEvents>;
} // namespace RPI
} // namespace AZ
@@ -12,6 +12,7 @@
#pragma once
#include <Atom/RPI.Public/Shader/ShaderVariant.h>
#include <Atom/RPI.Public/Shader/ShaderReloadNotificationBus.h>
#include <Atom/RPI.Reflect/Shader/ShaderAsset.h>
#include <Atom/RPI.Reflect/Shader/ShaderOptionGroup.h>
@@ -57,6 +58,7 @@ namespace AZ
: public Data::InstanceData
, public Data::AssetBus::Handler
, public ShaderVariantFinderNotificationBus::Handler
, public ShaderReloadNotificationBus::Handler
{
friend class ShaderSystem;
public:
@@ -149,6 +151,15 @@ namespace AZ
void OnShaderVariantTreeAssetReady(Data::Asset<ShaderVariantTreeAsset> /*shaderVariantTreeAsset*/, bool /*isError*/) override {};
void OnShaderVariantAssetReady(Data::Asset<ShaderVariantAsset> shaderVariantAsset, bool IsError) override;
///////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////
// ShaderReloadNotificationBus overrides...
void OnShaderAssetReinitialized(const Data::Asset<ShaderAsset>& shaderAsset) override;
// Note we don't need OnShaderVariantReinitialized because the Shader class doesn't do anything with the data inside
// the ShaderVariant object. The only thing we might want to do is propagate the message upward, but that's unnecessary
// because the ShaderReloadNotificationBus uses the Shader's AssetId as the ID for all messages including those from the variants.
// And of course we don't need to handle OnShaderReinitialized because this *is* this Shader.
///////////////////////////////////////////////////////////////////
/// Returns the path to the pipeline library cache file.
AZStd::string GetPipelineLibraryPath() const;
@@ -15,6 +15,7 @@
#include <AzCore/std/containers/vector.h>
#include <AtomCore/std/containers/array_view.h>
#include <Atom/RPI.Public/AssetInitBus.h>
#include <Atom/RPI.Reflect/Base.h>
#include <Atom/RPI.Reflect/Material/MaterialTypeAsset.h>
#include <Atom/RPI.Reflect/Material/MaterialPropertyValue.h>
@@ -38,6 +39,7 @@ namespace AZ
: public AZ::Data::AssetData
, public Data::AssetBus::Handler
, public MaterialReloadNotificationBus::Handler
, public AssetInitBus::Handler
{
friend class MaterialAssetCreator;
friend class MaterialAssetHandler;
@@ -90,13 +92,17 @@ namespace AZ
AZStd::array_view<MaterialPropertyValue> GetPropertyValues() const;
private:
bool PostLoadInit();
bool PostLoadInit() override;
//! Called by asset creators to assign the asset to a ready state.
void SetReady();
// AssetBus overrides...
void OnAssetReloaded(Data::Asset<Data::AssetData> asset) override;
void OnAssetReady(Data::Asset<Data::AssetData> asset) override;
//! Replaces the MaterialTypeAsset when a reload occurs
void ReinitializeMaterialTypeAsset(Data::Asset<Data::AssetData> asset);
// MaterialReloadNotificationBus overrides...
void OnMaterialTypeAssetReinitialized(const Data::Asset<MaterialTypeAsset>& materialTypeAsset) override;
@@ -17,6 +17,7 @@
#include <AzCore/EBus/Event.h>
#include <AtomCore/std/containers/array_view.h>
#include <Atom/RPI.Public/AssetInitBus.h>
#include <Atom/RPI.Reflect/Base.h>
#include <Atom/RPI.Reflect/Material/ShaderCollection.h>
#include <Atom/RPI.Reflect/Material/MaterialPropertiesLayout.h>
@@ -52,6 +53,7 @@ namespace AZ
class MaterialTypeAsset
: public AZ::Data::AssetData
, public Data::AssetBus::MultiHandler
, public AssetInitBus::Handler
{
friend class MaterialTypeAssetCreator;
friend class MaterialTypeAssetHandler;
@@ -100,13 +102,17 @@ namespace AZ
MaterialUvNameMap GetUvNameMap() const;
private:
bool PostLoadInit();
bool PostLoadInit() override;
//! Called by asset creators to assign the asset to a ready state.
void SetReady();
// AssetBus overrides...
void OnAssetReloaded(Data::Asset<Data::AssetData> asset) override;
void OnAssetReady(Data::Asset<Data::AssetData> asset) override;
//! Replaces the appropriate asset members when a reload occurs
void ReinitializeAsset(Data::Asset<Data::AssetData> asset);
//! Holds values for each material property, used to initialize Material instances.
//! This is indexed by MaterialPropertyIndex and aligns with entries in m_materialPropertiesLayout.
@@ -15,6 +15,7 @@
#include <AzCore/std/optional.h>
#include <AzCore/EBus/Event.h>
#include <Atom/RPI.Public/AssetInitBus.h>
#include <Atom/RPI.Reflect/Asset/AssetHandler.h>
#include <Atom/RPI.Reflect/Shader/ShaderOptionGroupLayout.h>
#include <Atom/RPI.Reflect/Shader/ShaderVariantAsset.h>
@@ -40,6 +41,7 @@ namespace AZ
: public Data::AssetData
, public ShaderVariantFinderNotificationBus::Handler
, public Data::AssetBus::Handler
, public AssetInitBus::Handler
{
friend class ShaderAssetCreator;
friend class ShaderAssetHandler;
@@ -134,8 +136,11 @@ namespace AZ
///////////////////////////////////////////////////////////////////
/// AssetBus overrides
void OnAssetReloaded(Data::Asset<Data::AssetData> asset) override;
void OnAssetReady(Data::Asset<Data::AssetData> asset) override;
///////////////////////////////////////////////////////////////////
void ReinitializeRootShaderVariant(Data::Asset<Data::AssetData> asset);
///////////////////////////////////////////////////////////////////
/// ShaderVariantFinderNotificationBus overrides
void OnShaderVariantTreeAssetReady(Data::Asset<ShaderVariantTreeAsset> shaderVariantTreeAsset, bool isError) override;
@@ -165,8 +170,13 @@ namespace AZ
RHI::ShaderStageAttributeMapList m_attributeMaps;
};
bool FinalizeAfterLoad();
bool PostLoadInit() override;
void SetReady();
//! SelectShaderApiData() must be called before most other ShaderAsset functions.
bool SelectShaderApiData();
//! Returns the active ShaderApiDataContainer which was selected in SelectShaderApiData().
ShaderApiDataContainer& GetCurrentShaderApiData();
const ShaderApiDataContainer& GetCurrentShaderApiData() const;
@@ -216,7 +226,6 @@ namespace AZ
const Data::Asset<Data::AssetData>& asset,
AZStd::shared_ptr<Data::AssetDataStream> stream,
const Data::AssetFilterCB& assetLoadFilterCB) override;
Data::AssetHandler::LoadResult PostLoadInit(const Data::Asset<Data::AssetData>& asset);
};
//////////////////////////////////////////////////////////////////////////
@@ -23,6 +23,7 @@
#include <Atom/RPI.Reflect/System/RenderPipelineDescriptor.h>
#include <Atom/RPI.Reflect/Asset/AssetUtils.h>
#include <Atom/RPI.Public/AssetInitBus.h>
#include <Atom/RPI.Public/FeatureProcessor.h>
#include <Atom/RPI.Public/GpuQuery/GpuQueryTypes.h>
#include <Atom/RPI.Public/Scene.h>
@@ -240,6 +241,8 @@ namespace AZ
}
AZ_ATOM_PROFILE_FUNCTION("RPI", "RPISystem: SimulationTick");
AssetInitBus::Broadcast(&AssetInitBus::Events::PostLoadInit);
// Update tick time info
FillTickTimeInfo();
@@ -21,7 +21,6 @@
#include <AtomCore/Instance/InstanceDatabase.h>
#include <AzCore/Interface/Interface.h>
#include <Atom/RPI.Public/Shader/ShaderReloadNotificationBus.h>
#include <Atom/RPI.Public/Shader/ShaderReloadDebugTracker.h>
namespace AZ
@@ -55,8 +54,9 @@ namespace AZ
RHI::ResultCode Shader::Init(ShaderAsset& shaderAsset)
{
Data::AssetBus::Handler::BusDisconnect();
ShaderReloadNotificationBus::Handler::BusDisconnect();
ShaderVariantFinderNotificationBus::Handler::BusDisconnect();
ShaderVariantFinderNotificationBus::Handler::BusConnect(shaderAsset.GetId());
RHI::RHISystemInterface* rhiSystem = RHI::RHISystemInterface::Get();
RHI::DrawListTagRegistry* drawListTagRegistry = rhiSystem->GetDrawListTagRegistry();
@@ -100,8 +100,10 @@ namespace AZ
AZ_Error("Shader", false, "Failed to acquire a DrawListTag. Entries are full.");
}
}
ShaderVariantFinderNotificationBus::Handler::BusConnect(m_asset.GetId());
Data::AssetBus::Handler::BusConnect(m_asset.GetId());
ShaderReloadNotificationBus::Handler::BusConnect(m_asset.GetId());
return RHI::ResultCode::Success;
}
@@ -110,6 +112,7 @@ namespace AZ
{
ShaderVariantFinderNotificationBus::Handler::BusDisconnect();
Data::AssetBus::Handler::BusDisconnect();
ShaderReloadNotificationBus::Handler::BusDisconnect();
if (m_pipelineLibraryHandle.IsValid())
{
@@ -139,7 +142,6 @@ namespace AZ
Data::Asset<ShaderAsset> newAsset = { asset.GetAs<ShaderAsset>(), AZ::Data::AssetLoadBehavior::PreLoad };
AZ_Assert(newAsset, "Reloaded ShaderAsset is null");
Data::AssetBus::Handler::BusDisconnect();
Init(*newAsset.Get());
ShaderReloadNotificationBus::Event(asset.GetId(), &ShaderReloadNotificationBus::Events::OnShaderReinitialized, *this);
}
@@ -196,6 +198,19 @@ namespace AZ
}
///////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////
// ShaderReloadNotificationBus overrides...
void Shader::OnShaderAssetReinitialized(const Data::Asset<ShaderAsset>& shaderAsset)
{
ShaderReloadDebugTracker::ScopedSection reloadSection("{%p}->Shader::OnShaderAssetReinitialized %s", this, shaderAsset.GetHint().c_str());
Init(*m_asset.Get());
ShaderReloadNotificationBus::Event(shaderAsset.GetId(), &ShaderReloadNotificationBus::Events::OnShaderReinitialized, *this);
}
///////////////////////////////////////////////////////////////////
ConstPtr<RHI::PipelineLibraryData> Shader::LoadPipelineLibrary() const
{
if (IO::FileIOBase::GetInstance())
@@ -18,6 +18,7 @@
#include <AzCore/Serialization/SerializeContext.h>
#include <AzCore/RTTI/BehaviorContext.h>
#include <AzCore/Component/TickBus.h>
namespace AZ
{
@@ -47,6 +48,7 @@ namespace AZ
{
MaterialReloadNotificationBus::Handler::BusDisconnect();
Data::AssetBus::Handler::BusDisconnect();
AssetInitBus::Handler::BusDisconnect();
}
const Data::Asset<MaterialTypeAsset>& MaterialAsset::GetMaterialTypeAsset() const
@@ -97,6 +99,8 @@ namespace AZ
{
if (!m_materialTypeAsset.Get())
{
AssetInitBus::Handler::BusDisconnect();
// Any MaterialAsset with invalid MaterialTypeAsset is not a successfully-loaded asset.
return false;
}
@@ -104,6 +108,8 @@ namespace AZ
{
Data::AssetBus::Handler::BusConnect(m_materialTypeAsset.GetId());
MaterialReloadNotificationBus::Handler::BusConnect(m_materialTypeAsset.GetId());
AssetInitBus::Handler::BusDisconnect();
return true;
}
@@ -116,11 +122,9 @@ namespace AZ
// Ultimately it's the Material that cares about these changes, so we just forward any signal we get.
MaterialReloadNotificationBus::Event(GetId(), &MaterialReloadNotifications::OnMaterialAssetReinitialized, Data::Asset<MaterialAsset>{this, AZ::Data::AssetLoadBehavior::PreLoad});
}
void MaterialAsset::OnAssetReloaded(Data::Asset<Data::AssetData> asset)
void MaterialAsset::ReinitializeMaterialTypeAsset(Data::Asset<Data::AssetData> asset)
{
ShaderReloadDebugTracker::ScopedSection reloadSection("{%p}->MaterialAsset::OnAssetReloaded %s", this, asset.GetHint().c_str());
Data::Asset<MaterialTypeAsset> newMaterialTypeAsset = { asset.GetAs<MaterialTypeAsset>(), AZ::Data::AssetLoadBehavior::PreLoad };
if (newMaterialTypeAsset)
@@ -135,16 +139,31 @@ namespace AZ
}
}
void MaterialAsset::OnAssetReloaded(Data::Asset<Data::AssetData> asset)
{
ShaderReloadDebugTracker::ScopedSection reloadSection("{%p}->MaterialAsset::OnAssetReloaded %s", this, asset.GetHint().c_str());
ReinitializeMaterialTypeAsset(asset);
}
void MaterialAsset::OnAssetReady(Data::Asset<Data::AssetData> asset)
{
// Regarding why we listen to both OnAssetReloaded and OnAssetReady, see explanation in ShaderAsset::OnAssetReady.
ShaderReloadDebugTracker::ScopedSection reloadSection("{%p}->MaterialAsset::OnAssetReady %s", this, asset.GetHint().c_str());
ReinitializeMaterialTypeAsset(asset);
}
Data::AssetHandler::LoadResult MaterialAssetHandler::LoadAssetData(
const AZ::Data::Asset<AZ::Data::AssetData>& asset,
AZStd::shared_ptr<AZ::Data::AssetDataStream> stream,
const AZ::Data::AssetFilterCB& assetLoadFilterCB)
{
Data::AssetHandler::LoadResult baseResult = Base::LoadAssetData(asset, stream, assetLoadFilterCB);
bool postLoadResult = asset.GetAs<MaterialAsset>()->PostLoadInit();
return ((baseResult == Data::AssetHandler::LoadResult::LoadComplete) && postLoadResult) ?
Data::AssetHandler::LoadResult::LoadComplete :
Data::AssetHandler::LoadResult::Error;
if (Base::LoadAssetData(asset, stream, assetLoadFilterCB) == Data::AssetHandler::LoadResult::LoadComplete)
{
asset.GetAs<MaterialAsset>()->AssetInitBus::Handler::BusConnect();
return Data::AssetHandler::LoadResult::LoadComplete;
}
return Data::AssetHandler::LoadResult::Error;
}
} // namespace RPI
@@ -65,6 +65,7 @@ namespace AZ
MaterialTypeAsset::~MaterialTypeAsset()
{
Data::AssetBus::MultiHandler::BusDisconnect();
AssetInitBus::Handler::BusDisconnect();
}
const ShaderCollection& MaterialTypeAsset::GetShaderCollection() const
@@ -116,6 +117,8 @@ namespace AZ
Data::AssetBus::MultiHandler::BusConnect(shaderItem.GetShaderAsset().GetId());
}
AssetInitBus::Handler::BusDisconnect();
return true;
}
@@ -127,11 +130,9 @@ namespace AZ
assetToReplace = newAsset;
}
}
void MaterialTypeAsset::OnAssetReloaded(Data::Asset<Data::AssetData> asset)
void MaterialTypeAsset::ReinitializeAsset(Data::Asset<Data::AssetData> asset)
{
ShaderReloadDebugTracker::ScopedSection reloadSection("{%p}->MaterialTypeAsset::OnAssetReloaded %s", this, asset.GetHint().c_str());
// The order of asset reloads is non-deterministic. If the MaterialTypeAsset reloads before these
// dependency assets, this will make sure the MaterialTypeAsset gets the latest ones when they reload.
// Or in some cases a these assets could get updated and reloaded without reloading the MaterialTypeAsset at all.
@@ -146,16 +147,31 @@ namespace AZ
MaterialReloadNotificationBus::Event(GetId(), &MaterialReloadNotifications::OnMaterialTypeAssetReinitialized, Data::Asset<MaterialTypeAsset>{this, AZ::Data::AssetLoadBehavior::PreLoad});
}
void MaterialTypeAsset::OnAssetReloaded(Data::Asset<Data::AssetData> asset)
{
ShaderReloadDebugTracker::ScopedSection reloadSection("{%p}->MaterialTypeAsset::OnAssetReloaded %s", this, asset.GetHint().c_str());
ReinitializeAsset(asset);
}
void MaterialTypeAsset::OnAssetReady(Data::Asset<Data::AssetData> asset)
{
// Regarding why we listen to both OnAssetReloaded and OnAssetReady, see explanation in ShaderAsset::OnAssetReady.
ShaderReloadDebugTracker::ScopedSection reloadSection("{%p}->MaterialTypeAsset::OnAssetReady %s", this, asset.GetHint().c_str());
ReinitializeAsset(asset);
}
AZ::Data::AssetHandler::LoadResult MaterialTypeAssetHandler::LoadAssetData(
const AZ::Data::Asset<AZ::Data::AssetData>& asset,
AZStd::shared_ptr<AZ::Data::AssetDataStream> stream,
const AZ::Data::AssetFilterCB& assetLoadFilterCB)
{
Data::AssetHandler::LoadResult baseResult = Base::LoadAssetData(asset, stream, assetLoadFilterCB);
bool postLoadResult = asset.GetAs<MaterialTypeAsset>()->PostLoadInit();
return ((baseResult == Data::AssetHandler::LoadResult::LoadComplete) && postLoadResult) ?
Data::AssetHandler::LoadResult::LoadComplete :
Data::AssetHandler::LoadResult::Error;
if (Base::LoadAssetData(asset, stream, assetLoadFilterCB) == Data::AssetHandler::LoadResult::LoadComplete)
{
asset.GetAs<MaterialTypeAsset>()->AssetInitBus::Handler::BusConnect();
return Data::AssetHandler::LoadResult::LoadComplete;
}
return Data::AssetHandler::LoadResult::Error;
}
}
@@ -85,6 +85,7 @@ namespace AZ
{
Data::AssetBus::Handler::BusDisconnect();
ShaderVariantFinderNotificationBus::Handler::BusDisconnect();
AssetInitBus::Handler::BusDisconnect();
}
const Name& ShaderAsset::GetName() const
@@ -331,8 +332,8 @@ namespace AZ
// We may only endup here when running in a Builder context.
return m_perAPIShaderData[0];
}
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,
@@ -370,28 +371,51 @@ 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.
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 } );
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)
@@ -425,25 +449,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
@@ -218,7 +218,7 @@ namespace AZ
return false;
}
if (!m_asset->FinalizeAfterLoad())
if (!m_asset->SelectShaderApiData())
{
ReportError("Failed to finalize the ShaderAsset.");
return false;
@@ -56,7 +56,7 @@ namespace AZ
AZ::Data::Asset<ShaderAsset> SerializeInHelper(const AZ::Data::AssetId& assetId)
{
AZ::Data::Asset<ShaderAsset> asset = Base::SerializeIn(assetId);
asset->FinalizeAfterLoad();
asset->SelectShaderApiData();
asset->SetReady();
return asset;
}
@@ -10,6 +10,7 @@
#
set(FILES
Include/Atom/RPI.Public/AssetInitBus.h
Include/Atom/RPI.Public/Base.h
Include/Atom/RPI.Public/Culling.h
Include/Atom/RPI.Public/FeatureProcessor.h
+4
View File
@@ -8,3 +8,7 @@
# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#
add_subdirectory(LookDevelopmentStudioPixar)
add_subdirectory(ReferenceMaterials)
add_subdirectory(Sponza)
@@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:6cfa740b94b898e85d93f970a7d7d76581e065662dd8e2b350ea076bd6fe8d35
size 37187591
@@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:254aacfb72ed12743f83740f9eb31a01d28c40c0abeacc39907d20ab82f42636
size 390896034
@@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:c164a61daf248f57eacee5167eb9d098a49d7dfc7aea6c68007d7e0c06a29906
size 74644256
@@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:ade44968832bf7a3e9cab95ddccc4018c7250b07437cddc51c784815b1dcb930
size 392066587
@@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:51dacbe0048b892a196ea9e6178cca908ba46a6f86b7ec979cf0fd7e381720b3
size 112681262
@@ -1,39 +0,0 @@
{
"description": "",
"materialType": "Materials/Types/StandardPBR.materialtype",
"parentMaterial": "",
"propertyLayoutVersion": 3,
"properties": {
"occlusion": {
"diffuseTextureMap": "Materials/Bricks038_8K/Bricks038_8K_AmbientOcclusion.png"
},
"baseColor": {
"color": [
0.496940553188324,
0.496940553188324,
0.496940553188324,
1.0
],
"factor": 0.6464645862579346,
"textureBlendMode": "LinearLight",
"textureMap": "Materials/Bricks038_8K/Bricks038_8K_BaseColor.png"
},
"general": {
"applySpecularAA": true
},
"normal": {
"textureMap": "Materials/Bricks038_8K/Bricks038_8K_Normal.png"
},
"parallax": {
"algorithm": "POM",
"factor": 0.02500000037252903,
"pdo": true,
"quality": "Ultra",
"textureMap": "Materials/Bricks038_8K/Bricks038_8K_Displacement.png"
},
"roughness": {
"upperBound": 0.5,
"textureMap": "Materials/Bricks038_8K/Bricks038_8K_Roughness.png"
}
}
}
@@ -1,41 +0,0 @@
{
"description": "",
"materialType": "Materials/Types/StandardPBR.materialtype",
"parentMaterial": "",
"propertyLayoutVersion": 3,
"properties": {
"baseColor": {
"color": [
0.19562065601348878,
0.22017242014408112,
0.2503242492675781,
1.0
],
"factor": 0.30000001192092898,
"textureBlendMode": "LinearLight",
"textureMap": "Materials/Concrete016_8K/Concrete016_8K_BaseColor.png"
},
"clearCoat": {
"enable": true,
"normalMap": "Materials/Concrete016_8K/roller_painted_metal_normal.tif",
"roughness": 0.18181820213794709
},
"general": {
"applySpecularAA": true
},
"normal": {
"factor": 0.6499999761581421,
"textureMap": "Materials/Concrete016_8K/Concrete016_8K_Normal.png"
},
"parallax": {
"algorithm": "ContactRefinement",
"factor": 0.019999999552965165,
"quality": "Ultra",
"textureMap": "Materials/Concrete016_8K/Concrete016_8K_Displacement.png",
"useTexture": false
},
"roughness": {
"textureMap": "Materials/Concrete016_8K/Concrete016_8K_Roughness.png"
}
}
}
@@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:42d3ef187f7f98bcee42ffc4ae0629370f4fc19e6532c2db8cc130ce9ece072a
size 74279846
@@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:b8e8149f5609ae85f876183f3b4461de4a334658660fc187c5fd469752e5b2d6
size 93715669
@@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:6f997219d3bb846ea0db7786a394e508d59f99be9548b63d3c73824d97cdacd7
size 379009988
@@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:9ea7f520b28d5232697ea9e4fb4cc7d655069d05f9de0313c92c56e4c1526556
size 25594794
@@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:94c9398b1f5d71aa3f4debb5a9571f0d9a4b1b1992b662e35ca94996b507e4ff
size 6933173
@@ -1,31 +0,0 @@
{
"description": "",
"materialType": "Materials/Types/StandardPBR.materialtype",
"parentMaterial": "",
"propertyLayoutVersion": 3,
"properties": {
"baseColor": {
"textureMap": "Materials/Fabric001_8K/Fabric001_8K_BaseColor.png"
},
"clearCoat": {
"enable": true,
"normalMap": "Materials/Fabric001_8K/Fabric001_8K_Normal.png",
"roughness": 0.4040403962135315
},
"general": {
"applySpecularAA": true
},
"normal": {
"textureMap": "Materials/Fabric001_8K/Fabric001_8K_Normal.png"
},
"parallax": {
"algorithm": "ContactRefinement",
"factor": 0.004999999888241291,
"quality": "Ultra",
"textureMap": "Materials/Fabric001_8K/Fabric001_8K_Displacement.png"
},
"roughness": {
"textureMap": "Materials/Fabric001_8K/Fabric001_8K_Roughness.png"
}
}
}
@@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:e04ea2d456e13fb45a2c4f3f88d2ed07c2799fbdaeba6b52bab64dcd84fefc77
size 69539547
@@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:4b41f8b8aa685c443216220063cd6c1de3f620ef66776aecd374025a689dec77
size 19743435
@@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:009302f8be232e7fd6b23d368c85afdb74ea4deda8147152f2c92d116a2ac585
size 56894065
@@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:a557862deee7f4ff9bb113f66b1fd432871338d5b801edec7c50f70aa302557d
size 26820294
@@ -1,32 +0,0 @@
{
"description": "",
"materialType": "Materials/Types/StandardPBR.materialtype",
"parentMaterial": "",
"propertyLayoutVersion": 3,
"properties": {
"baseColor": {
"textureMap": "Materials/Fabric030_4K/Fabric030_4K_BaseColor.png"
},
"clearCoat": {
"enable": true,
"normalMap": "Materials/Fabric030_4K/Fabric030_4K_Normal.png",
"roughness": 0.7676767706871033,
"roughnessMap": "Materials/Fabric030_4K/Fabric030_4K_Roughness.png",
"useInfluenceMap": false
},
"normal": {
"factor": 0.5,
"textureMap": "Materials/Fabric030_4K/Fabric030_4K_Normal.png"
},
"parallax": {
"algorithm": "ContactRefinement",
"factor": 0.0020000000949949028,
"pdo": true,
"quality": "Medium",
"textureMap": "Materials/Fabric030_4K/Fabric030_4K_Displacement.png"
},
"roughness": {
"textureMap": "Materials/Fabric030_4K/Fabric030_4K_Roughness.png"
}
}
}
@@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:eb2f62e3166428f137b8712f4527c62d3905a8e177840b56fb1775e39417448d
size 11268075
@@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:194674f50a0c868d2a2c12cc7a4ddbe5abbe6ebb9687be4be4e49eece3976e29
size 94910229
@@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:c3f29be8c7afe73b12f5c7df3e3ffd69a0bce46218cef57f73c11638aa07ccc3
size 19243987
@@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:0bc0c08f0b8e33b3251f7dba85c5042138a201e912752135a0bdcfe9c381d5ab
size 63142427
@@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:aa5ffdb5b9ef2363c58eb85b47adc9e1bdde13256bdc6de05cbfb5b04cf91f91
size 26802284
@@ -1,31 +0,0 @@
{
"description": "",
"materialType": "Materials/Types/StandardPBR.materialtype",
"parentMaterial": "",
"propertyLayoutVersion": 3,
"properties": {
"occlusion": {
"diffuseFactor": 0.30000001192092898,
"diffuseTextureMap": "Materials/PaintedPlaster015_8K/PaintedPlaster015_8K_AmbientOcclusion.png"
},
"baseColor": {
"textureMap": "Materials/PaintedPlaster015_8K/PaintedPlaster015_8K_BaseColor.png"
},
"general": {
"applySpecularAA": true
},
"normal": {
"textureMap": "Materials/PaintedPlaster015_8K/PaintedPlaster015_8K_Normal.png"
},
"parallax": {
"algorithm": "ContactRefinement",
"factor": 0.009999999776482582,
"pdo": true,
"quality": "Ultra",
"textureMap": "Materials/PaintedPlaster015_8K/PaintedPlaster015_8K_Displacement.png"
},
"roughness": {
"textureMap": "Materials/PaintedPlaster015_8K/PaintedPlaster015_8K_Roughness.png"
}
}
}
@@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:c271d8a3f305bacafb74037898e8d5841fb8a2fedc0092cbe14134d2ec891d01
size 115473298
@@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:720d85d530e192da6e7daaab89501a9612e145f4aa41405958ff49f765f072ab
size 325006015
@@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:71f256cde0427ab8558b09d743d9379899a9a72b4388ca14529bfc9090dd811e
size 88972723
@@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:4e7eb03dd1ae07ade8e8e99fe6f522fd268ef8e00d3e3f9c3594d9f887b864d8
size 382741403
@@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:3f065a3929ea98b54c725515528c2d40b3908a352d497bcce2f088a91b623b11
size 98105202
@@ -1,42 +0,0 @@
{
"description": "",
"materialType": "Materials/Types/StandardPBR.materialtype",
"parentMaterial": "",
"propertyLayoutVersion": 3,
"properties": {
"baseColor": {
"color": [
0.496940553188324,
0.496940553188324,
0.496940553188324,
1.0
],
"textureBlendMode": "LinearLight",
"textureMap": "Materials/Bricks038_8K/Bricks038_8K_BaseColor.png",
"useTexture": false
},
"emissive": {
"useTexture": false
},
"general": {
"applySpecularAA": true
},
"normal": {
"textureMap": "Materials/Bricks038_8K/Bricks038_8K_Normal.png",
"useTexture": false
},
"parallax": {
"algorithm": "POM",
"factor": 0.02500000037252903,
"pdo": true,
"quality": "Ultra",
"textureMap": "Materials/Bricks038_8K/Bricks038_8K_Displacement.png",
"useTexture": false
},
"roughness": {
"factor": 0.4343433976173401,
"textureMap": "Materials/Bricks038_8K/Bricks038_8K_Roughness.png",
"useTexture": false
}
}
}
@@ -1,34 +0,0 @@
{
"description": "",
"materialType": "Materials/Types/StandardPBR.materialtype",
"parentMaterial": "",
"propertyLayoutVersion": 3,
"properties": {
"baseColor": {
"color": [
0.496940553188324,
0.496940553188324,
0.496940553188324,
1.0
],
"factor": 0.6464645862579346,
"textureBlendMode": "LinearLight"
},
"general": {
"applySpecularAA": true
},
"normal": {
"textureMap": "Materials/Concrete016_8K/Concrete016_8K_Normal.png"
},
"parallax": {
"algorithm": "POM",
"factor": 0.02500000037252903,
"pdo": true,
"quality": "Ultra",
"textureMap": "Materials/Bricks038_8K/Bricks038_8K_Displacement.png"
},
"roughness": {
"textureMap": "Materials/Concrete016_8K/Concrete016_8K_Roughness.png"
}
}
}
@@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:486712a84618c56b79c6cb12966fe5c44a70bc6573c5eed74381ccdd68592e06
size 20574
@@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:7c2826872e937f6794a62f75b10b5217dd541fc419ebc1ebe2d4469a38344332
size 24339
@@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:9d603f570813bad6c2db2c055114a5990d5113f7b2c11074a0e8ba83c2007490
size 1849470
@@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:d2715b8a38b8198d84927a881440328b2fe565be27737c970da9366c9eab566a
size 3886331
@@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:1658a8fbf035d669c88e112c3922f223e77cccece7cb51a0fa2df50412fb02d0
size 435923
@@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:b63a99deac3bcf4b9d93359edb68bb22f28da4c9c3d5a7f1d715a84e8c603519
size 7522972
@@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:d4065dfea401af3b53bcd2906535239d54628c800704f96acbd2767042bc432c
size 8792244
@@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:93f5e3663a69d9e29bcc64715363420fb8a1331c8f714b9dbdf4d6a6577f943b
size 175120
@@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:d09adbd3e1ef1f1bed98c9ea3034c323bf3f1be25faba5d3721310f46029b0bb
size 24608
@@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:391a2e1931263446ee2f38810ee9fc4bc4de29c171cf557398d6bf4a0eba1263
size 110384
@@ -1,23 +0,0 @@
{
"description": "",
"materialType": "Materials/Types/StandardPBR.materialtype",
"parentMaterial": "",
"propertyLayoutVersion": 3,
"properties": {
"baseColor": {
"color": [
1.600000023841858,
1.600000023841858,
1.600000023841858,
1.0
]
},
"emissive": {
"enable": true,
"intensity": 0.0
},
"opacity": {
"factor": 1.0
}
}
}
@@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:c6c174dde81f8a37f591108b62666347920d0765f3e61c6d557ebf807f38cd3b
size 4512544
@@ -1,25 +0,0 @@
{
"description": "",
"materialType": "Materials/Types/StandardPBR.materialtype",
"parentMaterial": "",
"propertyLayoutVersion": 3,
"properties": {
"baseColor": {
"color": [
0.4000000059604645,
0.4000000059604645,
0.4000000059604645,
1.0
]
},
"metallic": {
"factor": 1.0
},
"opacity": {
"factor": 1.0
},
"roughness": {
"factor": 0.25
}
}
}
@@ -1,25 +0,0 @@
{
"description": "",
"materialType": "Materials/Types/StandardPBR.materialtype",
"parentMaterial": "",
"propertyLayoutVersion": 3,
"properties": {
"baseColor": {
"color": [
0.6000000238418579,
0.6000000238418579,
0.6000000238418579,
1.0
]
},
"metallic": {
"factor": 1.0
},
"opacity": {
"factor": 1.0
},
"roughness": {
"factor": 0.25
}
}
}
@@ -1,25 +0,0 @@
{
"description": "",
"materialType": "Materials/Types/StandardPBR.materialtype",
"parentMaterial": "",
"propertyLayoutVersion": 3,
"properties": {
"baseColor": {
"color": [
0.8199999928474426,
0.8199999928474426,
0.8199999928474426,
1.0
]
},
"metallic": {
"factor": 1.0
},
"opacity": {
"factor": 1.0
},
"roughness": {
"factor": 0.25
}
}
}
@@ -1,40 +0,0 @@
{
"description": "",
"materialType": "Materials/Types/StandardPBR.materialtype",
"parentMaterial": "",
"propertyLayoutVersion": 3,
"properties": {
"baseColor": {
"color": [
0.0,
0.800000011920929,
0.800000011920929,
1.0
]
},
"clearCoat": {
"enable": true,
"normalMap": "EngineAssets/Textures/perlinNoiseNormal_ddn.tif",
"normalStrength": 0.10000000149011612
},
"general": {
"applySpecularAA": true
},
"metallic": {
"factor": 0.10000000149011612
},
"normal": {
"factor": 0.05000000074505806,
"textureMap": "Materials/round_metal_flecks_4096_normal.png"
},
"opacity": {
"factor": 1.0
},
"roughness": {
"factor": 0.0
},
"specularF0": {
"enableMultiScatterCompensation": true
}
}
}
@@ -1,41 +0,0 @@
{
"description": "",
"materialType": "Materials/Types/StandardPBR.materialtype",
"parentMaterial": "",
"propertyLayoutVersion": 3,
"properties": {
"baseColor": {
"color": [
0.800000011920929,
0.0,
0.0,
1.0
]
},
"clearCoat": {
"enable": true,
"normalMap": "Materials/Concrete016_8K/roller_painted_metal_normal.tif",
"roughness": 0.1414141058921814
},
"general": {
"applySpecularAA": true
},
"metallic": {
"factor": 0.20000000298023225
},
"normal": {
"factor": 0.10000000149011612,
"textureMap": "Materials/round_metal_flecks_2048_normal.png"
},
"opacity": {
"factor": 1.0
},
"roughness": {
"factor": 0.5
},
"uv": {
"tileU": 2.0,
"tileV": 2.0
}
}
}
@@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:c2f3ea6e00e15901263c06fee2aa4d54b96277f7ac103dd8b3c0f8441158d31e
size 83584

Some files were not shown because too many files have changed in this diff Show More