diff --git a/Code/Framework/AzCore/AzCore/EBus/Policies.h b/Code/Framework/AzCore/AzCore/EBus/Policies.h index 0217874416..db11043ef8 100644 --- a/Code/Framework/AzCore/AzCore/EBus/Policies.h +++ b/Code/Framework/AzCore/AzCore/EBus/Policies.h @@ -268,7 +268,7 @@ namespace AZ m_messages.pop(); if (numMessages == 1) { - m_messages.get_container().clear(); // If it was the last message, free all memory. + m_messages = {}; } } ////////////////////////////////////////////////////////////////////////// @@ -280,7 +280,7 @@ namespace AZ void Clear() { AZStd::lock_guard lock(m_messagesMutex); - m_messages.get_container().clear(); + m_messages = {}; } void SetActive(bool isActive) @@ -289,7 +289,7 @@ namespace AZ m_isActive = isActive; if (!m_isActive) { - m_messages.get_container().clear(); + m_messages = {}; } }; diff --git a/Code/Framework/AzCore/AzCore/Serialization/AZStdContainers.inl b/Code/Framework/AzCore/AzCore/Serialization/AZStdContainers.inl index 35a2d64c0d..9eb65dec76 100644 --- a/Code/Framework/AzCore/AzCore/Serialization/AZStdContainers.inl +++ b/Code/Framework/AzCore/AzCore/Serialization/AZStdContainers.inl @@ -42,8 +42,6 @@ namespace AZStd class unordered_multiset; template class bitset; - template*/ > - class stack; template class intrusive_ptr; diff --git a/Code/Framework/AzCore/AzCore/std/containers/queue.h b/Code/Framework/AzCore/AzCore/std/containers/queue.h index f1df1dd787..8026ebe943 100644 --- a/Code/Framework/AzCore/AzCore/std/containers/queue.h +++ b/Code/Framework/AzCore/AzCore/std/containers/queue.h @@ -5,206 +5,17 @@ * SPDX-License-Identifier: Apache-2.0 OR MIT * */ -#ifndef AZSTD_QUEUE_H -#define AZSTD_QUEUE_H 1 +#pragma once #include #include #include +#include namespace AZStd { - /** - * FIFO queue complaint with \ref CStd (23.2.3.1) - * The only extension we have is that we allow access - * to the underlying container via: get_container function. - * Check the queue \ref AZStdExamples. - */ - template > - class queue - { - enum - { - CONTAINER_VERSION = 1 - }; - public: - typedef queue this_type; - typedef Container container_type; - typedef typename Container::value_type value_type; - typedef typename Container::size_type size_type; - typedef typename Container::reference reference; - typedef typename Container::const_reference const_reference; - - AZ_FORCE_INLINE queue() {} - - AZ_FORCE_INLINE explicit queue(const container_type& container) - : m_container(container) {} - AZ_FORCE_INLINE bool empty() const { return m_container.empty(); } - AZ_FORCE_INLINE size_type size() const { return m_container.size(); } - AZ_FORCE_INLINE reference front() { return m_container.front(); } - AZ_FORCE_INLINE const_reference front() const { return m_container.front(); } - AZ_FORCE_INLINE reference back() { return m_container.back(); } - AZ_FORCE_INLINE const_reference back() const { return m_container.back(); } - AZ_FORCE_INLINE void push(const value_type& value) { m_container.push_back(value); } - AZ_FORCE_INLINE void pop() { m_container.pop_front(); } - - AZ_FORCE_INLINE void push() { m_container.push_back(); } - - AZ_FORCE_INLINE queue(this_type&& rhs) - : m_container(AZStd::move(rhs.m_container)) {} - AZ_FORCE_INLINE explicit queue(Container&& container) - : m_container(AZStd::move(container)) {} - this_type& operator=(this_type&& rhs) - { - m_container = AZStd::move(rhs.m_container); - return (*this); - } - void push(value_type&& value) { m_container.push_back(AZStd::move(value)); } - template - void emplace(Args&&... args) { m_container.emplace_back(AZStd::forward(args)...); } - void swap(this_type& rhs) { AZStd::swap(m_container, rhs.m_container); } - - AZ_FORCE_INLINE Container& get_container() { return m_container; } - AZ_FORCE_INLINE const Container& get_container() const { return m_container; } - - protected: - Container m_container; - }; - - // queue TEMPLATE FUNCTIONS - template - AZ_FORCE_INLINE bool operator==(const AZStd::queue& left, const AZStd::queue& right) - { - return left.get_container() == right.get_container(); - } - - template - AZ_FORCE_INLINE bool operator!=(const AZStd::queue& left, const AZStd::queue& right) - { - return left.get_container() != right.get_container(); - } - - /* template - AZ_FORCE_INLINE bool operator<(const queue& left, const queue& right) - { - return left.get_container() < right.get_container(); - } - - template - AZ_FORCE_INLINE bool operator>(const queue& left, const queue& right) - { - return left.get_container() > right.get_container(); - } - - template - AZ_FORCE_INLINE operator<=(const queue& left, const queue& right) - { - return left.get_container() <= right.get_container(); - } - - template - AZ_FORCE_INLINE bool operator>=(const queue& left, const queue& right) - { - return left.get_container() >= right.get_container(); - }*/ - - /** - * Priority queue is complaint with \ref CStd (23.2.3.2) - * The only extension we have is that we allow access - * to the underlying container via: get_container function. - * Check the priority_queue \ref AZStdExamples. - */ - template, class Predicate = AZStd::less > - class priority_queue - { - enum - { - CONTAINER_VERSION = 1 - }; - public: - typedef priority_queue this_type; - typedef Container container_type; - typedef typename Container::value_type value_type; - typedef typename Container::size_type size_type; - typedef typename Container::reference reference; - typedef typename Container::const_reference const_reference; - - AZ_FORCE_INLINE priority_queue() {} - AZ_FORCE_INLINE explicit priority_queue(const Predicate& comp) - : m_comp(comp) {} - AZ_FORCE_INLINE priority_queue(const Predicate& comp, const container_type& container) - : m_container(container) - , m_comp(comp) - { - // construct by copying specified container, comparator - AZStd::make_heap(m_container.begin(), m_container.end(), comp); - } - template - AZ_FORCE_INLINE priority_queue(InputIterator first, InputIterator last) - : m_container(first, last) - , m_comp() - { - AZStd::make_heap(m_container.begin(), m_container.end(), m_comp); - } - - template - AZ_FORCE_INLINE priority_queue(InputIterator first, InputIterator last, const Predicate& comp) - : m_container(first, last) - , m_comp(comp) - { // construct by copying [_First, _Last), specified comparator - AZStd::make_heap(m_container.begin(), m_container.end(), m_comp); - } - - template - AZ_FORCE_INLINE priority_queue(InputIterator first, InputIterator last, const Predicate& comp, const container_type& container) - : m_container(container) - , m_comp(comp) - { // construct by copying [_First, _Last), container, and comparator - m_container.insert(m_container.end(), first, last); - AZStd::make_heap(m_container.begin(), m_container.end(), m_comp); - } - - AZ_FORCE_INLINE bool empty() const { return m_container.empty(); } - AZ_FORCE_INLINE size_type size() const { return m_container.size(); } - AZ_FORCE_INLINE const_reference top() const { return m_container.front(); } - AZ_FORCE_INLINE reference top() { return m_container.front(); } - AZ_FORCE_INLINE void push(const value_type& value) - { - m_container.push_back(value); - AZStd::push_heap(m_container.begin(), m_container.end(), m_comp); - } - - AZ_FORCE_INLINE void pop() - { - AZStd::pop_heap(m_container.begin(), m_container.end(), m_comp); - m_container.pop_back(); - } - - AZ_FORCE_INLINE priority_queue(this_type&& rhs) - : m_container(AZStd::move(rhs.m_container)) - , m_comp(AZStd::move(rhs.m_comp)) {} - AZ_FORCE_INLINE explicit priority_queue(const Predicate& pred, Container&& container) - : m_container(AZStd::move(container)) - , m_comp(pred) {} - this_type& operator=(this_type&& rhs) - { - m_container = AZStd::move(rhs.m_container); - m_comp = AZStd::move(rhs.m_comp); - return (*this); - } - void push(value_type&& value) { m_container.push_back(AZStd::move(value)); AZStd::push_heap(m_container.begin(), m_container.end(), m_comp); } - template - void emplace(Args&& args) { m_container.emplace_back(AZStd::forward(args)); AZStd::push_heap(m_container.begin(), m_container.end(), m_comp); } - void swap(this_type& rhs) { AZStd::swap(m_container, rhs.m_container); AZStd::swap(m_comp, rhs.m_comp); } - - AZ_FORCE_INLINE Container& get_container() { return m_container; } - AZ_FORCE_INLINE const Container& get_container() const { return m_container; } - - protected: - Container m_container; - Predicate m_comp; - }; + template> + using queue = std::queue; + template, class Compare = AZStd::less> + using priority_queue = std::priority_queue; } - -#endif // AZSTD_QUEUE_H -#pragma once diff --git a/Code/Framework/AzCore/AzCore/std/containers/stack.h b/Code/Framework/AzCore/AzCore/std/containers/stack.h index 715d46c933..aa0d62d105 100644 --- a/Code/Framework/AzCore/AzCore/std/containers/stack.h +++ b/Code/Framework/AzCore/AzCore/std/containers/stack.h @@ -5,103 +5,13 @@ * SPDX-License-Identifier: Apache-2.0 OR MIT * */ -#ifndef AZSTD_STACK_H -#define AZSTD_STACK_H 1 +#pragma once #include +#include namespace AZStd { - /** - * Stack container is complaint with \ref CStd (23.2.3.3) - * The only extension we have is that we allow access - * to the underlying container via: get_container function. - * Check the stack \ref AZStdExamples. - */ - template > - class stack - { - enum - { - CONTAINER_VERSION = 1 - }; - public: - typedef stack this_type; - typedef Container container_type; - typedef typename Container::value_type value_type; - typedef typename Container::size_type size_type; - typedef typename Container::reference reference; - typedef typename Container::const_reference const_reference; - - AZ_FORCE_INLINE stack() {} - AZ_FORCE_INLINE explicit stack(const container_type& container) - : m_container(container) {} - AZ_FORCE_INLINE bool empty() const { return m_container.empty(); } - AZ_FORCE_INLINE size_type size() const { return m_container.size(); } - AZ_FORCE_INLINE reference top() { return m_container.back(); } - AZ_FORCE_INLINE const_reference top() const { return m_container.back(); } - AZ_FORCE_INLINE reference back() { return m_container.back(); } - AZ_FORCE_INLINE const_reference back() const { return m_container.back(); } - AZ_FORCE_INLINE void push(const value_type& value) { m_container.push_back(value); } - AZ_FORCE_INLINE void pop() { m_container.pop_back(); } - AZ_FORCE_INLINE void push() { m_container.push_back(); } - - AZ_FORCE_INLINE stack(this_type&& rhs) - : m_container(AZStd::move(rhs.m_container)) {} - AZ_FORCE_INLINE explicit stack(Container&& container) - : m_container(AZStd::move(container)) {} - this_type& operator=(this_type&& rhs) { m_container = AZStd::move(rhs.m_container); return *this; } - void push(value_type&& value) { m_container.push_back(AZStd::move(value)); } - template - void emplace(Args&& args) { m_container.emplace_back(AZStd::forward(args)); } - void swap(this_type&& rhs) { m_container.swap(AZStd::move(rhs.m_container)); } - - void swap(this_type& rhs) { AZStd::swap(m_container, rhs.m_container); } - - AZ_FORCE_INLINE Container& get_container() { return m_container; } - AZ_FORCE_INLINE const Container& get_container() const { return m_container; } - - protected: - Container m_container; - }; - - // queue TEMPLATE FUNCTIONS - template - AZ_FORCE_INLINE bool operator==(const AZStd::stack& left, const AZStd::stack& right) - { - return left.get_container() == right.get_container(); - } - - template - AZ_FORCE_INLINE bool operator!=(const AZStd::stack& left, const AZStd::stack& right) - { - return left.get_container() != right.get_container(); - } - - /* template - AZ_FORCE_INLINE bool operator<(const queue& left, const queue& right) - { - return left.get_container() < right.get_container(); - } - - template - AZ_FORCE_INLINE bool operator>(const queue& left, const queue& right) - { - return left.get_container() > right.get_container(); - } - - template - AZ_FORCE_INLINE operator<=(const queue& left, const queue& right) - { - return left.get_container() <= right.get_container(); - } - - template - AZ_FORCE_INLINE bool operator>=(const queue& left, const queue& right) - { - return left.get_container() >= right.get_container(); - }*/ + template> + using stack = std::stack; } - -#endif // AZSTD_STACK_H -#pragma once diff --git a/Code/Framework/AzCore/Tests/AZStd/DequeAndSimilar.cpp b/Code/Framework/AzCore/Tests/AZStd/DequeAndSimilar.cpp index 587d900b90..33a5d29b4f 100644 --- a/Code/Framework/AzCore/Tests/AZStd/DequeAndSimilar.cpp +++ b/Code/Framework/AzCore/Tests/AZStd/DequeAndSimilar.cpp @@ -298,7 +298,7 @@ namespace UnitTest AZ_TEST_ASSERT(int_queue.empty()); AZ_TEST_ASSERT(int_queue.size() == 0); - // Queue uses deque as default container, so try to contruct to queue from a deque. + // Queue uses deque as default container, so try to construct to queue from a deque. deque container(40, 10); int_queue_type int_queue2(container); AZ_TEST_ASSERT(!int_queue2.empty()); @@ -324,7 +324,7 @@ namespace UnitTest AZ_TEST_ASSERT(int_queue2.size() == 40); AZ_TEST_ASSERT(int_queue2.back() == 20); - int_queue.push(); + int_queue.emplace(); AZ_TEST_ASSERT(!int_queue.empty()); AZ_TEST_ASSERT(int_queue.size() == 1); @@ -423,7 +423,7 @@ namespace UnitTest AZ_TEST_ASSERT(int_stack2.size() == 40); AZ_TEST_ASSERT(int_stack2.top() == 10); - int_stack.push(); + int_stack.emplace(); AZ_TEST_ASSERT(!int_stack.empty()); AZ_TEST_ASSERT(int_stack.size() == 1); // StackContainerTest-End @@ -669,4 +669,19 @@ namespace UnitTest ++iteration; } } + + using StackContainerTestFixture = ScopedAllocatorSetupFixture; + + TEST_F(StackContainerTestFixture, StackEmplaceOperator_SupportsZeroOrMoreArguments) + { + using TestPairType = AZStd::pair; + AZStd::stack testStack; + testStack.emplace(); + testStack.emplace(1); + testStack.emplace(2, 3); + + using ContainerType = typename AZStd::stack::container_type; + AZStd::stack expectedStack(ContainerType{ TestPairType{ 0, 0 }, TestPairType{ 1, 0 }, TestPairType{ 2, 3 } }); + EXPECT_EQ(expectedStack, testStack); + } } diff --git a/Code/Framework/AzFramework/AzFramework/UnitTest/TestDebugDisplayRequests.cpp b/Code/Framework/AzFramework/AzFramework/UnitTest/TestDebugDisplayRequests.cpp index cc663f36b8..ecbacd125b 100644 --- a/Code/Framework/AzFramework/AzFramework/UnitTest/TestDebugDisplayRequests.cpp +++ b/Code/Framework/AzFramework/AzFramework/UnitTest/TestDebugDisplayRequests.cpp @@ -32,7 +32,7 @@ namespace UnitTest void TestDebugDisplayRequests::DrawWireBox(const AZ::Vector3& min, const AZ::Vector3& max) { - const AZ::Transform& tm = m_transforms.back(); + const AZ::Transform& tm = m_transforms.top(); m_points.push_back(tm.TransformPoint(AZ::Vector3(min.GetX(), min.GetY(), min.GetZ()))); m_points.push_back(tm.TransformPoint(AZ::Vector3(min.GetX(), min.GetY(), max.GetZ()))); m_points.push_back(tm.TransformPoint(AZ::Vector3(min.GetX(), max.GetY(), min.GetZ()))); @@ -50,7 +50,7 @@ namespace UnitTest void TestDebugDisplayRequests::DrawWireQuad(float width, float height) { - const AZ::Transform& tm = m_transforms.back(); + const AZ::Transform& tm = m_transforms.top(); m_points.push_back(tm.TransformPoint(AZ::Vector3(-0.5f * width, 0.0f, -0.5f * height))); m_points.push_back(tm.TransformPoint(AZ::Vector3(-0.5f * width, 0.0f, 0.5f * height))); m_points.push_back(tm.TransformPoint(AZ::Vector3(0.5f * width, 0.0f, -0.5f * height))); @@ -64,7 +64,7 @@ namespace UnitTest void TestDebugDisplayRequests::DrawPoints(const AZStd::vector& points) { - const AZ::Transform& tm = m_transforms.back(); + const AZ::Transform& tm = m_transforms.top(); for (const auto& point : points) { m_points.push_back(tm.TransformPoint(point)); @@ -100,7 +100,7 @@ namespace UnitTest void TestDebugDisplayRequests::PushMatrix(const AZ::Transform& tm) { - m_transforms.push(m_transforms.back() * tm); + m_transforms.push(m_transforms.top() * tm); } void TestDebugDisplayRequests::PopMatrix() diff --git a/Code/Framework/AzFramework/AzFramework/Visibility/OctreeSystemComponent.cpp b/Code/Framework/AzFramework/AzFramework/Visibility/OctreeSystemComponent.cpp index 5ef1cda30e..b4cad8511f 100644 --- a/Code/Framework/AzFramework/AzFramework/Visibility/OctreeSystemComponent.cpp +++ b/Code/Framework/AzFramework/AzFramework/Visibility/OctreeSystemComponent.cpp @@ -481,7 +481,7 @@ namespace AzFramework if (!m_freeOctreeNodes.empty()) { // Take a free block of child nodes from our free list - ExtractPageAndOffsetFromIndex(m_freeOctreeNodes.back(), nextChildPage, nextChildOffset); + ExtractPageAndOffsetFromIndex(m_freeOctreeNodes.top(), nextChildPage, nextChildOffset); m_freeOctreeNodes.pop(); } else diff --git a/Code/Framework/AzFramework/Platform/Linux/AzFramework/API/ApplicationAPI_Linux.h b/Code/Framework/AzFramework/Platform/Linux/AzFramework/API/ApplicationAPI_Linux.h index 03c65ce0c3..9b57d1d49e 100644 --- a/Code/Framework/AzFramework/Platform/Linux/AzFramework/API/ApplicationAPI_Linux.h +++ b/Code/Framework/AzFramework/Platform/Linux/AzFramework/API/ApplicationAPI_Linux.h @@ -35,7 +35,7 @@ namespace AzFramework class LinuxXcbConnectionManager { public: - AZ_RTTI(LinuxXcbConnectionManager, "{649951316-3626-4C9D-9DCA-2E7ABF84C0A9}"); + AZ_RTTI(LinuxXcbConnectionManager, "{1F756E14-8D74-42FD-843C-4863307710DB}"); virtual ~LinuxXcbConnectionManager() = default; diff --git a/Code/Framework/GridMate/GridMate/Replica/ReplicaMgr.cpp b/Code/Framework/GridMate/GridMate/Replica/ReplicaMgr.cpp index 2bc8d3e9f0..b8eea00871 100644 --- a/Code/Framework/GridMate/GridMate/Replica/ReplicaMgr.cpp +++ b/Code/Framework/GridMate/GridMate/Replica/ReplicaMgr.cpp @@ -1688,12 +1688,12 @@ namespace GridMate return; //No connections to update } bool updateRate = false; - AZ::u32 minRateBytesPerSecond = m_connByCongestionState.top().m_rate; + AZ::u32 minRateBytesPerSecond = m_connByCongestionState.front().m_rate; //const AZ::u32 old = minRateBytesPerSecond; //For debugging - auto connIt = AZStd::find(m_connByCongestionState.get_container().begin(), m_connByCongestionState.get_container().end(), id); + auto connIt = AZStd::find(m_connByCongestionState.begin(), m_connByCongestionState.end(), id); - if ( connIt == m_connByCongestionState.get_container().end()) + if ( connIt == m_connByCongestionState.end()) { return; //Already disconnected } @@ -1708,11 +1708,11 @@ namespace GridMate //If new min or old min increased, rebuild the heap and send an update if (bytesPerSecond < minRateBytesPerSecond - || (id == m_connByCongestionState.top().m_connection && bytesPerSecond > minRateBytesPerSecond)) + || (id == m_connByCongestionState.front().m_connection && bytesPerSecond > minRateBytesPerSecond)) { updateRate = true; minRateBytesPerSecond = bytesPerSecond; - AZStd::make_heap(m_connByCongestionState.get_container().begin(), m_connByCongestionState.get_container().end()); + AZStd::make_heap(m_connByCongestionState.begin(), m_connByCongestionState.end()); } } diff --git a/Code/Framework/GridMate/GridMate/Replica/ReplicaMgr.h b/Code/Framework/GridMate/GridMate/Replica/ReplicaMgr.h index 93a46d8ad7..bd9f1a1ee9 100644 --- a/Code/Framework/GridMate/GridMate/Replica/ReplicaMgr.h +++ b/Code/Framework/GridMate/GridMate/Replica/ReplicaMgr.h @@ -459,7 +459,7 @@ namespace GridMate } }; static bool k_enableBackPressure; - AZStd::priority_queue m_connByCongestionState; ///< Connections priority queue sorted by congestion window + AZStd::vector m_connByCongestionState; ///< Connections priority queue sorted by congestion window /*** * Updates connection's rate in priority and updates send limit * @@ -479,7 +479,9 @@ namespace GridMate } AZ_Assert(carrier, "NULL carrier!"); - m_connByCongestionState.emplace(RateConnectionPair(AZ::u32(1500), id)); //default to 1500Bps (ex 1 Ethernet frame/second minimum) + m_connByCongestionState.emplace_back(AZ::u32(1500), id); //default to 1500Bps (ex 1 Ethernet frame/second minimum) + // Restore the heap property after pushing back another element + AZStd::push_heap(m_connByCongestionState.begin(), m_connByCongestionState.end()); } void OnDisconnect(Carrier* carrier, ConnectionID id, CarrierDisconnectReason reason) override { @@ -490,17 +492,17 @@ namespace GridMate } AZ_Assert(carrier, "NULL carrier!"); - auto connIt = AZStd::find(m_connByCongestionState.get_container().begin(), m_connByCongestionState.get_container().end(), id); - if (connIt != m_connByCongestionState.get_container().end()) + auto connIt = AZStd::find(m_connByCongestionState.begin(), m_connByCongestionState.end(), id); + if (connIt != m_connByCongestionState.end()) { //Since we are using a weakly sorted heap, we need to re-generate when the top is removed - bool remake = (connIt == m_connByCongestionState.get_container().begin()); + bool remake = (connIt == m_connByCongestionState.begin()); - m_connByCongestionState.get_container().erase(connIt); + m_connByCongestionState.erase(connIt); if (remake) { - AZStd::make_heap(m_connByCongestionState.get_container().begin(), m_connByCongestionState.get_container().end()); + AZStd::make_heap(m_connByCongestionState.begin(), m_connByCongestionState.end()); } } } diff --git a/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/Utils/IndexedDataVector.h b/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/Utils/IndexedDataVector.h new file mode 100644 index 0000000000..37835bd6a8 --- /dev/null +++ b/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/Utils/IndexedDataVector.h @@ -0,0 +1,57 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project. + * For complete copyright and license terms please see the LICENSE at the root of this distribution. + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ + +#pragma once + +#include +#include + +namespace AZ::Render +{ + // Growable vector that leverages indirection to support erasure of elements while maintaining + // resident data in a densely packed region of memory. Useful as a backing store for growable + // buffers intended to be uploaded to the GPU for example. + template + class IndexedDataVector + { + public: + IndexedDataVector(); + explicit IndexedDataVector(size_t initialReservedSize); + ~IndexedDataVector() = default; + + static constexpr IndexType NoFreeSlot = std::numeric_limits::max(); + IndexType m_firstFreeSlot = NoFreeSlot; + + void Clear(); + IndexType GetFreeSlotIndex(); + void RemoveIndex(IndexType index); + + DataType& GetData(IndexType index); + const DataType& GetData(IndexType index) const; + size_t GetDataCount() const; + + AZStd::vector& GetDataVector(); + const AZStd::vector& GetDataVector() const; + + AZStd::vector& GetIndexVector(); + const AZStd::vector& GetIndexVector() const; + + IndexType GetRawIndex(IndexType index) const; + + private: + constexpr static size_t InitialReservedSize = 128; + + // Stores data indices and an embedded free list + AZStd::vector m_indices; + // Stores the indirection index + AZStd::vector m_dataToIndices; + AZStd::vector m_data; + }; +} // namespace AZ::Render + +#include diff --git a/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/Utils/IndexedDataVector.inl b/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/Utils/IndexedDataVector.inl new file mode 100644 index 0000000000..076caad7f4 --- /dev/null +++ b/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/Utils/IndexedDataVector.inl @@ -0,0 +1,134 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project. + * For complete copyright and license terms please see the LICENSE at the root of this distribution. + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ + +namespace AZ::Render +{ + template + inline IndexedDataVector::IndexedDataVector() + : IndexedDataVector(InitialReservedSize) + { + } + + template + inline IndexedDataVector::IndexedDataVector(size_t initialReservedSize) + { + m_dataToIndices.reserve(initialReservedSize); + m_indices.reserve(initialReservedSize); + m_data.reserve(initialReservedSize); + } + + template + inline void IndexedDataVector::Clear() + { + m_dataToIndices.clear(); + m_indices.clear(); + m_data.clear(); + + m_firstFreeSlot = NoFreeSlot; + } + + template + inline IndexType IndexedDataVector::GetFreeSlotIndex() + { + IndexType freeSlotIndex = static_cast(m_indices.size()); + + if (freeSlotIndex == NoFreeSlot) + { + // the vector is full + return NoFreeSlot; + } + + if (m_firstFreeSlot == NoFreeSlot) + { + // If there's no free slot, add on to the end. + m_indices.push_back(freeSlotIndex); + } + else + { + // Fill the free slot. m_indices uses it's empty slots to store a linked list (via indices) to other empty slots. + freeSlotIndex = m_firstFreeSlot; + m_firstFreeSlot = m_indices.at(m_firstFreeSlot); + m_indices.at(freeSlotIndex) = static_cast(m_data.size()); + } + + // The data itself is always packed and m_indices points at it, so push a new entry to the back. + m_data.push_back(DataType()); + m_dataToIndices.push_back(freeSlotIndex); + + return freeSlotIndex; + } + + template + inline void IndexedDataVector::RemoveIndex(IndexType index) + { + IndexType dataIndex = m_indices.at(index); + + // Copy the back light on top of this one. + m_data.at(dataIndex) = m_data.back(); + m_dataToIndices.at(dataIndex) = m_dataToIndices.back(); + + // Update the index of the moved light + m_indices.at(m_dataToIndices.at(dataIndex)) = dataIndex; + + // Pop the back + m_data.pop_back(); + m_dataToIndices.pop_back(); + + // Use free slot to link to next free slot + m_indices.at(index) = m_firstFreeSlot; + m_firstFreeSlot = index; + } + + template + inline DataType& IndexedDataVector::GetData(IndexType index) + { + return m_data.at(m_indices.at(index)); + } + + template + inline const DataType& IndexedDataVector::GetData(IndexType index) const + { + return m_data.at(m_indices.at(index)); + } + + template + inline size_t IndexedDataVector::GetDataCount() const + { + return m_data.size(); + } + + template + inline AZStd::vector& IndexedDataVector::GetDataVector() + { + return m_data; + } + + template + inline const AZStd::vector& IndexedDataVector::GetDataVector() const + { + return m_data; + } + + template + inline AZStd::vector& IndexedDataVector::GetIndexVector() + { + return m_dataToIndices; + } + + template + inline const AZStd::vector& IndexedDataVector::GetIndexVector() const + { + return m_dataToIndices; + } + + template + IndexType IndexedDataVector::GetRawIndex(IndexType index) const + { + return m_indices.at(index); + } +} // namespace AZ::Render diff --git a/Gems/Atom/Feature/Common/Code/Source/CommonSystemComponent.cpp b/Gems/Atom/Feature/Common/Code/Source/CommonSystemComponent.cpp index 6ad0099686..1500079b00 100644 --- a/Gems/Atom/Feature/Common/Code/Source/CommonSystemComponent.cpp +++ b/Gems/Atom/Feature/Common/Code/Source/CommonSystemComponent.cpp @@ -284,7 +284,7 @@ namespace AZ passSystem->AddPassCreator(Name("ReflectionScreenSpaceCompositePass"), &Render::ReflectionScreenSpaceCompositePass::Create); passSystem->AddPassCreator(Name("ReflectionCopyFrameBufferPass"), &Render::ReflectionCopyFrameBufferPass::Create); - // Add RayTracing pas + // Add RayTracing pass passSystem->AddPassCreator(Name("RayTracingPass"), &Render::RayTracingPass::Create); // setup handler for load pass template mappings diff --git a/Gems/Atom/Feature/Common/Code/Source/CoreLights/CapsuleLightFeatureProcessor.h b/Gems/Atom/Feature/Common/Code/Source/CoreLights/CapsuleLightFeatureProcessor.h index a85831e290..6749acfcf5 100644 --- a/Gems/Atom/Feature/Common/Code/Source/CoreLights/CapsuleLightFeatureProcessor.h +++ b/Gems/Atom/Feature/Common/Code/Source/CoreLights/CapsuleLightFeatureProcessor.h @@ -10,7 +10,7 @@ #include #include -#include +#include #include namespace AZ diff --git a/Gems/Atom/Feature/Common/Code/Source/CoreLights/DirectionalLightFeatureProcessor.h b/Gems/Atom/Feature/Common/Code/Source/CoreLights/DirectionalLightFeatureProcessor.h index a312b31dda..4c486c4540 100644 --- a/Gems/Atom/Feature/Common/Code/Source/CoreLights/DirectionalLightFeatureProcessor.h +++ b/Gems/Atom/Feature/Common/Code/Source/CoreLights/DirectionalLightFeatureProcessor.h @@ -9,9 +9,9 @@ #pragma once #include -#include #include +#include #include #include #include diff --git a/Gems/Atom/Feature/Common/Code/Source/CoreLights/DiskLightFeatureProcessor.h b/Gems/Atom/Feature/Common/Code/Source/CoreLights/DiskLightFeatureProcessor.h index 2e97ae1ded..36837a67fb 100644 --- a/Gems/Atom/Feature/Common/Code/Source/CoreLights/DiskLightFeatureProcessor.h +++ b/Gems/Atom/Feature/Common/Code/Source/CoreLights/DiskLightFeatureProcessor.h @@ -11,7 +11,7 @@ #include #include #include -#include +#include #include namespace AZ diff --git a/Gems/Atom/Feature/Common/Code/Source/CoreLights/IndexedDataVector.h b/Gems/Atom/Feature/Common/Code/Source/CoreLights/IndexedDataVector.h deleted file mode 100644 index f2a372aca9..0000000000 --- a/Gems/Atom/Feature/Common/Code/Source/CoreLights/IndexedDataVector.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. - * For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#pragma once - -#include -#include - -namespace AZ -{ - namespace Render - { - template - class IndexedDataVector - { - public: - IndexedDataVector(); - ~IndexedDataVector() = default; - - static constexpr IndexType NoFreeSlot = std::numeric_limits::max(); - IndexType m_firstFreeSlot = NoFreeSlot; - - void Clear(); - IndexType GetFreeSlotIndex(); - void RemoveIndex(IndexType index); - - DataType& GetData(IndexType index); - const DataType& GetData(IndexType index) const; - size_t GetDataCount() const; - - AZStd::vector& GetDataVector(); - const AZStd::vector& GetDataVector() const; - - IndexType GetRawIndex(IndexType index) const; - - private: - - static constexpr size_t InitialReservedCount = 128; - - // stores the index of data vector for respective light, it also include a linked list to flag the free slots - AZStd::vector m_indices; - // stores the index of index vector for respective light - AZStd::vector m_dataToIndices; - // stores light data - AZStd::vector m_data; - }; - -#include "IndexedDataVector.inl" - } -} diff --git a/Gems/Atom/Feature/Common/Code/Source/CoreLights/IndexedDataVector.inl b/Gems/Atom/Feature/Common/Code/Source/CoreLights/IndexedDataVector.inl deleted file mode 100644 index da10e5a503..0000000000 --- a/Gems/Atom/Feature/Common/Code/Source/CoreLights/IndexedDataVector.inl +++ /dev/null @@ -1,113 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. - * For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -template -inline IndexedDataVector::IndexedDataVector() -{ - m_dataToIndices.reserve(InitialReservedCount); - m_indices.reserve(InitialReservedCount); - m_data.reserve(InitialReservedCount); -} - -template -inline void IndexedDataVector::Clear() -{ - m_dataToIndices.clear(); - m_indices.clear(); - m_data.clear(); - - m_firstFreeSlot = NoFreeSlot; -} - -template -inline IndexType IndexedDataVector::GetFreeSlotIndex() -{ - IndexType freeSlotIndex = static_cast(m_indices.size()); - - if (freeSlotIndex == NoFreeSlot) - { - // the vector is full - return NoFreeSlot; - } - - if (m_firstFreeSlot == NoFreeSlot) - { - // If there's no free slot, add on to the end. - m_indices.push_back(freeSlotIndex); - } - else - { - // Fill the free slot. m_indices uses it's empty slots to store a linked list (via indices) to other empty slots. - freeSlotIndex = m_firstFreeSlot; - m_firstFreeSlot = m_indices.at(m_firstFreeSlot); - m_indices.at(freeSlotIndex) = static_cast(m_data.size()); - } - - // The data itself is always packed and m_indices points at it, so push a new entry to the back. - m_data.push_back(DataType()); - m_dataToIndices.push_back(freeSlotIndex); - - return freeSlotIndex; -} - -template -inline void IndexedDataVector::RemoveIndex(IndexType index) -{ - IndexType dataIndex = m_indices.at(index); - - // Copy the back light on top of this one. - m_data.at(dataIndex) = m_data.back(); - m_dataToIndices.at(dataIndex) = m_dataToIndices.back(); - - // Update the index of the moved light - m_indices.at(m_dataToIndices.at(dataIndex)) = dataIndex; - - // Pop the back - m_data.pop_back(); - m_dataToIndices.pop_back(); - - // Use free slot to link to next free slot - m_indices.at(index) = m_firstFreeSlot; - m_firstFreeSlot = index; -} - -template -inline DataType& IndexedDataVector::GetData(IndexType index) -{ - return m_data.at(m_indices.at(index)); -} - -template -inline const DataType& IndexedDataVector::GetData(IndexType index) const -{ - return m_data.at(m_indices.at(index)); -} - -template -inline size_t IndexedDataVector::GetDataCount() const -{ - return m_data.size(); -} - -template -inline AZStd::vector& IndexedDataVector::GetDataVector() -{ - return m_data; -} - -template -inline const AZStd::vector& IndexedDataVector::GetDataVector() const -{ - return m_data; -} - -template -IndexType IndexedDataVector::GetRawIndex(IndexType index) const -{ - return m_indices.at(index); -} diff --git a/Gems/Atom/Feature/Common/Code/Source/CoreLights/PointLightFeatureProcessor.h b/Gems/Atom/Feature/Common/Code/Source/CoreLights/PointLightFeatureProcessor.h index b7b644da9e..3c231c1fb0 100644 --- a/Gems/Atom/Feature/Common/Code/Source/CoreLights/PointLightFeatureProcessor.h +++ b/Gems/Atom/Feature/Common/Code/Source/CoreLights/PointLightFeatureProcessor.h @@ -11,7 +11,7 @@ #include #include #include -#include +#include #include namespace AZ diff --git a/Gems/Atom/Feature/Common/Code/Source/CoreLights/QuadLightFeatureProcessor.h b/Gems/Atom/Feature/Common/Code/Source/CoreLights/QuadLightFeatureProcessor.h index 567d309dff..17d6aab304 100644 --- a/Gems/Atom/Feature/Common/Code/Source/CoreLights/QuadLightFeatureProcessor.h +++ b/Gems/Atom/Feature/Common/Code/Source/CoreLights/QuadLightFeatureProcessor.h @@ -10,7 +10,7 @@ #include #include -#include +#include namespace AZ { diff --git a/Gems/Atom/Feature/Common/Code/Source/CoreLights/SimplePointLightFeatureProcessor.h b/Gems/Atom/Feature/Common/Code/Source/CoreLights/SimplePointLightFeatureProcessor.h index 3d36bb1978..bd9160b171 100644 --- a/Gems/Atom/Feature/Common/Code/Source/CoreLights/SimplePointLightFeatureProcessor.h +++ b/Gems/Atom/Feature/Common/Code/Source/CoreLights/SimplePointLightFeatureProcessor.h @@ -11,7 +11,7 @@ #include #include #include -#include +#include namespace AZ { diff --git a/Gems/Atom/Feature/Common/Code/Source/CoreLights/SimpleSpotLightFeatureProcessor.h b/Gems/Atom/Feature/Common/Code/Source/CoreLights/SimpleSpotLightFeatureProcessor.h index 1d72c3e6cc..bc132be77c 100644 --- a/Gems/Atom/Feature/Common/Code/Source/CoreLights/SimpleSpotLightFeatureProcessor.h +++ b/Gems/Atom/Feature/Common/Code/Source/CoreLights/SimpleSpotLightFeatureProcessor.h @@ -11,7 +11,7 @@ #include #include #include -#include +#include namespace AZ { diff --git a/Gems/Atom/Feature/Common/Code/Source/Decals/DecalTextureArrayFeatureProcessor.h b/Gems/Atom/Feature/Common/Code/Source/Decals/DecalTextureArrayFeatureProcessor.h index 649928d26d..57c5c69e0d 100644 --- a/Gems/Atom/Feature/Common/Code/Source/Decals/DecalTextureArrayFeatureProcessor.h +++ b/Gems/Atom/Feature/Common/Code/Source/Decals/DecalTextureArrayFeatureProcessor.h @@ -9,6 +9,7 @@ #pragma once #include +#include #include #include #include @@ -16,7 +17,6 @@ #include #include #include -#include namespace AZ { diff --git a/Gems/Atom/Feature/Common/Code/Source/Shadows/ProjectedShadowFeatureProcessor.h b/Gems/Atom/Feature/Common/Code/Source/Shadows/ProjectedShadowFeatureProcessor.h index 3dbf88addb..8beed800b6 100644 --- a/Gems/Atom/Feature/Common/Code/Source/Shadows/ProjectedShadowFeatureProcessor.h +++ b/Gems/Atom/Feature/Common/Code/Source/Shadows/ProjectedShadowFeatureProcessor.h @@ -10,10 +10,10 @@ #include #include +#include #include #include #include -#include namespace AZ::Render { diff --git a/Gems/Atom/Feature/Common/Code/atom_feature_common_files.cmake b/Gems/Atom/Feature/Common/Code/atom_feature_common_files.cmake index 401fac8c0c..40188109ca 100644 --- a/Gems/Atom/Feature/Common/Code/atom_feature_common_files.cmake +++ b/Gems/Atom/Feature/Common/Code/atom_feature_common_files.cmake @@ -37,6 +37,8 @@ set(FILES Include/Atom/Feature/TransformService/TransformServiceFeatureProcessor.h Include/Atom/Feature/Utils/FrameCaptureBus.h Include/Atom/Feature/Utils/GpuBufferHandler.h + Include/Atom/Feature/Utils/IndexedDataVector.h + Include/Atom/Feature/Utils/IndexedDataVector.inl Include/Atom/Feature/Utils/MultiIndexedDataVector.h Include/Atom/Feature/Utils/MultiSparseVector.h Include/Atom/Feature/Utils/ProfilingCaptureBus.h @@ -77,8 +79,6 @@ set(FILES Source/CoreLights/DiskLightFeatureProcessor.cpp Source/CoreLights/EsmShadowmapsPass.h Source/CoreLights/EsmShadowmapsPass.cpp - Source/CoreLights/IndexedDataVector.h - Source/CoreLights/IndexedDataVector.inl Source/CoreLights/LtcCommon.h Source/CoreLights/LtcCommon.cpp Source/CoreLights/PointLightFeatureProcessor.h diff --git a/Gems/Atom/RHI/Code/Include/Atom/RHI/SwapChain.h b/Gems/Atom/RHI/Code/Include/Atom/RHI/SwapChain.h index 14e9968e42..c1fd4453d4 100644 --- a/Gems/Atom/RHI/Code/Include/Atom/RHI/SwapChain.h +++ b/Gems/Atom/RHI/Code/Include/Atom/RHI/SwapChain.h @@ -81,6 +81,15 @@ namespace AZ AZ_RTTI(SwapChain, "{888B64A5-D956-406F-9C33-CF6A54FC41B0}", Object); +#if defined(PAL_TRAIT_LINUX_WINDOW_MANAGER_XCB) + // On Linux platforms that uses XCB, a resize may occur in the swap chain but the command queue may still + // reference the original surface. This flag is a temporary fix to make sure that all the swap chains + // have finished their resize events before presenting the command queue. + + // [GFX TODO][GHI - 2678] + AZStd::atomic_bool m_resized{ false }; +#endif // PAL_TRAIT_LINUX_WINDOW_MANAGER_XCB + protected: SwapChain(); diff --git a/Gems/Atom/RHI/Code/Source/RHI/SwapChain.cpp b/Gems/Atom/RHI/Code/Source/RHI/SwapChain.cpp index b0501d937d..5fbb83fccf 100644 --- a/Gems/Atom/RHI/Code/Source/RHI/SwapChain.cpp +++ b/Gems/Atom/RHI/Code/Source/RHI/SwapChain.cpp @@ -164,6 +164,10 @@ namespace AZ m_currentImageIndex = 0; } +#if defined(PAL_TRAIT_LINUX_WINDOW_MANAGER_XCB) + m_resized.store(true); +#endif // PAL_TRAIT_LINUX_WINDOW_MANAGER_XCB + return resultCode; } diff --git a/Gems/Atom/RHI/Vulkan/Code/Source/RHI/CommandQueue.cpp b/Gems/Atom/RHI/Vulkan/Code/Source/RHI/CommandQueue.cpp index ca6c829cca..84b4964235 100644 --- a/Gems/Atom/RHI/Vulkan/Code/Source/RHI/CommandQueue.cpp +++ b/Gems/Atom/RHI/Vulkan/Code/Source/RHI/CommandQueue.cpp @@ -42,6 +42,15 @@ namespace AZ void CommandQueue::ExecuteWork(const RHI::ExecuteWorkRequest& rhiRequest) { +#if defined(PAL_TRAIT_LINUX_WINDOW_MANAGER_XCB) + for (RHI::SwapChain* swapChain : rhiRequest.m_swapChainsToPresent) + { + if (!swapChain->m_resized) + { + return; + } + } +#endif // PAL_TRAIT_LINUX_WINDOW_MANAGER_XCB const ExecuteWorkRequest& request = static_cast(rhiRequest); QueueCommand([=](void* queue) { diff --git a/Gems/EMotionFX/Code/EMotionFX/Source/BlendTreeParameterNode.cpp b/Gems/EMotionFX/Code/EMotionFX/Source/BlendTreeParameterNode.cpp index 682657e5bb..8197cae9d0 100644 --- a/Gems/EMotionFX/Code/EMotionFX/Source/BlendTreeParameterNode.cpp +++ b/Gems/EMotionFX/Code/EMotionFX/Source/BlendTreeParameterNode.cpp @@ -395,7 +395,7 @@ namespace EMotionFX } // If new parameter matches the last deleted parameter, we add it back to the parameter mask. - if (!m_deletedParameterNames.empty() && newParameterName == m_deletedParameterNames.back()) + if (!m_deletedParameterNames.empty() && newParameterName == m_deletedParameterNames.top()) { m_parameterNames.push_back(newParameterName); SortAndRemoveDuplicates(GetAnimGraph(), m_parameterNames); // make sure the mask is sorted correctly. diff --git a/Gems/Multiplayer/Code/Source/ReplicationWindows/ServerToClientReplicationWindow.cpp b/Gems/Multiplayer/Code/Source/ReplicationWindows/ServerToClientReplicationWindow.cpp index 740f9abea2..ba9740f8db 100644 --- a/Gems/Multiplayer/Code/Source/ReplicationWindows/ServerToClientReplicationWindow.cpp +++ b/Gems/Multiplayer/Code/Source/ReplicationWindows/ServerToClientReplicationWindow.cpp @@ -107,8 +107,10 @@ namespace Multiplayer void ServerToClientReplicationWindow::UpdateWindow() { // clear the candidate queue, we're going to rebuild it - ReplicationCandidateQueue clearQueue; - clearQueue.get_container().reserve(sv_MaxEntitiesToTrackReplication); + ReplicationCandidateQueue::container_type clearQueueContainer; + clearQueueContainer.reserve(sv_MaxEntitiesToTrackReplication); + // Move the clearQueueContainer into the ReplicationCandidateQueue to maintain the reserved memory + ReplicationCandidateQueue clearQueue(ReplicationCandidateQueue::value_compare{}, AZStd::move(clearQueueContainer)); m_candidateQueue.swap(clearQueue); m_replicationSet.clear(); diff --git a/Gems/PhysX/Code/Source/SystemComponent.cpp b/Gems/PhysX/Code/Source/SystemComponent.cpp index af38927f10..d8c4b47a2a 100644 --- a/Gems/PhysX/Code/Source/SystemComponent.cpp +++ b/Gems/PhysX/Code/Source/SystemComponent.cpp @@ -95,6 +95,7 @@ namespace PhysX { serialize->Class() ->Version(1) + ->Attribute(AZ::Edit::Attributes::SystemComponentTags, AZStd::vector({ AZ_CRC_CE("AssetBuilder") })) ->Field("Enabled", &SystemComponent::m_enabled) ; @@ -122,13 +123,14 @@ namespace PhysX incompatible.push_back(AZ_CRC("PhysXService", 0x75beae2d)); } - void SystemComponent::GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required) + void SystemComponent::GetRequiredServices([[maybe_unused]] AZ::ComponentDescriptor::DependencyArrayType& required) { - required.push_back(AZ_CRC("AssetDatabaseService", 0x3abf5601)); } - void SystemComponent::GetDependentServices([[maybe_unused]]AZ::ComponentDescriptor::DependencyArrayType& dependent) + void SystemComponent::GetDependentServices(AZ::ComponentDescriptor::DependencyArrayType& dependent) { + dependent.push_back(AZ_CRC_CE("AssetDatabaseService")); + dependent.push_back(AZ_CRC_CE("AssetCatalogService")); } SystemComponent::SystemComponent() diff --git a/Gems/ScriptEvents/Code/Include/ScriptEvents/Internal/VersionedProperty.h b/Gems/ScriptEvents/Code/Include/ScriptEvents/Internal/VersionedProperty.h index 07d85adf05..b308a074e0 100644 --- a/Gems/ScriptEvents/Code/Include/ScriptEvents/Internal/VersionedProperty.h +++ b/Gems/ScriptEvents/Code/Include/ScriptEvents/Internal/VersionedProperty.h @@ -109,7 +109,7 @@ namespace ScriptEventData { VersionedProperty property = VersionedProperty("Void"); property.Set(VoidType {}); - return AZStd::ref(property); + return property; } template