diff --git a/Gems/Atom/Feature/Common/Assets/Passes/SsaoCompute.pass b/Gems/Atom/Feature/Common/Assets/Passes/SsaoCompute.pass index 3c4a8c76f1..2c48506f8f 100644 --- a/Gems/Atom/Feature/Common/Assets/Passes/SsaoCompute.pass +++ b/Gems/Atom/Feature/Common/Assets/Passes/SsaoCompute.pass @@ -50,7 +50,8 @@ "FilePath": "Shaders/PostProcessing/SsaoCompute.shader" }, "Make Fullscreen Pass": true, - "PipelineViewTag": "MainCamera" + "PipelineViewTag": "MainCamera", + "Use Async Compute": true }, "FallbackConnections": [ { diff --git a/Gems/Atom/Feature/Common/Code/Source/DiffuseGlobalIllumination/DiffuseProbeGridVisualizationAccelerationStructurePass.cpp b/Gems/Atom/Feature/Common/Code/Source/DiffuseGlobalIllumination/DiffuseProbeGridVisualizationAccelerationStructurePass.cpp index 29e50fb158..94a441c769 100644 --- a/Gems/Atom/Feature/Common/Code/Source/DiffuseGlobalIllumination/DiffuseProbeGridVisualizationAccelerationStructurePass.cpp +++ b/Gems/Atom/Feature/Common/Code/Source/DiffuseGlobalIllumination/DiffuseProbeGridVisualizationAccelerationStructurePass.cpp @@ -72,7 +72,7 @@ namespace AZ void DiffuseProbeGridVisualizationAccelerationStructurePass::BuildInternal() { - SetScopeId(RHI::ScopeId(GetPathName())); + InitScope(RHI::ScopeId(GetPathName())); } void DiffuseProbeGridVisualizationAccelerationStructurePass::FrameBeginInternal(FramePrepareParams params) diff --git a/Gems/Atom/Feature/Common/Code/Source/PostProcessing/DepthOfFieldCopyFocusDepthToCpuPass.cpp b/Gems/Atom/Feature/Common/Code/Source/PostProcessing/DepthOfFieldCopyFocusDepthToCpuPass.cpp index 3a0efaa371..c79e98e345 100644 --- a/Gems/Atom/Feature/Common/Code/Source/PostProcessing/DepthOfFieldCopyFocusDepthToCpuPass.cpp +++ b/Gems/Atom/Feature/Common/Code/Source/PostProcessing/DepthOfFieldCopyFocusDepthToCpuPass.cpp @@ -50,7 +50,7 @@ namespace AZ void DepthOfFieldCopyFocusDepthToCpuPass::BuildInternal() { - SetScopeId(RHI::ScopeId(GetPathName())); + InitScope(RHI::ScopeId(GetPathName())); } void DepthOfFieldCopyFocusDepthToCpuPass::FrameBeginInternal(FramePrepareParams params) diff --git a/Gems/Atom/Feature/Common/Code/Source/RayTracing/RayTracingAccelerationStructurePass.cpp b/Gems/Atom/Feature/Common/Code/Source/RayTracing/RayTracingAccelerationStructurePass.cpp index 2073c0b8c0..9a99a9f82a 100644 --- a/Gems/Atom/Feature/Common/Code/Source/RayTracing/RayTracingAccelerationStructurePass.cpp +++ b/Gems/Atom/Feature/Common/Code/Source/RayTracing/RayTracingAccelerationStructurePass.cpp @@ -40,7 +40,7 @@ namespace AZ void RayTracingAccelerationStructurePass::BuildInternal() { - SetScopeId(RHI::ScopeId(GetPathName())); + InitScope(RHI::ScopeId(GetPathName())); } void RayTracingAccelerationStructurePass::FrameBeginInternal(FramePrepareParams params) diff --git a/Gems/Atom/RHI/Code/Include/Atom/RHI/Scope.h b/Gems/Atom/RHI/Code/Include/Atom/RHI/Scope.h index 0bcf35f107..2c5acf4c18 100644 --- a/Gems/Atom/RHI/Code/Include/Atom/RHI/Scope.h +++ b/Gems/Atom/RHI/Code/Include/Atom/RHI/Scope.h @@ -76,6 +76,9 @@ namespace AZ /// Returns the hardware queue class for this scope. HardwareQueueClass GetHardwareQueueClass() const; + /// Sets the hardware queue class for this scope. + void SetHardwareQueueClass(HardwareQueueClass hardwareQueueClass); + /** * Returns the estimated number of draw / dispatch / copy items that the user will submit * while in this scope. This is an estimation intended to be used by the platform-specific @@ -120,7 +123,7 @@ namespace AZ const AZStd::vector>& GetFencesToSignal() const; /// Initializes the scope. - void Init(const ScopeId& scopeId); + void Init(const ScopeId& scopeId, HardwareQueueClass hardwareQueueClass = HardwareQueueClass::Graphics); /// Activates the scope for the current frame. void Activate(const FrameGraph* frameGraph, uint32_t index, const GraphGroupId& groupId); diff --git a/Gems/Atom/RHI/Code/Include/Atom/RHI/ScopeProducer.h b/Gems/Atom/RHI/Code/Include/Atom/RHI/ScopeProducer.h index f27172afca..690b65803f 100644 --- a/Gems/Atom/RHI/Code/Include/Atom/RHI/ScopeProducer.h +++ b/Gems/Atom/RHI/Code/Include/Atom/RHI/ScopeProducer.h @@ -86,11 +86,22 @@ namespace AZ ScopeProducer(); /** - * Sets ID of the scope producer. Used by class that inherit from - * ScopeProducer but that can't supply a ScopeId at construction. + * Sets the HardwareQueueClass on the scope + */ + void SetHardwareQueueClass(HardwareQueueClass hardwareQueueClass); + + /** + * DEPRECATED. + * @deprecated Use InitScope instead */ void SetScopeId(const ScopeId& scopeId); + /** + * Initializes the scope with a ScopeId and HardwareQueueClass. + * Used by classes that inherit from ScopeProducer but can't supply a ScopeId at construction. + */ + void InitScope(const ScopeId& scopeId, HardwareQueueClass hardwareQueueClass = HardwareQueueClass::Graphics); + private: ////////////////////////////////////////////////////////////////////////// // User Overrides - Derived classes should override from these methods. diff --git a/Gems/Atom/RHI/Code/Source/RHI/Scope.cpp b/Gems/Atom/RHI/Code/Source/RHI/Scope.cpp index 472309929e..1fdfc137d8 100644 --- a/Gems/Atom/RHI/Code/Source/RHI/Scope.cpp +++ b/Gems/Atom/RHI/Code/Source/RHI/Scope.cpp @@ -24,12 +24,13 @@ namespace AZ return m_isActive; } - void Scope::Init(const ScopeId& scopeId) + void Scope::Init(const ScopeId& scopeId, HardwareQueueClass hardwareQueueClass) { AZ_Assert(!scopeId.IsEmpty(), "Scope id is not valid."); AZ_Assert(IsInitialized() == false, "Scope was previously initialized."); SetName(scopeId); m_id = scopeId; + m_hardwareQueueClass = hardwareQueueClass; InitInternal(); m_isInitialized = true; } @@ -134,6 +135,11 @@ namespace AZ return m_hardwareQueueClass; } + void Scope::SetHardwareQueueClass(HardwareQueueClass hardwareQueueClass) + { + m_hardwareQueueClass = hardwareQueueClass; + } + uint32_t Scope::GetEstimatedItemCount() const { return m_estimatedItemCount; diff --git a/Gems/Atom/RHI/Code/Source/RHI/ScopeProducer.cpp b/Gems/Atom/RHI/Code/Source/RHI/ScopeProducer.cpp index 7017deb862..6df5a18296 100644 --- a/Gems/Atom/RHI/Code/Source/RHI/ScopeProducer.cpp +++ b/Gems/Atom/RHI/Code/Source/RHI/ScopeProducer.cpp @@ -40,7 +40,18 @@ namespace AZ return m_scope.get(); } + void ScopeProducer::SetHardwareQueueClass(HardwareQueueClass hardwareQueueClass) + { + m_scope->SetHardwareQueueClass(hardwareQueueClass); + } + + // DEPRECATED: use InitScope instead void ScopeProducer::SetScopeId(const ScopeId& scopeId) + { + InitScope(scopeId); + } + + void ScopeProducer::InitScope(const ScopeId& scopeId, HardwareQueueClass hardwareQueueClass) { m_scopeId = scopeId; @@ -49,7 +60,7 @@ namespace AZ m_scope->Shutdown(); } - m_scope->Init(scopeId); + m_scope->Init(scopeId, hardwareQueueClass); } } } diff --git a/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Pass/RenderPass.h b/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Pass/RenderPass.h index bdd305b4eb..9ccfb2764e 100644 --- a/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Pass/RenderPass.h +++ b/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Pass/RenderPass.h @@ -113,6 +113,9 @@ namespace AZ // The shader resource group for this pass Data::Instance m_shaderResourceGroup = nullptr; + // Determines which hardware queue the pass will run on + RHI::HardwareQueueClass m_hardwareQueueClass = RHI::HardwareQueueClass::Graphics; + private: // Helper function that binds a single attachment to the pass shader resource group void BindAttachment(const RHI::FrameGraphCompileContext& context, PassAttachmentBinding& binding, int16_t& imageIndex, int16_t& bufferIndex); diff --git a/Gems/Atom/RPI/Code/Include/Atom/RPI.Reflect/Pass/ComputePassData.h b/Gems/Atom/RPI/Code/Include/Atom/RPI.Reflect/Pass/ComputePassData.h index f7b71b9483..e5e6c60c7f 100644 --- a/Gems/Atom/RPI/Code/Include/Atom/RPI.Reflect/Pass/ComputePassData.h +++ b/Gems/Atom/RPI/Code/Include/Atom/RPI.Reflect/Pass/ComputePassData.h @@ -29,12 +29,13 @@ namespace AZ if (auto* serializeContext = azrtti_cast(context)) { serializeContext->Class() - ->Version(1) + ->Version(2) ->Field("ShaderAsset", &ComputePassData::m_shaderReference) ->Field("Target Thread Count X", &ComputePassData::m_totalNumberOfThreadsX) ->Field("Target Thread Count Y", &ComputePassData::m_totalNumberOfThreadsY) ->Field("Target Thread Count Z", &ComputePassData::m_totalNumberOfThreadsZ) ->Field("Make Fullscreen Pass", &ComputePassData::m_makeFullscreenPass) + ->Field("Use Async Compute", &ComputePassData::m_useAsyncCompute) ; } } @@ -46,6 +47,9 @@ namespace AZ uint32_t m_totalNumberOfThreadsZ = 0; bool m_makeFullscreenPass = false; + + // Whether the pass should use async compute and run on the compute hardware queue. + bool m_useAsyncCompute = false; }; } // namespace RPI } // namespace AZ diff --git a/Gems/Atom/RPI/Code/Include/Atom/RPI.Reflect/Pass/CopyPassData.h b/Gems/Atom/RPI/Code/Include/Atom/RPI.Reflect/Pass/CopyPassData.h index 5f4e5b7f6c..3808dd35d1 100644 --- a/Gems/Atom/RPI/Code/Include/Atom/RPI.Reflect/Pass/CopyPassData.h +++ b/Gems/Atom/RPI/Code/Include/Atom/RPI.Reflect/Pass/CopyPassData.h @@ -32,7 +32,7 @@ namespace AZ if (auto* serializeContext = azrtti_cast(context)) { serializeContext->Class() - ->Version(0) + ->Version(1) ->Field("BufferSize", &CopyPassData::m_bufferSize) ->Field("BufferSourceOffset", &CopyPassData::m_bufferSourceOffset) ->Field("BufferSourceBytesPerRow", &CopyPassData::m_bufferSourceBytesPerRow) @@ -46,6 +46,7 @@ namespace AZ ->Field("ImageDestinationSubresource", &CopyPassData::m_imageDestinationSubresource) ->Field("ImageDestinationOrigin", &CopyPassData::m_imageDestinationOrigin) ->Field("CloneInput", &CopyPassData::m_cloneInput) + ->Field("UseCopyQueue", &CopyPassData::m_useCopyQueue) ; } } @@ -75,6 +76,9 @@ namespace AZ // If set to true, pass will automatically create a transient output attachment based on input // If false, the output target of the copy will need to be specified bool m_cloneInput = true; + + // Whether the pass should use the copy queue. + bool m_useCopyQueue = false; }; } // namespace RPI } // namespace AZ diff --git a/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/ComputePass.cpp b/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/ComputePass.cpp index 8bcf9b1b85..f20da50cc8 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/ComputePass.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/ComputePass.cpp @@ -58,6 +58,12 @@ namespace AZ return; } + // Hardware Queue Class + if (passData->m_useAsyncCompute) + { + m_hardwareQueueClass = RHI::HardwareQueueClass::Compute; + } + // Load Shader Data::Asset shaderAsset; if (passData->m_shaderReference.m_assetId.IsValid()) diff --git a/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/CopyPass.cpp b/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/CopyPass.cpp index 1dde615f77..fdc58ef97d 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/CopyPass.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/CopyPass.cpp @@ -38,6 +38,11 @@ namespace AZ if (copyData) { m_data = *copyData; + + if (copyData->m_useCopyQueue) + { + m_hardwareQueueClass = RHI::HardwareQueueClass::Copy; + } } } diff --git a/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/RenderPass.cpp b/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/RenderPass.cpp index fa5f41e615..661c03b34a 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/RenderPass.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/RenderPass.cpp @@ -183,7 +183,7 @@ namespace AZ { if (GetScopeId().IsEmpty()) { - SetScopeId(RHI::ScopeId(GetPathName())); + InitScope(RHI::ScopeId(GetPathName()), m_hardwareQueueClass); } params.m_frameGraphBuilder->ImportScopeProducer(*this); diff --git a/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/Specific/ImageAttachmentPreviewPass.cpp b/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/Specific/ImageAttachmentPreviewPass.cpp index 13c3fdb94a..0bbc17bf45 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/Specific/ImageAttachmentPreviewPass.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/Specific/ImageAttachmentPreviewPass.cpp @@ -32,7 +32,7 @@ namespace AZ m_destAttachmentId = destAttachmentId; // Use the unique destination attachment id as scope id - SetScopeId(m_destAttachmentId); + InitScope(m_destAttachmentId); // Clear the previous attachment and copy item m_copyItem = {}; @@ -124,7 +124,7 @@ namespace AZ ImageAttachmentPreviewPass::ImageAttachmentPreviewPass(const PassDescriptor& descriptor) : Pass(descriptor) { - SetScopeId(RHI::ScopeId(GetPathName())); + InitScope(RHI::ScopeId(GetPathName())); } ImageAttachmentPreviewPass::~ImageAttachmentPreviewPass()