Merge pull request #322 from aws-lumberyard-dev/Atom/qingtao/ATOM-6088
ATOM-6088 Unified approach to send draws to a single viewport
Created a template class TagRegistery which implements the previous DrawListTagRegistry. The template is used for both DrawListTagRegistry and DrawFilterTagRegistry
Added DrawFilterTag to DrawItemKeyPair
Added DrawFilterMask support in DrawPacket and DrawPacketBuilder
Added CreateDynamicContext for render pipeline which allows draw to selected render pipeline.
Updated RasterPass's BuildCommandListInternal function to filter draw items for its owner RenderPipeline.
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <Atom/RHI/DrawItem.h>
|
||||
#include <Atom/RHI/TagRegistry.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
namespace RHI
|
||||
{
|
||||
using DrawFilterTagRegistry = TagRegistry<DrawFilterTag, Limits::Pipeline::DrawFilterTagCountMax>;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user