Error operator()(GlState& state) { ANKI_TRACE_START_EVENT(GL_BIND_RESOURCES); m_rc->m_impl->bind(m_slot, m_info, state); ANKI_TRACE_STOP_EVENT(GL_BIND_RESOURCES); return ErrorCode::NONE; }
//============================================================================== void CommandBufferImpl::destroy() { ANKI_TRACE_START_EVENT(GL_CMD_BUFFER_DESTROY); #if ANKI_DEBUG if(!m_executed && m_firstCommand) { ANKI_LOGW("Chain contains commands but never executed. " "This should only happen on exceptions"); } #endif GlCommand* command = m_firstCommand; while(command != nullptr) { GlCommand* next = command->m_nextCommand; // Get next before deleting m_alloc.deleteInstance(command); command = next; } ANKI_ASSERT(m_alloc.getMemoryPool().getUsersCount() == 1 && "Someone is holding a reference to the command buffer's allocator"); m_alloc = CommandBufferAllocator<U8>(); ANKI_TRACE_STOP_EVENT(GL_CMD_BUFFER_DESTROY); }
Error operator()(GlState&) { ANKI_TRACE_START_EVENT(GL_2ND_LEVEL_CMD_BUFFER); Error err = m_cmdb->getImplementation().executeAllCommands(); ANKI_TRACE_STOP_EVENT(GL_2ND_LEVEL_CMD_BUFFER); return err; }
Error MainRenderer::render(SceneGraph& scene) { ANKI_TRACE_START_EVENT(RENDER); // First thing, reset the temp mem pool m_frameAlloc.getMemoryPool().reset(); GrManager& gl = m_r->getGrManager(); CommandBufferInitInfo cinf; cinf.m_hints = m_cbInitHints; CommandBufferPtr cmdb = gl.newInstance<CommandBuffer>(cinf); // Set some of the dynamic state cmdb->setPolygonOffset(0.0, 0.0); // Run renderer RenderingContext ctx(m_frameAlloc); if(m_rDrawToDefaultFb) { ctx.m_outFb = m_defaultFb; ctx.m_outFbWidth = m_width; ctx.m_outFbHeight = m_height; } ctx.m_commandBuffer = cmdb; ctx.m_frustumComponent = &scene.getActiveCamera().getComponent<FrustumComponent>(); ANKI_CHECK(m_r->render(ctx)); // Blit renderer's result to default FB if needed if(!m_rDrawToDefaultFb) { cmdb->beginRenderPass(m_defaultFb); cmdb->setViewport(0, 0, m_width, m_height); cmdb->bindPipeline(m_blitPpline); cmdb->bindResourceGroup(m_rcGroup, 0, nullptr); m_r->drawQuad(cmdb); cmdb->endRenderPass(); } // Flush the command buffer cmdb->flush(); // Set the hints m_cbInitHints = cmdb->computeInitHints(); ANKI_TRACE_STOP_EVENT(RENDER); return ErrorCode::NONE; }
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 RenderingThread::swapBuffersInternal() { ANKI_TRACE_START_EVENT(SWAP_BUFFERS); // Do the swap buffers m_manager->getImplementation().swapBuffers(); // Notify the main thread that we are done { LockGuard<Mutex> lock(m_frameMtx); m_frameWait = false; m_frameCondVar.notifyOne(); } ANKI_TRACE_STOP_EVENT(SWAP_BUFFERS); }
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; }
//============================================================================== void RenderingThread::threadLoop() { prepare(); while(1) { CommandBufferPtr cmd; // Wait for something { LockGuard<Mutex> lock(m_mtx); while(m_tail == m_head) { m_condVar.wait(m_mtx); } // Check signals if(m_renderingThreadSignal == 1) { // Requested to stop break; } U64 idx = m_head % m_queue.getSize(); // Pop a command cmd = m_queue[idx]; m_queue[idx] = CommandBufferPtr(); // Insert empty cmd buffer ++m_head; } ANKI_TRACE_START_EVENT(GL_THREAD); Error err = cmd->getImplementation().executeAllCommands(); ANKI_TRACE_STOP_EVENT(GL_THREAD); if(err) { ANKI_LOGE("Error in rendering thread. Aborting"); abort(); } } finish(); }
//============================================================================== void RenderingThread::swapBuffers() { ANKI_TRACE_START_EVENT(SWAP_BUFFERS); // Wait for the rendering thread to finish swap buffers... { LockGuard<Mutex> lock(m_frameMtx); while(m_frameWait) { m_frameCondVar.wait(m_frameMtx); } m_frameWait = true; } m_manager->getImplementation().getDynamicMemoryManager().endFrame(); // ...and then flush a new swap buffers flushCommandBuffer(m_swapBuffersCommands); ANKI_TRACE_STOP_EVENT(SWAP_BUFFERS); }
Error operator()(GlState& state) { if(state.m_lastPplineBoundUuid != m_ppline->getUuid()) { ANKI_TRACE_START_EVENT(GL_BIND_PPLINE); PipelineImpl& impl = m_ppline->getImplementation(); impl.bind(state); state.m_lastPplineBoundUuid = m_ppline->getUuid(); ANKI_TRACE_INC_COUNTER(GR_PIPELINE_BINDS_HAPPENED, 1); ANKI_TRACE_STOP_EVENT(GL_BIND_PPLINE); } else { ANKI_TRACE_INC_COUNTER(GR_PIPELINE_BINDS_SKIPPED, 1); } return ErrorCode::NONE; }