VkSemaphoreFactory.cpp 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. // Copyright (C) 2009-present, 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/VkSemaphoreFactory.h>
  6. #include <AnKi/Gr/Vulkan/VkGrManager.h>
  7. #include <AnKi/Util/Tracer.h>
  8. namespace anki {
  9. MicroSemaphore::MicroSemaphore(Bool isTimeline)
  10. : m_isTimeline(isTimeline)
  11. {
  12. VkSemaphoreTypeCreateInfo typeCreateInfo = {};
  13. typeCreateInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO;
  14. typeCreateInfo.semaphoreType = (m_isTimeline) ? VK_SEMAPHORE_TYPE_TIMELINE : VK_SEMAPHORE_TYPE_BINARY;
  15. typeCreateInfo.initialValue = 0;
  16. VkSemaphoreCreateInfo ci = {};
  17. ci.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
  18. ci.pNext = &typeCreateInfo;
  19. ANKI_TRACE_INC_COUNTER(VkSemaphoreCreate, 1);
  20. ANKI_VK_CHECKF(vkCreateSemaphore(getVkDevice(), &ci, nullptr, &m_handle));
  21. }
  22. MicroSemaphore::~MicroSemaphore()
  23. {
  24. if(m_handle)
  25. {
  26. vkDestroySemaphore(getVkDevice(), m_handle, nullptr);
  27. }
  28. }
  29. void MicroSemaphore::releaseInternal()
  30. {
  31. if(m_isTimeline)
  32. {
  33. SemaphoreFactory::getSingleton().m_timelineRecycler.recycle(this);
  34. }
  35. else
  36. {
  37. SemaphoreFactory::getSingleton().m_binaryRecycler.recycle(this);
  38. }
  39. }
  40. Bool MicroSemaphore::clientWait(Second seconds)
  41. {
  42. ANKI_ASSERT(m_isTimeline);
  43. seconds = min<Second>(seconds, g_cvarGrGpuTimeout);
  44. VkSemaphoreWaitInfo waitInfo = {};
  45. waitInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_WAIT_INFO;
  46. waitInfo.semaphoreCount = 1;
  47. waitInfo.pSemaphores = &m_handle;
  48. const U64 crntTimelineValue = m_timelineValue.load();
  49. waitInfo.pValues = &crntTimelineValue;
  50. const F64 nsf = 1e+9 * seconds;
  51. const U64 ns = U64(nsf);
  52. VkResult res;
  53. ANKI_VK_CHECKF(res = vkWaitSemaphores(getVkDevice(), &waitInfo, ns));
  54. return res != VK_TIMEOUT;
  55. }
  56. MicroSemaphorePtr SemaphoreFactory::newInstance(Bool isTimeline, CString name)
  57. {
  58. MicroSemaphore* out = (isTimeline) ? m_timelineRecycler.findToReuse() : m_binaryRecycler.findToReuse();
  59. if(out == nullptr)
  60. {
  61. // Create a new one
  62. out = anki::newInstance<MicroSemaphore>(GrMemoryPool::getSingleton(), isTimeline);
  63. }
  64. else
  65. {
  66. ANKI_ASSERT(out->m_isTimeline == isTimeline);
  67. if(out->m_isTimeline)
  68. {
  69. ANKI_ASSERT(out->m_timelineValue.getNonAtomically() > 0 && "Recycled without being signaled?");
  70. }
  71. }
  72. getGrManagerImpl().trySetVulkanHandleName(name, VK_OBJECT_TYPE_SEMAPHORE, out->m_handle);
  73. ANKI_ASSERT(out->m_refcount.getNonAtomically() == 0);
  74. return MicroSemaphorePtr(out);
  75. }
  76. } // end namespace anki