BakeAcesOutputTransformLutPass.cpp 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  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 <DisplayMapper/BakeAcesOutputTransformLutPass.h>
  9. #include <Atom/Feature/ACES/AcesDisplayMapperFeatureProcessor.h>
  10. #include <Atom/RHI/FrameGraphAttachmentInterface.h>
  11. #include <Atom/RPI.Public/RenderPipeline.h>
  12. #include <Atom/RPI.Public/Scene.h>
  13. namespace AZ
  14. {
  15. namespace Render
  16. {
  17. RPI::Ptr<BakeAcesOutputTransformLutPass> BakeAcesOutputTransformLutPass::Create(const RPI::PassDescriptor& descriptor)
  18. {
  19. RPI::Ptr<BakeAcesOutputTransformLutPass> pass = aznew BakeAcesOutputTransformLutPass(descriptor);
  20. return pass;
  21. }
  22. BakeAcesOutputTransformLutPass::BakeAcesOutputTransformLutPass(const RPI::PassDescriptor& descriptor)
  23. : RPI::ComputePass(descriptor)
  24. {
  25. m_needToUpdateLut = true;
  26. }
  27. BakeAcesOutputTransformLutPass::~BakeAcesOutputTransformLutPass()
  28. {
  29. ReleaseLutImage();
  30. }
  31. void BakeAcesOutputTransformLutPass::InitializeInternal()
  32. {
  33. AZ_Assert(m_shaderResourceGroup != nullptr, "BakeAcesOutputTransformLutPass %s has a null shader resource group when calling Init.", GetPathName().GetCStr());
  34. if (m_shaderResourceGroup != nullptr)
  35. {
  36. m_shaderInputColorMatIndex = m_shaderResourceGroup->FindShaderInputConstantIndex(Name{ "m_XYZtoDisplayPrimaries" });
  37. m_shaderInputCinemaLimitsIndex = m_shaderResourceGroup->FindShaderInputConstantIndex(Name{ "m_cinemaLimits" });
  38. m_shaderInputAcesSplineParamsIndex = m_shaderResourceGroup->FindShaderInputConstantIndex(Name{ "m_acesSplineParams" });
  39. m_shaderInputFlagsIndex = m_shaderResourceGroup->FindShaderInputConstantIndex(Name{ "m_outputDisplayTransformFlags" });
  40. m_shaderInputOutputModeIndex = m_shaderResourceGroup->FindShaderInputConstantIndex(Name{ "m_outputDisplayTransformMode" });
  41. m_shaderInputSurroundGammaIndex = m_shaderResourceGroup->FindShaderInputConstantIndex(Name{ "m_surroundGamma" });
  42. m_shaderInputGammaIndex = m_shaderResourceGroup->FindShaderInputConstantIndex(Name{ "m_gamma" });
  43. m_shaderInputLutImageIndex = m_shaderResourceGroup->FindShaderInputImageIndex(Name{ "m_lutTexture" });
  44. m_shaderInputShaperBiasIndex = m_shaderResourceGroup->FindShaderInputConstantIndex(Name{ "m_shaperBias" });
  45. m_shaderInputShaperScaleIndex = m_shaderResourceGroup->FindShaderInputConstantIndex(Name{ "m_shaperScale" });
  46. }
  47. }
  48. void BakeAcesOutputTransformLutPass::SetupFrameGraphDependencies(RHI::FrameGraphInterface frameGraph)
  49. {
  50. ComputePass::SetupFrameGraphDependencies(frameGraph);
  51. if (m_displayMapperLut.m_lutImage == nullptr)
  52. {
  53. AcquireLutImage();
  54. }
  55. AZ_Assert(m_displayMapperLut.m_lutImage != nullptr, "BakeAcesOutputTransformLutPass unable to acquire LUT image");
  56. AZ::RHI::AttachmentId imageAttachmentId = AZ::RHI::AttachmentId("DisplayMapperLutImageAttachmentId");
  57. [[maybe_unused]] RHI::ResultCode result = frameGraph.GetAttachmentDatabase().ImportImage(imageAttachmentId, m_displayMapperLut.m_lutImage.get());
  58. AZ_Error("BakeAcesOutputTransformLutPass", result == RHI::ResultCode::Success, "Failed to import compute buffer with error %d", result);
  59. RHI::ImageScopeAttachmentDescriptor desc;
  60. desc.m_attachmentId = imageAttachmentId;
  61. desc.m_imageViewDescriptor = m_displayMapperLut.m_lutImageViewDescriptor;
  62. desc.m_loadStoreAction.m_loadAction = AZ::RHI::AttachmentLoadAction::DontCare;
  63. frameGraph.UseShaderAttachment(desc, RHI::ScopeAttachmentAccess::ReadWrite, RHI::ScopeAttachmentStage::ComputeShader);
  64. }
  65. void BakeAcesOutputTransformLutPass::CompileResources(const RHI::FrameGraphCompileContext& context)
  66. {
  67. AZ_Assert(m_shaderResourceGroup != nullptr, "BakeAcesOutputTransformLutPass %s has a null shader resource group when calling FrameBeginInternal.", GetPathName().GetCStr());
  68. if (m_shaderResourceGroup != nullptr)
  69. {
  70. m_shaderResourceGroup->SetConstant(m_shaderInputColorMatIndex, m_displayMapperParameters.m_XYZtoDisplayPrimaries);
  71. m_shaderResourceGroup->SetConstant(m_shaderInputCinemaLimitsIndex, m_displayMapperParameters.m_cinemaLimits);
  72. m_shaderResourceGroup->SetConstantRaw(m_shaderInputAcesSplineParamsIndex, &m_displayMapperParameters.m_acesSplineParams, sizeof(SegmentedSplineParamsC9));
  73. m_shaderResourceGroup->SetConstant(m_shaderInputFlagsIndex, m_displayMapperParameters.m_OutputDisplayTransformFlags);
  74. m_shaderResourceGroup->SetConstant(m_shaderInputOutputModeIndex, m_displayMapperParameters.m_OutputDisplayTransformMode);
  75. m_shaderResourceGroup->SetConstant(m_shaderInputSurroundGammaIndex, m_displayMapperParameters.m_surroundGamma);
  76. m_shaderResourceGroup->SetConstant(m_shaderInputGammaIndex, m_displayMapperParameters.m_gamma);
  77. m_shaderResourceGroup->SetImageView(m_shaderInputLutImageIndex, m_displayMapperLut.m_lutImageView.get());
  78. m_shaderResourceGroup->SetConstant(m_shaderInputShaperBiasIndex, m_shaperParams.m_bias);
  79. m_shaderResourceGroup->SetConstant(m_shaderInputShaperScaleIndex, m_shaperParams.m_scale);
  80. }
  81. BindPassSrg(context, m_shaderResourceGroup);
  82. m_shaderResourceGroup->Compile();
  83. }
  84. void BakeAcesOutputTransformLutPass::BuildCommandListInternal(const RHI::FrameGraphExecuteContext& context)
  85. {
  86. if (m_needToUpdateLut)
  87. {
  88. ComputePass::BuildCommandListInternal(context);
  89. m_needToUpdateLut = false;
  90. }
  91. }
  92. void BakeAcesOutputTransformLutPass::AcquireLutImage()
  93. {
  94. auto displayMapper = m_pipeline->GetScene()->GetFeatureProcessor<AZ::Render::AcesDisplayMapperFeatureProcessor>();
  95. displayMapper->GetDisplayMapperLut(m_displayMapperLut);
  96. }
  97. void BakeAcesOutputTransformLutPass::ReleaseLutImage()
  98. {
  99. m_displayMapperLut.m_lutImage.reset();
  100. m_displayMapperLut.m_lutImageView.reset();
  101. m_displayMapperLut = {};
  102. }
  103. void BakeAcesOutputTransformLutPass::SetDisplayBufferFormat(RHI::Format format)
  104. {
  105. if (m_displayBufferFormat != format)
  106. {
  107. m_needToUpdateLut = true;
  108. m_displayBufferFormat = format;
  109. m_outputDeviceTransformType = AcesDisplayMapperFeatureProcessor::GetOutputDeviceTransformType(m_displayBufferFormat);
  110. AcesDisplayMapperFeatureProcessor::GetAcesDisplayMapperParameters(&m_displayMapperParameters, m_outputDeviceTransformType);
  111. m_shaperParams = GetAcesShaperParameters(m_outputDeviceTransformType);
  112. }
  113. }
  114. const ShaperParams& BakeAcesOutputTransformLutPass::GetShaperParams() const
  115. {
  116. return m_shaperParams;
  117. }
  118. } // namespace Render
  119. } // namespace AZ