SemaphoreFactory.inl.h 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. // Copyright (C) 2009-2021, Panagiotis Christopoulos Charitos and contributors.
  2. // All rights reserved.
  3. // Code licensed under the BSD License.
  4. // http://www.anki3d.org/LICENSE
  5. #include <AnKi/Gr/Vulkan/SemaphoreFactory.h>
  6. #include <AnKi/Util/Tracer.h>
  7. namespace anki {
  8. inline MicroSemaphore::MicroSemaphore(SemaphoreFactory* f, MicroFencePtr fence, Bool isTimeline)
  9. : m_factory(f)
  10. , m_fence(fence)
  11. , m_isTimeline(isTimeline)
  12. {
  13. ANKI_ASSERT(f);
  14. ANKI_ASSERT(fence.isCreated());
  15. VkSemaphoreTypeCreateInfo typeCreateInfo = {};
  16. typeCreateInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO;
  17. typeCreateInfo.semaphoreType = (m_isTimeline) ? VK_SEMAPHORE_TYPE_TIMELINE : VK_SEMAPHORE_TYPE_BINARY;
  18. typeCreateInfo.initialValue = 0;
  19. VkSemaphoreCreateInfo ci = {};
  20. ci.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
  21. ci.pNext = &typeCreateInfo;
  22. ANKI_TRACE_INC_COUNTER(VK_SEMAPHORE_CREATE, 1);
  23. ANKI_VK_CHECKF(vkCreateSemaphore(m_factory->m_dev, &ci, nullptr, &m_handle));
  24. }
  25. inline MicroSemaphore::~MicroSemaphore()
  26. {
  27. if(m_handle)
  28. {
  29. vkDestroySemaphore(m_factory->m_dev, m_handle, nullptr);
  30. }
  31. }
  32. inline GrAllocator<U8> MicroSemaphore::getAllocator() const
  33. {
  34. return m_factory->m_alloc;
  35. }
  36. inline Bool MicroSemaphore::clientWait(Second seconds)
  37. {
  38. ANKI_ASSERT(m_isTimeline);
  39. seconds = min(seconds, MAX_FENCE_OR_SEMAPHORE_WAIT_TIME);
  40. VkSemaphoreWaitInfo waitInfo = {};
  41. waitInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_WAIT_INFO;
  42. waitInfo.semaphoreCount = 1;
  43. waitInfo.pSemaphores = &m_handle;
  44. const U64 crntTimelineValue = m_timelineValue.load();
  45. waitInfo.pValues = &crntTimelineValue;
  46. const F64 nsf = 1e+9 * seconds;
  47. const U64 ns = U64(nsf);
  48. VkResult res;
  49. ANKI_VK_CHECKF(res = vkWaitSemaphores(m_factory->m_dev, &waitInfo, ns));
  50. return res != VK_TIMEOUT;
  51. }
  52. inline void MicroSemaphorePtrDeleter::operator()(MicroSemaphore* s)
  53. {
  54. ANKI_ASSERT(s);
  55. if(s->m_isTimeline)
  56. {
  57. s->m_factory->m_timelineRecycler.recycle(s);
  58. }
  59. else
  60. {
  61. s->m_factory->m_binaryRecycler.recycle(s);
  62. }
  63. }
  64. inline MicroSemaphorePtr SemaphoreFactory::newInstance(MicroFencePtr fence, Bool isTimeline)
  65. {
  66. ANKI_ASSERT(fence);
  67. MicroSemaphore* out = (isTimeline) ? m_timelineRecycler.findToReuse() : m_binaryRecycler.findToReuse();
  68. if(out == nullptr)
  69. {
  70. // Create a new one
  71. out = m_alloc.newInstance<MicroSemaphore>(this, fence, isTimeline);
  72. }
  73. else
  74. {
  75. out->m_fence = fence;
  76. ANKI_ASSERT(out->m_isTimeline == isTimeline);
  77. if(out->m_isTimeline)
  78. {
  79. ANKI_ASSERT(out->m_timelineValue.getNonAtomically() > 0 && "Recycled without being signaled?");
  80. }
  81. }
  82. ANKI_ASSERT(out->m_refcount.getNonAtomically() == 0);
  83. return MicroSemaphorePtr(out);
  84. }
  85. } // end namespace anki