AsyncComputeExampleComponent.h 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  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. #pragma once
  9. #include <Atom/RHI/BufferPool.h>
  10. #include <Atom/RHI/DrawItem.h>
  11. #include <Atom/RHI/ScopeProducer.h>
  12. #include <Atom/RHI/RHISystemInterface.h>
  13. #include <Atom/RPI.Public/Shader/Shader.h>
  14. #include <Atom/RPI.Public/Shader/ShaderResourceGroup.h>
  15. #include <Atom/RPI.Public/Model/Model.h>
  16. #include <Atom/RPI.Public/Model/ModelLod.h>
  17. #include <Atom/RPI.Reflect/ResourcePoolAssetCreator.h>
  18. #include <Atom/Utils/AssetCollectionAsyncLoader.h>
  19. #include <AzCore/Component/Component.h>
  20. #include <AzCore/Component/TickBus.h>
  21. #include <RHI/BasicRHIComponent.h>
  22. #include <ExampleComponentBus.h>
  23. #include <Utils/ImGuiSidebar.h>
  24. #include <Utils/ImGuiProgressList.h>
  25. namespace AtomSampleViewer
  26. {
  27. //! This sample demostrates the use of async compute.
  28. //! It applies a simple tonemapping post processing.
  29. //! In order to get better scheduling between graphic and compute work, the sample
  30. //! uses two scene textures, one from the previous frame and one from the current one.
  31. //! Tonemapping is applied to the previous frame scene image.
  32. //! The tonemapping scope runs on a compute shader in the compute queue.
  33. //! The average luminance calculation used for the tonemapping also runs in a compute shader in the compute queue.
  34. //! There's also a shadow generation and luminance map scopes.
  35. //! [GFX TODO][ATOM-2034] Add scope synchronization once it's supported in the RHI.
  36. //!
  37. //! Next / Previous Frame
  38. //! +--------------------------------------------------------------------+
  39. //! | |
  40. //! | +--------------+ +----------------+ +-------+ | +---------------+
  41. //! Graphics Queue +----->| LuminanceMap |---+ |ShadowGeneration|------>|Forward|----+ |CopyToSwapchain|------> Present
  42. //! +-------------++ | +----------------+ +-------+ +-------+-------+
  43. //! | ^
  44. //! | |
  45. //! | +---------------+ +-----------+ |
  46. //! Compute Queue +--->|LuminanceReduce|------->|Tonemapping|--------------+
  47. //! +---------------+ +-----------+
  48. //!
  49. //!
  50. class AsyncComputeExampleComponent final
  51. : public BasicRHIComponent
  52. , public AZ::TickBus::Handler
  53. , public ExampleComponentRequestBus::Handler
  54. {
  55. public:
  56. AZ_COMPONENT(AsyncComputeExampleComponent, "{782EA426-AB4A-4F4F-A296-775EE350FF0A}", AZ::Component);
  57. AZ_DISABLE_COPY(AsyncComputeExampleComponent);
  58. static void Reflect(AZ::ReflectContext* context);
  59. AsyncComputeExampleComponent();
  60. ~AsyncComputeExampleComponent() = default;
  61. protected:
  62. struct ScopeData
  63. {
  64. };
  65. struct NumThreadsCS
  66. {
  67. int m_X = 8;
  68. int m_Y = 8;
  69. int m_Z = 1;
  70. };
  71. // BasicRHIComponent overrides...
  72. void Activate() override;
  73. void Deactivate() override;
  74. bool ReadInConfig(const AZ::ComponentConfig* baseConfig) override;
  75. void FrameBeginInternal(AZ::RHI::FrameGraphBuilder& frameGraphBuilder) override;
  76. // TickBus::Handler
  77. void OnTick(float deltaTime, AZ::ScriptTimePoint time) override;
  78. // ExampleComponentRequestBus::Handler
  79. void ResetCamera() override;
  80. void OnAllAssetsReadyActivate();
  81. void CreateSceneRenderTargets();
  82. void CreateQuad();
  83. void LoadShaders();
  84. void LoadModel();
  85. void CreatePipelines();
  86. void SetupScene();
  87. void SetArcBallControllerParams();
  88. void CreateCopyTextureScope();
  89. void CreateShadowScope();
  90. void CreateForwardScope();
  91. void CreateTonemappingScope();
  92. void CreateLuminanceMapScope();
  93. void CreateLuminanceReduceScopes();
  94. // Scope types
  95. enum AsyncComputeScopes
  96. {
  97. CopyTextureScope = 0, // Copy content back to the swapchain (R16G16B16A16 to Swapchain format conversion).
  98. ShadowScope, // Generates shadow map.
  99. ForwardScope, // Renders the scene.
  100. LuminanceMapScope, // Creates the luminance map from the scene image.
  101. LuminanceReduceScope, // Reduce luminance map to a 1x1 image.
  102. TonemappingScope, // Appplies tonemapping.
  103. NumScopes
  104. };
  105. // Quad related variables
  106. AZ::RHI::Ptr<AZ::RHI::BufferPool> m_quadBufferPool;
  107. AZ::RHI::Ptr<AZ::RHI::Buffer> m_quadInputAssemblyBuffer;
  108. AZStd::array<AZ::RHI::GeometryView, NumScopes> m_geometryViews;
  109. // Terrain related variables
  110. AZStd::array<AZ::RHI::ConstPtr<AZ::RHI::PipelineState>, NumScopes> m_terrainPipelineStates;
  111. // Model related variables
  112. AZStd::array<AZ::RHI::StreamBufferIndices, NumScopes> m_modelStreamBufferIndices;
  113. AZStd::array<AZ::RHI::ConstPtr<AZ::RHI::PipelineState>, NumScopes> m_modelPipelineStates;
  114. AZ::Data::Instance<AZ::RPI::Model> m_model;
  115. // Copy Texture related variables
  116. AZ::RHI::ConstPtr<AZ::RHI::PipelineState> m_copyTexturePipelineState;
  117. // Luminance map related variables
  118. AZ::RHI::ConstPtr<AZ::RHI::PipelineState> m_luminancePipelineState;
  119. // Luminance reduce related variables
  120. AZ::RHI::ConstPtr<AZ::RHI::PipelineState> m_luminanceReducePipelineState;
  121. // Tonemapping related variables
  122. AZ::RHI::ConstPtr<AZ::RHI::PipelineState> m_tonemappingPipelineState;
  123. // Camera projection matrix
  124. AZ::Matrix4x4 m_projectionMatrix;
  125. AZStd::array<AZStd::vector<AZ::Data::Instance<AZ::RPI::ShaderResourceGroup>>, NumScopes> m_shaderResourceGroups;
  126. AZ::Data::Instance<AZ::RPI::ShaderResourceGroup> m_viewShaderResourceGroup;
  127. AZ::RHI::ShaderInputImageIndex m_shaderInputImageIndex;
  128. AZ::RHI::ShaderInputImageIndex m_copyTextureShaderInputImageIndex;
  129. AZ::RHI::ShaderInputImageIndex m_luminanceShaderInputImageIndex;
  130. AZ::RHI::ShaderInputImageIndex m_luminanceReduceShaderInputImageIndex;
  131. AZ::RHI::ShaderInputImageIndex m_luminanceReduceShaderOutputImageIndex;
  132. AZ::RHI::ShaderInputImageIndex m_tonemappingShaderImageIndex;
  133. AZ::RHI::ShaderInputImageIndex m_tonemappingLuminanceImageIndex;
  134. AZ::EntityId m_cameraEntityId;
  135. AZStd::array<AZ::Data::Instance<AZ::RPI::Shader>, NumScopes> m_shaders;
  136. AZStd::array<NumThreadsCS, NumScopes> m_numThreads;
  137. // Scene images
  138. static constexpr uint32_t NumSceneImages = 2;
  139. AZStd::array<AZ::RHI::AttachmentId, NumSceneImages> m_sceneIds = { { AZ::RHI::AttachmentId("SceneId1"), AZ::RHI::AttachmentId("SceneId2") } };
  140. AZ::RHI::Ptr<AZ::RHI::ImagePool> m_imagePool;
  141. AZStd::array<AZ::RHI::Ptr<AZ::RHI::Image>, NumSceneImages> m_sceneImages;
  142. uint32_t m_currentSceneImageIndex = 0;
  143. uint32_t m_previousSceneImageIndex = 1;
  144. ImGuiSidebar m_imguiSidebar;
  145. bool m_asyncComputeEnabled = true;
  146. AZ::RHI::AttachmentId m_forwardDepthStencilId;
  147. AZ::RHI::AttachmentId m_shadowAttachmentId;
  148. AZ::RHI::AttachmentId m_luminanceMapAttachmentId;
  149. AZ::RHI::AttachmentId m_averageLuminanceAttachmentId;
  150. AZStd::unique_ptr<AZ::AssetCollectionAsyncLoader> m_assetLoadManager;
  151. bool m_fullyActivated = false;
  152. ImGuiProgressList m_imguiProgressList;
  153. };
  154. }