Merge branch 'stabilization/2106' of https://github.com/aws-lumberyard/o3de into Atom/gallowj/stabilization/2106

main
gallowj 5 years ago
commit 49e183c30f

@ -10,7 +10,7 @@
#
if(NOT PROJECT_NAME)
cmake_minimum_required(VERSION 3.19)
cmake_minimum_required(VERSION 3.20)
project(AutomatedTesting
LANGUAGES C CXX
VERSION 1.0.0.0

@ -9,17 +9,8 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#
# Cmake version 3.19 is the minimum version needed for all of Open 3D Engine's supported platforms
cmake_minimum_required(VERSION 3.19)
# CMP0111 introduced in 3.19 has a bug that produces the policy to warn every time there is an
# INTERFACE IMPORTED library. We use this type of libraries for handling 3rdParty. The rest of
# the documentation states that INTERFACE IMPORTED libraries do not require to set locations, but
# the policy still warns about it. Issue: https://gitlab.kitware.com/cmake/cmake/-/issues/21470
# The issue was fixed in 3.19.1 so we just disable the policy for 3.19
if(CMAKE_VERSION VERSION_EQUAL 3.19)
cmake_policy(SET CMP0111 OLD)
endif()
# Cmake version 3.20 is the minimum version needed for all of Open 3D Engine's supported platforms
cmake_minimum_required(VERSION 3.20)
include(cmake/LySet.cmake)
include(cmake/Version.cmake)

@ -67,7 +67,7 @@ struct CryPakMock
MOCK_METHOD1(PoolMalloc, void*(size_t size));
MOCK_METHOD1(PoolFree, void(void* p));
MOCK_METHOD3(PoolAllocMemoryBlock, AZStd::intrusive_ptr<AZ::IO::MemoryBlock> (size_t nSize, const char* sUsage, size_t nAlign));
MOCK_METHOD3(FindFirst, AZ::IO::ArchiveFileIterator(AZStd::string_view pDir, uint32_t nFlags, bool bAllOwUseFileSystem));
MOCK_METHOD2(FindFirst, AZ::IO::ArchiveFileIterator(AZStd::string_view pDir, AZ::IO::IArchive::EFileSearchType));
MOCK_METHOD1(FindNext, AZ::IO::ArchiveFileIterator(AZ::IO::ArchiveFileIterator handle));
MOCK_METHOD1(FindClose, bool(AZ::IO::ArchiveFileIterator));
MOCK_METHOD1(GetModificationTime, AZ::IO::IArchive::FileTime(AZ::IO::HandleType f));

@ -306,8 +306,7 @@ void CLevelSystem::ScanFolder(const char* subfolder, bool modFolder)
AZStd::unordered_set<AZStd::string> pakList;
bool allowFileSystem = true;
AZ::IO::ArchiveFileIterator handle = pPak->FindFirst(search.c_str(), 0, allowFileSystem);
AZ::IO::ArchiveFileIterator handle = pPak->FindFirst(search.c_str(), AZ::IO::IArchive::eFileSearchType_AllowOnDiskOnly);
if (handle)
{
@ -320,7 +319,7 @@ void CLevelSystem::ScanFolder(const char* subfolder, bool modFolder)
{
if (AZ::StringFunc::Equal(handle.m_filename.data(), LevelPakName))
{
// level folder contain pak files like 'level.pak'
// level folder contain pak files like 'level.pak'
// which we only want to load during level loading.
continue;
}
@ -351,7 +350,7 @@ void CLevelSystem::ScanFolder(const char* subfolder, bool modFolder)
PopulateLevels(search, folder, pPak, modFolder, false);
// Load levels outside of the bundles to maintain backward compatibility.
PopulateLevels(search, folder, pPak, modFolder, true);
}
void CLevelSystem::PopulateLevels(
@ -360,7 +359,7 @@ void CLevelSystem::PopulateLevels(
{
// allow this find first to actually touch the file system
// (causes small overhead but with minimal amount of levels this should only be around 150ms on actual DVD Emu)
AZ::IO::ArchiveFileIterator handle = pPak->FindFirst(searchPattern.c_str(), 0, fromFileSystemOnly);
AZ::IO::ArchiveFileIterator handle = pPak->FindFirst(searchPattern.c_str(), AZ::IO::IArchive::eFileSearchType_AllowOnDiskOnly);
if (handle)
{
@ -973,7 +972,7 @@ void CLevelSystem::UnloadLevel()
m_lastLevelName.clear();
SAFE_RELEASE(m_pCurrentLevel);
// Force Lua garbage collection (may no longer be needed now the legacy renderer has been removed).
// Normally the GC step is triggered at the end of this method (by the ESYSTEM_EVENT_LEVEL_POST_UNLOAD event).
EBUS_EVENT(AZ::ScriptSystemRequestBus, GarbageCollect);

@ -9,8 +9,6 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#
cmake_minimum_required(VERSION 3.0)
ly_add_target(
NAME AzAutoGen HEADERONLY
NAMESPACE AZ

@ -1290,7 +1290,7 @@ namespace AZ::IO
//////////////////////////////////////////////////////////////////////////
AZ::IO::ArchiveFileIterator Archive::FindFirst(AZStd::string_view pDir, [[maybe_unused]] uint32_t nPathFlags, bool bAllowUseFileSystem)
AZ::IO::ArchiveFileIterator Archive::FindFirst(AZStd::string_view pDir, EFileSearchType searchType)
{
auto szFullPath = AZ::IO::FileIOBase::GetDirectInstance()->ResolvePath(pDir);
if (!szFullPath)
@ -1299,8 +1299,26 @@ namespace AZ::IO
return {};
}
bool bScanZips{};
bool bAllowUseFileSystem{};
switch (searchType)
{
case IArchive::eFileSearchType_AllowInZipsOnly:
bAllowUseFileSystem = false;
bScanZips = true;
break;
case IArchive::eFileSearchType_AllowOnDiskAndInZips:
bAllowUseFileSystem = true;
bScanZips = true;
break;
case IArchive::eFileSearchType_AllowOnDiskOnly:
bAllowUseFileSystem = true;
bScanZips = false;
break;
}
AZStd::intrusive_ptr<AZ::IO::FindData> pFindData = new AZ::IO::FindData();
pFindData->Scan(this, szFullPath->Native(), bAllowUseFileSystem);
pFindData->Scan(this, szFullPath->Native(), bAllowUseFileSystem, bScanZips);
return pFindData->Fetch();
}
@ -1676,7 +1694,7 @@ namespace AZ::IO
return true;
}
if (AZ::IO::ArchiveFileIterator fileIterator = FindFirst(pWildcardIn, 0, true); fileIterator)
if (AZ::IO::ArchiveFileIterator fileIterator = FindFirst(pWildcardIn, IArchive::eFileSearchType_AllowOnDiskOnly); fileIterator)
{
AZStd::vector<AZStd::string> files;
do

@ -234,7 +234,7 @@ namespace AZ::IO
uint64_t FTell(AZ::IO::HandleType handle) override;
int FFlush(AZ::IO::HandleType handle) override;
int FClose(AZ::IO::HandleType handle) override;
AZ::IO::ArchiveFileIterator FindFirst(AZStd::string_view pDir, uint32_t nPathFlags = 0, bool bAllOwUseFileSystem = false) override;
AZ::IO::ArchiveFileIterator FindFirst(AZStd::string_view pDir, EFileSearchType searchType = eFileSearchType_AllowInZipsOnly) override;
AZ::IO::ArchiveFileIterator FindNext(AZ::IO::ArchiveFileIterator fileIterator) override;
bool FindClose(AZ::IO::ArchiveFileIterator fileIterator) override;
int FEof(AZ::IO::HandleType handle) override;

@ -77,7 +77,7 @@ namespace AZ::IO
return m_findData && m_lastFetchValid;
}
void FindData::Scan(IArchive* archive, AZStd::string_view szDir, bool bAllowUseFS)
void FindData::Scan(IArchive* archive, AZStd::string_view szDir, bool bAllowUseFS, bool bScanZips)
{
// get the priority into local variable to avoid it changing in the course of
// this function execution
@ -87,12 +87,18 @@ namespace AZ::IO
{
// first, find the file system files
ScanFS(archive, szDir);
ScanZips(archive, szDir);
if (bScanZips)
{
ScanZips(archive, szDir);
}
}
else
{
// first, find the zip files
ScanZips(archive, szDir);
if (bScanZips)
{
ScanZips(archive, szDir);
}
if (bAllowUseFS || nVarPakPriority != ArchiveLocationPriority::ePakPriorityPakOnly)
{
ScanFS(archive, szDir);
@ -111,30 +117,31 @@ namespace AZ::IO
}
AZ::IO::FileIOBase::GetDirectInstance()->FindFiles(searchDirectory.c_str(), pattern.c_str(), [&](const char* filePath) -> bool
{
AZ::IO::FileDesc fileDesc;
AZStd::string filePathEntry{filePath};
AZ::IO::ArchiveFileIterator fileIterator;
fileIterator.m_filename = AZ::IO::PathView(filePath).Filename().Native();
fileIterator.m_fileDesc.nAttrib = {};
if (AZ::IO::FileIOBase::GetDirectInstance()->IsDirectory(filePath))
{
fileDesc.nAttrib = fileDesc.nAttrib | AZ::IO::FileDesc::Attribute::Subdirectory;
fileIterator.m_fileDesc.nAttrib = fileIterator.m_fileDesc.nAttrib | AZ::IO::FileDesc::Attribute::Subdirectory;
m_fileStack.emplace_back(AZStd::move(fileIterator));
}
else
{
if (AZ::IO::FileIOBase::GetDirectInstance()->IsReadOnly(filePath))
{
fileDesc.nAttrib = fileDesc.nAttrib | AZ::IO::FileDesc::Attribute::ReadOnly;
fileIterator.m_fileDesc.nAttrib = fileIterator.m_fileDesc.nAttrib | AZ::IO::FileDesc::Attribute::ReadOnly;
}
AZ::u64 fileSize = 0;
AZ::IO::FileIOBase::GetDirectInstance()->Size(filePath, fileSize);
fileDesc.nSize = fileSize;
fileDesc.tWrite = AZ::IO::FileIOBase::GetDirectInstance()->ModificationTime(filePath);
fileIterator.m_fileDesc.nSize = fileSize;
fileIterator.m_fileDesc.tWrite = AZ::IO::FileIOBase::GetDirectInstance()->ModificationTime(filePath);
// These times are not supported by our file interface
fileDesc.tAccess = fileDesc.tWrite;
fileDesc.tCreate = fileDesc.tWrite;
fileIterator.m_fileDesc.tAccess = fileIterator.m_fileDesc.tWrite;
fileIterator.m_fileDesc.tCreate = fileIterator.m_fileDesc.tWrite;
m_fileStack.emplace_back(AZStd::move(fileIterator));
}
[[maybe_unused]] auto result = m_mapFiles.emplace(AZStd::move(filePathEntry), fileDesc);
AZ_Assert(result.second, "Failed to insert FindData entry for filePath %s", filePath);
return true;
});
}
@ -164,7 +171,7 @@ namespace AZ::IO
fileDesc.nAttrib = AZ::IO::FileDesc::Attribute::ReadOnly | AZ::IO::FileDesc::Attribute::Archive;
fileDesc.nSize = fileEntry->desc.lSizeUncompressed;
fileDesc.tWrite = fileEntry->GetModificationTime();
m_mapFiles.emplace(fname, fileDesc);
m_fileStack.emplace_back(AZ::IO::ArchiveFileIterator{ this, fname, fileDesc });
}
ZipDir::FindDir findDirectoryEntry(zipCache);
@ -177,7 +184,7 @@ namespace AZ::IO
}
AZ::IO::FileDesc fileDesc;
fileDesc.nAttrib = AZ::IO::FileDesc::Attribute::ReadOnly | AZ::IO::FileDesc::Attribute::Archive | AZ::IO::FileDesc::Attribute::Subdirectory;
m_mapFiles.emplace(fname, fileDesc);
m_fileStack.emplace_back(AZ::IO::ArchiveFileIterator{ this, fname, fileDesc });
}
};
@ -246,7 +253,7 @@ namespace AZ::IO
if (!bindRootIter->empty() && AZStd::wildcard_match(sourcePathRemainder.Native(), bindRootIter->Native()))
{
AZ::IO::FileDesc fileDesc{ AZ::IO::FileDesc::Attribute::ReadOnly | AZ::IO::FileDesc::Attribute::Archive | AZ::IO::FileDesc::Attribute::Subdirectory };
m_mapFiles.emplace(bindRootIter->Native(), fileDesc);
m_fileStack.emplace_back(AZ::IO::ArchiveFileIterator{ this, bindRootIter->Native(), fileDesc });
}
}
else
@ -262,22 +269,19 @@ namespace AZ::IO
AZ::IO::ArchiveFileIterator FindData::Fetch()
{
AZ::IO::ArchiveFileIterator fileIterator;
fileIterator.m_findData = this;
if (m_mapFiles.empty())
if (m_fileStack.empty())
{
return fileIterator;
AZ::IO::ArchiveFileIterator emptyFileIterator;
emptyFileIterator.m_lastFetchValid = false;
emptyFileIterator.m_findData = this;
return emptyFileIterator;
}
auto pakFileIter = m_mapFiles.begin();
AZStd::string fullFilePath;
AZ::StringFunc::Path::GetFullFileName(pakFileIter->first.c_str(), fullFilePath);
fileIterator.m_filename = AZStd::move(fullFilePath);
fileIterator.m_fileDesc = pakFileIter->second;
fileIterator.m_lastFetchValid = true;
// Remove Fetched item from the FindData map so that the iteration continues
m_mapFiles.erase(pakFileIter);
AZ::IO::ArchiveFileIterator fileIterator{ m_fileStack.back() };
fileIterator.m_lastFetchValid = true;
fileIterator.m_findData = this;
m_fileStack.pop_back();
return fileIterator;
}
}

