ExposureControlRenderProxy.cpp 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  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 <PostProcessing/ExposureControlRenderProxy.h>
  9. #include <PostProcessing/ExposureControlFeatureProcessor.h>
  10. #include <PostProcessing/EyeAdaptationPass.h>
  11. #include <Atom/Feature/DisplayMapper/DisplayMapperPass.h>
  12. #include <Atom/RPI.Public/View.h>
  13. #include <Atom/RHI/FrameScheduler.h>
  14. #include <AzCore/Debug/Trace.h>
  15. #include <AzCore/Component/TickBus.h>
  16. namespace AZ
  17. {
  18. namespace Render
  19. {
  20. ExposureControlRenderProxy::ExposureControlRenderProxy()
  21. {
  22. }
  23. void ExposureControlRenderProxy::Init(const RPI::ViewPtr view, uint32_t idNumber)
  24. {
  25. AZ_Assert(view != nullptr, "Invalid view pointer passed to the exposure control render proxy.");
  26. if (view != nullptr)
  27. {
  28. m_viewPtr = view;
  29. m_viewSrg = view->GetShaderResourceGroup();
  30. m_eyeAdaptationBuffer.Init(m_viewSrg, idNumber);
  31. }
  32. InitCommonBuffer(idNumber);
  33. }
  34. void ExposureControlRenderProxy::Terminate()
  35. {
  36. TerminateCommonBuffer();
  37. m_eyeAdaptationBuffer.Terminate();
  38. m_viewSrg.reset();
  39. }
  40. bool ExposureControlRenderProxy::InitCommonBuffer(uint32_t idNumber)
  41. {
  42. AZStd::string bufferName = AZStd::string::format("%s_%d", ExposureControlBufferBaseName, idNumber);
  43. // Check to see if the buffer previously created already exists.
  44. // If the old buffer existed, this buffer will be reused to avoid initialization process.
  45. m_buffer = RPI::BufferSystemInterface::Get()->FindCommonBuffer(bufferName);
  46. if (m_buffer == nullptr)
  47. {
  48. RPI::CommonBufferDescriptor desc;
  49. desc.m_poolType = RPI::CommonBufferPoolType::Constant;
  50. desc.m_bufferName = bufferName;
  51. desc.m_byteCount = sizeof(ShaderParameters);
  52. desc.m_elementSize = sizeof(ShaderParameters);
  53. desc.m_isUniqueName = true;
  54. m_buffer = RPI::BufferSystemInterface::Get()->CreateBufferFromCommonPool(desc);
  55. }
  56. if (!m_buffer)
  57. {
  58. AZ_Assert(false, "Failed to create the RPI::Buffer[%s] which is used for the exposure control feature.", bufferName.c_str());
  59. return false;
  60. }
  61. return true;
  62. }
  63. void ExposureControlRenderProxy::TerminateCommonBuffer()
  64. {
  65. m_buffer = nullptr;
  66. }
  67. void ExposureControlRenderProxy::Simulate(const AZ::RPI::FeatureProcessor::SimulatePacket& packet)
  68. {
  69. m_eyeAdaptationBuffer.Simulate(m_eyeAdaptationDelayTime);
  70. // Update the eye adaptation shader parameters.
  71. m_shaderParameters.m_eyeAdaptationEnabled = m_type == ExposureControlType::EyeAdaptation;
  72. m_shaderParameters.m_subFrameInterpolationRatio = m_eyeAdaptationBuffer.GetSubFrameInterpolationRatio();
  73. m_shaderParameters.m_delaySubFrameUnitTime = m_eyeAdaptationBuffer.GetDelaySubFrameUnitTime();
  74. m_shaderParameters.m_needUpdateEyeAdaptationHistoryBuffer = m_eyeAdaptationBuffer.IsHistoryBufferUpdateRequired();
  75. m_eyeAdaptationBuffer.CalculateCurrentBufferIndices(m_shaderParameters.m_bufferIndices);
  76. m_buffer->UpdateData(&m_shaderParameters, sizeof(m_shaderParameters), 0);
  77. }
  78. void ExposureControlRenderProxy::UpdateViewSrg()
  79. {
  80. if (m_viewSrg == nullptr)
  81. {
  82. return;
  83. }
  84. m_eyeAdaptationBuffer.UpdateSrg();
  85. m_viewSrg->SetBufferView(m_exposureControlBufferInputIndex, m_buffer->GetBufferView());
  86. if (m_viewPtr)
  87. {
  88. m_viewPtr->InvalidateSrg();
  89. }
  90. }
  91. void ExposureControlRenderProxy::DeclareAttachmentsToScopeBuilder(RHI::FrameGraphScopeBuilder& scopeBuilder)
  92. {
  93. {
  94. RHI::BufferScopeAttachmentDescriptor desc;
  95. desc.m_attachmentId = GetBuffer()->GetAttachmentId();
  96. desc.m_bufferViewDescriptor = GetBufferViewDescriptorRead();
  97. desc.m_loadStoreAction.m_loadAction = AZ::RHI::AttachmentLoadAction::DontCare;
  98. scopeBuilder.UseShaderAttachment(desc, AZ::RHI::ScopeAttachmentAccess::Read);
  99. // [GFX TODO][ATOM-2739] The DX12 validation layer error occurs if a buffer is initilaized with initial data.
  100. // To avoid this problem, upload initial data to the RWBuffer after FrameGraphAttachmentBuilder::ImportBuffer() called.
  101. GetEyeAdaptationBuffer().UploadInitialDataIfNeeded();
  102. }
  103. }
  104. Data::Instance<RPI::ShaderResourceGroup> ExposureControlRenderProxy::GetViewSrg()
  105. {
  106. return m_viewSrg;
  107. }
  108. AZ::Data::Instance<RPI::Buffer> ExposureControlRenderProxy::GetBuffer()
  109. {
  110. return m_eyeAdaptationBuffer.GetBuffer();
  111. }
  112. const RHI::BufferViewDescriptor& ExposureControlRenderProxy::GetBufferViewDescriptorRead() const
  113. {
  114. return m_eyeAdaptationBuffer.GetBufferViewDescriptorRead();
  115. }
  116. EyeAdaptationHistoryBuffer& ExposureControlRenderProxy::GetEyeAdaptationBuffer()
  117. {
  118. return m_eyeAdaptationBuffer;
  119. }
  120. void ExposureControlRenderProxy::SetExposureControlType(ExposureControlType type)
  121. {
  122. m_type = type;
  123. }
  124. void ExposureControlRenderProxy::SetManualCompensationValue(float value)
  125. {
  126. m_shaderParameters.m_compensationValue = value;
  127. }
  128. void ExposureControlRenderProxy::SetLightAdaptationScale(float scale)
  129. {
  130. m_shaderParameters.m_adaptationScale_light_dark[static_cast<uint32_t>(EyeAdaptationType::Light)] = scale;
  131. }
  132. void ExposureControlRenderProxy::SetDarkAdaptationScale(float scale)
  133. {
  134. m_shaderParameters.m_adaptationScale_light_dark[static_cast<uint32_t>(EyeAdaptationType::Dark)] = scale;
  135. }
  136. void ExposureControlRenderProxy::SetLightAdaptationSensitivity(float sensitivity)
  137. {
  138. m_shaderParameters.m_adaptationSensitivity_light_dark[static_cast<uint32_t>(EyeAdaptationType::Light)] = sensitivity;
  139. }
  140. void ExposureControlRenderProxy::SetDarkAdaptationSensitivity(float sensitivity)
  141. {
  142. m_shaderParameters.m_adaptationSensitivity_light_dark[static_cast<uint32_t>(EyeAdaptationType::Dark)] = sensitivity;
  143. }
  144. void ExposureControlRenderProxy::SetLightAdaptationSpeedLimit(float speedLimit)
  145. {
  146. m_shaderParameters.m_adaptationSpeedLimitLog2_light_dark[static_cast<uint32_t>(EyeAdaptationType::Light)] = speedLimit;
  147. }
  148. void ExposureControlRenderProxy::SetDarkAdaptationSpeedLimit(float speedLimit)
  149. {
  150. m_shaderParameters.m_adaptationSpeedLimitLog2_light_dark[static_cast<uint32_t>(EyeAdaptationType::Dark)] = speedLimit;
  151. }
  152. void ExposureControlRenderProxy::SetEyeAdaptationExposureMin(float minExposure)
  153. {
  154. m_shaderParameters.m_exposureMinMax[0] = minExposure;
  155. }
  156. void ExposureControlRenderProxy::SetEyeAdaptationExposureMax(float maxExposure)
  157. {
  158. m_shaderParameters.m_exposureMinMax[1] = maxExposure;
  159. }
  160. void ExposureControlRenderProxy::SetEyeAdaptationLightDarkExposureBorder(float lightDarkAdaptationExposureBorder)
  161. {
  162. m_shaderParameters.m_lightDarkExposureBorderLog2 = lightDarkAdaptationExposureBorder;
  163. }
  164. void ExposureControlRenderProxy::SetEyeAdaptationDelayTime(float delayTime)
  165. {
  166. m_eyeAdaptationDelayTime = delayTime;
  167. }
  168. } // namespace Render
  169. } // namespace AZ