Merge branch 'main' into Atom/guthadam/ATOM-15372

This commit is contained in:
guthadam
2021-04-27 18:45:44 -05:00
58 changed files with 5065 additions and 685 deletions
@@ -16,7 +16,6 @@
#include <AzCore/Serialization/EditContext.h>
#include <AzToolsFramework/Prefab/PrefabPublicInterface.h>
#include <AzToolsFramework/UI/EditorEntityUi/EditorEntityUiInterface.h>
#include <AzToolsFramework/UI/Outliner/EntityOutlinerWidgetInterface.h>
#include <AzToolsFramework/UI/Prefab/PrefabIntegrationBus.h>
namespace AzToolsFramework
@@ -21,9 +21,9 @@
#include <AzToolsFramework/Prefab/Instance/TemplateInstanceMapperInterface.h>
#include <AzToolsFramework/Prefab/PrefabDomUtils.h>
#include <AzToolsFramework/Prefab/PrefabPublicInterface.h>
#include <AzToolsFramework/Prefab/PrefabPublicNotificationBus.h>
#include <AzToolsFramework/Prefab/PrefabSystemComponentInterface.h>
#include <AzToolsFramework/Prefab/Template/Template.h>
#include <AzToolsFramework/UI/Outliner/EntityOutlinerWidgetInterface.h>
namespace AzToolsFramework
{
@@ -90,17 +90,13 @@ namespace AzToolsFramework
if (instanceCountToUpdateInBatch > 0)
{
// Notify Propagation has begun
PrefabPublicNotificationBus::Broadcast(&PrefabPublicNotifications::OnPrefabInstancePropagationBegin);
EntityIdList selectedEntityIds;
ToolsApplicationRequestBus::BroadcastResult(selectedEntityIds, &ToolsApplicationRequests::GetSelectedEntities);
ToolsApplicationRequestBus::Broadcast(&ToolsApplicationRequests::SetSelectedEntities, EntityIdList());
// Disable the Outliner to avoid showing the propagation steps
EntityOutlinerWidgetInterface* entityOutlinerWidgetInterface = AZ::Interface<EntityOutlinerWidgetInterface>::Get();
if (entityOutlinerWidgetInterface)
{
entityOutlinerWidgetInterface->SetUpdatesEnabled(false);
}
for (int i = 0; i < instanceCountToUpdateInBatch; ++i)
{
Instance* instanceToUpdate = m_instancesUpdateQueue.front();
@@ -168,18 +164,8 @@ namespace AzToolsFramework
}
ToolsApplicationRequestBus::Broadcast(&ToolsApplicationRequests::SetSelectedEntities, selectedEntityIds);
// Enable the Outliner
if (entityOutlinerWidgetInterface)
{
entityOutlinerWidgetInterface->SetUpdatesEnabled(true);
auto prefabPublicInterface = AZ::Interface<PrefabPublicInterface>::Get();
if (prefabPublicInterface)
{
AZ::EntityId rootEntityId = prefabPublicInterface->GetLevelInstanceContainerEntityId();
entityOutlinerWidgetInterface->ExpandEntityChildren(rootEntityId);
}
}
// Notify Propagation has ended
PrefabPublicNotificationBus::Broadcast(&PrefabPublicNotifications::OnPrefabInstancePropagationEnd);
}
m_updatingTemplateInstancesInQueue = false;
@@ -0,0 +1,34 @@
/*
* 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 AzToolsFramework
{
namespace Prefab
{
class PrefabPublicNotifications
: public AZ::EBusTraits
{
public:
virtual ~PrefabPublicNotifications() = default;
virtual void OnPrefabInstancePropagationBegin() {}
virtual void OnPrefabInstancePropagationEnd() {}
};
using PrefabPublicNotificationBus = AZ::EBus<PrefabPublicNotifications>;
} // namespace Prefab
} // namespace AzToolsFramework
@@ -286,12 +286,12 @@ namespace AzToolsFramework
ComponentModeFramework::EditorComponentModeNotificationBus::Handler::BusConnect(
GetEntityContextId());
EditorEntityInfoNotificationBus::Handler::BusConnect();
AZ::Interface<EntityOutlinerWidgetInterface>::Register(this);
Prefab::PrefabPublicNotificationBus::Handler::BusConnect();
}
EntityOutlinerWidget::~EntityOutlinerWidget()
{
AZ::Interface<EntityOutlinerWidgetInterface>::Unregister(this);
Prefab::PrefabPublicNotificationBus::Handler::BusDisconnect();
ComponentModeFramework::EditorComponentModeNotificationBus::Handler::BusDisconnect();
EditorEntityInfoNotificationBus::Handler::BusDisconnect();
EditorPickModeNotificationBus::Handler::BusDisconnect();
@@ -1109,25 +1109,18 @@ namespace AzToolsFramework
setEnabled(true);
SetEntityOutlinerState(m_gui, true);
}
void EntityOutlinerWidget::SetUpdatesEnabled(bool enable)
void EntityOutlinerWidget::OnPrefabInstancePropagationBegin()
{
if (enable)
{
QTimer::singleShot(1, this, [this]() {
m_gui->m_objectTree->setUpdatesEnabled(true);
});
}
else
{
m_gui->m_objectTree->setUpdatesEnabled(false);
}
m_gui->m_objectTree->setUpdatesEnabled(false);
}
void EntityOutlinerWidget::ExpandEntityChildren(AZ::EntityId entityId)
void EntityOutlinerWidget::OnPrefabInstancePropagationEnd()
{
QModelIndex index = GetIndexFromEntityId(entityId);
m_gui->m_objectTree->expand(index);
QTimer::singleShot(1, this, [this]() {
m_gui->m_objectTree->setUpdatesEnabled(true);
m_gui->m_objectTree->expand(m_proxyModel->index(0,0));
});
}
void EntityOutlinerWidget::OnEntityInfoUpdatedAddChildEnd(AZ::EntityId /*parentId*/, AZ::EntityId childId)
@@ -20,10 +20,10 @@
#include <AzToolsFramework/ComponentMode/EditorComponentModeBus.h>
#include <AzToolsFramework/Entity/EditorEntityInfoBus.h>
#include <AzToolsFramework/Entity/EditorEntityContextBus.h>
#include <AzToolsFramework/Prefab/PrefabPublicNotificationBus.h>
#include <AzToolsFramework/ToolsMessaging/EntityHighlightBus.h>
#include <AzToolsFramework/UI/Outliner/EntityOutlinerCacheBus.h>
#include <AzToolsFramework/UI/Outliner/EntityOutlinerSearchWidget.h>
#include <AzToolsFramework/UI/Outliner/EntityOutlinerWidgetInterface.h>
#include <AzToolsFramework/UI/SearchWidget/SearchWidgetTypes.hxx>
#include <QIcon>
@@ -62,7 +62,7 @@ namespace AzToolsFramework
, private EditorEntityContextNotificationBus::Handler
, private EditorEntityInfoNotificationBus::Handler
, private ComponentModeFramework::EditorComponentModeNotificationBus::Handler
, private EntityOutlinerWidgetInterface
, private Prefab::PrefabPublicNotificationBus::Handler
{
Q_OBJECT;
public:
@@ -106,9 +106,9 @@ namespace AzToolsFramework
void EnteredComponentMode(const AZStd::vector<AZ::Uuid>& componentModeTypes) override;
void LeftComponentMode(const AZStd::vector<AZ::Uuid>& componentModeTypes) override;
// EntityOutlinerWidgetInterface
void SetUpdatesEnabled(bool enable) override;
void ExpandEntityChildren(AZ::EntityId entityId) override;
// PrefabPublicNotificationBus
void OnPrefabInstancePropagationBegin() override;
void OnPrefabInstancePropagationEnd() override;
// Build a selection object from the given entities. Entities already in the Widget's selection buffers are ignored.
template <class EntityIdCollection>
@@ -652,6 +652,7 @@ set(FILES
Prefab/PrefabPublicHandler.h
Prefab/PrefabPublicHandler.cpp
Prefab/PrefabPublicInterface.h
Prefab/PrefabPublicNotificationBus.h
Prefab/PrefabUndo.h
Prefab/PrefabUndo.cpp
Prefab/PrefabUndoCache.cpp
@@ -687,7 +688,6 @@ set(FILES
UI/Outliner/EntityOutlinerDisplayOptionsMenu.cpp
UI/Outliner/EntityOutlinerTreeView.hxx
UI/Outliner/EntityOutlinerTreeView.cpp
UI/Outliner/EntityOutlinerWidgetInterface.h
UI/Outliner/EntityOutlinerWidget.hxx
UI/Outliner/EntityOutlinerWidget.cpp
UI/Outliner/EntityOutlinerCacheBus.h
-11
View File
@@ -33,7 +33,6 @@
#include "Util/CryMemFile.h"
#include "Objects/ObjectManager.h"
#include "Objects/ObjectPhysicsManager.h"
#include "Objects/EntityObject.h"
#include "LensFlareEditor/LensFlareManager.h"
#include "LensFlareEditor/LensFlareLibrary.h"
@@ -192,14 +191,6 @@ bool CGameExporter::Export(unsigned int flags, [[maybe_unused]] EEndian eExportE
}
}
////////////////////////////////////////////////////////////////////////
// Inform all objects that an export is about to begin
////////////////////////////////////////////////////////////////////////
if (exportSuccessful)
{
GetIEditor()->GetObjectManager()->GetPhysicsManager()->PrepareForExport();
}
////////////////////////////////////////////////////////////////////////
// Export all data to the game
////////////////////////////////////////////////////////////////////////
@@ -519,8 +510,6 @@ void CGameExporter::ExportMapInfo(XmlNodeRef& node)
CXmlArchive xmlAr;
xmlAr.bLoading = false;
xmlAr.root = node;
GetIEditor()->GetObjectManager()->GetPhysicsManager()->SerializeCollisionClasses(xmlAr);
}
//////////////////////////////////////////////////////////////////////////
@@ -24,7 +24,6 @@ class CUsedResources;
class CSelectionGroup;
class CObjectClassDesc;
class CObjectArchive;
class CObjectPhysicsManager;
class CViewport;
struct HitContext;
enum class ImageRotationDegrees;
@@ -247,10 +246,6 @@ public:
virtual IGizmoManager* GetGizmoManager() = 0;
//////////////////////////////////////////////////////////////////////////
//! Get acess to object physics manager
virtual CObjectPhysicsManager* GetPhysicsManager() = 0;
//////////////////////////////////////////////////////////////////////////
//! Invalidate visibily settings of objects.
virtual void InvalidateVisibleList() = 0;
@@ -25,7 +25,6 @@
#include "Viewport.h"
#include "GizmoManager.h"
#include "AxisGizmo.h"
#include "ObjectPhysicsManager.h"
#include "GameEngine.h"
#include "WaitProgress.h"
#include "Util/Image.h"
@@ -109,7 +108,6 @@ CObjectManager::CObjectManager()
, m_pLoadProgress(nullptr)
, m_loadedObjects(0)
, m_totalObjectsToLoad(0)
, m_pPhysicsManager(new CObjectPhysicsManager())
, m_bExiting(false)
, m_isUpdateVisibilityList(false)
, m_currentHideCount(CBaseObject::s_invalidHiddenID)
@@ -138,7 +136,6 @@ CObjectManager::~CObjectManager()
DeleteAllObjects();
delete m_gizmoManager;
delete m_pPhysicsManager;
}
//////////////////////////////////////////////////////////////////////////
@@ -841,8 +838,6 @@ void CObjectManager::Update()
{
prevActiveWindow->setFocus();
}
m_pPhysicsManager->Update();
}
//////////////////////////////////////////////////////////////////////////
@@ -334,9 +334,6 @@ public:
virtual void FindAndRenameProperty2(const char* property2Name, const QString& oldValue, const QString& newValue);
virtual void FindAndRenameProperty2If(const char* property2Name, const QString& oldValue, const QString& newValue, const char* otherProperty2Name, const QString& otherValue);
class CObjectPhysicsManager* GetPhysicsManager()
{ return m_pPhysicsManager; }
bool IsReloading() const { return m_bInReloading; }
void SetSkipUpdate(bool bSkipUpdate) override { m_bSkipObjectUpdate = bSkipUpdate; }
@@ -433,8 +430,6 @@ private:
int m_totalObjectsToLoad;
//////////////////////////////////////////////////////////////////////////
class CObjectPhysicsManager* m_pPhysicsManager;
//////////////////////////////////////////////////////////////////////////
// Numbering for names.
//////////////////////////////////////////////////////////////////////////
@@ -1,191 +0,0 @@
/*
* 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.
*
*/
// Original file Copyright Crytek GMBH or its affiliates, used under license.
#include "EditorDefs.h"
#include "ObjectPhysicsManager.h"
// Editor
#include "GameEngine.h"
#include "Commands/CommandManager.h"
#include "Objects/SelectionGroup.h"
#include "Include/IObjectManager.h"
#include "CryPhysicsDeprecation.h"
#define MAX_OBJECTS_PHYS_SIMULATION_TIME (5)
//////////////////////////////////////////////////////////////////////////
CObjectPhysicsManager::CObjectPhysicsManager()
{
CommandManagerHelper::RegisterCommand(GetIEditor()->GetCommandManager(),
"physics", "simulate_objects", "", "",
AZStd::bind(&CObjectPhysicsManager::Command_SimulateObjects, this));
CommandManagerHelper::RegisterCommand(GetIEditor()->GetCommandManager(),
"physics", "reset_objects_state", "", "",
AZStd::bind(&CObjectPhysicsManager::Command_ResetPhysicsState, this));
CommandManagerHelper::RegisterCommand(GetIEditor()->GetCommandManager(),
"physics", "get_objects_state", "", "",
AZStd::bind(&CObjectPhysicsManager::Command_GetPhysicsState, this));
m_fStartObjectSimulationTime = 0;
m_bSimulatingObjects = false;
m_wasSimObjects = 0;
}
//////////////////////////////////////////////////////////////////////////
CObjectPhysicsManager::~CObjectPhysicsManager()
{
}
//////////////////////////////////////////////////////////////////////////
void CObjectPhysicsManager::Command_SimulateObjects()
{
SimulateSelectedObjectsPositions();
}
/////////////////////////////////////////////////////////////////////////
void CObjectPhysicsManager::Command_ResetPhysicsState()
{
CSelectionGroup* pSelection = GetIEditor()->GetSelection();
for (int i = 0; i < pSelection->GetCount(); i++)
{
pSelection->GetObject(i)->OnEvent(EVENT_PHYSICS_RESETSTATE);
}
}
/////////////////////////////////////////////////////////////////////////
void CObjectPhysicsManager::Command_GetPhysicsState()
{
CSelectionGroup* pSelection = GetIEditor()->GetSelection();
for (int i = 0; i < pSelection->GetCount(); i++)
{
pSelection->GetObject(i)->OnEvent(EVENT_PHYSICS_GETSTATE);
}
}
//////////////////////////////////////////////////////////////////////////
void CObjectPhysicsManager::Update()
{
if (m_bSimulatingObjects)
{
UpdateSimulatingObjects();
}
}
//////////////////////////////////////////////////////////////////////////
void CObjectPhysicsManager::SimulateSelectedObjectsPositions()
{
CSelectionGroup* pSel = GetIEditor()->GetObjectManager()->GetSelection();
if (pSel->IsEmpty())
{
return;
}
if (GetIEditor()->GetGameEngine()->GetSimulationMode())
{
return;
}
GetIEditor()->GetGameEngine()->SetSimulationMode(true, true);
m_simObjects.clear();
CRY_PHYSICS_REPLACEMENT_ASSERT();
m_wasSimObjects = m_simObjects.size();
m_fStartObjectSimulationTime = GetISystem()->GetITimer()->GetAsyncCurTime();
m_bSimulatingObjects = true;
}
//////////////////////////////////////////////////////////////////////////
void CObjectPhysicsManager::UpdateSimulatingObjects()
{
{
CUndo undo("Simulate");
CRY_PHYSICS_REPLACEMENT_ASSERT();
}
float curTime = GetISystem()->GetITimer()->GetAsyncCurTime();
float runningTime = (curTime - m_fStartObjectSimulationTime);
if (m_simObjects.empty() || (runningTime > MAX_OBJECTS_PHYS_SIMULATION_TIME))
{
m_fStartObjectSimulationTime = 0;
m_bSimulatingObjects = false;
GetIEditor()->GetGameEngine()->SetSimulationMode(false, true);
}
}
//////////////////////////////////////////////////////////////////////////
void CObjectPhysicsManager::PrepareForExport()
{
// Clear the collision class set, ready for objects to register
// their collision classes
m_collisionClasses.clear();
m_collisionClassExportId = 0;
// First collision-class IS always the default one
RegisterCollisionClass(SCollisionClass(0, 0));
}
//////////////////////////////////////////////////////////////////////////
bool operator == (const SCollisionClass& lhs, const SCollisionClass& rhs)
{
return lhs.type == rhs.type && lhs.ignore == rhs.ignore;
}
//////////////////////////////////////////////////////////////////////////
int CObjectPhysicsManager::RegisterCollisionClass(const SCollisionClass& collclass)
{
TCollisionClassVector::iterator it = std::find(m_collisionClasses.begin(), m_collisionClasses.end(), collclass);
if (it == m_collisionClasses.end())
{
m_collisionClasses.push_back(collclass);
return m_collisionClasses.size() - 1;
}
return it - m_collisionClasses.begin();
}
//////////////////////////////////////////////////////////////////////////
int CObjectPhysicsManager::GetCollisionClassId(const SCollisionClass& collclass)
{
TCollisionClassVector::iterator it = std::find(m_collisionClasses.begin(), m_collisionClasses.end(), collclass);
if (it == m_collisionClasses.end())
{
return 0;
}
return it - m_collisionClasses.begin();
}
//////////////////////////////////////////////////////////////////////////
void CObjectPhysicsManager::SerializeCollisionClasses(CXmlArchive& xmlAr)
{
if (!xmlAr.bLoading)
{
// Storing
CLogFile::WriteLine("Storing Collision Classes ...");
XmlNodeRef root = xmlAr.root->newChild("CollisionClasses");
int count = m_collisionClasses.size();
for (int i = 0; i < count; i++)
{
SCollisionClass& cc = m_collisionClasses[i];
XmlNodeRef xmlCC = root->newChild("CollisionClass");
xmlCC->setAttr("type", cc.type);
xmlCC->setAttr("ignore", cc.ignore);
}
}
}
@@ -1,56 +0,0 @@
/*
* 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.
*
*/
// Original file Copyright Crytek GMBH or its affiliates, used under license.
#ifndef CRYINCLUDE_EDITOR_OBJECTS_OBJECTPHYSICSMANAGER_H
#define CRYINCLUDE_EDITOR_OBJECTS_OBJECTPHYSICSMANAGER_H
#pragma once
//////////////////////////////////////////////////////////////////////////
class CObjectPhysicsManager
{
public:
CObjectPhysicsManager();
~CObjectPhysicsManager();
void SimulateSelectedObjectsPositions();
void Update();
//////////////////////////////////////////////////////////////////////////
/// Collision Classes
//////////////////////////////////////////////////////////////////////////
int RegisterCollisionClass(const SCollisionClass& collclass);
int GetCollisionClassId(const SCollisionClass& collclass);
void SerializeCollisionClasses(CXmlArchive& xmlAr);
void PrepareForExport();
private:
void Command_SimulateObjects();
void Command_GetPhysicsState();
void Command_ResetPhysicsState();
void UpdateSimulatingObjects();
bool m_bSimulatingObjects;
float m_fStartObjectSimulationTime;
int m_wasSimObjects;
std::vector<_smart_ptr<CBaseObject> > m_simObjects;
typedef std::vector<SCollisionClass> TCollisionClassVector;
int m_collisionClassExportId;
TCollisionClassVector m_collisionClasses;
};
#endif // CRYINCLUDE_EDITOR_OBJECTS_OBJECTPHYSICSMANAGER_H
@@ -638,8 +638,6 @@ set(FILES
Objects/ObjectManager.h
Objects/ObjectManagerLegacyUndo.cpp
Objects/ObjectManagerLegacyUndo.h
Objects/ObjectPhysicsManager.cpp
Objects/ObjectPhysicsManager.h
Objects/DisplayContext.cpp
Objects/DisplayContext.h
Objects/EntityObject.cpp
@@ -34,6 +34,7 @@ namespace AZ
constexpr uint32_t StreamCountMax = 12;
constexpr uint32_t StreamChannelCountMax = 16;
constexpr uint32_t DrawListTagCountMax = 64;
constexpr uint32_t DrawFilterTagCountMax = 32;
constexpr uint32_t MultiSampleCustomLocationsCountMax = 16;
constexpr uint32_t MultiSampleCustomLocationGridSize = 16;
constexpr uint32_t SubpassCountMax = 10;
@@ -9,22 +9,15 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
#include <AzCore/Interface/Interface.h>
#include <AzCore/Serialization/SerializeContext.h>
#include <Atom/RHI/DrawItem.h>
#include <Atom/RHI/TagRegistry.h>
namespace AzToolsFramework
namespace AZ
{
class EntityOutlinerWidgetInterface
namespace RHI
{
public:
AZ_RTTI(EntityOutlinerWidgetInterface, "{30C0F252-EC84-4196-BF59-EB9E73B8ADCB}");
virtual void SetUpdatesEnabled(bool enable) = 0;
virtual void ExpandEntityChildren(AZ::EntityId entityId) = 0;
};
} // namespace AzToolsFramework
using DrawFilterTagRegistry = TagRegistry<DrawFilterTag, Limits::Pipeline::DrawFilterTagCountMax>;
}
}
+27 -9
View File
@@ -11,6 +11,7 @@
*/
#pragma once
#include <Atom/RHI.Reflect/Handle.h>
#include <Atom/RHI.Reflect/Limits.h>
#include <Atom/RHI/StreamBufferView.h>
#include <Atom/RHI/IndexBufferView.h>
@@ -152,36 +153,53 @@ namespace AZ
};
using DrawItemSortKey = int64_t;
struct DrawItemKeyPair
// A filter associate to a DrawItem which can be used to filter the DrawItem when submitting to command list
using DrawFilterTag = Handle<uint8_t>;
using DrawFilterMask = uint32_t; // AZStd::bitset's impelmentation is too expensive.
constexpr uint32_t DrawFilterMaskDefaultValue = uint32_t(-1); // Default all bit to 1.
static_assert(sizeof(DrawFilterMask) * 8 >= Limits::Pipeline::DrawFilterTagCountMax, "DrawFilterMask doesn't have enough bits for maximum tag count");
struct DrawItemProperties
{
DrawItemKeyPair() = default;
DrawItemProperties() = default;
DrawItemKeyPair(const DrawItem* item, DrawItemSortKey sortKey)
DrawItemProperties(const DrawItem* item, DrawItemSortKey sortKey = 0, DrawFilterMask filterMask = DrawFilterMaskDefaultValue)
: m_item{item}
, m_sortKey{sortKey}
{}
, m_drawFilterMask{filterMask}
{
}
bool operator == (const DrawItemKeyPair& rhs) const
bool operator==(const DrawItemProperties& rhs) const
{
return m_item == rhs.m_item &&
m_sortKey == rhs.m_sortKey &&
m_depth == rhs.m_depth;
m_depth == rhs.m_depth &&
m_drawFilterMask == rhs.m_drawFilterMask
;
}
bool operator != (const DrawItemKeyPair& rhs) const
bool operator!=(const DrawItemProperties& rhs) const
{
return !(*this == rhs);
}
bool operator < (const DrawItemKeyPair& rhs) const
bool operator<(const DrawItemProperties& rhs) const
{
return m_sortKey < rhs.m_sortKey;
}
//! A pointer to the draw item
const DrawItem* m_item = nullptr;
//! A sorting key of this draw item which is used for sorting draw items in DrawList
// Check RHI::SortDrawList() function for detail
DrawItemSortKey m_sortKey = 0;
//! A depth value this draw item which is used for sorting draw items in DrawList
//! Check RHI::SortDrawList() function for detail
float m_depth = 0.0f;
//! A filter mask which helps decide whether to submit this draw item to a Scope's command list or not
DrawFilterMask m_drawFilterMask = DrawFilterMaskDefaultValue;
};
}
@@ -39,8 +39,8 @@ namespace AZ
using DrawListTag = Handle<uint8_t>;
using DrawListMask = AZStd::bitset<RHI::Limits::Pipeline::DrawListTagCountMax>;
using DrawList = AZStd::vector<RHI::DrawItemKeyPair>;
using DrawListView = AZStd::array_view<RHI::DrawItemKeyPair>;
using DrawList = AZStd::vector<RHI::DrawItemProperties>;
using DrawListView = AZStd::array_view<RHI::DrawItemProperties>;
/// Contains a table of draw lists, indexed by the tag.
using DrawListsByTag = AZStd::array<DrawList, RHI::Limits::Pipeline::DrawListTagCountMax>;
@@ -53,7 +53,7 @@ namespace AZ
/// Adds an individual draw item to the draw list associated with the provided tag. This will
/// no-op if the tag is not present in the internal draw list mask.
void AddDrawItem(DrawListTag drawListTag, DrawItemKeyPair drawItemKeyPair);
void AddDrawItem(DrawListTag drawListTag, DrawItemProperties drawItemProperties);
/// Coalesces the draw lists in preparation for access via GetList. This should
/// be called from a single thread as a sync point between the append / consume phases.
@@ -12,83 +12,12 @@
#pragma once
#include <Atom/RHI/DrawList.h>
#include <AzCore/Name/Name.h>
#include <AzCore/std/smart_ptr/intrusive_base.h>
#include <AzCore/std/parallel/shared_mutex.h>
#include <Atom/RHI/TagRegistry.h>
namespace AZ
{
namespace RHI
{
/**
* Allocates and registers draw list tags by name, allowing the user to acquire and find tags from names.
* The class is designed to map user-friendly tag names defined through content or higher level code to
* low-level tags, which are simple handles.
*
* Some notes about usage and design:
* - DrawListTag values represent indexes into a bitmask, which allows for fast comparison when filtering
* draw items into draw lists (see View::HasDrawListTag()).
* - Tags are reference counted, which means multiple calls to 'Acquire' with the same name will increment
* the internal reference count on the tag. This allows shared ownership between systems, if necessary.
* - FindTag is provided to search for a tag reference without taking ownership.
* - Names are case sensitive.
*/
class DrawListTagRegistry final
: public AZStd::intrusive_base
{
public:
AZ_CLASS_ALLOCATOR(DrawListTagRegistry, AZ::SystemAllocator, 0);
AZ_DISABLE_COPY_MOVE(DrawListTagRegistry);
static Ptr<DrawListTagRegistry> Create();
/**
* Resets the registry back to an empty state. All references are released.
*/
void Reset();
/**
* Acquires a draw list tag from the provided name (case sensitive). If the tag already existed, it is ref-counted.
* Returns a valid tag on success; returns a null tag if the registry is at full capacity. You must
* call ReleaseTag() if successful.
*/
DrawListTag AcquireTag(const Name& drawListName);
/**
* Releases a reference to a tag. Tags are ref-counted, so it's necessary to maintain ownership of the
* tag and release when its no longer needed.
*/
void ReleaseTag(DrawListTag drawListTag);
/**
* Finds the tag associated with the provided name (case sensitive). If a tag exists with that name, the tag
* is returned. The reference count is NOT incremented on success; ownership is not passed to the user. If
* the tag does not exist, a null tag is returned.
*/
DrawListTag FindTag(const Name& drawListName) const;
/**
* Returns the name of the given DrawListTag, or empty string if the tag is not registered.
*/
Name GetName(DrawListTag tag) const;
/**
* Returns the number of allocated tags in the registry.
*/
size_t GetAllocatedTagCount() const;
private:
DrawListTagRegistry() = default;
struct Entry
{
Name m_name;
size_t m_refCount = 0;
};
mutable AZStd::shared_mutex m_mutex;
AZStd::array<Entry, Limits::Pipeline::DrawListTagCountMax> m_entriesByTag;
size_t m_allocatedTagCount = 0;
};
using DrawListTagRegistry = TagRegistry<DrawListTag, Limits::Pipeline::DrawListTagCountMax>;
}
}
@@ -21,45 +21,48 @@ namespace AZ
namespace RHI
{
/**
* DrawPacket is a packed data structure (one contiguous allocation) containing a collection of
* DrawItems and their associated array data. Each draw item in the packet is associated
* with a DrawListTag. All draw items in the packet share the same set of shader resource
* groups, index buffer, and draw arguments.
*
* Some notes about design and usage:
* - Draw packets should be used to 'broadcast' variations of the same 'object' to multiple passes.
* For example: 'Shadow', 'Depth', 'Forward'.
*
* - Draw packets can be re-used between different views, scenes, or passes. The embedded shader resource groups
* should represent only the local data necessary to describe the 'object', not the full context including
* scene / view / pass specific state. They serve as a 'template'.
*
* - The packet is self-contained and does not reference external memory. Use DrawPacketBuilder to construct
* an instance and either store in an RHI::Ptr or call 'delete' to release.
*/
//!
//! DrawPacket is a packed data structure (one contiguous allocation) containing a collection of
//! DrawItems and their associated array data. Each draw item in the packet is associated
//! with a DrawListTag. All draw items in the packet share the same set of shader resource
//! groups, index buffer, one DrawFilterMask, and draw arguments.
//!
//! Some notes about design and usage:
//! - Draw packets should be used to 'broadcast' variations of the same 'object' to multiple passes.
//! For example: 'Shadow', 'Depth', 'Forward'.
//!
//! - Draw packets can be re-used between different views, scenes, or passes. The embedded shader resource groups
//! should represent only the local data necessary to describe the 'object', not the full context including
//! scene / view / pass specific state. They serve as a 'template'.
//!
//! - The packet is self-contained and does not reference external memory. Use DrawPacketBuilder to construct
//! an instance and either store in an RHI::Ptr or call 'delete' to release.
//!
class DrawPacket final : public AZStd::intrusive_base
{
friend class DrawPacketBuilder;
public:
using DrawItemVisitor = AZStd::function<void(DrawListTag, DrawItemKeyPair)>;
using DrawItemVisitor = AZStd::function<void(DrawListTag, DrawItemProperties)>;
/// Draw packets cannot be move constructed or copied, as they contain an additional memory payload.
//! Draw packets cannot be move constructed or copied, as they contain an additional memory payload.
AZ_DISABLE_COPY_MOVE(DrawPacket);
/// Returns the mask representing all the draw lists affected by the packet.
//! Returns the mask representing all the draw lists affected by the packet.
DrawListMask GetDrawListMask() const;
/// Returns the number of draw items stored in the packet.
//! Returns the number of draw items stored in the packet.
size_t GetDrawItemCount() const;
/// Returns the draw item / sort key associated with the provided index.
DrawItemKeyPair GetDrawItem(size_t index) const;
//! Returns the draw item and its properties associated with the provided index.
DrawItemProperties GetDrawItem(size_t index) const;
/// Returns the draw list tag associated with the provided index.
//! Returns the draw list tag associated with the provided index.
DrawListTag GetDrawListTag(size_t index) const;
/// Overloaded operator delete for freeing a draw packet.
//! Returns the draw filter mask which applied to all the draw items.
DrawFilterMask GetDrawFilterMask() const;
//! Overloaded operator delete for freeing a draw packet.
void operator delete(void* p, size_t size);
private:
@@ -72,6 +75,9 @@ namespace AZ
// The bit-mask of all active filter tags.
DrawListMask m_drawListMask = 0;
// The draw filter applies to each draw item
DrawFilterMask m_drawFilterMask = DrawFilterMaskDefaultValue;
// The index buffer view used when the draw call is indexed.
IndexBufferView m_indexBufferView;
@@ -29,23 +29,26 @@ namespace AZ
{
DrawRequest() = default;
/// The filter tag used to direct the draw item.
//! The filter tag used to direct the draw item.
DrawListTag m_listTag;
/// The stencil ref value used for this draw item.
//! The stencil ref value used for this draw item.
uint8_t m_stencilRef = 0;
/// The array of stream buffers to bind for this draw item.
//! The array of stream buffers to bind for this draw item.
AZStd::array_view<StreamBufferView> m_streamBufferViews;
/// Shader resource group unique for this draw request
//! Shader resource group unique for this draw request
const ShaderResourceGroup* m_uniqueShaderResourceGroup = nullptr;
/// The pipeline state assigned to this draw item.
//! The pipeline state assigned to this draw item.
const PipelineState* m_pipelineState = nullptr;
/// The sort key assigned to this draw item.
//! The sort key assigned to this draw item.
DrawItemSortKey m_sortKey = 0;
//! The filter associated to this draw item.
DrawFilterMask m_drawFilterMask = DrawFilterMaskDefaultValue;
};
// NOTE: This is configurable; just used to control the amount of memory held by the builder.
@@ -69,6 +72,8 @@ namespace AZ
void AddShaderResourceGroup(const ShaderResourceGroup* shaderResourceGroup);
void SetDrawFilterMask(DrawFilterMask filterMask);
void AddDrawItem(const DrawRequest& request);
const DrawPacket* End();
@@ -79,6 +84,7 @@ namespace AZ
IAllocatorAllocate* m_allocator = nullptr;
DrawArguments m_drawArguments;
DrawListMask m_drawListMask = 0;
DrawFilterMask m_drawFilterMask = DrawFilterMaskDefaultValue;
size_t m_streamBufferViewCount = 0;
IndexBufferView m_indexBufferView;
AZStd::fixed_vector<DrawRequest, DrawItemCountMax> m_drawRequests;
@@ -15,13 +15,13 @@
#include <AzCore/Name/Name.h>
#include <AzCore/EBus/EBus.h>
#include <Atom/RHI.Reflect/FrameSchedulerEnums.h>
#include <Atom/RHI/DrawListTagRegistry.h>
namespace AZ
{
namespace RHI
{
class Device;
class DrawListTagRegistry;
class FrameGraphBuilder;
class PipelineState;
class PipelineStateCache;
@@ -0,0 +1,188 @@
/*
* 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/Name/Name.h>
#include <AzCore/std/smart_ptr/intrusive_base.h>
#include <AzCore/std/parallel/shared_mutex.h>
namespace AZ
{
namespace RHI
{
//!
//! Allocates and registers tags by name, allowing the user to acquire and find tags from names.
//! The class is designed to map user-friendly tag names defined through content or higher level code to
//! low-level tags, which are simple handles.
//!
//! Some notes about usage and design:
//! - TagType need to be a Handle<Integer> type.
//! - Tags are reference counted, which means multiple calls to 'Acquire' with the same name will increment
//! the internal reference count on the tag. This allows shared ownership between systems, if necessary.
//! - FindTag is provided to search for a tag reference without taking ownership.
//! - Names are case sensitive.
//!
template<typename TagType, size_t MaxTagCount>
class TagRegistry final
: public AZStd::intrusive_base
{
public:
AZ_CLASS_ALLOCATOR(TagRegistry, AZ::SystemAllocator, 0);
AZ_DISABLE_COPY_MOVE(TagRegistry);
static Ptr<TagRegistry> Create();
//! Resets the registry back to an empty state. All references are released.
void Reset();
//! Acquires a tag from the provided name (case sensitive). If the tag already existed, it is ref-counted.
//! Returns a valid tag on success; returns a null tag if the registry is at full capacity. You must
//! call ReleaseTag() if successful.
TagType AcquireTag(const Name& tagName);
//! Releases a reference to a tag. Tags are ref-counted, so it's necessary to maintain ownership of the
//! tag and release when its no longer needed.
void ReleaseTag(TagType tagName);
//! Finds the tag associated with the provided name (case sensitive). If a tag exists with that name, the tag
//! is returned. The reference count is NOT incremented on success; ownership is not passed to the user. If
//! the tag does not exist, a null tag is returned.
TagType FindTag(const Name& tagName) const;
//! Returns the name of the given tag, or empty string if the tag is not registered.
Name GetName(TagType tag) const;
//! Returns the number of allocated tags in the registry.
size_t GetAllocatedTagCount() const;
private:
TagRegistry() = default;
struct Entry
{
Name m_name;
size_t m_refCount = 0;
};
mutable AZStd::shared_mutex m_mutex;
AZStd::array<Entry, MaxTagCount> m_entriesByTag;
size_t m_allocatedTagCount = 0;
};
template<typename TagType, size_t MaxTagCount>
Ptr<TagRegistry<TagType, MaxTagCount>> TagRegistry<TagType, MaxTagCount>::Create()
{
return aznew TagRegistry<TagType, MaxTagCount>();
}
template<typename TagType, size_t MaxTagCount>
void TagRegistry<TagType, MaxTagCount>::Reset()
{
AZStd::unique_lock<AZStd::shared_mutex> lock(m_mutex);
m_entriesByTag.fill({});
m_allocatedTagCount = 0;
}
template<typename TagType, size_t MaxTagCount>
TagType TagRegistry<TagType, MaxTagCount>::AcquireTag(const Name& tagName)
{
if (tagName.IsEmpty())
{
return {};
}
TagType tag;
Entry* foundEmptyEntry = nullptr;
AZStd::unique_lock<AZStd::shared_mutex> lock(m_mutex);
for (size_t i = 0; i < m_entriesByTag.size(); ++i)
{
Entry& entry = m_entriesByTag[i];
// Found an empty entry. Cache off the tag and pointer, but keep searching to find if
// another entry holds the same name.
if (entry.m_refCount == 0 && !foundEmptyEntry)
{
foundEmptyEntry = &entry;
tag = TagType(i);
}
else if (entry.m_name == tagName)
{
entry.m_refCount++;
return TagType(i);
}
}
// No other entry holds the name, so allocate the empty entry.
if (foundEmptyEntry)
{
foundEmptyEntry->m_refCount = 1;
foundEmptyEntry->m_name = tagName;
++m_allocatedTagCount;
}
return tag;
}
template<typename TagType, size_t MaxTagCount>
void TagRegistry<TagType, MaxTagCount>::ReleaseTag(TagType tag)
{
if (tag.IsValid())
{
AZStd::unique_lock<AZStd::shared_mutex> lock(m_mutex);
Entry& entry = m_entriesByTag[tag.GetIndex()];
const size_t refCount = --entry.m_refCount;
AZ_Assert(
refCount != static_cast<size_t>(-1), "Attempted to forfeit a tag that is not valid. Tag{%d},Name{'%s'}", tag,
entry.m_name.GetCStr());
if (refCount == 0)
{
entry.m_name = Name();
--m_allocatedTagCount;
}
}
}
template<typename TagType, size_t MaxTagCount>
TagType TagRegistry<TagType, MaxTagCount>::FindTag(const Name& tagName) const
{
AZStd::shared_lock<AZStd::shared_mutex> lock(m_mutex);
for (size_t i = 0; i < m_entriesByTag.size(); ++i)
{
if (m_entriesByTag[i].m_name == tagName)
{
return TagType(i);
}
}
return {};
}
template<typename TagType, size_t MaxTagCount>
Name TagRegistry<TagType, MaxTagCount>::GetName(TagType tag) const
{
if (tag.GetIndex() < m_entriesByTag.size())
{
return m_entriesByTag[tag.GetIndex()].m_name;
}
else
{
return Name();
}
}
template<typename TagType, size_t MaxTagCount>
size_t TagRegistry<TagType, MaxTagCount>::GetAllocatedTagCount() const
{
return m_allocatedTagCount;
}
}
}
+4 -8
View File
@@ -35,8 +35,7 @@ namespace AZ
switch (sortType)
{
case DrawListSortType::KeyThenDepth:
AZStd::sort(drawList.begin(), drawList.end(),
[](const DrawItemKeyPair& a, const DrawItemKeyPair& b)
AZStd::sort(drawList.begin(), drawList.end(), [](const DrawItemProperties& a, const DrawItemProperties& b)
{
if (a.m_sortKey != b.m_sortKey)
{
@@ -48,8 +47,7 @@ namespace AZ
break;
case DrawListSortType::KeyThenReverseDepth:
AZStd::sort(drawList.begin(), drawList.end(),
[](const DrawItemKeyPair& a, const DrawItemKeyPair& b)
AZStd::sort(drawList.begin(), drawList.end(), [](const DrawItemProperties& a, const DrawItemProperties& b)
{
if (a.m_sortKey != b.m_sortKey)
{
@@ -61,8 +59,7 @@ namespace AZ
break;
case DrawListSortType::DepthThenKey:
AZStd::sort(drawList.begin(), drawList.end(),
[](const DrawItemKeyPair& a, const DrawItemKeyPair& b)
AZStd::sort(drawList.begin(), drawList.end(), [](const DrawItemProperties& a, const DrawItemProperties& b)
{
if (a.m_depth != b.m_depth)
{
@@ -74,8 +71,7 @@ namespace AZ
break;
case DrawListSortType::ReverseDepthThenKey:
AZStd::sort(drawList.begin(), drawList.end(),
[](const DrawItemKeyPair& a, const DrawItemKeyPair& b)
AZStd::sort(drawList.begin(), drawList.end(), [](const DrawItemProperties& a, const DrawItemProperties& b)
{
if (a.m_depth != b.m_depth)
{
@@ -63,14 +63,14 @@ namespace AZ
if (m_drawListMask[drawListTag.GetIndex()])
{
DrawItemKeyPair drawItem = drawPacket->GetDrawItem(i);
DrawItemProperties drawItem = drawPacket->GetDrawItem(i);
drawItem.m_depth = depth;
threadListsByTag[drawListTag.GetIndex()].push_back(drawItem);
}
}
}
void DrawListContext::AddDrawItem(DrawListTag drawListTag, DrawItemKeyPair drawItemKeyPair)
void DrawListContext::AddDrawItem(DrawListTag drawListTag, DrawItemProperties drawItemProperties)
{
if (Validation::IsEnabled())
{
@@ -84,7 +84,7 @@ namespace AZ
if (m_drawListMask[drawListTag.GetIndex()])
{
DrawListsByTag& drawListsByTag = m_threadListsByTag.GetStorage();
drawListsByTag[drawListTag.GetIndex()].push_back(drawItemKeyPair);
drawListsByTag[drawListTag.GetIndex()].push_back(drawItemProperties);
}
}
@@ -1,117 +0,0 @@
/*
* 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 <Atom/RHI/DrawListTagRegistry.h>
namespace AZ
{
namespace RHI
{
Ptr<DrawListTagRegistry> DrawListTagRegistry::Create()
{
return aznew DrawListTagRegistry;
}
void DrawListTagRegistry::Reset()
{
AZStd::unique_lock<AZStd::shared_mutex> lock(m_mutex);
m_entriesByTag.fill({});
m_allocatedTagCount = 0;
}
DrawListTag DrawListTagRegistry::AcquireTag(const Name& drawListName)
{
if (drawListName.IsEmpty())
{
return {};
}
DrawListTag drawListTag;
Entry* foundEmptyEntry = nullptr;
AZStd::unique_lock<AZStd::shared_mutex> lock(m_mutex);
for (size_t i = 0; i < m_entriesByTag.size(); ++i)
{
Entry& entry = m_entriesByTag[i];
// Found an empty entry. Cache off the tag and pointer, but keep searching to find if
// another entry holds the same name.
if (entry.m_refCount == 0 && !foundEmptyEntry)
{
foundEmptyEntry = &entry;
drawListTag = DrawListTag(i);
}
else if (entry.m_name == drawListName)
{
entry.m_refCount++;
return DrawListTag(i);
}
}
// No other entry holds the name, so allocate the empty entry.
if (foundEmptyEntry)
{
foundEmptyEntry->m_refCount = 1;
foundEmptyEntry->m_name = drawListName;
++m_allocatedTagCount;
}
return drawListTag;
}
void DrawListTagRegistry::ReleaseTag(DrawListTag drawListTag)
{
if (drawListTag.IsValid())
{
AZStd::unique_lock<AZStd::shared_mutex> lock(m_mutex);
Entry& entry = m_entriesByTag[drawListTag.GetIndex()];
const size_t refCount = --entry.m_refCount;
AZ_Assert(refCount != static_cast<size_t>(-1), "Attempted to forfeit a tag that is not valid. Tag{%d},Name{'%s'}", drawListTag, entry.m_name.GetCStr());
if (refCount == 0)
{
entry.m_name = Name();
--m_allocatedTagCount;
}
}
}
DrawListTag DrawListTagRegistry::FindTag(const Name& drawListName) const
{
AZStd::shared_lock<AZStd::shared_mutex> lock(m_mutex);
for (size_t i = 0; i < m_entriesByTag.size(); ++i)
{
if (m_entriesByTag[i].m_name == drawListName)
{
return DrawListTag(i);
}
}
return {};
}
Name DrawListTagRegistry::GetName(DrawListTag tag) const
{
if (tag.GetIndex() < m_entriesByTag.size())
{
return m_entriesByTag[tag.GetIndex()].m_name;
}
else
{
return Name();
}
}
size_t DrawListTagRegistry::GetAllocatedTagCount() const
{
return m_allocatedTagCount;
}
}
}
+7 -2
View File
@@ -24,10 +24,10 @@ namespace AZ
return m_drawItemCount;
}
DrawItemKeyPair DrawPacket::GetDrawItem(size_t index) const
DrawItemProperties DrawPacket::GetDrawItem(size_t index) const
{
AZ_Assert(index < GetDrawItemCount(), "Out of bounds array access!");
return DrawItemKeyPair(&m_drawItems[index], m_drawItemSortKeys[index]);
return DrawItemProperties(&m_drawItems[index], m_drawItemSortKeys[index], m_drawFilterMask);
}
DrawListTag DrawPacket::GetDrawListTag(size_t index) const
@@ -36,6 +36,11 @@ namespace AZ
return m_drawListTags[index];
}
DrawFilterMask DrawPacket::GetDrawFilterMask() const
{
return m_drawFilterMask;
}
DrawListMask DrawPacket::GetDrawListMask() const
{
return m_drawListMask;
@@ -82,6 +82,11 @@ namespace AZ
}
}
void DrawPacketBuilder::SetDrawFilterMask(DrawFilterMask filterMask)
{
m_drawFilterMask = filterMask;
}
void DrawPacketBuilder::AddDrawItem(const DrawRequest& request)
{
if (request.m_listTag.IsValid())
@@ -165,6 +170,7 @@ namespace AZ
drawPacket->m_allocator = m_allocator;
drawPacket->m_indexBufferView = m_indexBufferView;
drawPacket->m_drawListMask = m_drawListMask;
drawPacket->m_drawFilterMask = m_drawFilterMask;
if (shaderResourceGroupsOffset.IsValid())
{
@@ -288,6 +294,7 @@ namespace AZ
m_rootConstants = {};
m_scissors.clear();
m_viewports.clear();
m_drawFilterMask = DrawFilterMaskDefaultValue;
}
}
}
+1 -2
View File
@@ -60,7 +60,7 @@ namespace AZ
AZ_Assert(false, "RHISystem", "Unable to initialize RHI! \n");
return;
}
m_drawListTagRegistry = RHI::DrawListTagRegistry::Create();
m_pipelineStateCache = RHI::PipelineStateCache::Create(*m_device);
@@ -199,7 +199,6 @@ namespace AZ
m_frameScheduler.Shutdown();
m_platformLimitsDescriptor = nullptr;
m_drawListTagRegistry = nullptr;
m_pipelineStateCache = nullptr;
m_device->PreShutdown();
AZ_Assert(m_device->use_count()==1, "The ref count for Device is %i but it should be 1 here to ensure all the resources are released", m_device->use_count());
+3 -3
View File
@@ -80,11 +80,11 @@ namespace UnitTest
m_indexBufferView = RHI::IndexBufferView(*m_bufferEmpty, random.GetRandom(), random.GetRandom(), RHI::IndexFormat::Uint16);
}
void ValidateDrawItem(const DrawItemData& drawItemData, RHI::DrawItemKeyPair itemKeyPair) const
void ValidateDrawItem(const DrawItemData& drawItemData, RHI::DrawItemProperties itemProperties) const
{
const RHI::DrawItem* drawItem = itemKeyPair.m_item;
const RHI::DrawItem* drawItem = itemProperties.m_item;
EXPECT_EQ(itemKeyPair.m_sortKey, drawItemData.m_sortKey);
EXPECT_EQ(itemProperties.m_sortKey, drawItemData.m_sortKey);
EXPECT_EQ(drawItem->m_stencilRef, drawItemData.m_stencilRef);
EXPECT_EQ(drawItem->m_pipelineState, drawItemData.m_pipelineState);
@@ -36,6 +36,7 @@ set(FILES
Include/Atom/RHI/CopyItem.h
Include/Atom/RHI/ConstantsData.h
Include/Atom/RHI/DispatchItem.h
Include/Atom/RHI/DrawFilterTagRegistry.h
Include/Atom/RHI/DrawItem.h
Include/Atom/RHI/DrawList.h
Include/Atom/RHI/DrawListTagRegistry.h
@@ -48,7 +49,6 @@ set(FILES
Source/RHI/ConstantsData.cpp
Source/RHI/DrawList.cpp
Source/RHI/DrawListContext.cpp
Source/RHI/DrawListTagRegistry.cpp
Source/RHI/DrawPacket.cpp
Source/RHI/DrawPacketBuilder.cpp
Include/Atom/RHI/Device.h
@@ -201,4 +201,5 @@ set(FILES
Include/Atom/RHI/CpuProfiler.h
Include/Atom/RHI/CpuProfilerImpl.h
Source/RHI/CpuProfilerImpl.cpp
Include/Atom/RHI/TagRegistry.h
)
@@ -214,6 +214,10 @@ namespace AZ
Scene* m_scene = nullptr;
RHI::DrawListTag m_drawListTag;
// All draw items use this filter when submit them to views
// It's set to RenderPipeline's draw filter mask if the DynamicDrawContext was created for a render pipeline.
RHI::DrawFilterMask m_drawFilter = RHI::DrawFilterMaskDefaultValue;
// Cached draw data
AZStd::vector<RHI::StreamBufferView> m_cachedStreamBufferViews;
AZStd::vector<RHI::IndexBufferView> m_cachedIndexBufferViews;
@@ -56,9 +56,11 @@ namespace AZ
//! Draw calls which are made to this DynamicDrawContext will only be submitted for this scene.
//! The created DynamicDrawContext is managed by dynamic draw system.
virtual RHI::Ptr<DynamicDrawContext> CreateDynamicDrawContext(Scene* scene) = 0;
//! Create a DynamicDrawContext for specified pass
virtual RHI::Ptr<DynamicDrawContext> CreateDynamicDrawContext(Pass* pass = nullptr) = 0;
//! Create a DynamicDrawContext for specified render pipeline
//! Draw calls submitted through the context created by this function are only submitted
//! to the supplied render pipeline (viewport)
virtual RHI::Ptr<DynamicDrawContext> CreateDynamicDrawContext(RenderPipeline* pipeline) = 0;
//! Get a DynamicBuffer from DynamicDrawSystem.
//! The returned buffer will be invalidated every time the RPISystem's RenderTick is called
@@ -36,7 +36,7 @@ namespace AZ
// DynamicDrawInterface overrides...
RHI::Ptr<DynamicDrawContext> CreateDynamicDrawContext(Scene* scene) override;
RHI::Ptr<DynamicDrawContext> CreateDynamicDrawContext(Pass* pass) override;
RHI::Ptr<DynamicDrawContext> CreateDynamicDrawContext(RenderPipeline* pipeline) override;
RHI::Ptr<DynamicBuffer> GetDynamicBuffer(uint32_t size, uint32_t alignment = 1) override;
void DrawGeometry(Data::Instance<Material> material, const GeometryData& geometry, ScenePtr scene) override;
void AddDrawPacket(Scene* scene, AZStd::unique_ptr<const RHI::DrawPacket> drawPacket) override;
@@ -184,6 +184,12 @@ namespace AZ
//! Get current render mode
RenderMode GetRenderMode() const;
//! Get draw filter tag
RHI::DrawFilterTag GetDrawFilterTag() const;
//! Get draw filter mask
RHI::DrawFilterMask GetDrawFilterMask() const;
private:
RenderPipeline() = default;
@@ -211,6 +217,8 @@ namespace AZ
// if the view already exists in map, its DrawListMask will be combined to the existing one's
void CollectPersistentViews(AZStd::map<ViewPtr, RHI::DrawListMask>& outViewMasks) const;
void SetDrawFilterTag(RHI::DrawFilterTag);
// End of functions accessed by Scene class
//////////////////////////////////////////////////
@@ -250,6 +258,13 @@ namespace AZ
// Original settings from RenderPipelineDescriptor, used to revert active render settings to original settings from RenderPipelineDescriptor
PipelineRenderSettings m_originalRenderSettings;
// A tag to filter draw items submitted by passes of this render pipeline.
// This tag is allocated when it's added to a scene. It's set to invalid when it's removed to the scene.
RHI::DrawFilterTag m_drawFilterTag;
// A mask to filter draw items submitted by passes of this render pipeline.
// This mask is created from the value of m_drawFilterTag.
RHI::DrawFilterMask m_drawFilterMask = 0;
};
} // namespace RPI
@@ -14,6 +14,7 @@
#include <Atom/RHI/DrawList.h>
#include <Atom/RHI/PipelineStateDescriptor.h>
#include <Atom/RHI/DrawFilterTagRegistry.h>
#include <Atom/RHI.Reflect/FrameSchedulerEnums.h>
#include <Atom/RHI.Reflect/ShaderResourceGroupLayoutDescriptor.h>
#include <Atom/RPI.Reflect/System/SceneDescriptor.h>
@@ -234,6 +235,9 @@ namespace AZ
// reference of dynamic draw system (from RPISystem)
DynamicDrawSystem* m_dynamicDrawSystem = nullptr;
// Registry which allocates draw filter tag for RenderPipeline
RHI::Ptr<RHI::DrawFilterTagRegistry> m_drawFilterTagRegistry;
};
// --- Template functions ---
@@ -75,7 +75,7 @@ namespace AZ
void AddDrawPacket(const RHI::DrawPacket* drawPacket, Vector3 worldPosition);
//! Add a draw item to this view with its associated draw list tag
void AddDrawItem(RHI::DrawListTag drawListTag, const RHI::DrawItemKeyPair& drawItemKeyPair);
void AddDrawItem(RHI::DrawListTag drawListTag, const RHI::DrawItemProperties& drawItemProperties);
//! Sets the worldToView matrix and recalculates the other matrices.
void SetWorldToViewMatrix(const AZ::Matrix4x4& worldToView);
@@ -17,6 +17,7 @@
#include <Atom/RPI.Public/DynamicDraw/DynamicBuffer.h>
#include <Atom/RPI.Public/DynamicDraw/DynamicDrawContext.h>
#include <Atom/RPI.Public/DynamicDraw/DynamicDrawInterface.h>
#include <Atom/RPI.Public/RenderPipeline.h>
#include <Atom/RPI.Public/View.h>
@@ -601,10 +602,11 @@ namespace AZ
drawItemInfo.m_drawItem.m_streamBufferViews = &m_cachedStreamBufferViews[drawItemInfo.m_vertexBufferViewIndex];
}
RHI::DrawItemKeyPair drawItemKeyPair;
drawItemKeyPair.m_sortKey = sortKey;
drawItemKeyPair.m_item = &drawItemInfo.m_drawItem;
view->AddDrawItem(m_drawListTag, drawItemKeyPair);
RHI::DrawItemProperties drawItemProperties;
drawItemProperties.m_sortKey = sortKey;
drawItemProperties.m_item = &drawItemInfo.m_drawItem;
drawItemProperties.m_drawFilterMask = m_drawFilter;
view->AddDrawItem(m_drawListTag, drawItemProperties);
sortKey++;
}
}
@@ -59,6 +59,11 @@ namespace AZ
RHI::Ptr<DynamicDrawContext> DynamicDrawSystem::CreateDynamicDrawContext(Scene* scene)
{
if (!scene)
{
AZ_Error("RPI", false, "Failed to create a DynamicDrawContext: the input scene is invalid");
return nullptr;
}
RHI::Ptr<DynamicDrawContext> drawContext = aznew DynamicDrawContext();
drawContext->m_scene = scene;
@@ -67,11 +72,17 @@ namespace AZ
return drawContext;
}
// [GFX TODO][ATOM-13185] Add support for creating DynamicDrawContext for Pass
RHI::Ptr<DynamicDrawContext> DynamicDrawSystem::CreateDynamicDrawContext([[maybe_unused]] Pass* pass)
RHI::Ptr<DynamicDrawContext> DynamicDrawSystem::CreateDynamicDrawContext(RenderPipeline* pipeline)
{
AZ_Error("RPI", false, "Unimplemented function");
return nullptr;
if (!pipeline || !pipeline->GetScene())
{
AZ_Error("RPI", false, "Failed to create a DynamicDrawContext: the input RenderPipeline is invalid or wasn't added to a Scene");
return nullptr;
}
auto context = CreateDynamicDrawContext(pipeline->GetScene());
context->m_drawFilter = pipeline->GetDrawFilterMask();
return context;
}
// [GFX TODO][ATOM-13184] Add support of draw geometry with material for DynamicDrawSystemInterface
@@ -195,9 +195,12 @@ namespace AZ
SetSrgsForDraw(commandList);
}
for (const RHI::DrawItemKeyPair& drawItemKeyPair : drawListViewPartition)
for (const RHI::DrawItemProperties& drawItemProperties : drawListViewPartition)
{
commandList->Submit(*drawItemKeyPair.m_item);
if (drawItemProperties.m_drawFilterMask & m_pipeline->GetDrawFilterMask())
{
commandList->Submit(*drawItemProperties.m_item);
}
}
}
@@ -300,6 +300,9 @@ namespace AZ
m_scene = nullptr;
m_rootPass->SetEnabled(false);
m_rootPass->QueueForRemoval();
m_drawFilterTag.Reset();
m_drawFilterMask = 0;
}
void RenderPipeline::OnPassModified()
@@ -506,5 +509,28 @@ namespace AZ
{
return m_renderMode != RenderMode::NoRender;
}
RHI::DrawFilterTag RenderPipeline::GetDrawFilterTag() const
{
return m_drawFilterTag;
}
RHI::DrawFilterMask RenderPipeline::GetDrawFilterMask() const
{
return m_drawFilterMask;
}
void RenderPipeline::SetDrawFilterTag(RHI::DrawFilterTag tag)
{
m_drawFilterTag = tag;
if (m_drawFilterTag.IsValid())
{
m_drawFilterMask = 1 << tag.GetIndex();
}
else
{
m_drawFilterMask = 0;
}
}
}
}
@@ -87,6 +87,7 @@ namespace AZ
m_id = Uuid::CreateRandom();
m_cullingScene = aznew CullingScene();
SceneRequestBus::Handler::BusConnect(m_id);
m_drawFilterTagRegistry = RHI::DrawFilterTagRegistry::Create();
}
Scene::~Scene()
@@ -269,6 +270,8 @@ namespace AZ
return;
}
pipeline->SetDrawFilterTag(m_drawFilterTagRegistry->AcquireTag(pipelineId));
m_pipelines.push_back(pipeline);
// Set this pipeline as default if the default pipeline was empty. This pipeline should be the first pipeline be added to the scene
@@ -303,6 +306,8 @@ namespace AZ
m_defaultPipeline = nullptr;
}
m_drawFilterTagRegistry->ReleaseTag(pipelineToRemove->GetDrawFilterTag());
pipelineToRemove->OnRemovedFromScene(this);
m_pipelines.erase(it);
@@ -90,9 +90,9 @@ namespace AZ
AddDrawPacket(drawPacket, depth);
}
void View::AddDrawItem(RHI::DrawListTag drawListTag, const RHI::DrawItemKeyPair& drawItemKeyPair)
void View::AddDrawItem(RHI::DrawListTag drawListTag, const RHI::DrawItemProperties& drawItemProperties)
{
m_drawListContext.AddDrawItem(drawListTag, drawItemKeyPair);
m_drawListContext.AddDrawItem(drawListTag, drawItemProperties);
}
void View::SetWorldToViewMatrix(const AZ::Matrix4x4& worldToView)
@@ -510,7 +510,7 @@ namespace ScriptCanvas
AZ_Assert(lua_isuserdata(lua, 1), "CallExecutionOut: Error in compiled lua file, 1st argument to SetExecutionOut is not userdata (Nodeable)");
AZ_Assert(lua_isnumber(lua, 2), "CallExecutionOut: Error in compiled lua file, 2nd argument to SetExecutionOut is not a number");
Nodeable* nodeable = AZ::ScriptValue<Nodeable*>::StackRead(lua, 1);
size_t index = aznumeric_caster(lua_tointeger(lua, -2));
size_t index = aznumeric_caster(lua_tointeger(lua, 2));
nodeable->CallOut(index, nullptr, nullptr, argsCount - 2);
// Lua: results...
return lua_gettop(lua);
@@ -697,7 +697,7 @@ namespace ScriptCanvas
AZ_Assert(lua_islightuserdata(lua, 2), "Error in compiled lua file, 2nd argument to UnpackDependencyArgs is not userdata (AZStd::vector<AZ::Data::Asset<RuntimeAsset>>*), but a :%s", lua_typename(lua, 2));
auto dependentAssets = reinterpret_cast<AZStd::vector<AZ::Data::Asset<RuntimeAsset>>*>(lua_touserdata(lua, 2));
AZ_Assert(lua_isinteger(lua, 3), "Error in compiled Lua file, 3rd argument to UnpackDependencyArgs is not a number");
const size_t dependentAssetsIndex = lua_tointeger(lua, 3);
const size_t dependentAssetsIndex = aznumeric_caster(lua_tointeger(lua, 3));
return DependencyConstructionPack{ executionState, dependentAssets, dependentAssetsIndex, (*dependentAssets)[dependentAssetsIndex].Get()->m_runtimeData };
}
@@ -3257,13 +3257,12 @@ namespace ScriptCanvas
return;
}
execution->SetNodeable(iter->second->m_nodeable);
child->SetNodeable(iter->second->m_nodeable);
for (auto& childOutSlot : childOutSlots)
{
AZ_Assert(childOutSlot, "null slot in child out slot list");
ExecutionTreePtr internalOut = OpenScope(child, node, childOutSlot);
internalOut->SetNodeable(execution->GetNodeable());
const size_t outIndex = node->GetOutIndex(*childOutSlot);
if (outIndex == std::numeric_limits<size_t>::max())
@@ -262,9 +262,6 @@ namespace ScriptCanvas
void SetSymbol(Symbol val);
protected:
VariableConstPtr m_nodeable;
private:
// the (possible) slot(s) through which execution exited, along with associated output
AZStd::vector<ExecutionChild> m_children;
@@ -316,6 +313,8 @@ namespace ScriptCanvas
Symbol m_symbol = Symbol::FunctionCall;
VariableConstPtr m_nodeable;
size_t FindIndexOfChild(ExecutionTreeConstPtr child) const;
};
@@ -276,7 +276,7 @@ namespace ScriptCanvas
if (IsMethodOverloaded() && BehaviorContextUtils::FindExplicitOverload(method, bcClass, className, methodName, &prettyClassName))
{
MethodConfiguration config(*method, method->IsMember() ? MethodType::Member : MethodType::Free);
MethodConfiguration config(*method, MethodType::Member);
config.m_class = bcClass;
config.m_namespaces = &m_namespaces;
config.m_className = &className;
@@ -582,7 +582,7 @@ namespace ScriptCanvas
void GraphToLua::TranslateExecutionTreeFunctionCall(Grammar::ExecutionTreeConstPtr execution)
{
TranslateNodeableOuts(execution);
TranslateNodeableOuts(execution->GetNodeable(), execution);
WriteDebugInfoIn(execution, "TranslateExecutionTreeFunctionCall begin");
m_dotLua.WriteIndent();
WriteLocalOutputInitialization(execution);
@@ -955,7 +955,7 @@ namespace ScriptCanvas
for (auto& out : nodeAndParse->m_latents)
{
m_dotLua.WriteNewLine();
TranslateNodeableOut(out.second);
TranslateNodeableOut(nodeAndParse->m_nodeable, out.second);
}
if (!nodeAndParse->m_latents.empty())
@@ -1017,7 +1017,7 @@ namespace ScriptCanvas
m_dotLua.WriteNewLine();
}
void GraphToLua::TranslateNodeableOut(Grammar::ExecutionTreeConstPtr execution)
void GraphToLua::TranslateNodeableOut(Grammar::VariableConstPtr host, Grammar::ExecutionTreeConstPtr execution)
{
auto outCallIndexOptional = execution->GetOutCallIndex();
if (!outCallIndexOptional)
@@ -1037,7 +1037,7 @@ namespace ScriptCanvas
m_dotLua.WriteLineIndented("%s(self.%s, %zu, -- %s"
, setExecutionOutName
, execution->GetNodeable()->m_name.data()
, host->m_name.data()
, outIndex
, execution->GetName().data());
@@ -1048,14 +1048,14 @@ namespace ScriptCanvas
m_dotLua.Outdent();
}
void GraphToLua::TranslateNodeableOuts(Grammar::ExecutionTreeConstPtr execution)
void GraphToLua::TranslateNodeableOuts(Grammar::VariableConstPtr host, Grammar::ExecutionTreeConstPtr execution)
{
const auto outs = execution->GetInternalOuts();
for (const auto& out : outs)
{
m_dotLua.WriteNewLine();
TranslateNodeableOut(out);
TranslateNodeableOut(host, out);
}
if (!outs.empty())
@@ -111,8 +111,8 @@ namespace ScriptCanvas
void TranslateFunctionBlock(Grammar::ExecutionTreeConstPtr execution, FunctionBlockConfig functionBlockConfig, IsNamed lex);
void TranslateFunctionDefinition(Grammar::ExecutionTreeConstPtr execution, IsNamed lex);
void TranslateInheritance();
void TranslateNodeableOut(Grammar::ExecutionTreeConstPtr execution);
void TranslateNodeableOuts(Grammar::ExecutionTreeConstPtr execution);
void TranslateNodeableOut(Grammar::VariableConstPtr host, Grammar::ExecutionTreeConstPtr execution);
void TranslateNodeableOuts(Grammar::VariableConstPtr host, Grammar::ExecutionTreeConstPtr execution);
void TranslateNodeableParse();
void TranslateStaticInitialization();
void TranslateVariableInitialization(AZStd::string_view leftValue);
@@ -100,6 +100,11 @@ TEST_F(ScriptCanvasTestFixture, InterpretedReadEnumConstant)
RunUnitTestGraph("LY_SC_UnitTest_ReadEnumConstant");
}
TEST_F(ScriptCanvasTestFixture, UserBranchSanityCheck)
{
RunUnitTestGraph("LY_SC_UnitTest_UserBranchSanityCheck");
}
TEST_F(ScriptCanvasTestFixture, InterpretedEventHandlerNoDisconnect)
{
GlobalHandler handler;
-17
View File
@@ -1,17 +0,0 @@
#
# 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.
#
ly_add_external_target(
NAME libav
VERSION 11.7
INCLUDE_DIRECTORIES
usr/include
)
@@ -13,6 +13,5 @@ set(FILES
BuiltInPackages_windows.cmake
dyad_windows.cmake
FbxSdk_windows.cmake
libav_windows.cmake
Wwise_windows.cmake
)
-46
View File
@@ -1,46 +0,0 @@
#
# 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.
#
set(LIBAV_LIB_PATH ${BASE_PATH}/usr/bin/)
set(LIBAV_LIBS
avcodec
avdevice
avfilter
avformat
avresample
avutil
swscale
)
list(TRANSFORM LIBAV_LIBS PREPEND ${LIBAV_LIB_PATH}${CMAKE_STATIC_LIBRARY_PREFIX})
list(TRANSFORM LIBAV_LIBS APPEND "${CMAKE_STATIC_LIBRARY_SUFFIX}")
set(LIBAV_SHARED
avcodec-56
avdevice-55
avfilter-5
avformat-56
avresample-2
avutil-54
libogg-0
libopus-0
libvo-aacenc-0
libvorbis-0
libvorbisenc-2
swscale-3
zlib1
)
list(TRANSFORM LIBAV_SHARED PREPEND ${LIBAV_LIB_PATH}${CMAKE_SHARED_LIBRARY_PREFIX})
list(TRANSFORM LIBAV_SHARED APPEND "${CMAKE_SHARED_LIBRARY_SUFFIX}")
list(JOIN LIBAV_SHARED ";" LIBAV_SHARED_STRING)
set(LIBAV_RUNTIME_DEPENDENCIES ${LIBAV_SHARED_STRING})
-1
View File
@@ -14,7 +14,6 @@ set(FILES
FindClang.cmake
Finddyad.cmake
FindFbxSdk.cmake
Findlibav.cmake
FindOpenGLInterface.cmake
FindRadTelemetry.cmake
FindVkValidation.cmake
@@ -10,7 +10,6 @@
"etc2comp/2017_04_24-az.2/**": "#include",
"expat/2.1.0-pkg.3/**": "#include",
"FbxSdk/2016.1.2-az.1/**": "#include",
"libav/11.7/**": "#include",
"OpenSSL/1.1.1b-noasm-az/**": "#include",
"Qt/5.15.1.2-az/**": "#include",
"RadTelemetry/3.5.0.17/**": "#include",