@ -15,7 +15,6 @@
#include <AzCore/std/smart_ptr/intrusive_base.h>
#include <AzCore/std/string/fixed_string.h>
namespace AZ::IO
{
struct IArchive;
@ -74,13 +73,13 @@ namespace AZ::IO
AZ_CLASS_ALLOCATOR(FindData, AZ::SystemAllocator, 0);
FindData() = default;
AZ::IO::ArchiveFileIterator Fetch();
void Scan(IArchive* archive, AZStd::string_view path, bool bAllowUseFS = false);
void Scan(IArchive* archive, AZStd::string_view path, bool bAllowUseFS = false, bool bScanZips = true);
protected:
void ScanFS(IArchive* archive, AZStd::string_view path);
void ScanZips(IArchive* archive, AZStd::string_view path);
using FileMap = AZStd::map<AZStd::string, AZ::IO::FileDesc, AZStdStringLessCaseInsensitive>;
FileMap m_mapFiles;
using FileStack = AZStd::vector<ArchiveFileIterator>;
FileStack m_fileStack;
};
}

@ -197,6 +197,13 @@ namespace AZ::IO
eInMemoryPakLocale_PAK,
};
enum EFileSearchType
{
eFileSearchType_AllowInZipsOnly = 0,
eFileSearchType_AllowOnDiskAndInZips,
eFileSearchType_AllowOnDiskOnly
};
using SignedFileSize = int64_t;
virtual ~IArchive() = default;
@ -315,7 +322,7 @@ namespace AZ::IO
// Arguments:
// nFlags is a combination of EPathResolutionRules flags.
virtual ArchiveFileIterator FindFirst(AZStd::string_view pDir, uint32_t nFlags = 0, bool bAllowUseFileSystem = false) = 0;
virtual ArchiveFileIterator FindFirst(AZStd::string_view pDir, EFileSearchType searchType = eFileSearchType_AllowInZipsOnly) = 0;
virtual ArchiveFileIterator FindNext(AZ::IO::ArchiveFileIterator handle) = 0;
virtual bool FindClose(AZ::IO::ArchiveFileIterator handle) = 0;
//returns file modification time

@ -187,13 +187,14 @@ namespace AzToolsFramework
return removedEntity;
}
void Instance::DetachNestedEntities(const AZStd::function<void(AZStd::unique_ptr<AZ::Entity>)>& callback)
void Instance::DetachAllEntitiesInHierarchy(const AZStd::function<void(AZStd::unique_ptr<AZ::Entity>)>& callback)
{
callback(AZStd::move(DetachContainerEntity()));
DetachEntities(callback);
for (const auto& [instanceAlias, instance] : m_nestedInstances)
{
instance->DetachNestedEntities(callback);
instance->DetachAllEntitiesInHierarchy(callback);
}
}

@ -87,7 +87,15 @@ namespace AzToolsFramework
bool AddEntity(AZ::Entity& entity, EntityAlias entityAlias);
AZStd::unique_ptr<AZ::Entity> DetachEntity(const AZ::EntityId& entityId);
void DetachEntities(const AZStd::function<void(AZStd::unique_ptr<AZ::Entity>)>& callback);
void DetachNestedEntities(const AZStd::function<void(AZStd::unique_ptr<AZ::Entity>)>& callback);
/**
* Detaches all entities in the instance hierarchy.
* Includes all direct entities, all nested entities, and all container entities.
* Note that without container entities the hierarchy that remains cannot be used further without restoring new ones.
* @param callback A user provided callback that can be used to capture ownership and manipulate the detached entities.
*/
void DetachAllEntitiesInHierarchy(const AZStd::function<void(AZStd::unique_ptr<AZ::Entity>)>& callback);
void RemoveNestedEntities(const AZStd::function<bool(const AZStd::unique_ptr<AZ::Entity>&)>& filter);
void Reset();

@ -154,7 +154,7 @@ namespace AzToolsFramework
InstanceOptionalReference owningInstanceReference = m_storingInstance->m_instanceEntityMapper->FindOwningInstance(entityId);
// Start with an empty alias to build out our reference path
// If we can't resolve this id we'll return a random new alias instead of a reference path
// If we can't resolve this id we'll return a new alias based on the entity ID instead of a reference path
AliasPath relativeEntityAliasPath;
if (!owningInstanceReference)
{
@ -162,7 +162,7 @@ namespace AzToolsFramework
"Prefab - EntityIdMapper: Entity with Id %s has no registered owning instance",
entityId.ToString().c_str());
return Instance::GenerateEntityAlias();
return AZStd::string::format("Entity_%s", entityId.ToString().c_str());
}
Instance* owningInstance = &(owningInstanceReference->get());

@ -38,11 +38,7 @@ namespace AzToolsFramework::Prefab::SpawnableUtils
// going to be used to create clones of the entities.
{
AzFramework::Spawnable::EntityList& entities = spawnable.GetEntities();
if (instance.HasContainerEntity())
{
entities.emplace_back(AZStd::move(instance.DetachContainerEntity()));
}
instance.DetachNestedEntities(
instance.DetachAllEntitiesInHierarchy(
[&entities](AZStd::unique_ptr<AZ::Entity> entity)
{
entities.emplace_back(AZStd::move(entity));

@ -71,24 +71,29 @@ namespace UnitTest
m_prefabSystemComponent->CreatePrefab({ entitiesCreated[0] }, {}, "test/path1"));
ASSERT_TRUE(firstInstance);
ASSERT_TRUE(firstInstance->HasContainerEntity());
expectedEntityNameSet.insert(firstInstance->GetContainerEntity()->get().GetName());
AZStd::unique_ptr<AzToolsFramework::Prefab::Instance> secondInstance(
m_prefabSystemComponent->CreatePrefab({ entitiesCreated[1] }, MakeInstanceList(AZStd::move(firstInstance)), "test/path2"));
ASSERT_TRUE(secondInstance);
ASSERT_TRUE(secondInstance->HasContainerEntity());
expectedEntityNameSet.insert(secondInstance->GetContainerEntity()->get().GetName());
AZStd::unique_ptr<AzToolsFramework::Prefab::Instance> thirdInstance(
m_prefabSystemComponent->CreatePrefab({ entitiesCreated[2] }, MakeInstanceList(AZStd::move(secondInstance)), "test/path3"));
ASSERT_TRUE(thirdInstance);
ASSERT_TRUE(thirdInstance->HasContainerEntity());
auto& containerEntity = thirdInstance->GetContainerEntity()->get();
expectedEntityNameSet.insert(containerEntity.GetName());
expectedEntityNameSet.insert(thirdInstance->GetContainerEntity()->get().GetName());
//Create Spawnable
auto& prefabDom = m_prefabSystemComponent->FindTemplateDom(thirdInstance->GetTemplateId());
AzFramework::Spawnable spawnable;
AzToolsFramework::Prefab::SpawnableUtils::CreateSpawnable(spawnable, prefabDom);
EXPECT_EQ(spawnable.GetEntities().size() - 1, normalEntityCount); // 1 for container entity
EXPECT_EQ(spawnable.GetEntities().size(), normalEntityCount + 3); // +1 for each container entity
const auto& spawnableEntities = spawnable.GetEntities();
AZStd::unordered_set<AZStd::string> actualEntityNameSet;
@ -97,6 +102,6 @@ namespace UnitTest
actualEntityNameSet.insert(spawnableEntity->GetName());
}
EXPECT_EQ(expectedEntityNameSet, actualEntityNameSet);
EXPECT_EQ(actualEntityNameSet, expectedEntityNameSet);
}
}

