//============================================================================== OcclusionQueryResult OcclusionQueryImpl::getResult() const { ANKI_ASSERT(m_handle); U64 out = 0; VkResult res; ANKI_VK_CHECKF( res = vkGetQueryPoolResults(getDevice(), m_handle, 0, 1, sizeof(out), &out, sizeof(out), VK_QUERY_RESULT_64_BIT | VK_QUERY_RESULT_WITH_AVAILABILITY_BIT | VK_QUERY_RESULT_PARTIAL_BIT)); OcclusionQueryResult qout = OcclusionQueryResult::NOT_AVAILABLE; if(res == VK_SUCCESS) { qout = (out) ? OcclusionQueryResult::VISIBLE : OcclusionQueryResult::NOT_VISIBLE; } else if(res == VK_NOT_READY) { qout = OcclusionQueryResult::NOT_AVAILABLE; } else { ANKI_ASSERT(0); } return qout; }
Error allocate(U classIdx, ClassGpuAllocatorMemory*& cmem) { Memory* mem; LockGuard<Mutex> lock(m_mtx); if(!m_vacantMemory[classIdx].isEmpty()) { // Recycle mem = &m_vacantMemory[classIdx].getFront(); m_vacantMemory[classIdx].popFront(); } else { // Create new mem = m_alloc.newInstance<Memory>(); VkMemoryAllocateInfo ci = {}; ci.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; ci.allocationSize = CLASSES[classIdx].m_chunkSize; ci.memoryTypeIndex = m_memTypeIdx; ANKI_VK_CHECKF(vkAllocateMemory(m_dev, &ci, nullptr, &mem->m_handle)); mem->m_classIdx = classIdx; } ANKI_ASSERT(mem); ANKI_ASSERT(mem->m_handle); ANKI_ASSERT(mem->m_classIdx == classIdx); ANKI_ASSERT(mem->m_mappedAddress == nullptr); cmem = mem; return ErrorCode::NONE; }
VkCommandBuffer CommandBufferFactory::newCommandBuffer(CommandBufferFlag cmdbFlags) { ANKI_ASSERT(isCreated()); Bool secondLevel = !!(cmdbFlags & CommandBufferFlag::SECOND_LEVEL); Bool smallBatch = !!(cmdbFlags & CommandBufferFlag::SMALL_BATCH); CmdbType& type = m_types[secondLevel][smallBatch]; LockGuard<Mutex> lock(type.m_mtx); VkCommandBuffer out = VK_NULL_HANDLE; if(type.m_count > 0) { // Recycle --type.m_count; out = type.m_cmdbs[type.m_count]; } else { // Create a new one VkCommandBufferAllocateInfo ci = {}; ci.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; ci.commandPool = m_pool; ci.level = (secondLevel) ? VK_COMMAND_BUFFER_LEVEL_SECONDARY : VK_COMMAND_BUFFER_LEVEL_PRIMARY; ci.commandBufferCount = 1; ANKI_TRACE_INC_COUNTER(VK_CMD_BUFFER_CREATE, 1); ANKI_VK_CHECKF(vkAllocateCommandBuffers(m_dev, &ci, &out)); } ANKI_ASSERT(out); return out; }
void GrManagerImpl::endFrame() { LockGuard<Mutex> lock(m_globalMtx); PerFrame& frame = m_perFrame[m_frame % MAX_FRAMES_IN_FLIGHT]; // Wait for the fence of N-2 frame U waitFrameIdx = (m_frame + 1) % MAX_FRAMES_IN_FLIGHT; PerFrame& waitFrame = m_perFrame[waitFrameIdx]; if(waitFrame.m_presentFence) { waitFrame.m_presentFence->wait(); } resetFrame(waitFrame); if(!frame.m_renderSemaphore) { ANKI_LOGW("Nobody draw to the default framebuffer"); } // Present VkResult res; VkPresentInfoKHR present = {}; present.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR; present.waitSemaphoreCount = (frame.m_renderSemaphore) ? 1 : 0; present.pWaitSemaphores = (frame.m_renderSemaphore) ? &frame.m_renderSemaphore->getHandle() : nullptr; present.swapchainCount = 1; present.pSwapchains = &m_swapchain; present.pImageIndices = &m_crntBackbufferIdx; present.pResults = &res; ANKI_VK_CHECKF(vkQueuePresentKHR(m_queue, &present)); ANKI_VK_CHECKF(res); m_transientMem.endFrame(); // Finalize ++m_frame; }
void GrManagerImpl::flushCommandBuffer(CommandBufferPtr cmdb, Bool wait) { CommandBufferImpl& impl = *cmdb->m_impl; VkCommandBuffer handle = impl.getHandle(); VkSubmitInfo submit = {}; submit.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; FencePtr fence = newFence(); LockGuard<Mutex> lock(m_globalMtx); PerFrame& frame = m_perFrame[m_frame % MAX_FRAMES_IN_FLIGHT]; // Do some special stuff for the last command buffer VkPipelineStageFlags waitFlags; if(impl.renderedToDefaultFramebuffer()) { submit.pWaitSemaphores = &frame.m_acquireSemaphore->getHandle(); waitFlags = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; submit.pWaitDstStageMask = &waitFlags; submit.waitSemaphoreCount = 1; // Create the semaphore to signal ANKI_ASSERT(!frame.m_renderSemaphore && "Only one begin/end render pass is allowed with the default fb"); frame.m_renderSemaphore = m_semaphores.newInstance(fence); submit.signalSemaphoreCount = 1; submit.pSignalSemaphores = &frame.m_renderSemaphore->getHandle(); frame.m_presentFence = fence; } submit.commandBufferCount = 1; submit.pCommandBuffers = &handle; frame.m_cmdbsSubmitted.pushBack(getAllocator(), cmdb); ANKI_TRACE_START_EVENT(VK_QUEUE_SUBMIT); ANKI_VK_CHECKF(vkQueueSubmit(m_queue, 1, &submit, fence->getHandle())); ANKI_TRACE_STOP_EVENT(VK_QUEUE_SUBMIT); if(wait) { vkQueueWaitIdle(m_queue); } }
void GrManagerImpl::beginFrame() { PerFrame& frame = m_perFrame[m_frame % MAX_FRAMES_IN_FLIGHT]; // Create sync objects FencePtr fence = newFence(); frame.m_acquireSemaphore = m_semaphores.newInstance(fence); // Get new image uint32_t imageIdx; ANKI_TRACE_START_EVENT(VK_ACQUIRE_IMAGE); ANKI_VK_CHECKF(vkAcquireNextImageKHR( m_device, m_swapchain, UINT64_MAX, frame.m_acquireSemaphore->getHandle(), fence->getHandle(), &imageIdx)); ANKI_TRACE_STOP_EVENT(VK_ACQUIRE_IMAGE); ANKI_ASSERT(imageIdx < MAX_FRAMES_IN_FLIGHT); m_crntBackbufferIdx = imageIdx; }
// Mapp memory void* mapMemory(ClassGpuAllocatorMemory* cmem) { ANKI_ASSERT(cmem); Memory* mem = static_cast<Memory*>(cmem); void* out; LockGuard<SpinLock> lock(mem->m_mtx); if(mem->m_mappedAddress) { out = mem->m_mappedAddress; } else { ANKI_VK_CHECKF(vkMapMemory(m_dev, mem->m_handle, 0, CLASSES[mem->m_classIdx].m_chunkSize, 0, &out)); mem->m_mappedAddress = out; } ANKI_ASSERT(out); return out; }
//============================================================================== void CommandBufferImpl::endRecording() { commandCommon(); ANKI_ASSERT(!m_finalized); ANKI_ASSERT(!m_empty); if((m_flags & CommandBufferFlag::FRAME_LAST) == CommandBufferFlag::FRAME_LAST) { // Default FB barrier/transition setImageBarrier(VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, VK_ACCESS_MEMORY_READ_BIT, VK_IMAGE_LAYOUT_PRESENT_SRC_KHR, getGrManagerImpl().getDefaultSurfaceImage( getGrManagerImpl().getFrame() % MAX_FRAMES_IN_FLIGHT), VkImageSubresourceRange{VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1}); } ANKI_VK_CHECKF(vkEndCommandBuffer(m_handle)); m_finalized = true; }