Skip to content

Commit b174ef8

Browse files
Merge pull request o3de#17234 from hosea1008/aa_switchable
Support switching anti-aliasing and multi-sampling from CVar
2 parents 24e677c + d7c3828 commit b174ef8

File tree

10 files changed

+249
-12
lines changed

10 files changed

+249
-12
lines changed

Gems/Atom/Bootstrap/Code/Include/Atom/Bootstrap/BootstrapRequestBus.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ namespace AZ::Render::Bootstrap
2525
virtual AZ::RPI::ScenePtr GetOrCreateAtomSceneFromAzScene(AzFramework::Scene* scene) = 0;
2626
virtual bool EnsureDefaultRenderPipelineInstalledForScene(AZ::RPI::ScenePtr scene, AZ::RPI::ViewportContextPtr viewportContext) = 0;
2727
virtual void SwitchRenderPipeline(const AZ::RPI::RenderPipelineDescriptor& newRenderPipelineDesc, AZ::RPI::ViewportContextPtr viewportContext) = 0;
28+
virtual void SwitchAntiAliasing(const AZStd::string& newAntiAliasing, AZ::RPI::ViewportContextPtr viewportContext) = 0;
29+
virtual void SwitchMultiSample(const uint16_t newSampleCount, AZ::RPI::ViewportContextPtr viewportContext) = 0;
2830

2931
protected:
3032
~Request() = default;

Gems/Atom/Bootstrap/Code/Source/BootstrapSystemComponent.cpp

Lines changed: 85 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,45 @@ void cvar_r_renderPipelinePath_Changed(const AZ::CVarFixedString& newPipelinePat
7474
}
7575
}
7676

77+
void cvar_r_antiAliasing_Changed(const AZ::CVarFixedString& newAntiAliasing)
78+
{
79+
auto viewportContextManager = AZ::Interface<AZ::RPI::ViewportContextRequestsInterface>::Get();
80+
if (!viewportContextManager)
81+
{
82+
return;
83+
}
84+
auto viewportContext = viewportContextManager->GetDefaultViewportContext();
85+
if (!viewportContext)
86+
{
87+
return;
88+
}
89+
90+
AZ::Render::Bootstrap::RequestBus::Broadcast(&AZ::Render::Bootstrap::RequestBus::Events::SwitchAntiAliasing, newAntiAliasing.c_str(), viewportContext);
91+
}
92+
93+
void cvar_r_multiSample_Changed(const uint16_t& newSampleCount)
94+
{
95+
auto viewportContextManager = AZ::Interface<AZ::RPI::ViewportContextRequestsInterface>::Get();
96+
if (!viewportContextManager)
97+
{
98+
return;
99+
}
100+
auto viewportContext = viewportContextManager->GetDefaultViewportContext();
101+
if (!viewportContext)
102+
{
103+
return;
104+
}
105+
if (newSampleCount > 0 && ((newSampleCount & (newSampleCount - 1))) == 0)
106+
{
107+
AZ::Render::Bootstrap::RequestBus::Broadcast(&AZ::Render::Bootstrap::RequestBus::Events::SwitchMultiSample, AZStd::clamp(newSampleCount, uint16_t(1), uint16_t(8)), viewportContext);
108+
}
109+
else
110+
{
111+
AZ_Warning("SetMultiSampleCount", false, "Failed to set multi-sample count %d: invalid multi-sample count", newSampleCount);
112+
}
113+
}
114+
115+
77116
AZ_CVAR(AZ::CVarFixedString, r_renderPipelinePath, AZ_TRAIT_BOOTSTRAPSYSTEMCOMPONENT_PIPELINE_NAME, cvar_r_renderPipelinePath_Changed, AZ::ConsoleFunctorFlags::DontReplicate, "The asset (.azasset) path for default render pipeline");
78117
AZ_CVAR(AZ::CVarFixedString, r_default_openxr_pipeline_name, "passes/MultiViewRenderPipeline.azasset", nullptr, AZ::ConsoleFunctorFlags::DontReplicate, "Default openXr render pipeline name");
79118
AZ_CVAR(AZ::CVarFixedString, r_default_openxr_left_pipeline_name, "passes/XRLeftRenderPipeline.azasset", nullptr, AZ::ConsoleFunctorFlags::DontReplicate, "Default openXr Left eye render pipeline name");
@@ -83,6 +122,8 @@ AZ_CVAR(uint32_t, r_height, 1080, nullptr, AZ::ConsoleFunctorFlags::DontReplicat
83122
AZ_CVAR(uint32_t, r_fullscreen, false, nullptr, AZ::ConsoleFunctorFlags::DontReplicate, "Starting fullscreen state.");
84123
AZ_CVAR(uint32_t, r_resolutionMode, 0, nullptr, AZ::ConsoleFunctorFlags::DontReplicate, "0: render resolution same as window client area size, 1: render resolution use the values specified by r_width and r_height");
85124
AZ_CVAR(float, r_renderScale, 1.0f, nullptr, AZ::ConsoleFunctorFlags::DontReplicate, "Scale to apply to the window resolution.");
125+
AZ_CVAR(AZ::CVarFixedString, r_antiAliasing, "", cvar_r_antiAliasing_Changed, AZ::ConsoleFunctorFlags::DontReplicate, "The anti-aliasing to be used for the current render pipeline. Available options: MSAA, TAA, SMAA");
126+
AZ_CVAR(uint16_t, r_multiSampleCount, 0, cvar_r_multiSample_Changed, AZ::ConsoleFunctorFlags::DontReplicate, "The multi-sample count to be used for the current render pipeline."); // 0 stands for unchanged, load the default setting from the pipeline itself
86127

87128
namespace AZ
88129
{
@@ -243,6 +284,24 @@ namespace AZ
243284
}
244285
}
245286
}
287+
288+
const AZStd::string multiSampleCvarName("r_multiSampleCount");
289+
if (pCmdLine->HasSwitch(multiSampleCvarName))
290+
{
291+
auto numValues = pCmdLine->GetNumSwitchValues(multiSampleCvarName);
292+
if (numValues > 0)
293+
{
294+
auto valueStr = pCmdLine->GetSwitchValue(multiSampleCvarName);
295+
if (AZ::StringFunc::LooksLikeInt(valueStr.c_str()))
296+
{
297+
auto multiSample = AZ::StringFunc::ToInt(valueStr.c_str());
298+
if (multiSample > 0)
299+
{
300+
r_multiSampleCount = static_cast<uint16_t>(multiSample);
301+
}
302+
}
303+
}
304+
}
246305
}
247306

