Merge branch 'development' into Prefab/ClearEntityMapsTogether
Signed-off-by: srikappa-amzn <srikappa@amazon.com>
This commit is contained in:
@@ -103,7 +103,7 @@
|
||||
AZ_CVAR(
|
||||
bool, ed_visibility_logTiming, false, nullptr, AZ::ConsoleFunctorFlags::Null, "Output the timing of the new IVisibilitySystem query");
|
||||
AZ_CVAR(bool, ed_useNewCameraSystem, true, nullptr, AZ::ConsoleFunctorFlags::Null, "Use the new Editor camera system");
|
||||
AZ_CVAR(bool, ed_showCursorCameraLook, false, nullptr, AZ::ConsoleFunctorFlags::Null, "Show the cursor when using free look with the new camera system");
|
||||
AZ_CVAR(bool, ed_showCursorCameraLook, true, nullptr, AZ::ConsoleFunctorFlags::Null, "Show the cursor when using free look with the new camera system");
|
||||
|
||||
namespace SandboxEditor
|
||||
{
|
||||
|
||||
@@ -18,6 +18,10 @@ namespace AZ
|
||||
{
|
||||
namespace RPI
|
||||
{
|
||||
class Scene;
|
||||
class RenderPipeline;
|
||||
class RasterPass;
|
||||
|
||||
//! This class helps setup dynamic draw data as well as provide draw functions to draw dynamic items.
|
||||
//! The draw calls added to the context are only valid for one frame.
|
||||
//! DynamicDrawContext is only associated with
|
||||
@@ -80,17 +84,20 @@ namespace AZ
|
||||
//! This function can only be called before EndInit() is called
|
||||
void AddDrawStateOptions(DrawStateOptions options);
|
||||
|
||||
//! Call any one of these functions to decide which scope this DynamicDrawContext may draw to.
|
||||
//! One of the function has to be called once before EndInit() is called.
|
||||
//! After DynamicDrawContext is initialized, the output scope can be changed.
|
||||
//! But it has to be called after existing draw calls are submitted.
|
||||
//! @Param scene Draw calls made with this DynamicDrawContext will be submit to this scene
|
||||
//! @Param pipeline Draw calls made with this DynamicDrawContext will be submit to this render pipeline
|
||||
//! @Param pass Draw calls made with this DynamicDrawContext will only be submit to this pass
|
||||
void SetOutputScope(Scene* scene);
|
||||
void SetOutputScope(RenderPipeline* pipeline);
|
||||
void SetOutputScope(RasterPass* pass);
|
||||
|
||||
//! Finalize and validate initialization. Any initialization functions should be called before EndInit is called.
|
||||
void EndInit();
|
||||
|
||||
//! Set up the DynamicDrawContext for the input Scene.
|
||||
//! This should be called after the last frame is done and before any draw calls.
|
||||
void SetScene(Scene* scene);
|
||||
|
||||
//! Set up the DynamicDrawContext for the input RenderPipeline.
|
||||
//! This should be called after the last frame is done and before any draw calls.
|
||||
void SetRenderPipeline(RenderPipeline* pipeline);
|
||||
|
||||
//! Return if this DynamicDrawContext is ready to add draw calls
|
||||
bool IsReady();
|
||||
|
||||
@@ -177,14 +184,21 @@ namespace AZ
|
||||
DynamicDrawContext() = default;
|
||||
|
||||
// Submit draw items to a view
|
||||
void SubmitDrawData(ViewPtr view);
|
||||
void SubmitDrawList(ViewPtr view);
|
||||
|
||||
// Finalize the draw list for all submiited draws.
|
||||
void FinalizeDrawList();
|
||||
|
||||
RHI::DrawListView GetDrawList();
|
||||
|
||||
// Reset cached draw data when frame is end (draw data was submitted)
|
||||
void FrameEnd();
|
||||
|
||||
void ReInit();
|
||||
|
||||
// Get rhi pipeline state which matches current states
|
||||
const RHI::PipelineState* GetCurrentPipelineState();
|
||||
|
||||
|
||||
struct MultiStates
|
||||
{
|
||||
// states available for change
|
||||
@@ -230,10 +244,22 @@ namespace AZ
|
||||
// Draw variations allowed in this DynamicDrawContext
|
||||
DrawStateOptions m_drawStateOptions;
|
||||
|
||||
// For generate output attachment layout and filter draw items
|
||||
Scene* m_scene = nullptr;
|
||||
// DrawListTag used to help setup PipelineState's output
|
||||
// and also for submitting draw items to views
|
||||
RHI::DrawListTag m_drawListTag;
|
||||
|
||||
// Output scope related
|
||||
enum class OutputScopeType
|
||||
{
|
||||
Unset,
|
||||
Scene,
|
||||
RenderPipeline,
|
||||
RasterPass
|
||||
};
|
||||
Scene* m_scene = nullptr;
|
||||
RasterPass* m_pass = nullptr;
|
||||
OutputScopeType m_outputScope = OutputScopeType::Unset;
|
||||
|
||||
// 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;
|
||||
@@ -242,19 +268,22 @@ namespace AZ
|
||||
AZStd::vector<RHI::StreamBufferView> m_cachedStreamBufferViews;
|
||||
AZStd::vector<RHI::IndexBufferView> m_cachedIndexBufferViews;
|
||||
AZStd::vector<Data::Instance<ShaderResourceGroup>> m_cachedDrawSrg;
|
||||
|
||||
|
||||
// structure includes DrawItem and stream and index buffer index
|
||||
static const uint32_t InvalidIndex = static_cast<uint32_t>(-1);
|
||||
using BufferViewIndexType = uint32_t;
|
||||
static const BufferViewIndexType InvalidIndex = static_cast<BufferViewIndexType>(-1);
|
||||
struct DrawItemInfo
|
||||
{
|
||||
RHI::DrawItem m_drawItem;
|
||||
RHI::DrawItemSortKey m_sortKey;
|
||||
uint32_t m_vertexBufferViewIndex = InvalidIndex;
|
||||
uint32_t m_indexBufferViewIndex = InvalidIndex;
|
||||
BufferViewIndexType m_vertexBufferViewIndex = InvalidIndex;
|
||||
BufferViewIndexType m_indexBufferViewIndex = InvalidIndex;
|
||||
};
|
||||
|
||||
AZStd::vector<DrawItemInfo> m_cachedDrawItems;
|
||||
|
||||
// Cached draw list for render to rasterpass
|
||||
RHI::DrawList m_cachedDrawList;
|
||||
|
||||
// Flags if this DynamicDrawContext can change shader variants
|
||||
bool m_supportShaderVariants = false;
|
||||
ShaderVariantId m_currentShaderVariantId;
|
||||
@@ -266,6 +295,8 @@ namespace AZ
|
||||
bool m_initialized = false;
|
||||
|
||||
RHI::DrawItemSortKey m_sortKey = 0;
|
||||
|
||||
bool m_drawFinalized = false;
|
||||
};
|
||||
|
||||
AZ_DEFINE_ENUM_BITWISE_OPERATORS(AZ::RPI::DynamicDrawContext::DrawStateOptions);
|
||||
|
||||
@@ -48,15 +48,9 @@ namespace AZ
|
||||
|
||||
AZ_DISABLE_COPY_MOVE(DynamicDrawInterface);
|
||||
|
||||
//! Create a DynamicDrawContext for specified scene (and render pipeline).
|
||||
//! Draw calls which are made to this DynamicDrawContext will only be submitted for this scene.
|
||||
//! Create a DynamicDrawContext
|
||||
//! The created DynamicDrawContext is managed by dynamic draw system.
|
||||
virtual RHI::Ptr<DynamicDrawContext> CreateDynamicDrawContext(Scene* scene) = 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;
|
||||
virtual RHI::Ptr<DynamicDrawContext> CreateDynamicDrawContext() = 0;
|
||||
|
||||
//! Get a DynamicBuffer from DynamicDrawSystem.
|
||||
//! The returned buffer will be invalidated every time the RPISystem's RenderTick is called
|
||||
@@ -69,6 +63,9 @@ namespace AZ
|
||||
//! Note that ownership of the DrawPacket pointer is passed to the dynamic draw system.
|
||||
//! (it will be cleaned up correctly since the DrawPacket keeps track of the allocator that was used when it was built)
|
||||
virtual void AddDrawPacket(Scene* scene, AZStd::unique_ptr<const RHI::DrawPacket> drawPacket) = 0;
|
||||
|
||||
//! Get DrawLists from any DynamicDrawContext which output to the specified RasterPass.
|
||||
virtual AZStd::vector<RHI::DrawListView> GetDrawListsForPass(const RasterPass* pass) = 0;
|
||||
};
|
||||
|
||||
//! Global function to query the DynamicDrawInterface.
|
||||
|
||||
@@ -31,14 +31,15 @@ namespace AZ
|
||||
void Shutdown();
|
||||
|
||||
// DynamicDrawInterface overrides...
|
||||
RHI::Ptr<DynamicDrawContext> CreateDynamicDrawContext(Scene* scene) override;
|
||||
RHI::Ptr<DynamicDrawContext> CreateDynamicDrawContext(RenderPipeline* pipeline) override;
|
||||
RHI::Ptr<DynamicDrawContext> CreateDynamicDrawContext() 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;
|
||||
AZStd::vector<RHI::DrawListView> GetDrawListsForPass(const RasterPass* pass) override;
|
||||
|
||||
// Submit draw data for selected scene and pipeline
|
||||
void SubmitDrawData(Scene* scene, AZStd::vector<ViewPtr> views);
|
||||
|
||||
protected:
|
||||
|
||||
void FrameEnd();
|
||||
|
||||
@@ -55,6 +55,9 @@ namespace AZ
|
||||
void CompileResources(const RHI::FrameGraphCompileContext& context) override;
|
||||
void BuildCommandListInternal(const RHI::FrameGraphExecuteContext& context) override;
|
||||
|
||||
// Retrieve draw lists from view and dynamic draw system and generate final draw list
|
||||
void UpdateDrawList();
|
||||
|
||||
// The draw list tag used to fetch the draw list from the views
|
||||
RHI::DrawListTag m_drawListTag;
|
||||
|
||||
@@ -62,8 +65,12 @@ namespace AZ
|
||||
// This is the index of the pipeline state data that corresponds to this pass in the array of pipeline state data
|
||||
RHI::Handle<> m_pipelineStateDataIndex;
|
||||
|
||||
// The draw list returned from the view
|
||||
// The reference of the draw list to be drawn
|
||||
RHI::DrawListView m_drawListView;
|
||||
|
||||
// If there are more than one draw lists from different source: View, DynamicDrawSystem,
|
||||
// we need to creates a combined draw list which combines all the draw lists to one and cache it until they are submitted.
|
||||
RHI::DrawList m_combinedDrawList;
|
||||
|
||||
RHI::Scissor m_scissorState;
|
||||
RHI::Viewport m_viewportState;
|
||||
|
||||
@@ -13,6 +13,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/Pass/RasterPass.h>
|
||||
#include <Atom/RPI.Public/RenderPipeline.h>
|
||||
|
||||
#include <Atom/RPI.Public/View.h>
|
||||
@@ -173,9 +174,7 @@ namespace AZ
|
||||
|
||||
void DynamicDrawContext::EndInit()
|
||||
{
|
||||
AZ_Assert(m_scene != nullptr, "DynamicDrawContext should always belong to a scene");
|
||||
|
||||
AZ_Warning("RPI", m_pipelineState, "Failed to initialized shader for DynamicDrawContext");
|
||||
AZ_Warning("RPI", m_pipelineState, "Failed to initialize shader for DynamicDrawContext");
|
||||
AZ_Warning("RPI", m_drawListTag.IsValid(), "DynamicDrawContext doesn't have a valid DrawListTag");
|
||||
|
||||
if (!m_drawListTag.IsValid() || m_pipelineState == nullptr)
|
||||
@@ -183,8 +182,27 @@ namespace AZ
|
||||
return;
|
||||
}
|
||||
|
||||
m_pipelineState->SetOutputFromScene(m_scene, m_drawListTag);
|
||||
m_pipelineState->Finalize();
|
||||
if (m_outputScope == OutputScopeType::RenderPipeline || m_outputScope == OutputScopeType::Scene)
|
||||
{
|
||||
m_pipelineState->SetOutputFromScene(m_scene, m_drawListTag);
|
||||
}
|
||||
else if (m_outputScope == OutputScopeType::RasterPass)
|
||||
{
|
||||
m_pipelineState->SetOutputFromPass(m_pass);
|
||||
}
|
||||
else
|
||||
{
|
||||
AZ_Assert(false, "DynamicDrawContext need to set output scope before end initialization");
|
||||
return;
|
||||
}
|
||||
|
||||
m_rhiPipelineState = m_pipelineState->Finalize();
|
||||
|
||||
if (!m_rhiPipelineState)
|
||||
{
|
||||
AZ_Warning("RPI", false, "Failed to initialize PipelineState for DynamicDrawContext");
|
||||
return;
|
||||
}
|
||||
m_initialized = true;
|
||||
|
||||
// Acquire MultiStates from m_pipelineState
|
||||
@@ -199,16 +217,58 @@ namespace AZ
|
||||
m_rhiPipelineState = m_pipelineState->GetRHIPipelineState();
|
||||
}
|
||||
|
||||
void DynamicDrawContext::SetScene(Scene* scene)
|
||||
void DynamicDrawContext::SetOutputScope(Scene* scene)
|
||||
{
|
||||
AZ_Assert(scene, "SetScene called with an invalid scene");
|
||||
if (!scene || m_scene == scene)
|
||||
AZ_Assert(scene, "SetOutputScope was called with an invalid Scene");
|
||||
if (!scene)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
m_outputScope = OutputScopeType::Scene;
|
||||
m_scene = scene;
|
||||
m_pass = nullptr;
|
||||
m_drawFilter = RHI::DrawFilterMaskDefaultValue;
|
||||
// Reinitialize if it was initialized
|
||||
|
||||
ReInit();
|
||||
}
|
||||
|
||||
void DynamicDrawContext::SetOutputScope(RenderPipeline* pipeline)
|
||||
{
|
||||
AZ_Assert(pipeline, "SetOutputScope was called with an invalid RenderPipeline");
|
||||
AZ_Assert(pipeline->GetScene(), "SetOutputScope called with a RenderPipeline without adding to a scene");
|
||||
if (!pipeline || !pipeline->GetScene())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
m_outputScope = OutputScopeType::RenderPipeline;
|
||||
m_scene = pipeline->GetScene();
|
||||
m_pass = nullptr;
|
||||
m_drawFilter = pipeline->GetDrawFilterMask();
|
||||
|
||||
ReInit();
|
||||
}
|
||||
|
||||
void DynamicDrawContext::SetOutputScope(RasterPass* pass)
|
||||
{
|
||||
AZ_Assert(pass, "SetOutputScope was called with an invalid RasterPass");
|
||||
if (!pass)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
m_outputScope = OutputScopeType::RasterPass;
|
||||
m_scene = nullptr;
|
||||
m_pass = pass;
|
||||
m_drawFilter = RHI::DrawFilterMaskDefaultValue;
|
||||
|
||||
ReInit();
|
||||
}
|
||||
|
||||
void DynamicDrawContext::ReInit()
|
||||
{
|
||||
// Reinitialize if it was initialized
|
||||
if (m_initialized)
|
||||
{
|
||||
// Report warning if there were some draw data
|
||||
@@ -224,17 +284,6 @@ namespace AZ
|
||||
}
|
||||
}
|
||||
|
||||
void DynamicDrawContext::SetRenderPipeline(RenderPipeline* pipeline)
|
||||
{
|
||||
AZ_Assert(pipeline, "SetRenderPipeline called with an invalid pipeline");
|
||||
if (!pipeline)
|
||||
{
|
||||
return;
|
||||
}
|
||||
SetScene(pipeline->GetScene());
|
||||
m_drawFilter = pipeline->GetDrawFilterMask();
|
||||
}
|
||||
|
||||
bool DynamicDrawContext::IsReady()
|
||||
{
|
||||
return m_initialized;
|
||||
@@ -402,10 +451,16 @@ namespace AZ
|
||||
AZ_Assert(false, "DynamicDrawContext isn't initialized");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!m_drawSrgLayout)
|
||||
|
||||
if (m_drawFinalized)
|
||||
{
|
||||
AZ_Assert(false, "PerDrawSrg need to be provided since the shader uses it");
|
||||
AZ_Assert(false, "Can't add draw calls after draw data was finalized");
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_drawSrgLayout && !drawSrg)
|
||||
{
|
||||
AZ_Assert(false, "drawSrg need to be provided since the shader requires it");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -446,12 +501,12 @@ namespace AZ
|
||||
vertexBuffer->Write(vertexData, vertexDataSize);
|
||||
m_cachedStreamBufferViews.push_back(vertexBuffer->GetStreamBufferView(m_perVertexDataSize));
|
||||
drawItem.m_streamBufferViewCount = 1;
|
||||
drawItemInfo.m_vertexBufferViewIndex = uint32_t(m_cachedStreamBufferViews.size() - 1);
|
||||
drawItemInfo.m_vertexBufferViewIndex = static_cast<BufferViewIndexType>(m_cachedStreamBufferViews.size() - 1);
|
||||
|
||||
// Write data to index buffer and set up index buffer view for DrawItem
|
||||
indexBuffer->Write(indexData, indexDataSize);
|
||||
m_cachedIndexBufferViews.push_back(indexBuffer->GetIndexBufferView(indexFormat));
|
||||
drawItemInfo.m_indexBufferViewIndex = uint32_t(m_cachedIndexBufferViews.size() - 1);
|
||||
drawItemInfo.m_indexBufferViewIndex = static_cast<BufferViewIndexType>(m_cachedIndexBufferViews.size() - 1);
|
||||
|
||||
// Setup per context srg if it exists
|
||||
if (m_srgPerContext)
|
||||
@@ -487,7 +542,7 @@ namespace AZ
|
||||
drawItemInfo.m_sortKey = m_sortKey++;
|
||||
m_cachedDrawItems.emplace_back(drawItemInfo);
|
||||
}
|
||||
|
||||
|
||||
void DynamicDrawContext::DrawLinear(const void* vertexData, uint32_t vertexCount, Data::Instance<ShaderResourceGroup> drawSrg)
|
||||
{
|
||||
if (!m_initialized)
|
||||
@@ -496,9 +551,15 @@ namespace AZ
|
||||
return;
|
||||
}
|
||||
|
||||
if (!m_drawSrgLayout)
|
||||
if (m_drawFinalized)
|
||||
{
|
||||
AZ_Assert(false, "PerDrawSrg need to be provided since the shader uses it");
|
||||
AZ_Assert(false, "Can't add draw calls after draw data was finalized");
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_drawSrgLayout && !drawSrg)
|
||||
{
|
||||
AZ_Assert(false, "drawSrg need to be provided since the shader requires it");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -569,7 +630,6 @@ namespace AZ
|
||||
m_cachedDrawItems.emplace_back(drawItemInfo);
|
||||
}
|
||||
|
||||
|
||||
Data::Instance<ShaderResourceGroup> DynamicDrawContext::NewDrawSrg()
|
||||
{
|
||||
if (!m_drawSrgLayout)
|
||||
@@ -626,18 +686,14 @@ namespace AZ
|
||||
return m_sortKey;
|
||||
}
|
||||
|
||||
void DynamicDrawContext::SubmitDrawData(ViewPtr view)
|
||||
void DynamicDrawContext::FinalizeDrawList()
|
||||
{
|
||||
if (!m_initialized)
|
||||
if (m_drawFinalized)
|
||||
{
|
||||
return;
|
||||
}
|
||||
AZ_Assert(m_cachedDrawList.size() == 0, "m_cachedDrawList should be cleared ine the end of last frame ");
|
||||
|
||||
if (!view->HasDrawListTag(m_drawListTag))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (auto& drawItemInfo : m_cachedDrawItems)
|
||||
{
|
||||
if (drawItemInfo.m_indexBufferViewIndex != InvalidIndex)
|
||||
@@ -654,10 +710,34 @@ namespace AZ
|
||||
drawItemProperties.m_sortKey = drawItemInfo.m_sortKey;
|
||||
drawItemProperties.m_item = &drawItemInfo.m_drawItem;
|
||||
drawItemProperties.m_drawFilterMask = m_drawFilter;
|
||||
m_cachedDrawList.emplace_back(drawItemProperties);
|
||||
}
|
||||
m_drawFinalized = true;
|
||||
}
|
||||
|
||||
void DynamicDrawContext::SubmitDrawList(ViewPtr view)
|
||||
{
|
||||
if (!m_initialized || m_outputScope == OutputScopeType::RasterPass)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!view->HasDrawListTag(m_drawListTag))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (auto& drawItemProperties : m_cachedDrawList)
|
||||
{
|
||||
view->AddDrawItem(m_drawListTag, drawItemProperties);
|
||||
}
|
||||
}
|
||||
|
||||
RHI::DrawListView DynamicDrawContext::GetDrawList()
|
||||
{
|
||||
return m_cachedDrawList;
|
||||
}
|
||||
|
||||
void DynamicDrawContext::FrameEnd()
|
||||
{
|
||||
m_sortKey = 0;
|
||||
@@ -665,6 +745,8 @@ namespace AZ
|
||||
m_cachedStreamBufferViews.clear();
|
||||
m_cachedIndexBufferViews.clear();
|
||||
m_cachedDrawSrg.clear();
|
||||
m_cachedDrawList.clear();
|
||||
m_drawFinalized = false;
|
||||
}
|
||||
|
||||
const RHI::PipelineState* DynamicDrawContext::GetCurrentPipelineState()
|
||||
|
||||
@@ -53,34 +53,14 @@ namespace AZ
|
||||
return m_bufferAlloc->Allocate(size, alignment);
|
||||
}
|
||||
|
||||
RHI::Ptr<DynamicDrawContext> DynamicDrawSystem::CreateDynamicDrawContext(Scene* scene)
|
||||
RHI::Ptr<DynamicDrawContext> DynamicDrawSystem::CreateDynamicDrawContext()
|
||||
{
|
||||
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;
|
||||
|
||||
AZStd::lock_guard<AZStd::mutex> lock(m_mutexDrawContext);
|
||||
m_dynamicDrawContexts.push_back(drawContext);
|
||||
return drawContext;
|
||||
}
|
||||
|
||||
RHI::Ptr<DynamicDrawContext> DynamicDrawSystem::CreateDynamicDrawContext(RenderPipeline* pipeline)
|
||||
{
|
||||
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
|
||||
void DynamicDrawSystem::DrawGeometry([[maybe_unused]] Data::Instance<Material> material, [[maybe_unused]] const GeometryData& geometry, [[maybe_unused]] ScenePtr scene)
|
||||
{
|
||||
@@ -101,9 +81,10 @@ namespace AZ
|
||||
{
|
||||
if (drawContext->m_scene == scene)
|
||||
{
|
||||
drawContext->FinalizeDrawList();
|
||||
for (auto& view : views)
|
||||
{
|
||||
drawContext->SubmitDrawData(view);
|
||||
drawContext->SubmitDrawList(view);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -121,6 +102,25 @@ namespace AZ
|
||||
}
|
||||
}
|
||||
|
||||
AZStd::vector<RHI::DrawListView> DynamicDrawSystem::GetDrawListsForPass(const RasterPass* pass)
|
||||
{
|
||||
AZStd::vector<RHI::DrawListView> result;
|
||||
AZStd::lock_guard<AZStd::mutex> lock(m_mutexDrawContext);
|
||||
for (RHI::Ptr<DynamicDrawContext> drawContext : m_dynamicDrawContexts)
|
||||
{
|
||||
if (drawContext->m_pass == pass)
|
||||
{
|
||||
drawContext->FinalizeDrawList();
|
||||
auto drawListView = drawContext->GetDrawList();
|
||||
if (drawListView.size() > 0)
|
||||
{
|
||||
result.push_back(drawListView);
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void DynamicDrawSystem::FrameEnd()
|
||||
{
|
||||
{
|
||||
|
||||
@@ -7,17 +7,18 @@
|
||||
*/
|
||||
|
||||
#include <Atom/RHI/CommandList.h>
|
||||
#include <Atom/RHI/ShaderResourceGroup.h>
|
||||
#include <Atom/RHI/DrawListTagRegistry.h>
|
||||
|
||||
#include <Atom/RPI.Reflect/Asset/AssetUtils.h>
|
||||
#include <Atom/RPI.Public/RenderPipeline.h>
|
||||
#include <Atom/RHI/RHISystemInterface.h>
|
||||
#include <Atom/RHI/ShaderResourceGroup.h>
|
||||
|
||||
#include <Atom/RPI.Public/DynamicDraw/DynamicDrawInterface.h>
|
||||
#include <Atom/RPI.Public/Pass/RasterPass.h>
|
||||
#include <Atom/RPI.Public/RenderPipeline.h>
|
||||
#include <Atom/RPI.Public/RPISystemInterface.h>
|
||||
#include <Atom/RPI.Public/Scene.h>
|
||||
#include <Atom/RPI.Public/View.h>
|
||||
#include <Atom/RPI.Public/Pass/RasterPass.h>
|
||||
|
||||
#include <Atom/RPI.Reflect/Asset/AssetUtils.h>
|
||||
#include <Atom/RPI.Reflect/Pass/RasterPassData.h>
|
||||
|
||||
namespace AZ
|
||||
@@ -133,10 +134,19 @@ namespace AZ
|
||||
m_viewportState = params.m_viewportState;
|
||||
}
|
||||
|
||||
// -- View & DrawList --
|
||||
const AZStd::vector<ViewPtr>& views = m_pipeline->GetViews(GetPipelineViewTag());
|
||||
m_drawListView = {};
|
||||
UpdateDrawList();
|
||||
|
||||
RenderPass::FrameBeginInternal(params);
|
||||
}
|
||||
|
||||
void RasterPass::UpdateDrawList()
|
||||
{
|
||||
// DrawLists from dynamic draw
|
||||
AZStd::vector<RHI::DrawListView> drawLists = DynamicDrawInterface::Get()->GetDrawListsForPass(this);
|
||||
|
||||
// Get DrawList from view
|
||||
const AZStd::vector<ViewPtr>& views = m_pipeline->GetViews(GetPipelineViewTag());
|
||||
RHI::DrawListView viewDrawList;
|
||||
if (!views.empty())
|
||||
{
|
||||
const ViewPtr& view = views.front();
|
||||
@@ -144,11 +154,40 @@ namespace AZ
|
||||
// Assert the view has our draw list (the view's DrawlistTags are collected from passes using its viewTag)
|
||||
AZ_Assert(view->HasDrawListTag(m_drawListTag), "View's DrawListTags out of sync with pass'. ");
|
||||
|
||||
// Draw List
|
||||
m_drawListView = view->GetDrawList(m_drawListTag);
|
||||
viewDrawList = view->GetDrawList(m_drawListTag);
|
||||
}
|
||||
|
||||
RenderPass::FrameBeginInternal(params);
|
||||
// clean up data
|
||||
m_drawListView = {};
|
||||
m_combinedDrawList.clear();
|
||||
|
||||
// draw list from view was sorted and if it's the only draw list then we can use it directly
|
||||
if (viewDrawList.size() > 0 && drawLists.size() == 0)
|
||||
{
|
||||
m_drawListView = viewDrawList;
|
||||
return;
|
||||
}
|
||||
|
||||
// add view's draw list to drawLists too
|
||||
drawLists.push_back(viewDrawList);
|
||||
|
||||
// combine draw items from mutiple draw lists to one draw list and sort it.
|
||||
size_t itemCount = 0;
|
||||
for (auto drawList : drawLists)
|
||||
{
|
||||
itemCount += drawList.size();
|
||||
}
|
||||
m_combinedDrawList.resize(itemCount);
|
||||
RHI::DrawItemProperties* currentBuffer = m_combinedDrawList.data();
|
||||
for (auto drawList : drawLists)
|
||||
{
|
||||
memcpy(currentBuffer, drawList.data(), drawList.size()*sizeof(RHI::DrawItemProperties));
|
||||
currentBuffer += drawList.size();
|
||||
}
|
||||
SortDrawList(m_combinedDrawList);
|
||||
|
||||
// have the final draw list point to the combined draw list.
|
||||
m_drawListView = m_combinedDrawList;
|
||||
}
|
||||
|
||||
// --- DrawList and PipelineView Tags ---
|
||||
|
||||
@@ -83,7 +83,7 @@ namespace AZ::AtomBridge
|
||||
ViewportData& viewportData = m_viewportData[viewportId];
|
||||
for (auto& context : viewportData.m_dynamicDrawContexts)
|
||||
{
|
||||
context.second->SetRenderPipeline(pipeline.get());
|
||||
context.second->SetOutputScope(pipeline.get());
|
||||
}
|
||||
});
|
||||
viewportData.m_viewportDestroyedHandler = AZ::Event<AzFramework::ViewportId>::Handler([this, viewportId](AzFramework::ViewportId id)
|
||||
@@ -106,7 +106,8 @@ namespace AZ::AtomBridge
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
context = RPI::DynamicDrawInterface::Get()->CreateDynamicDrawContext(pipeline);
|
||||
context = RPI::DynamicDrawInterface::Get()->CreateDynamicDrawContext();
|
||||
context->SetOutputScope(pipeline);
|
||||
contextFactoryIt->second(context);
|
||||
}
|
||||
|
||||
|
||||
@@ -96,7 +96,7 @@ void CDraw2d::OnBootstrapSceneReady([[maybe_unused]] AZ::RPI::Scene* bootstrapSc
|
||||
AZ_Assert(scene != nullptr, "Attempting to create a DynamicDrawContext for a viewport context that has not been associated with a scene yet.");
|
||||
|
||||
// Create and initialize a DynamicDrawContext for 2d drawing
|
||||
m_dynamicDraw = AZ::RPI::DynamicDrawInterface::Get()->CreateDynamicDrawContext(scene.get());
|
||||
m_dynamicDraw = AZ::RPI::DynamicDrawInterface::Get()->CreateDynamicDrawContext();
|
||||
AZ::RPI::ShaderOptionList shaderOptions;
|
||||
shaderOptions.push_back(AZ::RPI::ShaderOption(AZ::Name("o_useColorChannels"), AZ::Name("true")));
|
||||
shaderOptions.push_back(AZ::RPI::ShaderOption(AZ::Name("o_clamp"), AZ::Name("false")));
|
||||
@@ -107,6 +107,7 @@ void CDraw2d::OnBootstrapSceneReady([[maybe_unused]] AZ::RPI::Scene* bootstrapSc
|
||||
{"TEXCOORD0", AZ::RHI::Format::R32G32_FLOAT} });
|
||||
m_dynamicDraw->AddDrawStateOptions(AZ::RPI::DynamicDrawContext::DrawStateOptions::PrimitiveType
|
||||
| AZ::RPI::DynamicDrawContext::DrawStateOptions::BlendMode);
|
||||
m_dynamicDraw->SetOutputScope(scene.get());
|
||||
m_dynamicDraw->EndInit();
|
||||
|
||||
AZ::RHI::TargetBlendState targetBlendState;
|
||||
|
||||
@@ -110,7 +110,7 @@ AZ::RPI::ScenePtr UiRenderer::CreateScene(AZStd::shared_ptr<AZ::RPI::ViewportCon
|
||||
|
||||
void UiRenderer::CreateDynamicDrawContext(AZ::RPI::ScenePtr scene, AZ::Data::Instance<AZ::RPI::Shader> uiShader)
|
||||
{
|
||||
m_dynamicDraw = AZ::RPI::DynamicDrawInterface::Get()->CreateDynamicDrawContext(scene.get());
|
||||
m_dynamicDraw = AZ::RPI::DynamicDrawInterface::Get()->CreateDynamicDrawContext();
|
||||
|
||||
// Initialize the dynamic draw context
|
||||
m_dynamicDraw->InitShader(uiShader);
|
||||
@@ -122,6 +122,7 @@ void UiRenderer::CreateDynamicDrawContext(AZ::RPI::ScenePtr scene, AZ::Data::Ins
|
||||
);
|
||||
m_dynamicDraw->AddDrawStateOptions(AZ::RPI::DynamicDrawContext::DrawStateOptions::StencilState
|
||||
| AZ::RPI::DynamicDrawContext::DrawStateOptions::BlendMode);
|
||||
m_dynamicDraw->SetOutputScope(scene.get());
|
||||
m_dynamicDraw->EndInit();
|
||||
}
|
||||
|
||||
|
||||
@@ -21,8 +21,9 @@ namespace PhysX
|
||||
setTextInteractionFlags(Qt::TextBrowserInteraction);
|
||||
setOpenExternalLinks(true);
|
||||
setAlignment(Qt::AlignCenter);
|
||||
setContentsMargins(60, 15, 60, 15);
|
||||
setContentsMargins(60, 7, 60, 7);
|
||||
setWordWrap(true);
|
||||
setStyleSheet(QString::fromUtf8("background-color: rgb(51, 51, 51);"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user