MeshFeatureProcessor.h 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394
  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/Feature/Mesh/MeshFeatureProcessorInterface.h>
  10. #include <Atom/Feature/Mesh/ModelReloaderSystemInterface.h>
  11. #include <Atom/RHI/TagBitRegistry.h>
  12. #include <Atom/RPI.Public/Culling.h>
  13. #include <Atom/RPI.Public/MeshDrawPacket.h>
  14. #include <Atom/RPI.Public/Shader/ShaderSystemInterface.h>
  15. #include <AtomCore/std/parallel/concurrency_checker.h>
  16. #include <AzCore/Asset/AssetCommon.h>
  17. #include <AzCore/Component/TickBus.h>
  18. #include <AzCore/Console/Console.h>
  19. #include <AzFramework/Asset/AssetCatalogBus.h>
  20. #include <Mesh/MeshInstanceManager.h>
  21. #include <RayTracing/RayTracingFeatureProcessor.h>
  22. #include <TransformService/TransformServiceFeatureProcessor.h>
  23. namespace AZ
  24. {
  25. namespace Render
  26. {
  27. class TransformServiceFeatureProcessor;
  28. class RayTracingFeatureProcessor;
  29. class ReflectionProbeFeatureProcessor;
  30. class MeshFeatureProcessor;
  31. class GpuBufferHandler;
  32. class ModelDataInstance : ModelDataInstanceInterface
  33. {
  34. friend class MeshFeatureProcessor;
  35. friend class MeshLoader;
  36. public:
  37. AZ_RTTI(AZ::Render::ModelDataInstance, "{AF38DCED-9692-4B88-8738-9710BA70F49C}", AZ::Render::ModelDataInstanceInterface);
  38. ModelDataInstance();
  39. const Data::Instance<RPI::Model>& GetModel() override
  40. {
  41. return m_model;
  42. }
  43. const RPI::Cullable& GetCullable() override
  44. {
  45. return m_cullable;
  46. }
  47. const uint32_t GetLightingChannelMask() override
  48. {
  49. return m_lightingChannelMask;
  50. }
  51. using InstanceGroupHandle = StableDynamicArrayWeakHandle<MeshInstanceGroupData>;
  52. using PostCullingInstanceDataList = AZStd::vector<PostCullingInstanceData>;
  53. const bool IsSkinnedMesh() override
  54. {
  55. return m_descriptor.m_isSkinnedMesh;
  56. }
  57. const AZ::Uuid& GetRayTracingUuid() const override
  58. {
  59. return m_rayTracingUuid;
  60. }
  61. void HandleDrawPacketUpdate(uint32_t lodIndex, uint32_t meshIndex, RPI::MeshDrawPacket& meshDrawPacket) override;
  62. void ConnectMeshDrawPacketUpdatedHandler(MeshDrawPacketUpdatedEvent::Handler& handler) override;
  63. CustomMaterialInfo GetCustomMaterialWithFallback(const CustomMaterialId& id) const override;
  64. private:
  65. class MeshLoader
  66. : private SystemTickBus::Handler
  67. , private Data::AssetBus::Handler
  68. , private AzFramework::AssetCatalogEventBus::Handler
  69. {
  70. public:
  71. MeshLoader(const Data::Asset<RPI::ModelAsset>& modelAsset, ModelDataInstance* parent);
  72. ~MeshLoader();
  73. private:
  74. // SystemTickBus::Handler overrides...
  75. void OnSystemTick() override;
  76. // AssetBus::Handler overrides...
  77. void OnAssetReady(Data::Asset<Data::AssetData> asset) override;
  78. void OnAssetError(Data::Asset<Data::AssetData> asset) override;
  79. // AssetCatalogEventBus::Handler overrides...
  80. void OnCatalogAssetRemoved(const AZ::Data::AssetId& assetId, const AZ::Data::AssetInfo& assetInfo) override;
  81. void OnCatalogAssetChanged(const AZ::Data::AssetId& assetId) override;
  82. void OnCatalogAssetAdded(const AZ::Data::AssetId& assetId) override;
  83. void OnModelReloaded(Data::Asset<Data::AssetData> asset);
  84. ModelReloadedEvent::Handler m_modelReloadedEventHandler{ [&](Data::Asset<RPI::ModelAsset> modelAsset)
  85. {
  86. OnModelReloaded(modelAsset);
  87. } };
  88. Data::Asset<RPI::ModelAsset> m_modelAsset;
  89. ModelDataInstance* m_parent = nullptr;
  90. };// class MeshLoader
  91. // Free all the resources owned by this mesh handle
  92. void DeInit(MeshFeatureProcessor* meshFeatureProcessor);
  93. // Clear all the data that is created by the MeshFeatureProcessor, such as the draw packets, cullable, and ray-tracing data,
  94. // but preserve all the settings such as the model, material assignment, etc., then queue it for re-initialization
  95. void ReInit(MeshFeatureProcessor* meshFeatureProcessor);
  96. void QueueInit(const Data::Instance<RPI::Model>& model);
  97. void Init(MeshFeatureProcessor* meshFeatureProcessor);
  98. void BuildDrawPacketList(MeshFeatureProcessor* meshFeatureProcessor, size_t modelLodIndex);
  99. void SetRayTracingData(MeshFeatureProcessor* meshFeatureProcessor);
  100. void RemoveRayTracingData(RayTracingFeatureProcessor* rayTracingFeatureProcessor);
  101. void SetIrradianceData(
  102. RayTracingFeatureProcessor::SubMesh& subMesh,
  103. const Data::Instance<RPI::Material> material,
  104. const Data::Instance<RPI::Image> baseColorImage);
  105. void SetRayTracingReflectionProbeData(
  106. MeshFeatureProcessor* meshFeatureProcessor,
  107. RayTracingFeatureProcessor::Mesh::ReflectionProbe& reflectionProbe);
  108. void SetSortKey(MeshFeatureProcessor* meshFeatureProcessor, RHI::DrawItemSortKey sortKey);
  109. RHI::DrawItemSortKey GetSortKey() const;
  110. void SetLightingChannelMask(uint32_t lightingChannelMask);
  111. void SetMeshLodConfiguration(RPI::Cullable::LodConfiguration meshLodConfig);
  112. RPI::Cullable::LodConfiguration GetMeshLodConfiguration() const;
  113. void UpdateDrawPackets(bool forceUpdate = false);
  114. void BuildCullable();
  115. void UpdateCullBounds(const MeshFeatureProcessor* meshFeatureProcessor);
  116. void UpdateObjectSrg(MeshFeatureProcessor* meshFeatureProcessor);
  117. bool MaterialRequiresForwardPassIblSpecular(Data::Instance<RPI::Material> material) const;
  118. void SetVisible(bool isVisible);
  119. // When instancing is disabled, draw packets are owned by the ModelDataInstance
  120. RPI::MeshDrawPacketLods m_meshDrawPacketListsByLod;
  121. // When instancing is enabled, draw packets are owned by the MeshInstanceManager,
  122. // and the ModelDataInstance refers to those draw packets via InstanceGroupHandles,
  123. // which are turned into instance draw calls after culling
  124. AZStd::vector<PostCullingInstanceDataList> m_postCullingInstanceDataByLod;
  125. size_t m_lodBias = 0;
  126. RPI::Cullable m_cullable;
  127. MeshHandleDescriptor m_descriptor;
  128. Data::Instance<RPI::Model> m_model;
  129. //! A reference to the original model asset in case it got cloned before creating the model instance.
  130. Data::Asset<RPI::ModelAsset> m_originalModelAsset;
  131. //! List of object SRGs used by meshes in this model
  132. AZStd::vector<Data::Instance<RPI::ShaderResourceGroup>> m_objectSrgList;
  133. //! Event that gets triggered whenever the model is changed, loaded, or reloaded.
  134. MeshHandleDescriptor::ModelChangedEvent m_modelChangedEvent;
  135. //! Event that triggers whenever the ObjectSrg is created.
  136. MeshHandleDescriptor::ObjectSrgCreatedEvent m_objectSrgCreatedEvent;
  137. //! Event that triggers whenever a MeshDrawPacket gets updated.
  138. MeshDrawPacketUpdatedEvent m_meshDrawPacketUpdatedEvent;
  139. // MeshLoader is a shared pointer because it can queue a reference to itself on the SystemTickBus. The reference
  140. // needs to stay alive until the queued function is executed.
  141. AZStd::shared_ptr<MeshLoader> m_meshLoader;
  142. RPI::Scene* m_scene = nullptr;
  143. RHI::DrawItemSortKey m_sortKey = 0;
  144. uint32_t m_lightingChannelMask = 1;
  145. TransformServiceFeatureProcessorInterface::ObjectId m_objectId;
  146. AZ::Uuid m_rayTracingUuid;
  147. Aabb m_aabb = Aabb::CreateNull();
  148. struct Flags
  149. {
  150. bool m_cullBoundsNeedsUpdate : 1;
  151. bool m_cullableNeedsRebuild : 1;
  152. bool m_needsInit : 1;
  153. bool m_objectSrgNeedsUpdate : 1;
  154. bool m_isAlwaysDynamic : 1;
  155. bool m_dynamic : 1; // True if the model's transformation was changed than the initial position
  156. bool m_isDrawMotion : 1; // Whether draw to the motion vector
  157. bool m_visible : 1;
  158. bool m_useForwardPassIblSpecular : 1;
  159. bool m_hasForwardPassIblSpecularMaterial : 1;
  160. bool m_needsSetRayTracingData : 1;
  161. bool m_hasRayTracingReflectionProbe : 1;
  162. bool m_keepBufferAssetsInMemory : 1; // If true, we need to keep BufferAssets referenced by ModelAsset stay in memory. This is needed when editor use RayIntersection
  163. } m_flags;
  164. }; //class ModelDataInstance
  165. //! This feature processor handles static and dynamic non-skinned meshes.
  166. class MeshFeatureProcessor final : public MeshFeatureProcessorInterface
  167. {
  168. public:
  169. AZ_CLASS_ALLOCATOR(MeshFeatureProcessor, AZ::SystemAllocator)
  170. AZ_RTTI(AZ::Render::MeshFeatureProcessor, "{6E3DFA1D-22C7-4738-A3AE-1E10AB88B29B}", AZ::Render::MeshFeatureProcessorInterface);
  171. AZ_CONSOLEFUNC(MeshFeatureProcessor, ReportShaderOptionFlags, AZ::ConsoleFunctorFlags::Null, "Report currently used shader option flags.");
  172. using FlagRegistry = RHI::TagBitRegistry<RPI::Cullable::FlagType>;
  173. static void Reflect(AZ::ReflectContext* context);
  174. MeshFeatureProcessor() = default;
  175. virtual ~MeshFeatureProcessor() = default;
  176. // FeatureProcessor overrides ...
  177. //! Creates pools, buffers, and buffer views
  178. void Activate() override;
  179. //! Releases GPU resources.
  180. void Deactivate() override;
  181. //! Updates GPU buffers with latest data from render proxies
  182. void Simulate(const FeatureProcessor::SimulatePacket& packet) override;
  183. //! Updates ViewSrgs with per-view instance data for visible instances
  184. void OnEndCulling(const RenderPacket& packet) override;
  185. // RPI::SceneNotificationBus overrides ...
  186. void OnBeginPrepareRender() override;
  187. void OnEndPrepareRender() override;
  188. TransformServiceFeatureProcessorInterface::ObjectId GetObjectId(const MeshHandle& meshHandle) const override;
  189. MeshHandle AcquireMesh(const MeshHandleDescriptor& descriptor) override;
  190. bool ReleaseMesh(MeshHandle& meshHandle) override;
  191. MeshHandle CloneMesh(const MeshHandle& meshHandle) override;
  192. void PrintDrawPacketInfo(const MeshHandle& meshHandle) override;
  193. void SetDrawItemEnabled(const MeshHandle& meshHandle, RHI::DrawListTag drawListTag, bool enabled) override;
  194. Data::Instance<RPI::Model> GetModel(const MeshHandle& meshHandle) const override;
  195. Data::Asset<RPI::ModelAsset> GetModelAsset(const MeshHandle& meshHandle) const override;
  196. const RPI::MeshDrawPacketLods& GetDrawPackets(const MeshHandle& meshHandle) const override;
  197. const AZStd::vector<Data::Instance<RPI::ShaderResourceGroup>>& GetObjectSrgs(const MeshHandle& meshHandle) const override;
  198. void QueueObjectSrgForCompile(const MeshHandle& meshHandle) const override;
  199. void SetCustomMaterials(const MeshHandle& meshHandle, const Data::Instance<RPI::Material>& material) override;
  200. void SetCustomMaterials(const MeshHandle& meshHandle, const CustomMaterialMap& materials) override;
  201. const CustomMaterialMap& GetCustomMaterials(const MeshHandle& meshHandle) const override;
  202. AZStd::unique_ptr<StreamBufferViewsBuilderInterface> CreateStreamBufferViewsBuilder(const MeshHandle& meshHandle) const override;
  203. DispatchDrawItemList BuildDispatchDrawItemList(const MeshHandle& meshHandle,
  204. const uint32_t lodIndex, const uint32_t meshIndex,
  205. const RHI::DrawListMask drawListTagsFilter, const RHI::DrawFilterMask materialPipelineFilter,
  206. DispatchArgumentsSetupCB dispatchArgumentsSetupCB) const override;
  207. void SetTransform(const MeshHandle& meshHandle, const AZ::Transform& transform,
  208. const AZ::Vector3& nonUniformScale = AZ::Vector3::CreateOne()) override;
  209. Transform GetTransform(const MeshHandle& meshHandle) override;
  210. Vector3 GetNonUniformScale(const MeshHandle& meshHandle) override;
  211. void SetLocalAabb(const MeshHandle& meshHandle, const AZ::Aabb& localAabb) override;
  212. AZ::Aabb GetLocalAabb(const MeshHandle& meshHandle) const override;
  213. void SetSortKey(const MeshHandle& meshHandle, RHI::DrawItemSortKey sortKey) override;
  214. RHI::DrawItemSortKey GetSortKey(const MeshHandle& meshHandle) const override;
  215. void SetLightingChannelMask(const MeshHandle& meshHandle, uint32_t lightingChannelMask) override;
  216. uint32_t GetLightingChannelMask(const MeshHandle& meshHandle) const override;
  217. void SetMeshLodConfiguration(const MeshHandle& meshHandle, const RPI::Cullable::LodConfiguration& meshLodConfig) override;
  218. RPI::Cullable::LodConfiguration GetMeshLodConfiguration(const MeshHandle& meshHandle) const override;
  219. void SetExcludeFromReflectionCubeMaps(const MeshHandle& meshHandle, bool excludeFromReflectionCubeMaps) override;
  220. bool GetExcludeFromReflectionCubeMaps(const MeshHandle& meshHandle) const override;
  221. void SetIsAlwaysDynamic(const MeshHandle& meshHandle, bool isAlwaysDynamic) override;
  222. bool GetIsAlwaysDynamic(const MeshHandle& meshHandle) const override;
  223. void SetRayTracingEnabled(const MeshHandle& meshHandle, bool enabled) override;
  224. bool GetRayTracingEnabled(const MeshHandle& meshHandle) const override;
  225. void SetVisible(const MeshHandle& meshHandle, bool visible) override;
  226. bool GetVisible(const MeshHandle& meshHandle) const override;
  227. void SetUseForwardPassIblSpecular(const MeshHandle& meshHandle, bool useForwardPassIblSpecular) override;
  228. void SetRayTracingDirty(const MeshHandle& meshHandle) override;
  229. RHI::Ptr <FlagRegistry> GetShaderOptionFlagRegistry();
  230. // called when reflection probes are modified in the editor so that meshes can re-evaluate their probes
  231. void UpdateMeshReflectionProbes();
  232. void ReportShaderOptionFlags(const AZ::ConsoleCommandContainer& arguments);
  233. // Quick functions to get other relevant feature processors that have already been cached by the MeshFeatureProcessor
  234. // without needing to go through the RPI's list of feature processors
  235. RayTracingFeatureProcessor* GetRayTracingFeatureProcessor() const;
  236. ReflectionProbeFeatureProcessor* GetReflectionProbeFeatureProcessor() const;
  237. TransformServiceFeatureProcessor* GetTransformServiceFeatureProcessor() const;
  238. RHI::DrawListTag GetTransparentDrawListTag() const;
  239. MeshInstanceManager& GetMeshInstanceManager();
  240. bool IsMeshInstancingEnabled() const;
  241. const Data::Instance<RPI::ShaderResourceGroup>& GetDrawSrg(const MeshHandle& meshHandle, uint32_t lodIndex, uint32_t subMeshIndex,
  242. RHI::DrawListTag drawListTag, RHI::DrawFilterMask materialPipelineMask) const override;
  243. private:
  244. MeshFeatureProcessor(const MeshFeatureProcessor&) = delete;
  245. void ForceRebuildDrawPackets(const AZ::ConsoleCommandContainer& arguments);
  246. AZ_CONSOLEFUNC(MeshFeatureProcessor,
  247. ForceRebuildDrawPackets,
  248. AZ::ConsoleFunctorFlags::Null,
  249. "(For Testing) Invalidates all mesh draw packets, causing them to rebuild on the next frame."
  250. );
  251. void PrintShaderOptionFlags();
  252. // RPI::SceneNotificationBus::Handler overrides...
  253. void OnRenderPipelineChanged(AZ::RPI::RenderPipeline* pipeline, RPI::SceneNotification::RenderPipelineChangeType changeType) override;
  254. void CheckForInstancingCVarChange();
  255. AZStd::vector<AZ::Job*> CreateInitJobQueue();
  256. AZStd::vector<AZ::Job*> CreatePerInstanceGroupJobQueue();
  257. AZStd::vector<AZ::Job*> CreateUpdateCullingJobQueue();
  258. void ExecuteSimulateJobQueue(AZStd::span<Job*> jobQueue, Job* parentJob);
  259. void ExecuteCombinedJobQueue(AZStd::span<Job*> initQueue, AZStd::span<Job*> updateCullingQueue, Job* parentJob);
  260. void ResizePerViewInstanceVectors(size_t viewCount);
  261. void AddVisibleObjectsToBuckets(TaskGraph& addVisibleObjectsToBucketsTG, size_t viewIndex, const RPI::ViewPtr& view);
  262. void SortInstanceBufferBuckets(TaskGraph& sortInstanceBufferBucketsTG, size_t viewIndex);
  263. void BuildInstanceBufferAndDrawCalls(TaskGraph& taskGraph, size_t viewIndex, const RPI::ViewPtr& view);
  264. void UpdateGPUInstanceBufferForView(size_t viewIndex, const RPI::ViewPtr& view);
  265. // Helper function for BuildDispatchDrawItemList()
  266. void InitializeDispatchItemFromDrawItem(
  267. RHI::DispatchItem& dstDispatchItem, const RHI::DrawItem* srcDrawItem,
  268. const RHI::DispatchDirect& dispatchDirect) const;
  269. AZStd::concurrency_checker m_meshDataChecker;
  270. StableDynamicArray<ModelDataInstance> m_modelData;
  271. MeshInstanceManager m_meshInstanceManager;
  272. // SortInstanceData represents the data needed to do the sorting (sort by instance group, then by depth)
  273. // as well as the data being sorted (ObjectId)
  274. struct SortInstanceData
  275. {
  276. ModelDataInstance::InstanceGroupHandle m_instanceGroupHandle;
  277. float m_depth = 0.0f;
  278. TransformServiceFeatureProcessorInterface::ObjectId m_objectId;
  279. bool operator<(const SortInstanceData& rhs) const
  280. {
  281. return AZStd::tie(m_instanceGroupHandle, m_depth) < AZStd::tie(rhs.m_instanceGroupHandle, rhs.m_depth);
  282. }
  283. };
  284. // An InstanceGroupBucket represents all of the instance groups from a single page in the MeshInstanceManager
  285. // There is one InstanceGroupBucket per-page, per-view
  286. // This is used to perform a bucket-sort, where all of the visible meshes for a given view are first added to their bucket,
  287. // then they are sorted within the bucket.
  288. struct InstanceGroupBucket
  289. {
  290. AZStd::atomic<uint32_t> m_currentElementIndex{};
  291. AZStd::vector<SortInstanceData> m_sortInstanceData{};
  292. InstanceGroupBucket() = default;
  293. InstanceGroupBucket(const InstanceGroupBucket& rhs)
  294. : m_currentElementIndex(rhs.m_currentElementIndex.load())
  295. , m_sortInstanceData(rhs.m_sortInstanceData)
  296. {
  297. }
  298. void operator=(const InstanceGroupBucket& rhs)
  299. {
  300. m_currentElementIndex = rhs.m_currentElementIndex.load();
  301. m_sortInstanceData = rhs.m_sortInstanceData;
  302. }
  303. };
  304. AZStd::vector<AZStd::vector<InstanceGroupBucket>> m_perViewInstanceGroupBuckets;
  305. AZStd::vector<AZStd::vector<TransformServiceFeatureProcessorInterface::ObjectId>> m_perViewInstanceData;
  306. AZStd::vector<GpuBufferHandler> m_perViewInstanceDataBufferHandlers;
  307. TransformServiceFeatureProcessor* m_transformService = nullptr;
  308. RayTracingFeatureProcessor* m_rayTracingFeatureProcessor = nullptr;
  309. ReflectionProbeFeatureProcessor* m_reflectionProbeFeatureProcessor = nullptr;
  310. AZ::RPI::ShaderSystemInterface::GlobalShaderOptionUpdatedEvent::Handler m_handleGlobalShaderOptionUpdate;
  311. RPI::MeshDrawPacketLods m_emptyDrawPacketLods;
  312. RHI::Ptr<FlagRegistry> m_flagRegistry = nullptr;
  313. AZ::RHI::Handle<uint32_t> m_meshMovedFlag;
  314. RHI::DrawListTag m_meshMotionDrawListTag;
  315. RHI::DrawListTag m_transparentDrawListTag;
  316. bool m_forceRebuildDrawPackets = false;
  317. bool m_reportShaderOptionFlags = false;
  318. bool m_enablePerMeshShaderOptionFlags = false;
  319. bool m_enableMeshInstancing = false;
  320. bool m_enableMeshInstancingForTransparentObjects = false;
  321. };
  322. } // namespace Render
  323. } // namespace AZ