248307
void BootstrapSystemComponent::Activate()
@@ -507,11 +566,18 @@ namespace AZ
507566
}
508567
}
509568

510-
if (!LoadPipeline(scene, viewportContext, pipelineName, AZ::RPI::ViewType::Default, multisampleState))
569+
RPI::RenderPipelinePtr renderPipeline = LoadPipeline(scene, viewportContext, pipelineName, AZ::RPI::ViewType::Default, multisampleState);
570+
if (!renderPipeline)
511571
{
512572
return false;
513573
}
514574

575+
AZ::CVarFixedString antiAliasing = static_cast<AZ::CVarFixedString>(r_antiAliasing);
576+
if (antiAliasing != "")
577+
{
578+
renderPipeline->SetActiveAAMethod(antiAliasing.c_str());
579+
}
580+
515581
// As part of our initialization we need to create the BRDF texture generation pipeline
516582
AZ::RPI::RenderPipelineDescriptor pipelineDesc;
517583
pipelineDesc.m_mainViewTagName = "MainCamera";
@@ -564,6 +630,11 @@ namespace AZ
564630
// been created so the same values are applied to all.
565631
// As it cannot be applied MSAA values per pipeline,
566632
// it's setting the MSAA state from the last pipeline loaded.
633+
const auto cvarMultiSample = static_cast<uint16_t>(r_multiSampleCount);
634+
if (cvarMultiSample > 0 && ((cvarMultiSample & (cvarMultiSample - 1))) == 0)
635+
{
636+
multisampleState.m_samples = static_cast<uint16_t>(cvarMultiSample);
637+
}
567638
AZ::RPI::RPISystemInterface::Get()->SetApplicationMultisampleState(multisampleState);
568639