@ -213,7 +213,7 @@ namespace UnitTest
AZStd::unique_ptr<Instance> convertedInstance(aznew Instance());
ASSERT_TRUE(AzToolsFramework::Prefab::PrefabDomUtils::LoadInstanceFromPrefabDom(*convertedInstance, m_prefabDom));
convertedInstance->DetachNestedEntities(
convertedInstance->DetachAllEntitiesInHierarchy(
[this](AZStd::unique_ptr<AZ::Entity> entity)
{
m_runtimeEntities.emplace_back(entity.release());

@ -715,11 +715,11 @@ QMenu* LevelEditorMenuHandler::CreateViewMenu()
{
return view.IsViewportPane();
});
#endif
viewportViewsMenuWrapper.AddAction(ID_WIREFRAME);
viewportViewsMenuWrapper.AddSeparator();
#endif
if (CViewManager::IsMultiViewportEnabled())
{
viewportViewsMenuWrapper.AddAction(ID_VIEW_CONFIGURELAYOUT);

@ -1139,7 +1139,7 @@ bool CCryEditDoc::SaveLevel(const QString& filename)
const QString oldLevelPattern = QDir(oldLevelFolder).absoluteFilePath("*.*");
const QString oldLevelName = Path::GetFile(GetLevelPathName());
const QString oldLevelXml = Path::ReplaceExtension(oldLevelName, "xml");
AZ::IO::ArchiveFileIterator findHandle = pIPak->FindFirst(oldLevelPattern.toUtf8().data(), 0, true);
AZ::IO::ArchiveFileIterator findHandle = pIPak->FindFirst(oldLevelPattern.toUtf8().data(), AZ::IO::IArchive::eFileSearchType_AllowOnDiskAndInZips);
if (findHandle)
{
do

@ -2664,6 +2664,18 @@ bool EditorViewportWidget::GetActiveCameraPosition(AZ::Vector3& cameraPos)
return false;
}
bool EditorViewportWidget::GetActiveCameraState(AzFramework::CameraState& cameraState)
{
if (m_pPrimaryViewport == this)
{
cameraState = GetCameraState();
return true;
}
return false;
}
void EditorViewportWidget::OnStartPlayInEditor()
{
if (m_viewEntityId.IsValid())

@ -184,6 +184,7 @@ public:
void SetViewAndMovementLockFromEntityPerspective(const AZ::EntityId& entityId, bool lockCameraMovement) override;
AZ::EntityId GetCurrentViewEntityId() override { return m_viewEntityId; }
bool GetActiveCameraPosition(AZ::Vector3& cameraPos) override;
bool GetActiveCameraState(AzFramework::CameraState& cameraState) override;
// AzToolsFramework::EditorEntityContextNotificationBus (handler moved to cpp to resolve link issues in unity builds)
virtual void OnStartPlayInEditor();

@ -833,13 +833,6 @@ void MainWindow::InitActions()
.Connect(&QAction::triggered, []() { SandboxEditor::SetAngleSnapping(!SandboxEditor::AngleSnappingEnabled()); });
// Display actions
am->AddAction(ID_WIREFRAME, tr("&Wireframe"))
.SetShortcut(tr("F3"))
.SetToolTip(tr("Wireframe (F3)"))
.SetCheckable(true)
.SetStatusTip(tr("Render in Wireframe Mode."))
.RegisterUpdateCallback(cryEdit, &CCryEditApp::OnUpdateWireframe);
am->AddAction(ID_SWITCHCAMERA_DEFAULTCAMERA, tr("Default Camera")).SetCheckable(true)
.RegisterUpdateCallback(cryEdit, &CCryEditApp::OnUpdateSwitchToDefaultCamera);
am->AddAction(ID_SWITCHCAMERA_SEQUENCECAMERA, tr("Sequence Camera")).SetCheckable(true)

@ -115,10 +115,10 @@ protected:
float m_prevMoveSpeed;
// Speed combobox/lineEdit settings
double m_minSpeed = 0.1;
double m_minSpeed = 0.01;
double m_maxSpeed = 100.0;
double m_speedStep = 0.1;
int m_numDecimals = 1;
double m_speedStep = 0.01;
int m_numDecimals = 3;
// Speed presets
float m_speedPresetValues[3] = { 0.1f, 1.0f, 10.0f };

@ -35,7 +35,7 @@ namespace AZ
Application::Application(int argc, char** argv)
: AzToolsFramework::ToolsApplication(&argc, &argv)
{
// We need a specialized variant of EditorEntityContextCompnent for the SliceConverter, so we register the descriptor here.
// We need a specialized variant of EditorEntityContextComponent for the SliceConverter, so we register the descriptor here.
RegisterComponentDescriptor(AzToolsFramework::SliceConverterEditorEntityContextComponent::CreateDescriptor());
AZ::IO::FixedMaxPath projectPath = AZ::Utils::GetProjectPath();

@ -128,8 +128,7 @@ namespace AZ
return result;
}
bool SliceConverter::ConvertSliceFile(
AZ::SerializeContext* serializeContext, const AZStd::string& slicePath, bool isDryRun)
bool SliceConverter::ConvertSliceFile(AZ::SerializeContext* serializeContext, const AZStd::string& slicePath, bool isDryRun)
{
/* To convert a slice file, we read the input file in via ObjectStream, then use the "class ready" callback to convert
* the data in memory to a Prefab.
@ -177,11 +176,22 @@ namespace AZ
}
AZ::Entity* rootEntity = reinterpret_cast<AZ::Entity*>(classPtr);
return ConvertSliceToPrefab(context, outputPath, isDryRun, rootEntity);
bool convertResult = ConvertSliceToPrefab(context, outputPath, isDryRun, rootEntity);
// Clear out the references to any nested slices so that the nested assets get unloaded correctly at the end of
// the conversion.
ClearSliceAssetReferences(rootEntity);
return convertResult;
};
// Read in the slice file and call the callback on completion to convert the read-in slice to a prefab.
if (!Utilities::InspectSerializedFile(inputPath.c_str(), serializeContext, callback))
// This will also load dependent slice assets, but no other dependent asset types.
// Since we're not actually initializing any of the entities, we don't need any of the non-slice assets to be loaded.
if (!Utilities::InspectSerializedFile(
inputPath.c_str(), serializeContext, callback,
[](const AZ::Data::AssetFilterInfo& filterInfo)
{
return (filterInfo.m_assetType == azrtti_typeid<AZ::SliceAsset>());
}))
{
AZ_Warning("Convert-Slice", false, "Failed to load '%s'. File may not contain an object stream.", inputPath.c_str());
result = false;
@ -256,7 +266,7 @@ namespace AZ
for (auto& alias : entityAliases)
{
auto id = sourceInstance->GetEntityId(alias);
auto result = m_aliasIdMapper.emplace(TemplateEntityIdPair(templateId, id), alias);
auto result = m_aliasIdMapper.emplace(id, SliceEntityMappingInfo(templateId, alias));
if (!result.second)
{
AZ_Printf("Convert-Slice", " Duplicate entity alias -> entity id entries found, conversion may not be successful.\n");
@ -342,10 +352,9 @@ namespace AZ
// For each nested slice, convert it.
for (auto& slice : sliceList)
{
// Get the nested slice asset
// Get the nested slice asset. These should already be preloaded due to loading the root asset.
auto sliceAsset = slice.GetSliceAsset();
sliceAsset.QueueLoad();
sliceAsset.BlockUntilLoadComplete();
AZ_Assert(sliceAsset.IsReady(), "slice asset hasn't been loaded yet!");
// The slice list gives us asset IDs, and we need to get to the source path. So first we get the asset path from the ID,
// then we get the source path from the asset path.
@ -429,6 +438,28 @@ namespace AZ
auto instanceToTemplateInterface = AZ::Interface<AzToolsFramework::Prefab::InstanceToTemplateInterface>::Get();
auto prefabSystemComponentInterface = AZ::Interface<AzToolsFramework::Prefab::PrefabSystemComponentInterface>::Get();
// When creating the new instance, we would like to have deterministic instance aliases. Prefabs that depend on this one
// will have patches that reference the alias, so if we reconvert this slice a second time, we would like it to produce
// the same results. To get a deterministic and unique alias, we rely on the slice instance. The slice instance contains
// a map of slice entity IDs to unique instance entity IDs. We'll just consistently use the first entry in the map as the
// unique instance ID.
AZStd::string instanceAlias;
auto entityIdMap = instance.GetEntityIdMap();
if (!entityIdMap.empty())
{
instanceAlias = AZStd::string::format("Instance_%s", entityIdMap.begin()->second.ToString().c_str());
}
else
{
instanceAlias = AZStd::string::format("Instance_%s", AZ::Entity::MakeId().ToString().c_str());
}
// Before processing any further, save off all the known entity IDs from this instance and how they map back to the base
// nested prefab that they've come from (i.e. this one). As we proceed up the chain of nesting, this will build out a
// hierarchical list of owning instances for each entity that we can trace upwards to know where to add the entity into
// our nested prefab instance.
UpdateSliceEntityInstanceMappings(instance.GetEntityIdToBaseMap(), instanceAlias);
// Create a new unmodified prefab Instance for the nested slice instance.
auto nestedInstance = AZStd::make_unique<AzToolsFramework::Prefab::Instance>();
AzToolsFramework::Prefab::Instance::EntityList newEntities;
@ -465,62 +496,125 @@ namespace AZ
auto instantiated =
dataPatch.Apply(&sourceObjects, dependentSlice->GetSerializeContext(), filterDesc, sourceDataFlags, targetDataFlags);
// Run through all the instantiated entities and fix up their parent hierarchy:
// - Invalid parents need to get set to the container.
// - Valid parents into the top-level instance mean that the nested slice instance is also child-nested under an entity.
// Prefabs handle this type of nesting differently - we need to set the parent to the container, and the container's
// parent to that other instance.
auto containerEntity = nestedInstance->GetContainerEntity();
auto containerEntityId = containerEntity->get().GetId();
for (auto entity : instantiated->m_entities)
{
AzToolsFramework::Components::TransformComponent* transformComponent =
entity->FindComponent<AzToolsFramework::Components::TransformComponent>();
if (transformComponent)
{
bool onlySetIfInvalid = true;
auto parentId = transformComponent->GetParentId();
if (parentId.IsValid())
{
auto parentAlias = m_aliasIdMapper.find(TemplateEntityIdPair(topLevelInstance->GetTemplateId(), parentId));
if (parentAlias != m_aliasIdMapper.end())
{
// Set the container's parent to this entity's parent, and set this entity's parent to the container
// (i.e. go from A->B to A->container->B)
auto newParentId = topLevelInstance->GetEntityId(parentAlias->second);
SetParentEntity(containerEntity->get(), newParentId, false);
onlySetIfInvalid = false;
}
}
SetParentEntity(*entity, containerEntityId, onlySetIfInvalid);
}
}
// Replace all the entities in the instance with the new patched ones.
// Replace all the entities in the instance with the new patched ones. To do this, we'll remove all existing entities
// throughout the entire nested hierarchy, then add the new patched entities back in at the appropriate place in the hierarchy.
// (This is easier than trying to figure out what the patched data changes are - we can let the JSON patch handle it for us)
nestedInstance->RemoveNestedEntities(
[](const AZStd::unique_ptr<AZ::Entity>&)
{
return true;
});
AZStd::vector<AZStd::pair<AZ::Entity*, AzToolsFramework::Prefab::Instance*>> addedEntityList;
for (auto& entity : instantiated->m_entities)
{
auto entityAlias = m_aliasIdMapper.find(TemplateEntityIdPair(nestedInstance->GetTemplateId(), entity->GetId()));
if (entityAlias != m_aliasIdMapper.end())
auto entityEntry = m_aliasIdMapper.find(entity->GetId());
if (entityEntry != m_aliasIdMapper.end())
{
nestedInstance->AddEntity(*entity, entityAlias->second);
auto& mappingStruct = entityEntry->second;
// Starting with the current nested instance, walk downwards through the nesting hierarchy until we're at the
// correct level for this instanced entity ID, then add it. Because we're adding it with the non-instanced alias,
// it doesn't matter what the slice's instanced entity ID is, and the JSON patch will correctly pick up the changes
// we've made for this instance.
AzToolsFramework::Prefab::Instance* addingInstance = nestedInstance.get();
for (auto it = mappingStruct.m_nestedInstanceAliases.rbegin(); it != mappingStruct.m_nestedInstanceAliases.rend(); it++)
{
auto foundInstance = addingInstance->FindNestedInstance(*it);
if (foundInstance.has_value())
{
addingInstance = &(foundInstance->get());
}
else
{
AZ_Assert(false, "Couldn't find nested instance %s", it->c_str());
}
}
addingInstance->AddEntity(*entity, mappingStruct.m_entityAlias);
addedEntityList.emplace_back(entity, addingInstance);
}
else
{
AZ_Assert(false, "Failed to find entity alias.");
nestedInstance->AddEntity(*entity);
addedEntityList.emplace_back(entity, nestedInstance.get());
}
}
for (auto& [entity, addingInstance] : addedEntityList)
{
// Fix up the parent hierarchy:
// - Invalid parents need to get set to the container.
// - Valid parents into the top-level instance mean that the nested slice instance is also child-nested under an entity.
// Prefabs handle this type of nesting differently - we need to set the parent to the container, and the container's
// parent to that other instance.
auto containerEntity = addingInstance->GetContainerEntity();
auto containerEntityId = containerEntity->get().GetId();
AzToolsFramework::Components::TransformComponent* transformComponent =
entity->FindComponent<AzToolsFramework::Components::TransformComponent>();
if (transformComponent)
{
bool onlySetIfInvalid = true;
auto parentId = transformComponent->GetParentId();
if (parentId.IsValid())
{
// Look to see if the parent ID exists in the same instance (i.e. an entity in the nested slice is a
// child of an entity in the containing slice). If this case exists, we need to adjust the parents so that
// the child entity connects to the prefab container, and the *container* is the child of the entity in the
// containing slice. (i.e. go from A->B to A->container->B)
auto parentEntry = m_aliasIdMapper.find(parentId);
if (parentEntry != m_aliasIdMapper.end())
{
auto& parentMappingInfo = parentEntry->second;
if (parentMappingInfo.m_templateId != addingInstance->GetTemplateId())
{
if (topLevelInstance->GetTemplateId() == parentMappingInfo.m_templateId)
{
parentId = topLevelInstance->GetEntityId(parentMappingInfo.m_entityAlias);
}
else
{
AzToolsFramework::Prefab::Instance* parentInstance = addingInstance;
while ((parentInstance->GetParentInstance().has_value()) &&
(parentInstance->GetTemplateId() != parentMappingInfo.m_templateId))
{
parentInstance = &(parentInstance->GetParentInstance()->get());
}
if (parentInstance->GetTemplateId() == parentMappingInfo.m_templateId)
{
parentId = parentInstance->GetEntityId(parentMappingInfo.m_entityAlias);
}
else
{
AZ_Assert(false, "Could not find parent instance");
}
}
// Set the container's parent to this entity's parent, and set this entity's parent to the container
// auto newParentId = topLevelInstance->GetEntityId(parentMappingInfo.m_entityAlias);
SetParentEntity(containerEntity->get(), parentId, false);
onlySetIfInvalid = false;
}
}
// If the parent ID is valid, but NOT in the top-level instance, then it's just a nested hierarchy inside
// the slice and we don't need to adjust anything. "onlySetIfInvalid" will still be true, which means we
// won't change the parent ID below.
}
SetParentEntity(*entity, containerEntityId, onlySetIfInvalid);
}
}
// Set the container entity of the nested prefab to have the top-level prefab as the parent if it hasn't already gotten
// another entity as its parent.
{
auto containerEntity = nestedInstance->GetContainerEntity();
constexpr bool onlySetIfInvalid = true;
SetParentEntity(containerEntity->get(), topLevelInstance->GetContainerEntityId(), onlySetIfInvalid);
}
@ -531,21 +625,7 @@ namespace AZ
AzToolsFramework::Prefab::PrefabDom topLevelInstanceDomBefore;
instanceToTemplateInterface->GenerateDomForInstance(topLevelInstanceDomBefore, *topLevelInstance);
// When creating the new instance, we would like to have deterministic instance aliases. Prefabs that depend on this one
// will have patches that reference the alias, so if we reconvert this slice a second time, we would like it to produce
// the same results. To get a deterministic and unique alias, we rely on the slice instance. The slice instance contains
// a map of slice entity IDs to unique instance entity IDs. We'll just consistently use the first entry in the map as the
// unique instance ID.
AZStd::string instanceAlias;
auto entityIdMap = instance.GetEntityIdMap();
if (!entityIdMap.empty())
{
instanceAlias = AZStd::string::format("Instance_%s", entityIdMap.begin()->second.ToString().c_str());
}
else
{
instanceAlias = AZStd::string::format("Instance_%s", AZ::Entity::MakeId().ToString().c_str());
}
// Use the deterministic instance alias for this new instance
AzToolsFramework::Prefab::Instance& addedInstance = topLevelInstance->AddInstance(AZStd::move(nestedInstance), instanceAlias);
AzToolsFramework::Prefab::PrefabDom topLevelInstanceDomAfter;
@ -670,5 +750,48 @@ namespace AZ
AZ_Error("Convert-Slice", disconnected, "Asset Processor failed to disconnect successfully.");
}
void SliceConverter::ClearSliceAssetReferences(AZ::Entity* rootEntity)
{
SliceComponent* sliceComponent = AZ::EntityUtils::FindFirstDerivedComponent<SliceComponent>(rootEntity);
// Make a copy of the slice list and remove all of them from the loaded component.
AZ::SliceComponent::SliceList slices = sliceComponent->GetSlices();
for (auto& slice : slices)
{
sliceComponent->RemoveSlice(&slice);
}
}
void SliceConverter::UpdateSliceEntityInstanceMappings(
const AZ::SliceComponent::EntityIdToEntityIdMap& sliceEntityIdMap, const AZStd::string& currentInstanceAlias)
{
// For each instanced entity, map its ID all the way back to the original prefab template and entity ID that it came from.
// This counts on being run recursively from the leaf nodes upwards, so we first get B->A,
// then C->B which becomes a C->A entry, then D->C which becomes D->A, etc.
for (auto& [newId, oldId] : sliceEntityIdMap)
{
// Try to find the conversion chain from the old ID. if it's there, copy it and use it for the new ID, plus add this
// instance's name to the end of the chain. If it's not there, skip it, since it's probably the slice metadata entity,
// which we didn't convert.
auto parentEntry = m_aliasIdMapper.find(oldId);
if (parentEntry != m_aliasIdMapper.end())
{
// Only add this instance's name if we don't already have an entry for the new ID.
if (m_aliasIdMapper.find(newId) == m_aliasIdMapper.end())
{
auto newMappingEntry = m_aliasIdMapper.emplace(newId, parentEntry->second).first;
newMappingEntry->second.m_nestedInstanceAliases.emplace_back(currentInstanceAlias);
}
else
{
// If we already had an entry for the new ID, it might be because the old and new ID are the same. This happens
// when nesting multiple prefabs directly underneath each other without a nesting entity in-between.
// If the IDs are different, it's an unexpected error condition.
AZ_Assert(oldId == newId, "The same entity instance ID has unexpectedly appeared twice in the same nested prefab.");
}
}
}
}
} // namespace SerializeContextTools
} // namespace AZ

@ -42,8 +42,6 @@ namespace AZ
bool ConvertSliceFiles(Application& application);
private:
using TemplateEntityIdPair = AZStd::pair<AzToolsFramework::Prefab::TemplateId, AZ::EntityId>;
bool ConnectToAssetProcessor();
void DisconnectFromAssetProcessor();
@ -60,10 +58,32 @@ namespace AZ
void SetParentEntity(const AZ::Entity& entity, const AZ::EntityId& parentId, bool onlySetIfInvalid);
void PrintPrefab(AzToolsFramework::Prefab::TemplateId templateId);
bool SavePrefab(AZ::IO::PathView outputPath, AzToolsFramework::Prefab::TemplateId templateId);
void ClearSliceAssetReferences(AZ::Entity* rootEntity);
void UpdateSliceEntityInstanceMappings(
const AZ::SliceComponent::EntityIdToEntityIdMap& sliceEntityIdMap,
const AZStd::string& currentInstanceAlias);
// When converting slice entities, especially for nested slices, we need to keep track of the original
// entity ID, the entity alias it uses in the prefab, and which template and nested instance path it maps to.
// As we encounter each instanced entity ID, we can look it up in this structure and use this to determine how to properly
// add it to the correct place in the hierarchy.
struct SliceEntityMappingInfo
{
SliceEntityMappingInfo(AzToolsFramework::Prefab::TemplateId templateId, AzToolsFramework::Prefab::EntityAlias entityAlias)
: m_templateId(templateId)
, m_entityAlias(entityAlias)
{
}
AzToolsFramework::Prefab::TemplateId m_templateId;
AzToolsFramework::Prefab::EntityAlias m_entityAlias;
AZStd::vector<AzToolsFramework::Prefab::InstanceAlias> m_nestedInstanceAliases;
};
// Track all of the entity IDs created and the prefab entity aliases that map to them. This mapping is used
// with nested slice conversion to remap parent entity IDs to the correct prefab entity IDs.
AZStd::unordered_map<TemplateEntityIdPair, AzToolsFramework::Prefab::EntityAlias> m_aliasIdMapper;
// Track all of the entity IDs created and associate them with enough conversion information to know how to place the
// entities in the correct place in the prefab hierarchy and fix up parent entity ID mappings to work with the nested
// prefab schema.
AZStd::unordered_map<AZ::EntityId, SliceEntityMappingInfo> m_aliasIdMapper;
// Track all of the created prefab template IDs on a slice conversion so that they can get removed at the end of the
// conversion for that file.

@ -36,7 +36,7 @@ namespace AzToolsFramework
SliceConverterEditorEntityContextComponent() : EditorEntityContextComponent() {}
// Simple API to selectively disable this logic *only* when performing slice to prefab conversion.
static void DisableOnContextEntityLogic()
static inline void DisableOnContextEntityLogic()
{
m_enableOnContextEntityLogic = false;
}

@ -209,7 +209,11 @@ namespace AZ::SerializeContextTools
return result;
}
bool Utilities::InspectSerializedFile(const char* filePath, SerializeContext* sc, const ObjectStream::ClassReadyCB& classCallback)
bool Utilities::InspectSerializedFile(
const char* filePath,
SerializeContext* sc,
const ObjectStream::ClassReadyCB& classCallback,
Data::AssetFilterCB assetFilterCallback)
{
if (!AZ::IO::FileIOBase::GetInstance()->Exists(filePath))
{
@ -248,9 +252,9 @@ namespace AZ::SerializeContextTools
AZ::IO::MemoryStream stream(data.data(), fileLength);
ObjectStream::FilterDescriptor filter;
// Never load dependencies. That's another file that would need to be processed
// By default, never load dependencies. That's another file that would need to be processed
// separately from this one.
filter.m_assetCB = AZ::Data::AssetFilterNoAssetLoading;
filter.m_assetCB = assetFilterCallback;
if (!ObjectStream::LoadBlocking(&stream, *sc, classCallback, filter))
{
AZ_Printf("Verify", "Failed to deserialize '%s'\n", filePath);

@ -39,7 +39,11 @@ namespace AZ
static AZStd::vector<AZ::Uuid> GetSystemComponents(const Application& application);
static bool InspectSerializedFile(const char* filePath, SerializeContext* sc, const ObjectStream::ClassReadyCB& classCallback);
static bool InspectSerializedFile(
const char* filePath,
SerializeContext* sc,
const ObjectStream::ClassReadyCB& classCallback,
Data::AssetFilterCB assetFilterCallback = AZ::Data::AssetFilterNoAssetLoading);
private:
Utilities() = delete;

@ -295,6 +295,10 @@ PbrLightingOutput ForwardPassPS_Common(VSOutput IN, bool isFrontFace, out float
lightingOutput.m_diffuseColor.rgb += lightingOutput.m_specularColor.rgb; // add specular
lightingOutput.m_specularColor.rgb = baseColor * (1.0 - lightingOutput.m_diffuseColor.w);
}
else
{
lightingOutput.m_diffuseColor.w = -1; // Disable subsurface scattering
}
return lightingOutput;
}
@ -341,4 +345,3 @@ ForwardPassOutput StandardPbr_ForwardPassPS_EDS(VSOutput IN, bool isFrontFace :
#endif
return OUT;
}

@ -322,7 +322,14 @@
"Pass": "AuxGeomPass",
"Attachment": "ColorInputOutput"
}
}
},
{
"LocalSlot": "DepthInputOutput",
"AttachmentRef": {
"Pass": "DepthPrePass",
"Attachment": "Depth"
}
}
]
},
{

@ -427,6 +427,13 @@
"Pass": "DebugOverlayPass",
"Attachment": "InputOutput"
}
},
{
"LocalSlot": "DepthInputOutput",
"AttachmentRef": {
"Pass": "DepthPrePass",
"Attachment": "Depth"
}
}
]
},

@ -7,6 +7,23 @@
"Name": "UIPassTemplate",
"PassClass": "RasterPass",
"Slots": [
{
"Name": "DepthInputOutput",
"SlotType": "InputOutput",
"ScopeAttachmentUsage": "DepthStencil",
"LoadStoreAction": {
"ClearValue": {
"Type": "DepthStencil",
"Value": [
0.0,
0.0,
0.0,
0.0
]
},
"LoadActionStencil": "Clear"
}
},
{
"Name": "InputOutput",
"SlotType": "InputOutput",

@ -10,6 +10,11 @@
{
"Name": "InputOutput",
"SlotType": "InputOutput"
},
{
"Name": "DepthInputOutput",
"SlotType": "InputOutput",
"ScopeAttachmentUsage": "DepthStencil"
}
],
"PassRequests": [
@ -24,6 +29,13 @@
"Pass": "Parent",
"Attachment": "InputOutput"
}
},
{
"LocalSlot": "DepthInputOutput",
"AttachmentRef": {
"Pass": "Parent",
"Attachment": "DepthInputOutput"
}
}
],
"PassData": {

@ -10,7 +10,5 @@
"type": "Compute"
}
]
},
"DisabledRHIBackends": ["metal"]
}
}

@ -16,7 +16,10 @@
ShaderResourceGroup MorphTargetPassSrg : SRG_PerPass
{
RWBuffer<int> m_accumulatedDeltas;
//Since we do Interlocked atomic operations on this buffer it can not be RWBuffer due to broken MetalSL generation.
//It stems from the fact that typed buffers gets converted to textures and that breaks with atomic operations.
//In future we can handle this under the hood via our metal shader pipeline
RWStructuredBuffer<int> m_accumulatedDeltas;
}
// This class represents the data that is passed to the morph target compute shader of an individual delta

@ -37,7 +37,7 @@ ShaderResourceGroup PassSrg : SRG_PerPass
Texture2D<float4> m_sceneLuminance;
// This should be of size NUM_HISTOGRAM_BINS.
Buffer<uint> m_histogram;
StructuredBuffer<uint> m_histogram;
Sampler LinearSampler
{

@ -20,7 +20,11 @@
ShaderResourceGroup PassSrg : SRG_PerPass
{
Texture2D<float4> m_inputTexture;
RWBuffer<uint> m_outputTexture;
//Since we do Interlocked atomic operations on this buffer it can not be RWBuffer due to broken MetalSL generation.
//It stems from the fact that typed buffers gets converted to textures and that breaks with atomic operations.
//In future we can handle this under the hood via our metal shader pipeline
RWStructuredBuffer<uint> m_outputTexture;
}
groupshared uint shared_histogramBins[NUM_HISTOGRAM_BINS];

@ -12,7 +12,5 @@
"type": "Compute"
}
]
},
"DisabledRHIBackends": ["metal"]
}
}

@ -16,7 +16,7 @@
ShaderResourceGroup PassSrg : SRG_PerPass
{
RWBuffer<float> m_skinnedMeshOutputStream;
RWStructuredBuffer<float> m_skinnedMeshOutputStream;
}
ShaderResourceGroup InstanceSrg : SRG_PerDraw

@ -48,7 +48,9 @@ namespace AZ
void SetShaperParams(const ShaperParams& shaperParams);
private:
explicit AcesOutputTransformLutPass(const RPI::PassDescriptor& descriptor);
void Init() override;
// Pass behavior overrides...
void InitializeInternal() override;
// Scope producer functions...
void SetupFrameGraphDependencies(RHI::FrameGraphInterface frameGraph) override;

@ -50,7 +50,9 @@ namespace AZ
private:
explicit AcesOutputTransformPass(const RPI::PassDescriptor& descriptor);
void Init() override;
// Pass behavior overrides
void InitializeInternal() override;
// Scope producer functions...
void CompileResources(const RHI::FrameGraphCompileContext& context) override;

@ -45,7 +45,9 @@ namespace AZ
protected:
explicit ApplyShaperLookupTablePass(const RPI::PassDescriptor& descriptor);
void Init() override;
// Pass behavior overrides...
void InitializeInternal() override;
RHI::ShaderInputImageIndex m_shaderInputLutImageIndex;

@ -57,15 +57,13 @@ namespace AZ
explicit BakeAcesOutputTransformLutPass(const RPI::PassDescriptor& descriptor);
// Pass behavior overrides...
void FrameBeginInternal(FramePrepareParams params) override;
void InitializeInternal() override;
// RHI::ScopeProducer overrides...
void SetupFrameGraphDependencies(RHI::FrameGraphInterface frameGraph) override;
void CompileResources(const RHI::FrameGraphCompileContext& context) override;
void BuildCommandListInternal(const RHI::FrameGraphExecuteContext& context) override;
void Init();
void AcquireLutImage();
void ReleaseLutImage();

@ -41,14 +41,11 @@ namespace AZ
void SetInputReferencePassName(const Name& passName);
void SetInputReferenceAttachmentName(const Name& attachmentName);
// Pass behavior overrides
virtual void BuildAttachmentsInternal() override;
protected:
explicit DisplayMapperFullScreenPass(const RPI::PassDescriptor& descriptor);
// FullscreenTrianglePass behavior overrides
virtual void Init();
// Pass behavior overrides...
virtual void BuildInternal() override;
private:
Name m_inputReferencePassName = Name{ "Parent" };

@ -76,7 +76,8 @@ namespace AZ
DisplayMapperPass(const RPI::PassDescriptor& descriptor);
// Pass behavior overrides
void BuildAttachmentsInternal() final;
void BuildInternal() final;
void InitializeInternal() final;
void FrameBeginInternal(FramePrepareParams params) final;
void FrameEndInternal() final;
void CreateChildPassesInternal() final;

@ -49,7 +49,9 @@ namespace AZ
protected:
explicit OutputTransformPass(const RPI::PassDescriptor& descriptor);
void Init() override;
// Pass behavior overrides
void InitializeInternal() override;
private:
// Scope producer functions...

@ -42,7 +42,7 @@ namespace AZ
protected:
// Pass behavior overrides
void CreateChildPassesInternal() final;
void BuildAttachmentsInternal() final;
void BuildInternal() final;
void FrameBeginInternal(FramePrepareParams params) final;
private:

@ -46,7 +46,7 @@ namespace AZ
private:
void BuildAttachmentsInternal() override;
void BuildInternal() override;
void FrameBeginInternal(FramePrepareParams params) override;
void UpdataAttachment();

@ -60,7 +60,7 @@ namespace AZ
Base::FrameBeginInternal(params);
}
void CheckerboardColorResolvePass::BuildAttachmentsInternal()
void CheckerboardColorResolvePass::BuildInternal()
{
// For each bound attachments they are the inputs from current frame.
// We use them to get their owner CheckerboardPass then find the render targets from last frame
@ -99,7 +99,7 @@ namespace AZ
// reset frame offset to 0 since attachments are rebuilt
m_frameOffset = 0;
Base::BuildAttachmentsInternal();
Base::BuildInternal();
}
void CheckerboardColorResolvePass::CompileResources(const RHI::FrameGraphCompileContext& context)
@ -135,7 +135,7 @@ namespace AZ
void CheckerboardColorResolvePass::FrameEndInternal()
{
// For the input slots for current frame, they always get updated when CheckerboardPass updates the render targets
// But for the input slots for previous frame, we need to manually update them since they were manually attached in BuildAttachmentsInternal()
// But for the input slots for previous frame, we need to manually update them since they were manually attached in BuildInternal()
//
// When pass attachment was built, CheckerboardPass creates two resources for each render target.
// For example, diffuse_0 and diffuse_1 which diffuse_0 is for even frame and diffuse_1 is for odd frame.

@ -52,7 +52,7 @@ namespace AZ
protected:
// Pass overrides...
void FrameBeginInternal(FramePrepareParams params) override;
void BuildAttachmentsInternal() override;
void BuildInternal() override;
void FrameEndInternal() override;
// Scope producer functions...

@ -50,7 +50,7 @@ namespace AZ
Base::FrameBeginInternal(params);
}
void CheckerboardPass::BuildAttachmentsInternal()
void CheckerboardPass::BuildInternal()
{
Data::Instance<RPI::AttachmentImagePool> pool = RPI::ImageSystemInterface::Get()->GetSystemAttachmentPool();
@ -101,7 +101,7 @@ namespace AZ
// reset frame offset to 0 since attachments are rebuilt
m_frameOffset = 0;
Base::BuildAttachmentsInternal();
Base::BuildInternal();
}

@ -40,7 +40,7 @@ namespace AZ
protected:
// Pass overrides...
void FrameBeginInternal(FramePrepareParams params);
void BuildAttachmentsInternal() override;
void BuildInternal() override;
void FrameEndInternal() override;
private:

@ -100,7 +100,7 @@ namespace AZ
m_arraySize = arraySize;
m_updateChildren = true;
QueueForBuildAttachments();
QueueForBuildAndInitialization();
m_atlas.Initialize();
for (size_t cascadeIndex = 0; cascadeIndex < m_arraySize; ++cascadeIndex)
@ -149,7 +149,7 @@ namespace AZ
return m_atlas;
}
void CascadedShadowmapsPass::BuildAttachmentsInternal()
void CascadedShadowmapsPass::BuildInternal()
{
UpdateChildren();
@ -159,7 +159,7 @@ namespace AZ
}
UpdateShadowmapImageSize();
Base::BuildAttachmentsInternal();
Base::BuildInternal();
}
void CascadedShadowmapsPass::GetPipelineViewTags(RPI::SortedPipelineViewTags& outTags) const
@ -215,7 +215,7 @@ namespace AZ
AZ_RPI_PASS_WARNING(child, "CascadedShadowmapsPass child Pass creation failed for %d", cascadeIndex);
if (child)
{
child->QueueForBuildAttachments();
child->QueueForBuildAndInitialization();
AddChild(child);
}
}

@ -53,7 +53,7 @@ namespace AZ
explicit CascadedShadowmapsPass(const RPI::PassDescriptor& descriptor);
// RPI::Pass overrides...
void BuildAttachmentsInternal() override;
void BuildInternal() override;
void GetPipelineViewTags(RPI::SortedPipelineViewTags& outTags) const override;
void GetViewDrawListInfo(RHI::DrawListMask& outDrawListMask, RPI::PassesByDrawList& outPassesByDrawList, const RPI::PipelineViewTag& viewTag) const override;

@ -1106,7 +1106,7 @@ namespace AZ
{
for (EsmShadowmapsPass* pass : it.second)
{
pass->QueueForBuildAttachments();
pass->QueueForBuildAndInitialization();
}
}
}

@ -163,7 +163,6 @@ namespace AZ
void LightCullingPass::ResetInternal()
{
m_initialized = false;
m_tileDataIndex = -1;
m_constantDataIndex.Reset();
@ -260,7 +259,7 @@ namespace AZ
return gridPixelSize;
}
void LightCullingPass::BuildAttachmentsInternal()
void LightCullingPass::BuildInternal()
{
m_tileDataIndex = FindInputBinding(AZ::Name("TileLightData"));
CreateLightList();

@ -50,7 +50,7 @@ namespace AZ
// Pass behavior overrides...
void ResetInternal()override;
void BuildAttachmentsInternal() override;
void BuildInternal() override;
// Scope producer functions...
void CompileResources(const RHI::FrameGraphCompileContext& context) override;
@ -96,7 +96,6 @@ namespace AZ
AZ::RHI::ShaderInputNameIndex m_constantDataIndex = "m_constantData";
bool m_initialized = false;
Data::Instance<RPI::Buffer> m_lightList;
uint32_t m_tileDataIndex = -1;

@ -108,7 +108,7 @@ namespace AZ
return -1;
}
void LightCullingRemap::BuildAttachmentsInternal()
void LightCullingRemap::BuildInternal()
{
m_tileDataIndex = FindInputOutputBinding(AZ::Name("TileLightData"));
m_tileDim = GetTileDataBufferResolution();

@ -55,7 +55,7 @@ namespace AZ
// Pass behavior overrides...
void ResetInternal()override;
void BuildAttachmentsInternal() override;
void BuildInternal() override;
// RHI::ScopeProducer overrides...
void SetupFrameGraphDependencies(RHI::FrameGraphInterface frameGraph) override;

@ -167,37 +167,36 @@ namespace AZ
AZ_Assert(setOk, "LightCullingTilePreparePass::SetConstantData() - could not set constant data");
}
void LightCullingTilePreparePass::BuildAttachmentsInternal()
void LightCullingTilePreparePass::BuildInternal()
{
ChooseShaderVariant();
}
void LightCullingTilePreparePass::OnShaderReinitialized(const AZ::RPI::Shader&)
void LightCullingTilePreparePass::OnShaderReloaded()
{
LoadShader();
if (!m_flags.m_queuedForBuildAttachment && !m_flags.m_isBuildingAttachments)
AZ_Assert(GetPassState() != RPI::PassState::Rendering, "LightCullingTilePreparePass: Trying to reload shader during rendering");
if (GetPassState() == RPI::PassState::Idle)
{
ChooseShaderVariant();
}
}
void LightCullingTilePreparePass::OnShaderReinitialized(const AZ::RPI::Shader&)
{
OnShaderReloaded();
}
void LightCullingTilePreparePass::OnShaderAssetReinitialized(const Data::Asset<AZ::RPI::ShaderAsset>&)
{
LoadShader();
if (!m_flags.m_queuedForBuildAttachment && !m_flags.m_isBuildingAttachments)
{
ChooseShaderVariant();
}
OnShaderReloaded();
}
void LightCullingTilePreparePass::OnShaderVariantReinitialized(
const AZ::RPI::Shader&, const AZ::RPI::ShaderVariantId&,
AZ::RPI::ShaderVariantStableId)
{
LoadShader();
if (!m_flags.m_queuedForBuildAttachment && !m_flags.m_isBuildingAttachments)
{
ChooseShaderVariant();
}
OnShaderReloaded();
}
} // namespace Render

@ -50,7 +50,7 @@ namespace AZ
LightCullingTilePreparePass(const RPI::PassDescriptor& descriptor);
// Pass behavior overrides...
void BuildAttachmentsInternal() override;
void BuildInternal() override;
///////////////////////////////////////////////////////////////////
// ShaderReloadNotificationBus overrides...
@ -73,6 +73,7 @@ namespace AZ
const AZ::RPI::ShaderVariant& CreateShaderVariant();
void CreatePipelineStateFromShaderVariant(const RPI::ShaderVariant& shaderVariant);
void SetConstantData();
void OnShaderReloaded();
AZ::RHI::ShaderInputNameIndex m_constantDataIndex = "m_constantData";

@ -73,7 +73,7 @@ namespace AZ
{
m_sizes = sizes;
m_updateChildren = true;
QueueForBuildAttachments();
QueueForBuildAndInitialization();
m_atlas.Initialize();
for (const auto& it : m_sizes)
@ -156,7 +156,7 @@ namespace AZ
return m_atlas;
}
void ProjectedShadowmapsPass::BuildAttachmentsInternal()
void ProjectedShadowmapsPass::BuildInternal()
{
UpdateChildren();
@ -177,7 +177,7 @@ namespace AZ
imageDescriptor.m_size = RHI::Size(shadowmapWidth, shadowmapWidth, 1);
imageDescriptor.m_arraySize = m_atlas.GetArraySliceCount();
Base::BuildAttachmentsInternal();
Base::BuildInternal();
}
void ProjectedShadowmapsPass::GetPipelineViewTags(RPI::SortedPipelineViewTags& outTags) const

@ -71,7 +71,7 @@ namespace AZ
explicit ProjectedShadowmapsPass(const RPI::PassDescriptor& descriptor);
// RPI::Pass overrides...
void BuildAttachmentsInternal() override;
void BuildInternal() override;
void GetPipelineViewTags(RPI::SortedPipelineViewTags& outTags) const override;
void GetViewDrawListInfo(RHI::DrawListMask& outDrawListMask, RPI::PassesByDrawList& outPassesByDrawList, const RPI::PipelineViewTag& viewTag) const override;

@ -107,7 +107,7 @@ namespace AZ
m_scissorState = scissor;
}
void ShadowmapPass::BuildAttachmentsInternal()
void ShadowmapPass::BuildInternal()
{
RPI::Ptr<RPI::ParentPass> parentPass = GetParent();
if (!parentPass)
@ -135,7 +135,7 @@ namespace AZ
action.m_loadAction = m_clearEnabled ? RHI::AttachmentLoadAction::Clear : RHI::AttachmentLoadAction::DontCare;
binding.m_unifiedScopeDesc = RHI::UnifiedScopeAttachmentDescriptor(attachmentId, imageViewDescriptor, action);
Base::BuildAttachmentsInternal();
Base::BuildInternal();
}
} // namespace Render

@ -58,7 +58,7 @@ namespace AZ
explicit ShadowmapPass(const RPI::PassDescriptor& descriptor);
// RHI::Pass overrides...
void BuildAttachmentsInternal() override;
void BuildInternal() override;
uint16_t m_arraySlice = 0;
bool m_clearEnabled = true;

@ -42,9 +42,9 @@ namespace AZ
ReleaseLutImage();
}
void AcesOutputTransformLutPass::Init()
void AcesOutputTransformLutPass::InitializeInternal()
{
DisplayMapperFullScreenPass::Init();
DisplayMapperFullScreenPass::InitializeInternal();
AZ_Assert(m_shaderResourceGroup != nullptr, "AcesOutputTransformLutPass %s has a null shader resource group when calling Init.", GetPathName().GetCStr());

@ -44,9 +44,9 @@ namespace AZ
{
}
void AcesOutputTransformPass::Init()
void AcesOutputTransformPass::InitializeInternal()
{
DisplayMapperFullScreenPass::Init();
DisplayMapperFullScreenPass::InitializeInternal();
AZ_Assert(m_shaderResourceGroup != nullptr, "AcesOutputTransformPass %s has a null shader resource group when calling Init.", GetPathName().GetCStr());

@ -38,9 +38,9 @@ namespace AZ
ReleaseLutImage();
}
void ApplyShaperLookupTablePass::Init()
void ApplyShaperLookupTablePass::InitializeInternal()
{
DisplayMapperFullScreenPass::Init();
DisplayMapperFullScreenPass::InitializeInternal();
AZ_Assert(m_shaderResourceGroup != nullptr, "ApplyShaperLookupTablePass %s has a null shader resource group when calling Init.", GetPathName().GetCStr());

@ -38,17 +38,7 @@ namespace AZ
ReleaseLutImage();
}
void BakeAcesOutputTransformLutPass::FrameBeginInternal(FramePrepareParams params)
{
if (!m_flags.m_initialized)
{
Init();
}
ComputePass::FrameBeginInternal(params);
}
void BakeAcesOutputTransformLutPass::Init()
void BakeAcesOutputTransformLutPass::InitializeInternal()
{
AZ_Assert(m_shaderResourceGroup != nullptr, "BakeAcesOutputTransformLutPass %s has a null shader resource group when calling Init.", GetPathName().GetCStr());
@ -67,7 +57,6 @@ namespace AZ
m_shaderInputShaperBiasIndex = m_shaderResourceGroup->FindShaderInputConstantIndex(Name{ "m_shaperBias" });
m_shaderInputShaperScaleIndex = m_shaderResourceGroup->FindShaderInputConstantIndex(Name{ "m_shaperScale" });
}
m_flags.m_initialized = true;
}
void BakeAcesOutputTransformLutPass::SetupFrameGraphDependencies(RHI::FrameGraphInterface frameGraph)

@ -34,7 +34,7 @@ namespace AZ
{
}
void DisplayMapperFullScreenPass::BuildAttachmentsInternal()
void DisplayMapperFullScreenPass::BuildInternal()
{
RPI::PassConnection inConnection;
inConnection.m_localSlot = InputAttachmentName;
@ -53,9 +53,5 @@ namespace AZ
m_inputReferenceAttachmentName = attachmentName;
}
void DisplayMapperFullScreenPass::Init()
{
FullscreenTrianglePass::Init();
}
} // namespace Render
} // namespace AZ

@ -46,8 +46,6 @@ namespace AZ
DisplayMapperPass::DisplayMapperPass(const RPI::PassDescriptor& descriptor)
: RPI::ParentPass(descriptor)
{
m_flags.m_alreadyCreated = false;
AzFramework::NativeWindowHandle windowHandle = nullptr;
AzFramework::WindowSystemRequestBus::BroadcastResult(
windowHandle,
@ -61,8 +59,6 @@ namespace AZ
{
m_displayMapperConfigurationDescriptor = passData->m_config;
}
m_needToRebuildChildren = true;
}
DisplayMapperPass::~DisplayMapperPass()
@ -86,7 +82,7 @@ namespace AZ
const Name& passName = fullscreenTrianglePass->GetName();
if (passName.GetStringView() == "CopyToSwapChain")
{
fullscreenTrianglePass->Invalidate();
fullscreenTrianglePass->QueueForInitialization();
}
}
}
@ -137,7 +133,7 @@ namespace AZ
}
}
void DisplayMapperPass::BuildAttachmentsInternal()
void DisplayMapperPass::BuildInternal()
{
const Name outputName = Name{ "Output" };
Name inputPass = Name{ "Parent" };
@ -187,7 +183,21 @@ namespace AZ
m_swapChainAttachmentBinding = FindAttachmentBinding(Name("SwapChainOutput"));
ParentPass::BuildAttachmentsInternal();
ParentPass::BuildInternal();
}
void DisplayMapperPass::InitializeInternal()
{
// Force update on bindings because children of display mapper pass have their outputs connect to
// their parent's output, which is a non-conventional and non-standard workflow. Parent outputs are
// updated after child outputs, so post-build the child outputs do not yet point to the attachments on
// the parent bindings they are connected to. Forcing this refresh sets the attachment on the child output.
for (const RPI::Ptr<Pass>& child : m_children)
{
child->UpdateConnectedBindings();
}
RPI::ParentPass::InitializeInternal();
}
void DisplayMapperPass::FrameBeginInternal(FramePrepareParams params)
@ -199,24 +209,14 @@ namespace AZ
void DisplayMapperPass::FrameEndInternal()
{
GetDisplayMapperConfiguration();
if (m_needToRebuildChildren)
{
ClearChildren();
BuildGradingLutTemplate();
CreateGradingAndAcesPasses();
}
ParentPass::FrameEndInternal();
}
void DisplayMapperPass::CreateChildPassesInternal()
{
if (m_needToRebuildChildren)
{
ClearChildren();
BuildGradingLutTemplate();
CreateGradingAndAcesPasses();
}
ParentPass::CreateChildPassesInternal();
ClearChildren();
BuildGradingLutTemplate();
CreateGradingAndAcesPasses();
}
AZStd::shared_ptr<RPI::PassTemplate> CreatePassTemplateHelper(
@ -485,7 +485,6 @@ namespace AZ
{
AddChild(m_ldrGradingLookupTablePass);
}
m_needToRebuildChildren = false;
}
void DisplayMapperPass::GetDisplayMapperConfiguration()
@ -513,7 +512,8 @@ namespace AZ
desc.m_ldrColorGradingLut != m_displayMapperConfigurationDescriptor.m_ldrColorGradingLut ||
desc.m_acesParameterOverrides.m_overrideDefaults != m_displayMapperConfigurationDescriptor.m_acesParameterOverrides.m_overrideDefaults)
{
m_needToRebuildChildren = true;
m_flags.m_createChildren = true;
QueueForBuildAndInitialization();
}
m_displayMapperConfigurationDescriptor = desc;
}
@ -527,41 +527,15 @@ namespace AZ
void DisplayMapperPass::ClearChildren()
{
if (m_acesOutputTransformPass)
{
RemoveChild(m_acesOutputTransformPass);
m_acesOutputTransformPass = nullptr;
}
if (m_bakeAcesOutputTransformLutPass)
{
RemoveChild(m_bakeAcesOutputTransformLutPass);
m_bakeAcesOutputTransformLutPass = nullptr;
}
if (m_acesOutputTransformLutPass)
{
RemoveChild(m_acesOutputTransformLutPass);
m_acesOutputTransformLutPass = nullptr;
}
if (m_displayMapperPassthroughPass)
{
RemoveChild(m_displayMapperPassthroughPass);
m_displayMapperPassthroughPass = nullptr;
}
if (m_displayMapperOnlyGammaCorrectionPass)
{
RemoveChild(m_displayMapperOnlyGammaCorrectionPass);
m_displayMapperOnlyGammaCorrectionPass = nullptr;
}
if (m_ldrGradingLookupTablePass)
{
RemoveChild(m_ldrGradingLookupTablePass);
m_ldrGradingLookupTablePass = nullptr;
}
if (m_outputTransformPass)
{
RemoveChild(m_outputTransformPass);
m_outputTransformPass = nullptr;
}
RemoveChildren();
m_acesOutputTransformPass = nullptr;
m_bakeAcesOutputTransformLutPass = nullptr;
m_acesOutputTransformLutPass = nullptr;
m_displayMapperPassthroughPass = nullptr;
m_displayMapperOnlyGammaCorrectionPass = nullptr;
m_ldrGradingLookupTablePass = nullptr;
m_outputTransformPass = nullptr;
}
} // namespace Render
} // namespace AZ

@ -39,9 +39,9 @@ namespace AZ
{
}
void OutputTransformPass::Init()
void OutputTransformPass::InitializeInternal()
{
DisplayMapperFullScreenPass::Init();
DisplayMapperFullScreenPass::InitializeInternal();
AZ_Assert(m_shaderResourceGroup != nullptr, "OutputTransformPass %s has a null shader resource group when calling Init.", GetPathName().GetCStr());

@ -519,13 +519,13 @@ namespace AZ
io.Fonts->TexID = reinterpret_cast<ImTextureID>(m_fontAtlas.get());
}
void ImGuiPass::OnBuildAttachmentsFinishedInternal()
void ImGuiPass::InitializeInternal()
{
// Set output format and finalize pipeline state
m_pipelineState->SetOutputFromPass(this);
m_pipelineState->Finalize();
Base::OnBuildAttachmentsFinishedInternal();
Base::InitializeInternal();
}
void ImGuiPass::SetupFrameGraphDependencies(RHI::FrameGraphInterface frameGraph)

@ -94,7 +94,7 @@ namespace AZ
explicit ImGuiPass(const RPI::PassDescriptor& descriptor);
// Pass Behaviour Overrides...
void OnBuildAttachmentsFinishedInternal() override;
void InitializeInternal() override;
void FrameBeginInternal(FramePrepareParams params) override;
// Scope producer functions

@ -28,8 +28,6 @@ namespace AZ
LuxCoreTexturePass::LuxCoreTexturePass(const RPI::PassDescriptor& descriptor)
: ParentPass(descriptor)
{
m_flags.m_alreadyCreated = false;
RPI::PassSystemInterface* passSystem = RPI::PassSystemInterface::Get();
// Create render target pass
@ -41,8 +39,6 @@ namespace AZ
// Create readback
m_readback = AZStd::make_shared<AZ::RPI::AttachmentReadback>(AZ::RHI::ScopeId{ Uuid::CreateRandom().ToString<AZStd::string>() });
CreateChildPasses();
}
LuxCoreTexturePass::~LuxCoreTexturePass()
@ -61,9 +57,9 @@ namespace AZ
AddChild(m_renderTargetPass);
}
void LuxCoreTexturePass::BuildAttachmentsInternal()
void LuxCoreTexturePass::BuildInternal()
{
ParentPass::BuildAttachmentsInternal();
ParentPass::BuildInternal();
}
void LuxCoreTexturePass::FrameBeginInternal(FramePrepareParams params)

@ -38,13 +38,13 @@ namespace AZ
m_attachmentSize = image->GetRHIImage()->GetDescriptor().m_size;
m_attachmentFormat = format;
m_shaderResourceGroup->SetImage(m_textureIndex, image);
QueueForBuildAttachments();
QueueForBuildAndInitialization();
}
void RenderTexturePass::BuildAttachmentsInternal()
void RenderTexturePass::BuildInternal()
{
UpdataAttachment();
FullscreenTrianglePass::BuildAttachmentsInternal();
FullscreenTrianglePass::BuildInternal();
}
void RenderTexturePass::FrameBeginInternal(FramePrepareParams params)

@ -44,7 +44,7 @@ namespace AZ
m_skinnedMeshFeatureProcessor = skinnedMeshFeatureProcessor;
}
void MorphTargetComputePass::BuildAttachmentsInternal()
void MorphTargetComputePass::BuildInternal()
{
// The same buffer that skinning writes to is used to manage the computed vertex deltas that are passed from the
// morph target pass to the skinning pass. This simplifies things by only requiring one class to manage the memory

@ -37,7 +37,7 @@ namespace AZ
void SetFeatureProcessor(SkinnedMeshFeatureProcessor* m_skinnedMeshFeatureProcessor);
private:
void BuildAttachmentsInternal() override;
void BuildInternal() override;
void BuildCommandListInternal(const RHI::FrameGraphExecuteContext& context) override;
SkinnedMeshFeatureProcessor* m_skinnedMeshFeatureProcessor = nullptr;

@ -43,14 +43,9 @@ namespace AZ
ReleaseLutImage();
}
void BlendColorGradingLutsPass::FrameBeginInternal(FramePrepareParams params)
void BlendColorGradingLutsPass::InitializeInternal()
{
if (!m_flags.m_initialized)
{
Init();
}
ComputePass::FrameBeginInternal(params);
InitializeShaderVariant();
}
void BlendColorGradingLutsPass::InitializeShaderVariant()
@ -106,12 +101,6 @@ namespace AZ
m_needToUpdateShaderVariant = false;
}
void BlendColorGradingLutsPass::Init()
{
InitializeShaderVariant();
m_flags.m_initialized = true;
}
void BlendColorGradingLutsPass::SetupFrameGraphDependencies(RHI::FrameGraphInterface frameGraph)
{
ComputePass::SetupFrameGraphDependencies(frameGraph);

@ -56,7 +56,7 @@ namespace AZ
explicit BlendColorGradingLutsPass(const RPI::PassDescriptor& descriptor);
// Pass behavior overrides...
void FrameBeginInternal(FramePrepareParams params) override;
void InitializeInternal() override;
// Scope producer functions...
void SetupFrameGraphDependencies(RHI::FrameGraphInterface frameGraph) override;
@ -66,8 +66,6 @@ namespace AZ
void InitializeShaderVariant();
void UpdateCurrentShaderVariant();
void Init();
void AcquireLutImage();
void ReleaseLutImage();

@ -252,10 +252,10 @@ namespace AZ
}
}
void BloomBlurPass::BuildAttachmentsInternal()
void BloomBlurPass::BuildInternal()
{
BuildChildPasses();
ParentPass::BuildAttachmentsInternal();
ParentPass::BuildInternal();
}
void BloomBlurPass::FrameBeginInternal(FramePrepareParams params)

@ -47,7 +47,7 @@ namespace AZ
BloomBlurPass(const RPI::PassDescriptor& descriptor);
// Pass behaviour overrides...
void BuildAttachmentsInternal() override;
void BuildInternal() override;
void FrameBeginInternal(FramePrepareParams params) override;
void GetInputInfo();

@ -56,10 +56,10 @@ namespace AZ
m_passData = *passData;
}
void BloomCompositePass::BuildAttachmentsInternal()
void BloomCompositePass::BuildInternal()
{
BuildChildPasses();
ParentPass::BuildAttachmentsInternal();
ParentPass::BuildInternal();
}
void BloomCompositePass::FrameBeginInternal(FramePrepareParams params)

@ -44,7 +44,7 @@ namespace AZ
BloomCompositePass(const RPI::PassDescriptor& descriptor);
// Pass behaviour overrides...
void BuildAttachmentsInternal() override;
void BuildInternal() override;
void FrameBeginInternal(FramePrepareParams params) override;
void GetAttachmentInfo();

@ -74,10 +74,10 @@ namespace AZ
AddAttachmentBinding(outBinding);
}
ComputePass::BuildAttachmentsInternal();
ComputePass::BuildInternal();
}
void BloomDownsamplePass::BuildAttachmentsInternal()
void BloomDownsamplePass::BuildInternal()
{
BuildOutAttachmentBinding();
}

@ -37,7 +37,7 @@ namespace AZ
BloomDownsamplePass(const RPI::PassDescriptor& descriptor);
// Pass Behaviour Overrides...
void BuildAttachmentsInternal() override;
void BuildInternal() override;
void FrameBeginInternal(FramePrepareParams params) override;
void BuildOutAttachmentBinding();

@ -43,9 +43,9 @@ namespace AZ
{
}
void DepthOfFieldBokehBlurPass::Init()
void DepthOfFieldBokehBlurPass::InitializeInternal()
{
FullscreenTrianglePass::Init();
FullscreenTrianglePass::InitializeInternal();
m_sampleNumberIndex.Reset();
m_radiusMinIndex.Reset();

@ -39,11 +39,11 @@ namespace AZ
protected:
// Behaviour functions override...
void InitializeInternal() override;
void FrameBeginInternal(FramePrepareParams params) override;
private:
DepthOfFieldBokehBlurPass(const RPI::PassDescriptor& descriptor);
void Init() override;
void InitializeShaderVariant();
void UpdateCurrentShaderVariant();

@ -40,9 +40,9 @@ namespace AZ
{
}
void DepthOfFieldCompositePass::Init()
void DepthOfFieldCompositePass::InitializeInternal()
{
FullscreenTrianglePass::Init();
FullscreenTrianglePass::InitializeInternal();
m_backBlendFactorDivision2Index.Reset();
m_backBlendFactorDivision4Index.Reset();

@ -37,11 +37,11 @@ namespace AZ
protected:
// Pass behavior overrides...
void InitializeInternal() override;
void FrameBeginInternal(FramePrepareParams params) override;
private:
DepthOfFieldCompositePass(const RPI::PassDescriptor& descriptor);
void Init() override;
void InitializeShaderVariant();
void UpdateCurrentShaderVariant();

@ -52,7 +52,7 @@ namespace AZ
return depth;
}
void DepthOfFieldCopyFocusDepthToCpuPass::BuildAttachmentsInternal()
void DepthOfFieldCopyFocusDepthToCpuPass::BuildInternal()
{
SetScopeId(RHI::ScopeId(GetPathName()));
}

@ -48,7 +48,7 @@ namespace AZ
void BuildCommandList(const RHI::FrameGraphExecuteContext& context) override;
// Pass overrides
void BuildAttachmentsInternal() override;
void BuildInternal() override;
void FrameBeginInternal(FramePrepareParams params) override;
RPI::Ptr<RPI::Buffer> m_bufferRef;

@ -33,9 +33,9 @@ namespace AZ
{
}
void DepthOfFieldMaskPass::Init()
void DepthOfFieldMaskPass::InitializeInternal()
{
FullscreenTrianglePass::Init();
FullscreenTrianglePass::InitializeInternal();
m_blendFactorIndex.Reset();
m_inputResolutionInverseIndex.Reset();

@ -37,11 +37,11 @@ namespace AZ
protected:
// Pass behavior overrides...
void InitializeInternal() override;
void FrameBeginInternal(FramePrepareParams params) override;
private:
DepthOfFieldMaskPass(const RPI::PassDescriptor& descriptor);
virtual void Init() override;
// SRG binding indices...
RHI::ShaderInputNameIndex m_blendFactorIndex = "m_blendFactor";

@ -34,18 +34,6 @@ namespace AZ
DepthOfFieldReadBackFocusDepthPass::DepthOfFieldReadBackFocusDepthPass(const RPI::PassDescriptor& descriptor)
: ParentPass(descriptor)
{
RPI::PassSystemInterface* passSystem = RPI::PassSystemInterface::Get();
// Create read back pass
m_readbackPass = passSystem->CreatePass<DepthOfFieldCopyFocusDepthToCpuPass>(AZ::Name("DepthOfFieldReadBackPass"));
AZ_Assert(m_readbackPass, "DepthOfFieldReadBackFocusDepthPass : read back pass is invalid");
AddChild(m_readbackPass);
// Find GetDepth pass on template
auto pass = FindChildPass(Name("DepthOfFieldWriteFocusDepthFromGpu"));
m_getDepthPass = static_cast<DepthOfFieldWriteFocusDepthFromGpuPass*>(pass.get());
// Create buffer for read back focus depth. We append static counter to avoid name conflicts.
RPI::CommonBufferDescriptor desc;
desc.m_bufferName = "DepthOfFieldReadBackAutoFocusDepthBuffer";
@ -55,9 +43,6 @@ namespace AZ
desc.m_bufferData = nullptr;
desc.m_elementFormat = RHI::Format::R32_FLOAT;
m_buffer = RPI::BufferSystemInterface::Get()->CreateBufferFromCommonPool(desc);
m_getDepthPass->SetBufferRef(m_buffer);
m_readbackPass->SetBufferRef(m_buffer);
}
DepthOfFieldReadBackFocusDepthPass::~DepthOfFieldReadBackFocusDepthPass()
@ -85,6 +70,24 @@ namespace AZ
}
}
void DepthOfFieldReadBackFocusDepthPass::CreateChildPassesInternal()
{
RPI::PassSystemInterface* passSystem = RPI::PassSystemInterface::Get();
// Create read back pass
m_readbackPass = passSystem->CreatePass<DepthOfFieldCopyFocusDepthToCpuPass>(AZ::Name("DepthOfFieldReadBackPass"));
AZ_Assert(m_readbackPass, "DepthOfFieldReadBackFocusDepthPass : read back pass is invalid");
AddChild(m_readbackPass);
// Find GetDepth pass on template
auto pass = FindChildPass(Name("DepthOfFieldWriteFocusDepthFromGpu"));
m_getDepthPass = static_cast<DepthOfFieldWriteFocusDepthFromGpuPass*>(pass.get());
m_getDepthPass->SetBufferRef(m_buffer);
m_readbackPass->SetBufferRef(m_buffer);
}
void DepthOfFieldReadBackFocusDepthPass::FrameBeginInternal(FramePrepareParams params)
{
RPI::Scene* scene = GetScene();

@ -43,6 +43,7 @@ namespace AZ
protected:
// Pass behavior overrides...
void CreateChildPassesInternal() override;
void FrameBeginInternal(FramePrepareParams params) override;
private:

@ -62,9 +62,9 @@ namespace AZ
m_bufferRef = bufferRef;
}
void DepthOfFieldWriteFocusDepthFromGpuPass::BuildAttachmentsInternal()
void DepthOfFieldWriteFocusDepthFromGpuPass::BuildInternal()
{
AZ_Assert(m_bufferRef != nullptr, "%s has a null buffer when calling BuildAttachmentsInternal.", GetPathName().GetCStr());
AZ_Assert(m_bufferRef != nullptr, "%s has a null buffer when calling BuildInternal.", GetPathName().GetCStr());
AttachBufferToSlot(Name("DofDepthInputOutput"), m_bufferRef);
}

@ -51,7 +51,7 @@ namespace AZ
void CompileResources(const RHI::FrameGraphCompileContext& context) override;
// Pass overrides
void BuildAttachmentsInternal() override;
void BuildInternal() override;
};
} // namespace Render
} // namespace AZ

@ -60,7 +60,7 @@ namespace AZ
m_buffer = RPI::BufferSystemInterface::Get()->CreateBufferFromCommonPool(desc);
}
void EyeAdaptationPass::BuildAttachmentsInternal()
void EyeAdaptationPass::BuildInternal()
{
if (!m_buffer)
{

@ -58,7 +58,7 @@ namespace AZ
float m_exposureValue = 1.0f;
};
void BuildAttachmentsInternal() override;
void BuildInternal() override;
void FrameBeginInternal(FramePrepareParams params) override;

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

Loading…
Cancel
Save