OutputTransformPass.cpp 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. /*
  2. * Copyright (c) Contributors to the Open 3D Engine Project.
  3. * For complete copyright and license terms please see the LICENSE at the root of this distribution.
  4. *
  5. * SPDX-License-Identifier: Apache-2.0 OR MIT
  6. *
  7. */
  8. #include <Atom/Feature/DisplayMapper/OutputTransformPass.h>
  9. #include <Atom/Feature/ACES/AcesDisplayMapperFeatureProcessor.h>
  10. #include <Atom/RHI/Factory.h>
  11. #include <Atom/RHI/FrameGraphAttachmentInterface.h>
  12. #include <Atom/RPI.Public/RenderPipeline.h>
  13. #include <Atom/RPI.Public/Scene.h>
  14. namespace AZ
  15. {
  16. namespace Render
  17. {
  18. RPI::Ptr<OutputTransformPass> OutputTransformPass::Create(const RPI::PassDescriptor& descriptor)
  19. {
  20. RPI::Ptr<OutputTransformPass> pass = aznew OutputTransformPass(descriptor);
  21. return AZStd::move(pass);
  22. }
  23. OutputTransformPass::OutputTransformPass(const RPI::PassDescriptor& descriptor)
  24. : DisplayMapperFullScreenPass(descriptor)
  25. , m_toneMapperShaderVariantOptionName(ToneMapperShaderVariantOptionName)
  26. , m_transferFunctionShaderVariantOptionName(TransferFunctionShaderVariantOptionName)
  27. {
  28. }
  29. OutputTransformPass::~OutputTransformPass()
  30. {
  31. }
  32. void OutputTransformPass::InitializeInternal()
  33. {
  34. DisplayMapperFullScreenPass::InitializeInternal();
  35. AZ_Assert(m_shaderResourceGroup != nullptr, "OutputTransformPass %s has a null shader resource group when calling Init.", GetPathName().GetCStr());
  36. if (m_shaderResourceGroup != nullptr)
  37. {
  38. m_shaderInputCinemaLimitsIndex = m_shaderResourceGroup->FindShaderInputConstantIndex(Name{ "m_cinemaLimits" });
  39. }
  40. InitializeShaderVariant();
  41. }
  42. void OutputTransformPass::SetupFrameGraphDependencies(RHI::FrameGraphInterface frameGraph)
  43. {
  44. DeclareAttachmentsToFrameGraph(frameGraph);
  45. DeclarePassDependenciesToFrameGraph(frameGraph);
  46. frameGraph.SetEstimatedItemCount(1);
  47. }
  48. void OutputTransformPass::CompileResources(const RHI::FrameGraphCompileContext& context)
  49. {
  50. AZ_Assert(m_shaderResourceGroup != nullptr, "OutputTransformPass %s has a null shader resource group when calling Compile.", GetPathName().GetCStr());
  51. if (m_needToUpdateShaderVariant)
  52. {
  53. UpdateCurrentShaderVariant();
  54. }
  55. m_shaderResourceGroup->SetConstant(m_shaderInputCinemaLimitsIndex, m_displayMapperParameters.m_cinemaLimits);
  56. BindPassSrg(context, m_shaderResourceGroup);
  57. m_shaderResourceGroup->Compile();
  58. }
  59. void OutputTransformPass::BuildCommandListInternal(const RHI::FrameGraphExecuteContext& context)
  60. {
  61. AZ_Assert(m_shaderResourceGroup != nullptr, "LookModificationPass %s has a null shader resource group when calling Execute.", GetPathName().GetCStr());
  62. RHI::CommandList* commandList = context.GetCommandList();
  63. commandList->SetViewport(m_viewportState);
  64. commandList->SetScissor(m_scissorState);
  65. SetSrgsForDraw(context);
  66. m_item.SetPipelineState(GetPipelineStateFromShaderVariant());
  67. commandList->Submit(m_item.GetDeviceDrawItem(context.GetDeviceIndex()));
  68. }
  69. void OutputTransformPass::SetToneMapperType(const ToneMapperType& toneMapperType)
  70. {
  71. if (m_toneMapperType != toneMapperType)
  72. {
  73. m_toneMapperType = toneMapperType;
  74. m_needToUpdateShaderVariant = true;
  75. }
  76. }
  77. void OutputTransformPass::SetTransferFunctionType(const TransferFunctionType& transferFunctionType)
  78. {
  79. if (m_transferFunctionType != transferFunctionType)
  80. {
  81. m_transferFunctionType = transferFunctionType;
  82. m_needToUpdateShaderVariant = true;
  83. }
  84. }
  85. void OutputTransformPass::InitializeShaderVariant()
  86. {
  87. AZ_Assert(m_shader != nullptr, "OutputTransformPass %s has a null shader when calling InitializeShaderVariant.", GetPathName().GetCStr());
  88. AZStd::vector<AZ::Name> toneMapperVariationTypes = { AZ::Name("ToneMapperType::None"), AZ::Name("ToneMapperType::Reinhard")};
  89. AZStd::vector<AZ::Name> transferFunctionVariationTypes = {
  90. AZ::Name("TransferFunctionType::None"),
  91. AZ::Name("TransferFunctionType::Gamma22"),
  92. AZ::Name("TransferFunctionType::PerceptualQuantizer") };
  93. auto toneMapperVariationTypeCount = toneMapperVariationTypes.size();
  94. auto totalVariationCount = toneMapperVariationTypes.size() * transferFunctionVariationTypes.size();
  95. // Caching all pipeline state for each shader variation for performance reason.
  96. for (auto shaderVariantIndex = 0; shaderVariantIndex < totalVariationCount; ++shaderVariantIndex)
  97. {
  98. auto shaderOption = m_shader->CreateShaderOptionGroup();
  99. shaderOption.SetValue(m_toneMapperShaderVariantOptionName, toneMapperVariationTypes[shaderVariantIndex % toneMapperVariationTypeCount]);
  100. shaderOption.SetValue(m_transferFunctionShaderVariantOptionName, transferFunctionVariationTypes[shaderVariantIndex / toneMapperVariationTypeCount]);
  101. PreloadShaderVariant(m_shader, shaderOption, GetRenderAttachmentConfiguration(), GetMultisampleState());
  102. }
  103. m_needToUpdateShaderVariant = true;
  104. }
  105. void OutputTransformPass::UpdateCurrentShaderVariant()
  106. {
  107. AZ_Assert(m_shader != nullptr, "OutputTransformPass %s has a null shader when calling UpdateCurrentShaderVariant.", GetPathName().GetCStr());
  108. auto shaderOption = m_shader->CreateShaderOptionGroup();
  109. // Decide which shader to use.
  110. switch (m_toneMapperType)
  111. {
  112. case ToneMapperType::Reinhard:
  113. shaderOption.SetValue(m_toneMapperShaderVariantOptionName, AZ::Name("ToneMapperType::Reinhard"));
  114. break;
  115. default:
  116. shaderOption.SetValue(m_toneMapperShaderVariantOptionName, AZ::Name("ToneMapperType::None"));
  117. break;
  118. }
  119. switch (m_transferFunctionType)
  120. {
  121. case TransferFunctionType::Gamma22:
  122. shaderOption.SetValue(m_transferFunctionShaderVariantOptionName, AZ::Name("TransferFunctionType::Gamma22"));
  123. break;
  124. case TransferFunctionType::PerceptualQuantizer:
  125. shaderOption.SetValue(m_transferFunctionShaderVariantOptionName, AZ::Name("TransferFunctionType::PerceptualQuantizer"));
  126. break;
  127. default:
  128. shaderOption.SetValue(m_transferFunctionShaderVariantOptionName, AZ::Name("TransferFunctionType::None"));
  129. break;
  130. }
  131. UpdateShaderVariant(shaderOption);
  132. m_needToUpdateShaderVariant = false;
  133. }
  134. void OutputTransformPass::SetDisplayBufferFormat(RHI::Format format)
  135. {
  136. if (m_displayBufferFormat != format)
  137. {
  138. m_displayBufferFormat = format;
  139. if (m_displayBufferFormat == RHI::Format::R8G8B8A8_UNORM ||
  140. m_displayBufferFormat == RHI::Format::B8G8R8A8_UNORM)
  141. {
  142. AcesDisplayMapperFeatureProcessor::GetAcesDisplayMapperParameters(&m_displayMapperParameters, OutputDeviceTransformType_48Nits);
  143. }
  144. else if (m_displayBufferFormat == RHI::Format::R10G10B10A2_UNORM)
  145. {
  146. AcesDisplayMapperFeatureProcessor::GetAcesDisplayMapperParameters(&m_displayMapperParameters, OutputDeviceTransformType_1000Nits);
  147. }
  148. else
  149. {
  150. AZ_Assert(false, "Not yet supported.");
  151. // To work normally on unsupported environment, initialize the display parameters by OutputDeviceTransformType_48Nits.
  152. AcesDisplayMapperFeatureProcessor::GetAcesDisplayMapperParameters(&m_displayMapperParameters, OutputDeviceTransformType_48Nits);
  153. }
  154. }
  155. }
  156. } // namespace Render
  157. } // namespace AZ