HairSharedBufferInterface.h 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  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 <AzCore/std/smart_ptr/intrusive_ptr.h>
  10. #include <AzCore/std/smart_ptr/intrusive_base.h>
  11. #include <AzCore/Interface/Interface.h>
  12. #include <AzCore/Asset/AssetCommon.h>
  13. #include <AzCore/EBus/Event.h>
  14. #include <AtomCore/Instance/Instance.h>
  15. #include <Atom/RHI/Allocator.h>
  16. namespace AZ
  17. {
  18. namespace RHI
  19. {
  20. class Buffer;
  21. class BufferView;
  22. }
  23. namespace RPI
  24. {
  25. class BufferAsset;
  26. class Buffer;
  27. }
  28. namespace Render
  29. {
  30. class HairSharedBufferAllocation;
  31. //! A class for allocating memory for skinning buffers
  32. class HairSharedBufferInterface
  33. {
  34. public:
  35. AZ_RTTI(AZ::Render::HairSharedBufferInterface, "{3CCB13CB-16FF-43F5-98DC-F36B2A9F8E5E}");
  36. HairSharedBufferInterface()
  37. {
  38. Interface<HairSharedBufferInterface>::Register(this);
  39. }
  40. virtual ~HairSharedBufferInterface()
  41. {
  42. Interface<HairSharedBufferInterface>::Unregister(this);
  43. }
  44. static HairSharedBufferInterface* Get()
  45. {
  46. return Interface<HairSharedBufferInterface>::Get();
  47. }
  48. //! Returns the shared buffer asset used for all Hair objects and passes
  49. virtual Data::Asset<RPI::BufferAsset> GetBufferAsset() const = 0;
  50. //! Returns the buffer that is used for all skinned mesh outputs
  51. virtual Data::Instance<RPI::Buffer> GetBuffer() = 0;
  52. //! If the allocation succeeds, returns a ref-counted pointer to a VirtualAddress which will be automatically freed if the ref-count drops to zero
  53. //! If the allocation fails, returns nullptr
  54. virtual AZStd::intrusive_ptr<HairSharedBufferAllocation> Allocate(size_t byteCount) = 0;
  55. //! Mark the memory as available and queue garbage collection to recycle it later (see RHI::Allocator::DeAllocate)
  56. //! After garbage collection is done signal handlers that memory has been freed
  57. virtual void DeAllocate(RHI::VirtualAddress allocation) = 0;
  58. //! Same as DeAllocate, but the signal after garbage collection is ignored
  59. //! If multiple allocations succeeded before one failed, use this to release the successful allocations
  60. //! without triggering new events indicating that new memory has been freed
  61. virtual void DeAllocateNoSignal(RHI::VirtualAddress allocation) = 0;
  62. //! Update buffer's content with sourceData at an offset of bufferByteOffset
  63. virtual bool UpdateData(const void* sourceData, uint64_t sourceDataSizeInBytes, uint64_t bufferByteOffset = 0) = 0;
  64. // Note that you have to delete these for safety reasons, you will trip a static_assert if you do not
  65. AZ_DISABLE_COPY_MOVE(HairSharedBufferInterface);
  66. };
  67. class HairSharedBufferNotifications
  68. : public AZ::EBusTraits
  69. {
  70. public:
  71. static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Multiple;
  72. //! This event will fire if memory is freed up, so a listener can wait for there to be free space
  73. //! and attempt to allocate memory again if it failed initially
  74. virtual void OnSharedBufferMemoryAvailable() = 0;
  75. };
  76. using SharedBufferNotificationBus = AZ::EBus<HairSharedBufferNotifications>;
  77. //! An intrusive_ptr wrapper around an RHI::Allocation that will automatically free the memory
  78. //! from the SharedBuffer when the ref count drops to zero
  79. class HairSharedBufferAllocation
  80. : public AZStd::intrusive_base
  81. {
  82. public:
  83. AZ_CLASS_ALLOCATOR(HairSharedBufferAllocation, AZ::SystemAllocator);
  84. explicit HairSharedBufferAllocation(RHI::VirtualAddress virtualAddress)
  85. : m_virtualAddress(virtualAddress)
  86. {}
  87. ~HairSharedBufferAllocation()
  88. {
  89. if (!m_suppressSignalOnDeallocate)
  90. {
  91. HairSharedBufferInterface::Get()->DeAllocate(m_virtualAddress);
  92. }
  93. else
  94. {
  95. HairSharedBufferInterface::Get()->DeAllocateNoSignal(m_virtualAddress);
  96. }
  97. }
  98. //! If this function is called, the SharedBuffer will not signal when the memory is freed
  99. void SuppressSignalOnDeallocate() { m_suppressSignalOnDeallocate = true; }
  100. RHI::VirtualAddress GetVirtualAddress() const { return m_virtualAddress; }
  101. private:
  102. RHI::VirtualAddress m_virtualAddress;
  103. bool m_suppressSignalOnDeallocate = false;
  104. };
  105. } // namespace Render
  106. } // namespace AZ