GpuBufferHandler.cpp 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  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/Feature/Utils/GpuBufferHandler.h>
  9. #include <Atom/RHI/Buffer.h>
  10. #include <Atom/RHI/Factory.h>
  11. #include <Atom/RPI.Public/Buffer/BufferSystemInterface.h>
  12. #include <Atom/Utils/Utils.h>
  13. #include <cinttypes>
  14. namespace AZ
  15. {
  16. namespace Render
  17. {
  18. [[maybe_unused]] static const char* ClassName = "GpuBufferHandler";
  19. static const uint32_t BufferMinSize = 1 << 16; // Min 64Kb.
  20. GpuBufferHandler::GpuBufferHandler(const Descriptor& descriptor)
  21. {
  22. m_elementSize = descriptor.m_elementFormat == RHI::Format::Unknown ? descriptor.m_elementSize
  23. : RHI::GetFormatSize(descriptor.m_elementFormat);
  24. m_elementCount = 0;
  25. m_bufferIndex = descriptor.m_srgLayout->FindShaderInputBufferIndex(Name(descriptor.m_bufferSrgName));
  26. AZ_Error(ClassName, m_bufferIndex.IsValid(), "Unable to find %s in %s shader resource group.", descriptor.m_bufferSrgName.c_str(), descriptor.m_srgLayout->GetName().GetCStr());
  27. if (!descriptor.m_elementCountSrgName.empty())
  28. {
  29. m_elementCountIndex = descriptor.m_srgLayout->FindShaderInputConstantIndex(Name(descriptor.m_elementCountSrgName));
  30. AZ_Error(ClassName, m_elementCountIndex.IsValid(), "Unable to find %s in %s shader resource group.", descriptor.m_elementCountSrgName.c_str(), descriptor.m_srgLayout->GetName().GetCStr());
  31. }
  32. if (m_bufferIndex.IsValid())
  33. {
  34. uint32_t byteCount = RHI::NextPowerOfTwo(GetMax<uint32_t>(BufferMinSize, m_elementCount * m_elementSize));
  35. RPI::CommonBufferDescriptor desc;
  36. desc.m_poolType = RPI::CommonBufferPoolType::ReadOnly;
  37. desc.m_bufferName = descriptor.m_bufferName;
  38. desc.m_byteCount = byteCount;
  39. desc.m_elementSize = m_elementSize;
  40. desc.m_elementFormat = descriptor.m_elementFormat;
  41. m_buffer = RPI::BufferSystemInterface::Get()->CreateBufferFromCommonPool(desc);
  42. }
  43. }
  44. bool GpuBufferHandler::IsValid() const
  45. {
  46. // Consider this is valid if the buffer is valid.
  47. return m_buffer;
  48. }
  49. void GpuBufferHandler::Release()
  50. {
  51. m_buffer = nullptr;
  52. m_bufferIndex.Reset();
  53. m_elementCountIndex.Reset();
  54. }
  55. bool GpuBufferHandler::UpdateBuffer(uint32_t elementCount, const void* data)
  56. {
  57. if (!IsValid())
  58. {
  59. return false;
  60. }
  61. m_elementCount = elementCount;
  62. AZ::u64 currentByteCount = m_buffer->GetBufferSize();
  63. uint32_t dataSize = elementCount * m_elementSize;
  64. if (dataSize > currentByteCount)
  65. {
  66. uint32_t byteCount = RHI::NextPowerOfTwo(GetMax<uint32_t>(BufferMinSize, dataSize));
  67. m_buffer->Resize(byteCount);
  68. }
  69. if (dataSize > 0)
  70. {
  71. return m_buffer->UpdateData(data, dataSize, 0);
  72. }
  73. return true;
  74. }
  75. bool GpuBufferHandler::UpdateBuffer(const AZStd::unordered_map<int, const void*>& data, uint32_t elementCount)
  76. {
  77. if (!IsValid())
  78. {
  79. return false;
  80. }
  81. m_elementCount = elementCount;
  82. AZ::u64 currentByteCount = m_buffer->GetBufferSize();
  83. uint32_t dataSize = elementCount * m_elementSize;
  84. if (dataSize > currentByteCount)
  85. {
  86. uint32_t byteCount = RHI::NextPowerOfTwo(GetMax<uint32_t>(BufferMinSize, dataSize));
  87. m_buffer->Resize(byteCount);
  88. }
  89. if (dataSize > 0)
  90. {
  91. return m_buffer->UpdateData(data, dataSize, 0);
  92. }
  93. return true;
  94. }
  95. void GpuBufferHandler::UpdateSrg(RPI::ShaderResourceGroup* srg) const
  96. {
  97. if (m_bufferIndex.IsValid())
  98. {
  99. srg->SetBufferView(m_bufferIndex, m_buffer->GetBufferView());
  100. }
  101. if (m_elementCountIndex.IsValid())
  102. {
  103. srg->SetConstant<uint32_t>(m_elementCountIndex, m_elementCount);
  104. }
  105. }
  106. } // namespace Render
  107. } // namespace AZ