FixedShapeProcessor.h 11 KB

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