// Copyright (C) 2009-present, Panagiotis Christopoulos Charitos and contributors. // All rights reserved. // Code licensed under the BSD License. // http://www.anki3d.org/LICENSE #include #include #include namespace anki { MicroSemaphore::MicroSemaphore(Bool isTimeline) : m_isTimeline(isTimeline) { VkSemaphoreTypeCreateInfo typeCreateInfo = {}; typeCreateInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO; typeCreateInfo.semaphoreType = (m_isTimeline) ? VK_SEMAPHORE_TYPE_TIMELINE : VK_SEMAPHORE_TYPE_BINARY; typeCreateInfo.initialValue = 0; VkSemaphoreCreateInfo ci = {}; ci.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO; ci.pNext = &typeCreateInfo; ANKI_TRACE_INC_COUNTER(VkSemaphoreCreate, 1); ANKI_VK_CHECKF(vkCreateSemaphore(getVkDevice(), &ci, nullptr, &m_handle)); } MicroSemaphore::~MicroSemaphore() { if(m_handle) { vkDestroySemaphore(getVkDevice(), m_handle, nullptr); } } void MicroSemaphore::releaseInternal() { if(m_isTimeline) { SemaphoreFactory::getSingleton().m_timelineRecycler.recycle(this); } else { SemaphoreFactory::getSingleton().m_binaryRecycler.recycle(this); } } Bool MicroSemaphore::clientWait(Second seconds) { ANKI_ASSERT(m_isTimeline); seconds = min(seconds, g_cvarGrGpuTimeout); VkSemaphoreWaitInfo waitInfo = {}; waitInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_WAIT_INFO; waitInfo.semaphoreCount = 1; waitInfo.pSemaphores = &m_handle; const U64 crntTimelineValue = m_timelineValue.load(); waitInfo.pValues = &crntTimelineValue; const F64 nsf = 1e+9 * seconds; const U64 ns = U64(nsf); VkResult res; ANKI_VK_CHECKF(res = vkWaitSemaphores(getVkDevice(), &waitInfo, ns)); return res != VK_TIMEOUT; } MicroSemaphorePtr SemaphoreFactory::newInstance(Bool isTimeline, CString name) { MicroSemaphore* out = (isTimeline) ? m_timelineRecycler.findToReuse() : m_binaryRecycler.findToReuse(); if(out == nullptr) { // Create a new one out = anki::newInstance(GrMemoryPool::getSingleton(), isTimeline); } else { ANKI_ASSERT(out->m_isTimeline == isTimeline); if(out->m_isTimeline) { ANKI_ASSERT(out->m_timelineValue.getNonAtomically() > 0 && "Recycled without being signaled?"); } } getGrManagerImpl().trySetVulkanHandleName(name, VK_OBJECT_TYPE_SEMAPHORE, out->m_handle); ANKI_ASSERT(out->m_refcount.getNonAtomically() == 0); return MicroSemaphorePtr(out); } } // end namespace anki