DiffuseProbeGridTextureReadback.cpp 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  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 <Render/DiffuseProbeGridTextureReadback.h>
  9. #include <Render/DiffuseProbeGrid.h>
  10. namespace AZ
  11. {
  12. namespace Render
  13. {
  14. DiffuseProbeGridTextureReadback::DiffuseProbeGridTextureReadback(DiffuseProbeGrid* diffuseProbeGrid)
  15. : m_diffuseProbeGrid(diffuseProbeGrid)
  16. {
  17. }
  18. void DiffuseProbeGridTextureReadback::BeginTextureReadback(DiffuseProbeGridBakeTexturesCallback callback)
  19. {
  20. AZ_Assert(m_readbackState == DiffuseProbeGridReadbackState::Idle, "DiffuseProbeGridTextureReadback is already processing a readback request");
  21. m_callback = callback;
  22. m_remainingInitializationFrames = DefaultNumInitializationFrames;
  23. m_readbackState = DiffuseProbeGridReadbackState::Initializing;
  24. }
  25. void DiffuseProbeGridTextureReadback::Update(const AZ::Name& passName)
  26. {
  27. if (m_readbackState == DiffuseProbeGridReadbackState::Idle || m_readbackState == DiffuseProbeGridReadbackState::Complete)
  28. {
  29. return;
  30. }
  31. if (m_readbackState == DiffuseProbeGridReadbackState::Initializing)
  32. {
  33. if (m_remainingInitializationFrames > 0)
  34. {
  35. // still in the initialization state to allow the irradiance textures to settle, decrement the frame count
  36. m_remainingInitializationFrames--;
  37. return;
  38. }
  39. // settling complete, move to the irradiance readback state to begin the readback process
  40. m_readbackState = DiffuseProbeGridReadbackState::Irradiance;
  41. }
  42. if (m_attachmentReadback.get() && m_attachmentReadback->GetReadbackState() > RPI::AttachmentReadback::ReadbackState::Idle)
  43. {
  44. // still processing previous request
  45. return;
  46. }
  47. AZStd::string readbackName = AZStd::string::format("DiffuseProbeGridReadback_%s", passName.GetCStr());
  48. RHI::ImageDescriptor descriptor;
  49. RHI::AttachmentId attachmentId;
  50. RPI::AttachmentReadback::CallbackFunction callbackFunction;
  51. switch (m_readbackState)
  52. {
  53. case DiffuseProbeGridReadbackState::Irradiance:
  54. descriptor = m_diffuseProbeGrid->GetIrradianceImage()->GetDescriptor();
  55. attachmentId = m_diffuseProbeGrid->GetIrradianceImageAttachmentId();
  56. callbackFunction = [this](const AZ::RPI::AttachmentReadback::ReadbackResult& readbackResult)
  57. {
  58. m_irradianceReadbackResult = readbackResult;
  59. m_readbackState = DiffuseProbeGridReadbackState::Distance;
  60. };
  61. break;
  62. case DiffuseProbeGridReadbackState::Distance:
  63. descriptor = m_diffuseProbeGrid->GetDistanceImage()->GetDescriptor();
  64. attachmentId = m_diffuseProbeGrid->GetDistanceImageAttachmentId();
  65. callbackFunction = [this](const AZ::RPI::AttachmentReadback::ReadbackResult& readbackResult)
  66. {
  67. m_distanceReadbackResult = readbackResult;
  68. m_readbackState = DiffuseProbeGridReadbackState::ProbeData;
  69. };
  70. break;
  71. case DiffuseProbeGridReadbackState::ProbeData:
  72. descriptor = m_diffuseProbeGrid->GetProbeDataImage()->GetDescriptor();
  73. attachmentId = m_diffuseProbeGrid->GetProbeDataImageAttachmentId();
  74. callbackFunction = [this](const AZ::RPI::AttachmentReadback::ReadbackResult& readbackResult)
  75. {
  76. m_probeDataReadbackResult = readbackResult;
  77. m_readbackState = DiffuseProbeGridReadbackState::Complete;
  78. };
  79. break;
  80. default:
  81. AZ_Assert(false, "Unknown readback state");
  82. }
  83. m_attachmentReadback = AZStd::make_shared<AZ::RPI::AttachmentReadback>(AZ::RHI::ScopeId{ "DiffuseProbeGridTextureReadBack" });
  84. m_attachmentReadback->SetCallback(callbackFunction);
  85. AZ::RPI::PassAttachment passAttachment;
  86. passAttachment.m_descriptor = descriptor;
  87. passAttachment.m_path = attachmentId;
  88. passAttachment.m_name = readbackName;
  89. passAttachment.m_lifetime = RHI::AttachmentLifetimeType::Imported;
  90. m_attachmentReadback->ReadPassAttachment(&passAttachment, AZ::Name(readbackName));
  91. }
  92. void DiffuseProbeGridTextureReadback::FrameBegin(AZ::RPI::Pass::FramePrepareParams& params)
  93. {
  94. if (m_readbackState == DiffuseProbeGridReadbackState::Idle)
  95. {
  96. return;
  97. }
  98. if (!m_attachmentReadback.get())
  99. {
  100. return;
  101. }
  102. if (m_readbackState == DiffuseProbeGridReadbackState::Complete)
  103. {
  104. // readback of all textures is complete, invoke callback and return to Idle state
  105. m_callback(
  106. { m_irradianceReadbackResult.m_dataBuffer, m_irradianceReadbackResult.m_imageDescriptor.m_format, m_irradianceReadbackResult.m_imageDescriptor.m_size },
  107. { m_distanceReadbackResult.m_dataBuffer, m_distanceReadbackResult.m_imageDescriptor.m_format, m_distanceReadbackResult.m_imageDescriptor.m_size },
  108. { m_probeDataReadbackResult.m_dataBuffer, m_probeDataReadbackResult.m_imageDescriptor.m_format, m_probeDataReadbackResult.m_imageDescriptor.m_size });
  109. m_readbackState = DiffuseProbeGridReadbackState::Idle;
  110. m_attachmentReadback.reset();
  111. return;
  112. }
  113. m_attachmentReadback->FrameBegin(params);
  114. }
  115. } // namespace Render
  116. } // namespace AZ