FoveatedImagePass.cpp 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  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 <Passes/FoveatedImagePass.h>
  9. #include <Atom/RHI/RHISystemInterface.h>
  10. #include <Atom/RPI.Public/Image/AttachmentImagePool.h>
  11. #include <Atom/RPI.Public/Image/ImageSystemInterface.h>
  12. #include <Atom/RPI.Public/Pass/PassUtils.h>
  13. #include <Atom/RPI.Reflect/Pass/PassName.h>
  14. #include <AzCore/Settings/SettingsRegistry.h>
  15. namespace XR
  16. {
  17. AZ::RPI::Ptr<FoveatedImagePass> FoveatedImagePass::Create(const AZ::RPI::PassDescriptor& descriptor)
  18. {
  19. AZ::RPI::Ptr<FoveatedImagePass> pass = aznew FoveatedImagePass(descriptor);
  20. return pass;
  21. }
  22. FoveatedImagePass::FoveatedImagePass(const AZ::RPI::PassDescriptor& descriptor)
  23. : Base(descriptor)
  24. {
  25. const FoveatedImagePassData* passData = AZ::RPI::PassUtils::GetPassData<FoveatedImagePassData>(descriptor);
  26. if (passData)
  27. {
  28. m_foveatedLevel = passData->m_foveatedLevel;
  29. }
  30. }
  31. void FoveatedImagePass::ResetInternal()
  32. {
  33. m_foveatedImage.reset();
  34. m_foveatedAttachment.reset();
  35. Base::ResetInternal();
  36. }
  37. void FoveatedImagePass::BuildInternal()
  38. {
  39. AZ::RHI::XRRenderingInterface* xrSystem = AZ::RHI::RHISystemInterface::Get()->GetXRSystem();
  40. if (xrSystem)
  41. {
  42. m_foveatedAttachment = FindAttachment(AZ::Name("FoveatedImage"));
  43. // Update the image attachment descriptor to sync up size and format
  44. m_foveatedAttachment->Update(true);
  45. AZ::RHI::ImageDescriptor& imageDesc = m_foveatedAttachment->m_descriptor.m_image;
  46. // Calculate the size of the shading rate attachment.
  47. AZ::RHI::Device* device = AZ::RHI::RHISystemInterface::Get()->GetDevice();
  48. const auto& tileSize = device->GetLimits().m_shadingRateTileSize;
  49. const uint32_t width = aznumeric_cast<uint32_t>(ceil(static_cast<float>(imageDesc.m_size.m_width) / tileSize.m_width));
  50. const uint32_t height = aznumeric_cast<uint32_t>(ceil(static_cast<float>(imageDesc.m_size.m_height) / tileSize.m_height));
  51. AZ::RPI::AttachmentImage* currentImage = azrtti_cast<AZ::RPI::AttachmentImage*>(m_foveatedAttachment->m_importedResource.get());
  52. // If there's a resource already and the size didn't change, just keep using the old AttachmentImage.
  53. if (!m_foveatedAttachment->m_importedResource || AZ::RHI::Size(width, height, 1) != currentImage->GetDescriptor().m_size)
  54. {
  55. AZ::Data::Instance<AZ::RPI::AttachmentImagePool> pool = AZ::RPI::ImageSystemInterface::Get()->GetSystemAttachmentPool();
  56. imageDesc.m_size.m_width = width;
  57. imageDesc.m_size.m_height = height;
  58. imageDesc.m_bindFlags |= AZ::RHI::ImageBindFlags::ShadingRate;
  59. if (imageDesc.m_format == AZ::RHI::Format::Unknown)
  60. {
  61. // Find the appropriate format for the image
  62. for (uint32_t i = 0; i < static_cast<uint32_t>(AZ::RHI::Format::Count); ++i)
  63. {
  64. AZ::RHI::Format format = static_cast<AZ::RHI::Format>(i);
  65. AZ::RHI::FormatCapabilities capabilities = device->GetFormatCapabilities(format);
  66. if (AZ::RHI::CheckBitsAll(capabilities, AZ::RHI::FormatCapabilities::ShadingRate))
  67. {
  68. imageDesc.m_format = format;
  69. break;
  70. }
  71. }
  72. }
  73. // The ImageViewDescriptor must be specified to make sure the frame graph compiler doesn't treat this as a transient image.
  74. AZ::RHI::ImageViewDescriptor viewDesc = AZ::RHI::ImageViewDescriptor::Create(imageDesc.m_format, 0, 0);
  75. viewDesc.m_aspectFlags = AZ::RHI::ImageAspectFlags::Color;
  76. AZStd::string imageName = AZ::RPI::ConcatPassString(GetPathName(), m_foveatedAttachment->m_path);
  77. auto attachmentImage = AZ::RPI::AttachmentImage::Create(*pool.get(), imageDesc, AZ::Name(imageName), nullptr, &viewDesc);
  78. if (attachmentImage)
  79. {
  80. // Fill up the contents of the shading rate image
  81. xrSystem->InitVariableRateShadingImageContent(attachmentImage->GetRHIImage(), m_foveatedLevel);
  82. m_foveatedAttachment->m_path = attachmentImage->GetAttachmentId();
  83. m_foveatedAttachment->m_importedResource = attachmentImage;
  84. m_foveatedImage = attachmentImage;
  85. }
  86. }
  87. }
  88. Base::BuildInternal();
  89. }
  90. } // namespace XR