569640
// Send notification when the scene and its pipeline are ready.
@@ -612,6 +683,19 @@ namespace AZ
612683
AZ::RPI::RPISystemInterface::Get()->SetApplicationMultisampleState(newRenderPipeline->GetRenderSettings().m_multisampleState);
613684
}
614685

686+
void BootstrapSystemComponent::SwitchAntiAliasing(const AZStd::string& newAntiAliasing, AZ::RPI::ViewportContextPtr viewportContext)
687+
{
688+
auto defaultRenderPipeline = viewportContext->GetRenderScene()->GetDefaultRenderPipeline();
689+
defaultRenderPipeline->SetActiveAAMethod(newAntiAliasing);
690+
}
691+
692+
void BootstrapSystemComponent::SwitchMultiSample(const uint16_t newSampleCount, AZ::RPI::ViewportContextPtr viewportContext)
693+
{
694+
auto multiSampleStete = viewportContext->GetRenderScene()->GetDefaultRenderPipeline()->GetRenderSettings().m_multisampleState;
695+
multiSampleStete.m_samples = newSampleCount;
696+
AZ::RPI::RPISystemInterface::Get()->SetApplicationMultisampleState(multiSampleStete);
697+
}
698+
615699
RPI::RenderPipelinePtr BootstrapSystemComponent::LoadPipeline( AZ::RPI::ScenePtr scene, AZ::RPI::ViewportContextPtr viewportContext,
616700
AZStd::string_view pipelineName, AZ::RPI::ViewType viewType, AZ::RHI::MultisampleState& multisampleState)
617701
{

Gems/Atom/Bootstrap/Code/Source/BootstrapSystemComponent.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,8 @@ namespace AZ
7070
AZ::RPI::ScenePtr GetOrCreateAtomSceneFromAzScene(AzFramework::Scene* scene) override;
7171
bool EnsureDefaultRenderPipelineInstalledForScene(AZ::RPI::ScenePtr scene, AZ::RPI::ViewportContextPtr viewportContext) override;
7272
void SwitchRenderPipeline(const AZ::RPI::RenderPipelineDescriptor& newRenderPipelineDesc, AZ::RPI::ViewportContextPtr viewportContext) override;
73+
void SwitchAntiAliasing(const AZStd::string& newAntiAliasing, AZ::RPI::ViewportContextPtr viewportContext) override;
74+
void SwitchMultiSample(const uint16_t newSampleCount, AZ::RPI::ViewportContextPtr viewportContext) override;
7375

7476
protected:
7577
// Component overrides ...

Gems/Atom/Feature/Common/Assets/Passes/MainRenderPipeline.azasset

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
"MultisampleState": {
1313
"samples": 2
1414
}
15-
}
15+
},
16+
"DefaultAAMethod": "MSAA"
1617
}
17-
}
18+
}

