InputStreamLayoutBuilder.cpp 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  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 <Atom/RHI.Reflect/InputStreamLayoutBuilder.h>
  9. namespace AZ::RHI
  10. {
  11. InputStreamLayoutBuilder::InputStreamLayoutBuilder()
  12. {
  13. Begin();
  14. }
  15. void InputStreamLayoutBuilder::Begin()
  16. {
  17. m_topology = PrimitiveTopology::TriangleList;
  18. m_bufferDescriptorBuilders.clear();
  19. }
  20. InputStreamLayout InputStreamLayoutBuilder::End()
  21. {
  22. InputStreamLayout layout;
  23. layout.SetTopology(m_topology);
  24. for (BufferDescriptorBuilder& builder : m_bufferDescriptorBuilders)
  25. {
  26. builder.m_bufferDescriptor.m_byteStride = builder.m_byteOffset;
  27. layout.AddStreamBuffer(builder.m_bufferDescriptor);
  28. for (StreamChannelDescriptor& channelDescriptor : builder.m_channelDescriptors)
  29. {
  30. layout.AddStreamChannel(channelDescriptor);
  31. }
  32. }
  33. layout.Finalize();
  34. return layout;
  35. }
  36. void InputStreamLayoutBuilder::SetTopology(PrimitiveTopology topology)
  37. {
  38. m_topology = topology;
  39. }
  40. InputStreamLayoutBuilder::BufferDescriptorBuilder* InputStreamLayoutBuilder::BufferDescriptorBuilder::Channel(const ShaderSemantic& semantic, Format format)
  41. {
  42. if (m_channelDescriptors.size() == m_channelDescriptors.capacity())
  43. {
  44. AZ_Error("InputStreamLayoutBuilder", false, "No space to add stream channel.");
  45. }
  46. else
  47. {
  48. StreamChannelDescriptor& channel = m_channelDescriptors.emplace_back();
  49. channel.m_bufferIndex = m_bufferIndex;
  50. channel.m_byteOffset = m_byteOffset;
  51. channel.m_format = format;
  52. channel.m_semantic = semantic;
  53. m_byteOffset += GetFormatSize(format);
  54. }
  55. return this;
  56. }
  57. InputStreamLayoutBuilder::BufferDescriptorBuilder* InputStreamLayoutBuilder::BufferDescriptorBuilder::Channel(AZStd::string_view semantic, Format format)
  58. {
  59. return Channel(ShaderSemantic::Parse(semantic), format);
  60. }
  61. InputStreamLayoutBuilder::BufferDescriptorBuilder* InputStreamLayoutBuilder::BufferDescriptorBuilder::Padding(uint32_t byteCount)
  62. {
  63. m_byteOffset += byteCount;
  64. return this;
  65. }
  66. InputStreamLayoutBuilder::BufferDescriptorBuilder* InputStreamLayoutBuilder::AddBuffer(StreamStepFunction stepFunction, uint32_t stepRate)
  67. {
  68. if (m_bufferDescriptorBuilders.size() == m_bufferDescriptorBuilders.capacity())
  69. {
  70. AZ_Error("InputStreamLayoutBuilder", false, "No space to add stream buffer.");
  71. // Return a dummy so that subsequent calls to register channels won't crash and don't require null check clutter.
  72. return &m_dummyBufferDescriptorBuilder;
  73. }
  74. BufferDescriptorBuilder* builder = &m_bufferDescriptorBuilders.emplace_back();
  75. builder->m_bufferIndex = static_cast<uint32_t>(m_bufferDescriptorBuilders.size() - 1);
  76. builder->m_bufferDescriptor.m_stepFunction = stepFunction;
  77. builder->m_bufferDescriptor.m_stepRate = stepRate;
  78. return builder;
  79. }
  80. }