3
0

FixedShapeProcessor.h 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266
  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/Buffer.h>
  10. #include <Atom/RHI/BufferPool.h>
  11. #include <Atom/RHI/IndexBufferView.h>
  12. #include <Atom/RHI/StreamBufferView.h>
  13. #include <Atom/RHI/DevicePipelineState.h>
  14. #include <Atom/RPI.Public/FeatureProcessor.h>
  15. #include <Atom/RPI.Public/PipelineState.h>
  16. #include <Atom/RPI.Public/Shader/ShaderResourceGroup.h>
  17. #include <Atom/RHI.Reflect/InputStreamLayout.h>
  18. #include <Atom/RHI.Reflect/Limits.h>
  19. #include <AzCore/std/containers/fixed_vector.h>
  20. #include "AuxGeomBase.h"
  21. namespace AZ
  22. {
  23. namespace RHI
  24. {
  25. class DrawPacketBuilder;
  26. }
  27. namespace RPI
  28. {
  29. class Scene;
  30. class Shader;
  31. class ShaderVariant;
  32. class ShaderOptionGroup;
  33. }
  34. namespace Render
  35. {
  36. /**
  37. * FixedShapeProcessor does the feature processor work for fixed shapes such as
  38. * Sphere, Cone, Cylinder.
  39. * This class, manages setting up the shape buffers, the stream layout, the shader asset
  40. * and the pipeline states.
  41. */
  42. class FixedShapeProcessor final
  43. {
  44. public:
  45. using StreamBufferViewsForAllStreams = AZStd::fixed_vector<AZ::RHI::StreamBufferView, AZ::RHI::Limits::Pipeline::StreamCountMax>;
  46. using AuxGeomNormal = AuxGeomPosition;
  47. AZ_TYPE_INFO(FixedShapeProcessor, "{20A11645-F8B1-4BAC-847D-F8F49FD2E339}");
  48. AZ_CLASS_ALLOCATOR(FixedShapeProcessor, AZ::SystemAllocator);
  49. FixedShapeProcessor() = default;
  50. ~FixedShapeProcessor() = default;
  51. //! Initialize the FixedShapeProcessor and all its buffers, shaders, stream layouts etc
  52. bool Initialize(RHI::MultiDevice::DeviceMask deviceMask, const AZ::RPI::Scene* scene);
  53. //! Releases the FixedShapeProcessor and all buffers
  54. void Release();
  55. //! Processes all the fixed shape objects for a frame
  56. void ProcessObjects(const AuxGeomBufferData* bufferData, const RPI::FeatureProcessor::RenderPacket& fpPacket);
  57. //! Prepare frame.
  58. void PrepareFrame();
  59. //! Do any cleanup after current frame is rendered.
  60. void FrameEnd();
  61. //! Notify this FixedShapeProcessor to update its pipeline states
  62. void SetUpdatePipelineStates();
  63. private:
  64. using LodIndex = uint32_t;
  65. struct ShaderData; // forward declare internal struct;
  66. //! We store a struct of this type for each fixed object geometry (both shapes and boxes)
  67. struct ObjectBuffers
  68. {
  69. uint32_t m_pointIndexCount;
  70. AZ::RHI::Ptr<AZ::RHI::Buffer> m_pointIndexBuffer;
  71. AZ::RHI::IndexBufferView m_pointIndexBufferView;
  72. uint32_t m_lineIndexCount;
  73. AZ::RHI::Ptr<AZ::RHI::Buffer> m_lineIndexBuffer;
  74. AZ::RHI::IndexBufferView m_lineIndexBufferView;
  75. uint32_t m_triangleIndexCount;
  76. AZ::RHI::Ptr<AZ::RHI::Buffer> m_triangleIndexBuffer;
  77. AZ::RHI::IndexBufferView m_triangleIndexBufferView;
  78. AZ::RHI::Ptr<AZ::RHI::Buffer> m_positionBuffer;
  79. AZ::RHI::Ptr<AZ::RHI::Buffer> m_normalBuffer;
  80. StreamBufferViewsForAllStreams m_streamBufferViews;
  81. StreamBufferViewsForAllStreams m_streamBufferViewsWithNormals;
  82. };
  83. // This is a temporary structure used when building object meshes. The data is then copied into RHI buffers.
  84. struct MeshData
  85. {
  86. AZStd::vector<uint16_t> m_pointIndices; // Use indices because draws are all indexed.
  87. AZStd::vector<uint16_t> m_lineIndices;
  88. AZStd::vector<uint16_t> m_triangleIndices;
  89. AZStd::vector<AuxGeomPosition> m_positions;
  90. AZStd::vector<AuxGeomNormal> m_normals;
  91. };
  92. struct Shape
  93. {
  94. LodIndex m_numLods;
  95. AZStd::vector<ObjectBuffers> m_lodBuffers;
  96. AZStd::vector<float> m_lodScreenPercentages;
  97. };
  98. struct PipelineStateOptions
  99. {
  100. AuxGeomShapePerpectiveType m_perpectiveType = PerspectiveType_ViewProjection;
  101. AuxGeomBlendMode m_blendMode = BlendMode_Alpha;
  102. AuxGeomDrawStyle m_drawStyle = DrawStyle_Line;
  103. AuxGeomDepthReadType m_depthReadType = DepthRead_On;
  104. AuxGeomDepthWriteType m_depthWriteType = DepthWrite_Off;
  105. AuxGeomFaceCullMode m_faceCullMode = FaceCull_Back;
  106. };
  107. private: // functions
  108. enum class Facing
  109. {
  110. Up,
  111. Down,
  112. Both,
  113. };
  114. bool CreateSphereBuffersAndViews(AuxGeomShapeType sphereShapeType);
  115. void CreateSphereMeshData(MeshData& meshData, uint32_t numRings, uint32_t numSections, AuxGeomShapeType sphereShapeType);
  116. bool CreateQuadBuffersAndViews();
  117. void CreateQuadMeshDataSide(MeshData& meshData, bool isUp, bool drawLines);
  118. void CreateQuadMeshData(MeshData& meshData, Facing facing = Facing::Up);
  119. bool CreateDiskBuffersAndViews();
  120. void CreateDiskMeshDataSide(MeshData& meshData, uint32_t numSections, bool isUp, float yPosition);
  121. void CreateDiskMeshData(MeshData& meshData, uint32_t numSections, Facing facing = Facing::Up, float yPosition = 0.0f);
  122. bool CreateConeBuffersAndViews();
  123. void CreateConeMeshData(MeshData& meshData, uint32_t numRings, uint32_t numSections);
  124. bool CreateCylinderBuffersAndViews(AuxGeomShapeType cylinderShapeType);
  125. void CreateCylinderMeshData(MeshData& meshData, uint32_t numSections, AuxGeomShapeType cylinderShapeType);
  126. bool CreateBoxBuffersAndViews();
  127. void CreateBoxMeshData(MeshData& meshData);
  128. bool CreateBuffersAndViews(ObjectBuffers& objectBuffers, const MeshData& meshData);
  129. LodIndex GetLodIndexForShape(AuxGeomShapeType shapeType, const AZ::RPI::View* view, const AZ::Vector3& worldPosition, const AZ::Vector3& scale);
  130. void SetupInputStreamLayout(RHI::InputStreamLayout& inputStreamLayout, RHI::PrimitiveTopology topology, bool includeNormals);
  131. void LoadShaders();
  132. void FillShaderData(Data::Instance<RPI::Shader>& shader, ShaderData& shaderData);
  133. void InitPipelineState(const PipelineStateOptions& options);
  134. RPI::Ptr<RPI::PipelineStateForDraw>& GetPipelineState(const PipelineStateOptions& pipelineStateOptions);
  135. const AZ::RHI::IndexBufferView& GetShapeIndexBufferView(AuxGeomShapeType shapeType, int drawStyle, LodIndex lodIndex) const;
  136. const StreamBufferViewsForAllStreams& GetShapeStreamBufferViews(AuxGeomShapeType shapeType, LodIndex lodIndex, int drawStyle) const;
  137. uint32_t GetShapeIndexCount(AuxGeomShapeType shapeType, int drawStyle, LodIndex lodIndex);
  138. //! Uses the given drawPacketBuilder to build a draw packet for given shape and state and returns it
  139. RHI::ConstPtr<RHI::DrawPacket> BuildDrawPacketForShape(
  140. RHI::DrawPacketBuilder& drawPacketBuilder,
  141. const ShapeBufferEntry& shape,
  142. int drawStyle,
  143. const AZStd::vector<AZ::Matrix4x4>& viewProjOverrides,
  144. const RPI::Ptr<RPI::PipelineStateForDraw>& pipelineState,
  145. LodIndex lodIndex,
  146. RHI::DrawItemSortKey sortKey = 0);
  147. const AZ::RHI::IndexBufferView& GetBoxIndexBufferView(int drawStyle) const;
  148. const StreamBufferViewsForAllStreams& GetBoxStreamBufferViews(int drawStyle) const;
  149. uint32_t GetBoxIndexCount(int drawStyle);
  150. //! Uses the given drawPacketBuilder to build a draw packet for given box and state and returns it
  151. RHI::ConstPtr<RHI::DrawPacket> BuildDrawPacketForBox(
  152. RHI::DrawPacketBuilder& drawPacketBuilder,
  153. const BoxBufferEntry& box,
  154. int drawStyle,
  155. const AZStd::vector<AZ::Matrix4x4>& overrideViewProjMatrices,
  156. const RPI::Ptr<RPI::PipelineStateForDraw>& pipelineState,
  157. RHI::DrawItemSortKey sortKey = 0);
  158. //! Uses the given drawPacketBuilder to build a draw packet with the given data
  159. RHI::ConstPtr<RHI::DrawPacket> BuildDrawPacket(
  160. RHI::DrawPacketBuilder& drawPacketBuilder,
  161. AZ::Data::Instance<RPI::ShaderResourceGroup>& srg,
  162. uint32_t indexCount,
  163. const RHI::IndexBufferView& indexBufferView,
  164. const StreamBufferViewsForAllStreams& streamBufferViews,
  165. RHI::DrawListTag drawListTag,
  166. const AZ::RHI::PipelineState* pipelineState,
  167. RHI::DrawItemSortKey sortKey);
  168. private: // data
  169. //! The buffer pool that manages the index and vertex buffers for each shape
  170. RHI::Ptr<AZ::RHI::BufferPool> m_bufferPool;
  171. //! The descriptor for drawing an object of each draw style using predefined streams
  172. RHI::InputStreamLayout m_objectStreamLayout[DrawStyle_Count];
  173. //! Array of shape buffers for all shapes
  174. AZStd::array<Shape, ShapeType_Count> m_shapes;
  175. ObjectBuffers m_boxBuffers;
  176. // not sure what the required lifetime of these is
  177. AZStd::vector<AZ::Data::Instance<AZ::RPI::ShaderResourceGroup>> m_processSrgs;
  178. // The PSOs generated by this feature processor
  179. RPI::Ptr<RPI::PipelineStateForDraw> m_pipelineStates[PerspectiveType_Count][BlendMode_Count][DrawStyle_Count][DepthRead_Count][DepthWrite_Count][FaceCull_Count];
  180. AZStd::list<RPI::Ptr<RPI::PipelineStateForDraw>*> m_createdPipelineStates;
  181. Data::Instance<RPI::Shader> m_unlitShader;
  182. Data::Instance<RPI::Shader> m_litShader;
  183. enum ShapeLightingStyle
  184. {
  185. ShapeLightingStyle_ConstantColor, // color from srg
  186. ShapeLightingStyle_Directional, // color from srg * dot product(normal, hard coded direction)
  187. ShapeLightingStyle_Count
  188. };
  189. struct ShaderData
  190. {
  191. AZ::Data::Asset<AZ::RPI::ShaderAsset> m_shaderAsset; // For @m_perObjectSrgLayout.
  192. AZ::RPI::SupervariantIndex m_supervariantIndex; // For @m_perObjectSrgLayout.
  193. AZ::RHI::Ptr<AZ::RHI::ShaderResourceGroupLayout> m_perObjectSrgLayout; // Comes from @m_shaderAsset
  194. AZ::RHI::DrawListTag m_drawListTag;
  195. AZ::RHI::ShaderInputNameIndex m_colorIndex = "m_color";
  196. AZ::RHI::ShaderInputNameIndex m_modelToWorldIndex = "m_modelToWorld";
  197. AZ::RHI::ShaderInputNameIndex m_normalMatrixIndex = "m_normalMatrix";
  198. AZ::RHI::ShaderInputNameIndex m_viewProjectionOverrideIndex = "m_viewProjectionOverride";
  199. AZ::RHI::ShaderInputNameIndex m_pointSizeIndex = "m_pointSize";
  200. };
  201. ShaderData m_perObjectShaderData[ShapeLightingStyle_Count];
  202. ShaderData& GetShaderDataForDrawStyle(int drawStyle) {return m_perObjectShaderData[drawStyle == DrawStyle_Shaded];}
  203. AZStd::vector<AZ::RHI::ConstPtr<RHI::DrawPacket>> m_drawPackets;
  204. const AZ::RPI::Scene* m_scene = nullptr;
  205. bool m_needUpdatePipelineStates = false;
  206. };
  207. } // namespace Render
  208. } // namespace AZ