Gems/Atom/Feature/Common/Assets/Passes/PostProcessParent.pass

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@
6666
"PassRequests": [
6767
{
6868
"Name": "SMAA1xApplyLinearHDRColorPass",
69+
"Enabled": false,
6970
"TemplateName": "SMAA1xApplyLinearHDRColorTemplate",
7071
"Connections": [
7172
{

Gems/Atom/RPI/Code/Include/Atom/RPI.Public/RenderPipeline.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,12 @@ namespace AZ
9898
const ViewType viewType = ViewType::Default);
9999
static RenderPipelinePtr CreateRenderPipelineForWindow(Data::Asset<AnyAsset> pipelineAsset, const WindowContext& windowContext);
100100

101+
// Anti-aliasing
102+
bool SetActiveAAMethod(AZStd::string aaMethodName);
103+
static AntiAliasingMode GetAAMethodByName(AZStd::string aaMethodName);
104+
static AZStd::string GetAAMethodNameByIndex(AntiAliasingMode aaMethodIndex);
105+
AntiAliasingMode GetActiveAAMethod();
106+
101107
//! Create a render pipeline which renders to the specified attachment image
102108
//! The render pipeline's root pass is created from the pass template specified from RenderPipelineDescriptor::m_rootPassTemplate
103109
//! The input AttachmentImageAsset is used to connect to first output attachment of the root pass template
@@ -301,6 +307,11 @@ namespace AZ
301307
void SetDrawFilterTags(RHI::DrawFilterTagRegistry* tagRegistry);
302308
void ReleaseDrawFilterTags(RHI::DrawFilterTagRegistry* tagRegistry);
303309

310+
// AA method
311+
static bool SetAAMethod(RenderPipeline* pipeline, AZStd::string aaMethodName);
312+
static bool SetAAMethod(RenderPipeline* pipeline, AntiAliasingMode aaMethod);
313+
static bool EnablePass(RenderPipeline* pipeline, Name& passName, bool enable);
314+
304315
// End of functions accessed by Scene class
305316
//////////////////////////////////////////////////
306317

@@ -355,6 +366,8 @@ namespace AZ
355366
// The descriptor used to created this render pipeline
356367
RenderPipelineDescriptor m_descriptor;
357368

369+
AntiAliasingMode m_activeAAMethod = AntiAliasingMode::MSAA;
370+
358371
// View type associated with the Render Pipeline.
359372
ViewType m_viewType = ViewType::Default;
360373

Gems/Atom/RPI/Code/Include/Atom/RPI.Reflect/System/RenderPipelineDescriptor.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,16 @@ namespace AZ
1818

1919
namespace RPI
2020
{
21+
// Rendering Settings
22+
enum class AntiAliasingMode
23+
{
24+
MSAA,
25+
SMAA,
26+
TAA,
27+
Default = -1
28+
};
29+
30+
2131
//! A descriptor used to create a render pipeline
2232
struct RenderPipelineDescriptor final
2333
{
@@ -49,6 +59,9 @@ namespace AZ
4959

5060
//! Flag indicating if this pipeline can accept modifications from scene's feature processors
5161
bool m_allowModification = false;
62+
63+
//! Include(MSAA, TAA, SMAA)
64+
AZStd::string m_defaultAAMethod = "MSAA";
5265
};
5366

5467
} // namespace RPI

Gems/Atom/RPI/Code/Source/RPI.Public/RenderPipeline.cpp

Lines changed: 95 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -172,10 +172,12 @@ namespace AZ
172172
pipeline->m_nameId = desc.m_name.data();
173173
pipeline->m_materialPipelineTagName = Name{desc.m_materialPipelineTag};
174174
pipeline->m_activeRenderSettings = desc.m_renderSettings;
175+
pipeline->m_activeAAMethod = GetAAMethodByName(desc.m_defaultAAMethod);
175176
pipeline->m_passTree.m_rootPass->SetRenderPipeline(pipeline);
176177
pipeline->m_passTree.m_rootPass->m_flags.m_isPipelineRoot = true;
177178
pipeline->m_passTree.m_rootPass->ManualPipelineBuildAndInitialize();
178-
179+
180+
pipeline->SetActiveAAMethod(desc.m_defaultAAMethod);
179181
pipeline->UpdateViewportScissor();
180182
}
181183

@@ -624,6 +626,8 @@ namespace AZ
624626
newRoot->DebugPrint();
625627
#endif
626628
}
629+
630+
SetAAMethod(this, m_activeAAMethod);
627631
}
628632

629633
// Build and initialize any queued passes
@@ -651,9 +655,7 @@ namespace AZ
651655
SceneRequestBus::Event(m_scene->GetId(), &SceneRequest::PipelineStateLookupNeedsRebuild);
652656
}
653657
}
654-
655658
UpdateViewportScissor();
656-
657659
// Reset change flags
658660
m_pipelinePassChanges = PipelinePassChanges::NoPassChanges;
659661

