Merge pull request #6439 from aws-lumberyard-dev/Atom/antonmic/ClearPass

Atom/antonmic/clear pass
This commit is contained in:
antonmic
2021-12-16 12:12:36 -08:00
committed by GitHub
15 changed files with 243 additions and 11 deletions
@@ -64,6 +64,10 @@
"Name": "CascadedShadowmapsTemplate",
"Path": "Passes/CascadedShadowmaps.pass"
},
{
"Name": "SlowClearPassTemplate",
"Path": "Passes/SlowClear.pass"
},
{
"Name": "FullscreenCopyTemplate",
"Path": "Passes/FullscreenCopy.pass"
@@ -25,10 +25,7 @@
{
"Name": "OutputColor",
"SlotType": "Output",
"ScopeAttachmentUsage": "RenderTarget",
"LoadStoreAction": {
"LoadAction": "DontCare"
}
"ScopeAttachmentUsage": "RenderTarget"
}
],
"Connections": [
@@ -25,10 +25,7 @@
{
"Name": "OutputColor",
"SlotType": "Output",
"ScopeAttachmentUsage": "RenderTarget",
"LoadStoreAction": {
"LoadAction": "DontCare"
}
"ScopeAttachmentUsage": "RenderTarget"
}
],
"Connections": [
@@ -0,0 +1,34 @@
{
"Type": "JsonSerialization",
"Version": 1,
"ClassName": "PassAsset",
"ClassData": {
"PassTemplate": {
// This is for debug purposes and edge cases only
// If you want to clear an attachment you should
// use the LoadStoreAction on your pass slot.
"Name": "SlowClearPassTemplate",
"PassClass": "SlowClearPass",
"Slots": [
{
"Name": "ClearInputOutput",
"SlotType": "InputOutput",
"ScopeAttachmentUsage": "RenderTarget",
"LoadStoreAction": {
"ClearValue": {
"Value": [
0.0,
0.0,
0.0,
0.0
]
},
"LoadAction": "Clear",
"LoadActionStencil": "Clear"
}
}
]
}
}
}
@@ -53,6 +53,7 @@ set(FILES
Materials/Types/StandardPBR_LowEndForward.azsl
Materials/Types/StandardPBR_LowEndForward.shader
Materials/Types/StandardPBR_LowEndForward_EDS.shader
Materials/Types/StandardPBR_Metallic.lua
Materials/Types/StandardPBR_ParallaxState.lua
Materials/Types/StandardPBR_Roughness.lua
Materials/Types/StandardPBR_ShaderEnable.lua
@@ -129,6 +130,7 @@ set(FILES
Passes/DownsampleMipChain.pass
Passes/EnvironmentCubeMapDepthMSAA.pass
Passes/EnvironmentCubeMapForwardMSAA.pass
Passes/EnvironmentCubeMapForwardSubsurfaceMSAA.pass
Passes/EnvironmentCubeMapPipeline.pass
Passes/EnvironmentCubeMapSkyBox.pass
Passes/EsmShadowmaps.pass
@@ -198,6 +200,7 @@ set(FILES
Passes/Skinning.pass
Passes/SkyBox.pass
Passes/SkyBox_TwoOutputs.pass
Passes/SlowClear.pass
Passes/SMAA1xApplyLinearHDRColor.pass
Passes/SMAA1xApplyPerceptualColor.pass
Passes/SMAABlendingWeightCalculation.pass
@@ -303,6 +306,7 @@ set(FILES
ShaderLib/Atom/Features/ScreenSpace/ScreenSpaceUtil.azsli
ShaderLib/Atom/Features/Shadow/BicubicPcfFilters.azsli
ShaderLib/Atom/Features/Shadow/DirectionalLightShadow.azsli
ShaderLib/Atom/Features/Shadow/ESM.azsli
ShaderLib/Atom/Features/Shadow/NormalOffsetShadows.azsli
ShaderLib/Atom/Features/Shadow/ProjectedShadow.azsli
ShaderLib/Atom/Features/Shadow/ReceiverPlaneDepthBias.azsli
@@ -73,8 +73,6 @@ namespace AZ
return false;
}
AZ_Assert(m_pipeline->GetScene(), "EyeAdaptationPass's Pipeline does not have a valid scene pointer");
AZ::RPI::Scene* scene = GetScene();
bool enabled = false;
@@ -131,6 +131,19 @@ namespace AZ
// Generates child passes from source PassTemplate
void CreatePassesFromTemplate();
// Generates child clear passes to clear input and input/output attachments
// TODO: These two functions are a workaround for a complicated edge case:
// Let Parent Pass P1 have two children, C1 and C2. C1 writes to an attachment that C2 reads,
// but C1 can be disabled, in which case we just want C2 to read the cleared texture.
// Because of this, the attachment is owned by the parent pass, that way it is always available for C2
// to read even when C1 is disabled. However we still want to clear the attachment before C2 reads it.
// We tried overriding the LoadStoreAction to clear on C2's slot when C1 is disabled, but the RHI
// doesn't allow for clears on Input only slots. Changing the slot to InputOutput was in conflict with
// the texture definition in the SRG, and it couldn't be changed to RW because it was an MSAA texture.
// So now we detect clear actions on parent slots and generate a clear pass for them.
void CreateClearPassFromBinding(PassAttachmentBinding& binding, PassRequest& clearRequest);
void CreateClearPassesFromBindings();
};
template<typename PassType>
@@ -0,0 +1,42 @@
/*
* 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 <AzCore/Memory/SystemAllocator.h>
#include <Atom/RPI.Public/Pass/RenderPass.h>
namespace AZ
{
namespace RPI
{
//! Only use this for debug purposes and edge cases
//! The correct and efficient way to clear a pass is through the LoadStoreAction on the pass slot
//! This will clear a given image attachment to the specified clear value.
class SlowClearPass
: public RenderPass
{
AZ_RPI_PASS(SlowClearPass);
public:
AZ_RTTI(SlowClearPass, "{31CBAD6C-108F-4F3F-B498-ED968DFCFCE2}", RenderPass);
AZ_CLASS_ALLOCATOR(SlowClearPass, SystemAllocator, 0);
virtual ~SlowClearPass() = default;
//! Creates a SlowClearPass
static Ptr<SlowClearPass> Create(const PassDescriptor& descriptor);
protected:
SlowClearPass(const PassDescriptor& descriptor);
void InitializeInternal() override;
private:
RHI::ClearValue m_clearValue;
};
} // namespace RPI
} // namespace AZ
@@ -0,0 +1,43 @@
/*
* 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 <Atom/RHI.Reflect/ClearValue.h>
#include <Atom/RPI.Reflect/Pass/RenderPassData.h>
namespace AZ
{
namespace RPI
{
//! Custom data for the SlowClearPass. Should be specified in the PassRequest.
struct SlowClearPassData
: public RenderPassData
{
AZ_RTTI(SlowClearPassData, "{5F2C24A4-62D0-4E60-91EC-C207C10D15C6}", RenderPassData);
AZ_CLASS_ALLOCATOR(SlowClearPassData, SystemAllocator, 0);
SlowClearPassData() = default;
virtual ~SlowClearPassData() = default;
static void Reflect(ReflectContext* context)
{
if (auto* serializeContext = azrtti_cast<SerializeContext*>(context))
{
serializeContext->Class<SlowClearPassData, RenderPassData>()
->Version(0)
->Field("ClearValue", &SlowClearPassData::m_clearValue)
;
}
}
RHI::ClearValue m_clearValue;
};
} // namespace RPI
} // namespace AZ
@@ -9,11 +9,15 @@
#include <AtomCore/Instance/InstanceDatabase.h>
#include <AtomCore/std/containers/vector_set.h>
#include <Atom/RPI.Public/Pass/SlowClearPass.h>
#include <Atom/RPI.Public/Pass/ParentPass.h>
#include <Atom/RPI.Public/Pass/PassAttachment.h>
#include <Atom/RPI.Public/Pass/PassDefines.h>
#include <Atom/RPI.Public/Pass/PassSystemInterface.h>
#include <Atom/RPI.Public/RenderPipeline.h>
#include <Atom/RPI.Reflect/Pass/SlowClearPassData.h>
#include <Atom/RPI.Reflect/Pass/PassName.h>
#include <Atom/RPI.Reflect/Pass/PassRequest.h>
namespace AZ
@@ -196,7 +200,7 @@ namespace AZ
}
}
// --- PassTemplate related functions ---
// --- Child creation ---
void ParentPass::CreatePassesFromTemplate()
{
@@ -217,6 +221,49 @@ namespace AZ
}
}
void ParentPass::CreateClearPassFromBinding(PassAttachmentBinding& binding, PassRequest& clearRequest)
{
if (binding.m_unifiedScopeDesc.m_loadStoreAction.m_loadAction == RHI::AttachmentLoadAction::Clear ||
binding.m_unifiedScopeDesc.m_loadStoreAction.m_loadActionStencil == RHI::AttachmentLoadAction::Clear)
{
// Set the name of the child clear pass as well as the binding it's connected to
clearRequest.m_passName = ConcatPassName(Name("Clear"), binding.m_name);
clearRequest.m_connections[0].m_attachmentRef.m_attachment = binding.m_name;
// Set the pass clear value to the clear value of the attachment binding
SlowClearPassData* clearData = static_cast<SlowClearPassData*>(clearRequest.m_passData.get());
clearData->m_clearValue = binding.m_unifiedScopeDesc.m_loadStoreAction.m_clearValue;
// Create and add the pass
Ptr<Pass> clearPass = PassSystemInterface::Get()->CreatePassFromRequest(&clearRequest);
if (clearPass)
{
AddChild(clearPass);
}
}
}
void ParentPass::CreateClearPassesFromBindings()
{
PassRequest clearRequest;
clearRequest.m_templateName = Name("SlowClearPassTemplate");
clearRequest.m_passData = AZStd::make_shared<SlowClearPassData>();
clearRequest.m_connections.push_back();
clearRequest.m_connections[0].m_localSlot = Name("ClearInputOutput");
clearRequest.m_connections[0].m_attachmentRef.m_pass = Name("Parent");
for (uint32_t idx = 0; idx < GetInputCount(); ++idx)
{
CreateClearPassFromBinding(GetInputBinding(idx), clearRequest);
}
for (uint32_t idx = 0; idx < GetInputOutputCount(); ++idx)
{
CreateClearPassFromBinding(GetInputOutputBinding(idx), clearRequest);
}
}
// --- Pass behavior functions ---
void ParentPass::CreateChildPasses()
@@ -229,6 +276,7 @@ namespace AZ
m_flags.m_alreadyCreatedChildren = true;
RemoveChildren();
CreateClearPassesFromBindings();
CreatePassesFromTemplate();
CreateChildPassesInternal();
@@ -19,6 +19,7 @@
#include <Atom/RPI.Public/Pass/PassFilter.h>
#include <Atom/RPI.Public/Pass/RasterPass.h>
#include <Atom/RPI.Public/Pass/MSAAResolvePass.h>
#include <Atom/RPI.Public/Pass/SlowClearPass.h>
#include <Atom/RPI.Public/Pass/Specific/MSAAResolveFullScreenPass.h>
#include <Atom/RPI.Public/Pass/Specific/EnvironmentCubeMapPass.h>
#include <Atom/RPI.Public/Pass/Specific/RenderToTexturePass.h>
@@ -60,6 +61,7 @@ namespace AZ
{
AddPassCreator(Name("ParentPass"), &ParentPass::Create);
AddPassCreator(Name("RasterPass"), &RasterPass::Create);
AddPassCreator(Name("SlowClearPass"), &SlowClearPass::Create);
AddPassCreator(Name("CopyPass"), &CopyPass::Create);
AddPassCreator(Name("FullScreenTriangle"), &FullscreenTrianglePass::Create);
AddPassCreator(Name("ComputePass"), &ComputePass::Create);
@@ -39,6 +39,7 @@
#include <Atom/RPI.Reflect/Pass/PassTemplate.h>
#include <Atom/RPI.Reflect/Pass/RasterPassData.h>
#include <Atom/RPI.Reflect/Pass/RenderPassData.h>
#include <Atom/RPI.Reflect/Pass/SlowClearPassData.h>
namespace AZ
{
@@ -67,6 +68,7 @@ namespace AZ
PassSlot::Reflect(context);
PassData::Reflect(context);
SlowClearPassData::Reflect(context);
CopyPassData::Reflect(context);
RenderPassData::Reflect(context);
ComputePassData::Reflect(context);
@@ -0,0 +1,45 @@
/*
* 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
*
*/
#include <Atom/RPI.Public/Pass/SlowClearPass.h>
#include <Atom/RPI.Public/Pass/PassUtils.h>
#include <Atom/RPI.Reflect/Pass/SlowClearPassData.h>
namespace AZ
{
namespace RPI
{
Ptr<SlowClearPass> SlowClearPass::Create(const PassDescriptor& descriptor)
{
Ptr<SlowClearPass> pass = aznew SlowClearPass(descriptor);
return pass;
}
SlowClearPass::SlowClearPass(const PassDescriptor& descriptor)
: RenderPass(descriptor)
{
const SlowClearPassData* passData = PassUtils::GetPassData<SlowClearPassData>(descriptor);
if (passData != nullptr)
{
m_clearValue = passData->m_clearValue;
}
}
void SlowClearPass::InitializeInternal()
{
RenderPass::InitializeInternal();
// Set clear value
AZ_Assert(GetInputOutputCount() > 0, "SlowClearPass: Missing InputOutput binding!");
RPI::PassAttachmentBinding& binding = GetInputOutputBinding(0);
binding.m_unifiedScopeDesc.m_loadStoreAction.m_clearValue = m_clearValue;
}
} // namespace RPI
} // namespace AZ
@@ -73,6 +73,7 @@ set(FILES
Include/Atom/RPI.Public/Pass/RasterPass.h
Include/Atom/RPI.Public/Pass/RenderPass.h
Include/Atom/RPI.Public/Pass/MSAAResolvePass.h
Include/Atom/RPI.Public/Pass/SlowClearPass.h
Include/Atom/RPI.Public/Pass/Specific/DownsampleMipChainPass.h
Include/Atom/RPI.Public/Pass/Specific/ImageAttachmentPreviewPass.h
Include/Atom/RPI.Public/Pass/Specific/EnvironmentCubeMapPass.h
@@ -149,6 +150,7 @@ set(FILES
Source/RPI.Public/Pass/RasterPass.cpp
Source/RPI.Public/Pass/RenderPass.cpp
Source/RPI.Public/Pass/MSAAResolvePass.cpp
Source/RPI.Public/Pass/SlowClearPass.cpp
Source/RPI.Public/Pass/Specific/DownsampleMipChainPass.cpp
Source/RPI.Public/Pass/Specific/ImageAttachmentPreviewPass.cpp
Source/RPI.Public/Pass/Specific/EnvironmentCubeMapPass.cpp
@@ -75,6 +75,7 @@ set(FILES
Include/Atom/RPI.Reflect/Pass/PassTemplate.h
Include/Atom/RPI.Reflect/Pass/RasterPassData.h
Include/Atom/RPI.Reflect/Pass/RenderPassData.h
Include/Atom/RPI.Reflect/Pass/SlowClearPassData.h
Include/Atom/RPI.Reflect/Shader/ShaderCommonTypes.h
Include/Atom/RPI.Reflect/Shader/ShaderAsset.h
Include/Atom/RPI.Reflect/Shader/ShaderAssetCreator.h