Ejemplo n.º 1
0
	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;
	}
Ejemplo n.º 2
0
//==============================================================================
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);
}
Ejemplo n.º 3
0
	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;
	}
Ejemplo n.º 4
0
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;
}
Ejemplo n.º 5
0
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);
	}
}
Ejemplo n.º 6
0
//==============================================================================
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);
}
Ejemplo n.º 7
0
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;
}
Ejemplo n.º 8
0
//==============================================================================
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();
}
Ejemplo n.º 9
0
//==============================================================================
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);
}
Ejemplo n.º 10
0
	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;
	}