@@ -948,5 +950,95 @@ namespace AZ
948950
{
949951
return m_viewType;
950952
}
953+
954+
// ---------------------------- Anti-aliasing
955+
956+
bool RenderPipeline::SetActiveAAMethod(AZStd::string aaMethodName)
957+
{
958+
AntiAliasingMode antiAliasingMode = GetAAMethodByName(aaMethodName);
959+
if (antiAliasingMode == AntiAliasingMode::Default)
960+
{
961+
return false;
962+
}
963+
m_activeAAMethod = antiAliasingMode;
964+
return SetAAMethod(this, m_activeAAMethod);
965+
}
966+
967+
AntiAliasingMode RenderPipeline::GetActiveAAMethod()
968+
{
969+
return m_activeAAMethod;
970+
}
971+
972+
AntiAliasingMode RenderPipeline::GetAAMethodByName(AZStd::string aaMethodName)
973+
{
974+
const AZStd::unordered_map<AZStd::string, AntiAliasingMode> AAMethodsLookup = {
975+
{"MSAA", AntiAliasingMode::MSAA}, {"SMAA", AntiAliasingMode::SMAA},
976+
{"TAA", AntiAliasingMode::TAA}
977+
};
978+
979+
auto findIt = AAMethodsLookup.find(aaMethodName);
980+
if (findIt != AAMethodsLookup.end())
981+
{
982+
return findIt->second;
983+
}
984+
return AntiAliasingMode::Default;
985+
}
986+
987+
AZStd::string RenderPipeline::GetAAMethodNameByIndex(AntiAliasingMode aaMethodIndex)
988+
{
989+
const AZStd::unordered_map<AntiAliasingMode, AZStd::string> AAMethodNameLookup = {
990+
{AntiAliasingMode::MSAA, "MSAA"}, {AntiAliasingMode::SMAA, "SMAA"},
991+
{AntiAliasingMode::TAA, "TAA"}
992+
};
993+
994+
auto findIt = AAMethodNameLookup.find(aaMethodIndex);
995+
if (findIt != AAMethodNameLookup.end())
996+
{
997+
return findIt->second;
998+
}
999+
return "MSAA";
1000+
}
1001+
1002+
bool RenderPipeline::EnablePass(RenderPipeline* pipeline, Name& passName, bool enable)
1003+
{
1004+
PassFilter passFilter = PassFilter::CreateWithPassName(passName, pipeline);
1005+
Ptr<Pass> aaPass = PassSystemInterface::Get()->FindFirstPass(passFilter);
1006+
if (!aaPass)
1007+
{
1008+
return false;
1009+
}
1010+
if (aaPass->IsEnabled() != enable)
1011+
{
1012+
aaPass->SetEnabled(enable);
1013+
}
1014+
return true;
1015+
}
1016+
1017+
bool RenderPipeline::SetAAMethod(RenderPipeline* pipeline, AZStd::string aaMethodName)
1018+
{
1019+
AntiAliasingMode antiAliasingMode = GetAAMethodByName(aaMethodName);
1020+
return SetAAMethod(pipeline, antiAliasingMode);
1021+
}
1022+
1023+
bool RenderPipeline::SetAAMethod(RenderPipeline* pipeline, AntiAliasingMode antiAliasingMode)
1024+
{
1025+
if (antiAliasingMode == AntiAliasingMode::Default)
1026+
{
1027+
return false;
1028+
}
1029+
1030+
const AZStd::unordered_map<AntiAliasingMode, AZStd::vector<Name>> AAPassNamesLookup = {
1031+
{AntiAliasingMode::SMAA, {Name("SMAA1xApplyLinearHDRColorPass")}},
1032+
{AntiAliasingMode::TAA, {Name("TaaPass"), Name("ContrastAdaptiveSharpeningPass")}}
1033+
};
1034+
1035+
for (auto& aaPassMap : AAPassNamesLookup)
1036+
{
1037+
AZStd::for_each(aaPassMap.second.begin(), aaPassMap.second.end(), [&pipeline, &aaPassMap, &antiAliasingMode](Name passName){
1038+
EnablePass(pipeline, passName, aaPassMap.first == antiAliasingMode);
1039+
});
1040+
}
1041+
return true;
1042+
}
9511043
}
9521044
}

Gems/Atom/RPI/Code/Source/RPI.Reflect/System/RenderPipelineDescriptor.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ namespace AZ
2626
->Field("MaterialPipelineTag", &RenderPipelineDescriptor::m_materialPipelineTag)
2727
->Field("ExecuteOnce", &RenderPipelineDescriptor::m_executeOnce)
2828
->Field("RenderSettings", &RenderPipelineDescriptor::m_renderSettings)
29+
->Field("DefaultAAMethod", &RenderPipelineDescriptor::m_defaultAAMethod)
2930
->Field("AllowModification", &RenderPipelineDescriptor::m_allowModification)
3031
;
3132
}

0 commit comments

Comments
 (0)