Ejemplo n.º 1
0
//==============================================================================
void TexturePtr::create(
	CommandBufferPtr& commands, const Initializer& initS)
{
	ANKI_ASSERT(!isCreated());
	Initializer init(initS);

	// Copy data to temp buffers
	if(init.m_copyDataBeforeReturn)
	{
		for(U layer = 0; layer < MAX_TEXTURE_LAYERS; ++layer)
		{
			for(U level = 0; level < MAX_MIPMAPS; ++level)
			{
				SurfaceData& surf = init.m_data[level][layer];
				if(surf.m_ptr)
				{
					void* newData = commands.get().getInternalAllocator().
						allocate(surf.m_size);

					memcpy(newData, surf.m_ptr, surf.m_size);
					surf.m_ptr = newData;
				}
			}
		}
	}

	Base::create(commands.get().getManager());
	get().setStateAtomically(GlObject::State::TO_BE_CREATED);

	// Fire the command
	commands.get().pushBackNewCommand<CreateTextureCommand>(
		*this, init, init.m_copyDataBeforeReturn);
}
Ejemplo n.º 2
0
void Sampler::init(const SamplerInitInfo& init)
{
	m_impl.reset(getAllocator().newInstance<SamplerImpl>(&getManager()));

	CommandBufferPtr cmdb = getManager().newInstance<CommandBuffer>(CommandBufferInitInfo());

	cmdb->m_impl->pushBackNewCommand<CreateSamplerCommand>(this, init);
	cmdb->flush();
}
Ejemplo n.º 3
0
void Tiler::run(CommandBufferPtr& cmd)
{
	// Issue the min/max job
	U pboIdx = m_r->getFrameCount() % m_outBuffers.getSize();

	cmd->bindPipeline(m_ppline);
	cmd->bindResourceGroup(m_rcGroups[pboIdx], 0, nullptr);

	cmd->dispatchCompute(m_r->getTileCountXY().x(), m_r->getTileCountXY().y(), 1);
}
Ejemplo n.º 4
0
void Texture::init(const TextureInitInfo& init)
{
	m_impl.reset(getAllocator().newInstance<TextureImpl>(&getManager()));

	CommandBufferPtr cmdb =
		getManager().newInstance<CommandBuffer>(CommandBufferInitInfo());

	cmdb->getImplementation().pushBackNewCommand<CreateTextureCommand>(
		this, init);
	cmdb->flush();
}
Ejemplo n.º 5
0
void OcclusionQuery::init(OcclusionQueryResultBit condRenderingBit)
{
	m_impl.reset(getAllocator().newInstance<OcclusionQueryImpl>(&getManager()));

	CommandBufferPtr cmdb =
		getManager().newInstance<CommandBuffer>(CommandBufferInitInfo());

	cmdb->getImplementation().pushBackNewCommand<CreateOqCommand>(
		this, condRenderingBit);
	cmdb->flush();
}
Ejemplo n.º 6
0
//==============================================================================
void FramebufferPtr::create(GrManager* manager, Initializer& init)
{
	CommandBufferPtr cmdb;
	cmdb.create(manager);

	Base::create(cmdb.get().getManager());

	get().setStateAtomically(GlObject::State::TO_BE_CREATED);

	cmdb.get().pushBackNewCommand<CreateFramebufferCommand>(*this, init);
	cmdb.flush();
}
Ejemplo n.º 7
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.º 8
0
//==============================================================================
void RenderingThread::flushCommandBuffer(CommandBufferPtr cmdb)
{
	cmdb->getImplementation().makeImmutable();

	{
		LockGuard<Mutex> lock(m_mtx);

		// Set commands
		U64 diff = m_tail - m_head;

		if(diff < m_queue.getSize())
		{
			U64 idx = m_tail % m_queue.getSize();

			m_queue[idx] = cmdb;
			++m_tail;
		}
		else
		{
			ANKI_LOGW("Rendering queue too small");
		}

		m_condVar.notifyOne(); // Wake the thread
	}
}
Ejemplo n.º 9
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.º 10
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.º 11
0
//==============================================================================
void FramebufferPtr::blit(CommandBufferPtr& cmdb,
	const FramebufferPtr& b,
	const Array<U32, 4>& sourceRect,
	const Array<U32, 4>& destRect,
	GLbitfield attachmentMask,
	Bool linear)
{
	cmdb.get().pushBackNewCommand<BlitFramebufferCommand>(
		*this, b, sourceRect, destRect, attachmentMask, linear);
}
Ejemplo n.º 12
0
//==============================================================================
Error Fs::buildCommandBuffers(
	RenderingContext& ctx, U threadId, U threadCount) const
{
	// Get some stuff
	VisibilityTestResults& vis =
		ctx.m_frustumComponent->getVisibilityTestResults();

	U problemSize = vis.getCount(VisibilityGroupType::RENDERABLES_FS);
	PtrSize start, end;
	ThreadPoolTask::choseStartEnd(
		threadId, threadCount, problemSize, start, end);

	if(start == end)
	{
		// Early exit
		return ErrorCode::NONE;
	}

	// Create the command buffer and set some state
	CommandBufferInitInfo cinf;
	cinf.m_secondLevel = true;
	cinf.m_framebuffer = m_fb;
	CommandBufferPtr cmdb =
		m_r->getGrManager().newInstance<CommandBuffer>(cinf);
	ctx.m_fs.m_commandBuffers[threadId] = cmdb;

	cmdb->setViewport(0, 0, m_width, m_height);
	cmdb->setPolygonOffset(0.0, 0.0);
	cmdb->bindResourceGroup(m_globalResources, 1, &ctx.m_is.m_dynBufferInfo);

	// Start drawing
	Error err = m_r->getSceneDrawer().drawRange(Pass::MS_FS,
		*ctx.m_frustumComponent,
		cmdb,
		vis.getBegin(VisibilityGroupType::RENDERABLES_FS) + start,
		vis.getBegin(VisibilityGroupType::RENDERABLES_FS) + end);

	return err;
}
Ejemplo n.º 13
0
		Error operator()(CommandBufferImpl* commands)
		{
			GlState& state = commands->getManager().getImplementation().
				getRenderingThread().getState();

			if(state.m_blendSfunc != m_sfactor
				|| state.m_blendDfunc != m_dfactor)
			{
				glBlendFunc(m_sfactor, m_dfactor);

				state.m_blendSfunc = m_sfactor;
				state.m_blendDfunc = m_dfactor;
			}

			return ErrorCode::NONE;
		}
Ejemplo n.º 14
0
		Error operator()(CommandBufferImpl* commands)
		{
			GlState& state = commands->getManager().getImplementation().
				getRenderingThread().getState();

			if(state.m_viewport[0] != m_value[0]
				|| state.m_viewport[1] != m_value[1]
				|| state.m_viewport[2] != m_value[2]
				|| state.m_viewport[3] != m_value[3])
			{
				glViewport(m_value[0], m_value[1], m_value[2], m_value[3]);

				state.m_viewport = m_value;
			}

			return ErrorCode::NONE;
		}
Ejemplo n.º 15
0
//==============================================================================
void CommandBufferPtr::pushBackOtherCommandBuffer(
	CommandBufferPtr& commands)
{
	class Command: public GlCommand
	{
	public:
		CommandBufferPtr m_commands;

		Command(CommandBufferPtr& commands)
		:	m_commands(commands)
		{}

		Error operator()(CommandBufferImpl*)
		{
			return m_commands.get().executeAllCommands();
		}
	};

	commands.get().makeImmutable();
	get().pushBackNewCommand<Command>(commands);
}
Ejemplo n.º 16
0
ANKI_TEST(Gr, SimpleDrawcall)
{
	COMMON_BEGIN()

	PipelinePtr ppline = createSimplePpline(VERT_SRC, FRAG_SRC, *gr);
	FramebufferPtr fb = createDefaultFb(*gr);

	U iterations = 100;
	while(iterations--)
	{
		HighRezTimer timer;
		timer.start();

		gr->beginFrame();

		CommandBufferInitInfo cinit;
		CommandBufferPtr cmdb = gr->newInstance<CommandBuffer>(cinit);

		cmdb->setViewport(0, 0, WIDTH, HEIGHT);
		cmdb->setPolygonOffset(0.0, 0.0);
		cmdb->bindPipeline(ppline);
		cmdb->beginRenderPass(fb);
		cmdb->drawArrays(3);
		cmdb->endRenderPass();
		cmdb->flush();

		gr->swapBuffers();

		timer.stop();
		const F32 TICK = 1.0 / 30.0;
		if(timer.getElapsedTime() < TICK)
		{
			HighRezTimer::sleep(TICK - timer.getElapsedTime());
		}
	}

	COMMON_END()
}
Ejemplo n.º 17
0
//==============================================================================
void TexturePtr::generateMipmaps(CommandBufferPtr& commands)
{
	ANKI_ASSERT(isCreated());
	commands.get().pushBackNewCommand<GenMipmapsCommand>(*this);
}
Ejemplo n.º 18
0
//==============================================================================
void TexturePtr::bind(CommandBufferPtr& commands, U32 unit)
{
	ANKI_ASSERT(isCreated());
	commands.get().pushBackNewCommand<BindTextureCommand>(*this, unit);
}
Ejemplo n.º 19
0
ANKI_TEST(Gr, DrawWithUniforms)
{
	COMMON_BEGIN()

	// A non-uploaded buffer
	BufferPtr b = gr->newInstance<Buffer>(sizeof(Vec4) * 3, BufferUsageBit::UNIFORM_ALL, BufferMapAccessBit::WRITE);

	Vec4* ptr = static_cast<Vec4*>(b->map(0, sizeof(Vec4) * 3, BufferMapAccessBit::WRITE));
	ANKI_TEST_EXPECT_NEQ(ptr, nullptr);
	ptr[0] = Vec4(1.0, 0.0, 0.0, 0.0);
	ptr[1] = Vec4(0.0, 1.0, 0.0, 0.0);
	ptr[2] = Vec4(0.0, 0.0, 1.0, 0.0);
	b->unmap();

	// Resource group
	ResourceGroupInitInfo rcinit;
	rcinit.m_uniformBuffers[0].m_buffer = b;
	rcinit.m_uniformBuffers[0].m_usage = BufferUsageBit::UNIFORM_ALL_GRAPHICS;
	rcinit.m_uniformBuffers[1].m_uploadedMemory = true;
	rcinit.m_uniformBuffers[1].m_usage = BufferUsageBit::UNIFORM_ALL_GRAPHICS;
	ResourceGroupPtr rc = gr->newInstance<ResourceGroup>(rcinit);

	// Ppline
	PipelinePtr ppline = createSimplePpline(VERT_UBO_SRC, FRAG_UBO_SRC, *gr);

	// FB
	FramebufferPtr fb = createDefaultFb(*gr);

	const U ITERATION_COUNT = 100;
	U iterations = ITERATION_COUNT;
	while(iterations--)
	{
		HighRezTimer timer;
		timer.start();
		gr->beginFrame();

		// Uploaded buffer
		TransientMemoryInfo transientInfo;
		Vec4* rotMat = static_cast<Vec4*>(gr->allocateFrameTransientMemory(
			sizeof(Vec4), BufferUsageBit::UNIFORM_ALL, transientInfo.m_uniformBuffers[1]));
		F32 angle = toRad(360.0f / ITERATION_COUNT * iterations);
		(*rotMat)[0] = cos(angle);
		(*rotMat)[1] = -sin(angle);
		(*rotMat)[2] = sin(angle);
		(*rotMat)[3] = cos(angle);

		CommandBufferInitInfo cinit;
		CommandBufferPtr cmdb = gr->newInstance<CommandBuffer>(cinit);

		cmdb->setViewport(0, 0, WIDTH, HEIGHT);
		cmdb->setPolygonOffset(0.0, 0.0);
		cmdb->bindPipeline(ppline);
		cmdb->beginRenderPass(fb);
		cmdb->bindResourceGroup(rc, 0, &transientInfo);
		cmdb->drawArrays(3);
		cmdb->endRenderPass();
		cmdb->flush();

		gr->swapBuffers();

		timer.stop();
		const F32 TICK = 1.0 / 30.0;
		if(timer.getElapsedTime() < TICK)
		{
			HighRezTimer::sleep(TICK - timer.getElapsedTime());
		}
	}

	COMMON_END()
}
Ejemplo n.º 20
0
//==============================================================================
Error TexUploadTask::operator()(AsyncLoaderTaskContext& ctx)
{
	CommandBufferPtr cmdb;

	// Upload the data
	for(U depth = m_ctx.m_depth; depth < m_depth; ++depth)
	{
		for(U face = m_ctx.m_face; face < m_faces; ++face)
		{
			for(U mip = m_ctx.m_mip; mip < m_loader.getMipLevelsCount(); ++mip)
			{
				U surfIdx = max(depth, face);
				const auto& surf = m_loader.getSurface(mip, surfIdx);

				DynamicBufferToken token;
				void* data = m_gr->allocateFrameHostVisibleMemory(
					surf.m_data.getSize(), BufferUsage::TRANSFER, token);

				if(data)
				{
					// There is enough transfer memory

					memcpy(data, &surf.m_data[0], surf.m_data.getSize());

					if(!cmdb)
					{
						cmdb = m_gr->newInstance<CommandBuffer>(
							CommandBufferInitInfo());
					}

					cmdb->textureUpload(
						m_tex, TextureSurfaceInfo(mip, depth, face), token);
				}
				else
				{
					// Not enough transfer memory. Move the work to the future

					if(cmdb)
					{
						cmdb->flush();
					}

					m_ctx.m_depth = depth;
					m_ctx.m_mip = mip;
					m_ctx.m_face = face;

					ctx.m_pause = true;
					ctx.m_resubmitTask = true;

					return ErrorCode::NONE;
				}
			}
		}
	}

	// Finaly enque the command buffer
	if(cmdb)
	{
		cmdb->flush();
	}

	return ErrorCode::NONE;
}
Ejemplo n.º 21
0
//==============================================================================
Error TexUploadTask::operator()(AsyncLoaderTaskContext& ctx)
{
	CommandBufferPtr cmdb;

	// Upload the data
	for(U layer = m_ctx.m_layer; layer < m_layers; ++layer)
	{
		for(U depth = m_ctx.m_depth; depth < m_depth; ++depth)
		{
			for(U face = m_ctx.m_face; face < m_faces; ++face)
			{
				for(U mip = m_ctx.m_mip; mip < m_loader.getMipLevelsCount();
					++mip)
				{
					const auto& surf =
						m_loader.getSurface(mip, depth, face, layer);

					TransientMemoryToken token;
					Error err = ErrorCode::NONE;
					void* data = m_gr->allocateFrameTransientMemory(
						surf.m_data.getSize(),
						BufferUsageBit::TRANSFER_SOURCE,
						token,
						&err);

					if(!err)
					{
						// There is enough transfer memory

						memcpy(data, &surf.m_data[0], surf.m_data.getSize());

						if(!cmdb)
						{
							cmdb = m_gr->newInstance<CommandBuffer>(
								CommandBufferInitInfo());
						}

						cmdb->uploadTextureSurface(m_tex,
							TextureSurfaceInfo(mip, depth, face, layer),
							token);
					}
					else
					{
						// Not enough transfer memory. Move the work to the
						// future

						if(cmdb)
						{
							cmdb->flush();
						}

						m_ctx.m_depth = depth;
						m_ctx.m_mip = mip;
						m_ctx.m_face = face;
						m_ctx.m_layer = layer;

						ctx.m_pause = true;
						ctx.m_resubmitTask = true;

						return ErrorCode::NONE;
					}
				}
			}
		}
	}

	// Finaly enque the command buffer
	if(cmdb)
	{
		cmdb->flush();
	}

	return ErrorCode::NONE;
}
Ejemplo n.º 22
0
ANKI_TEST(Ui, Ui)
{
	Config cfg;
	initConfig(cfg);
	cfg.set("window.vsync", 1);
	cfg.set("window.debugContext", 0);
	cfg.set("width", 1024);
	cfg.set("height", 760);
	cfg.set("rsrc.dataPaths", "engine_data");

	NativeWindow* win = createWindow(cfg);
	Input* in = new Input();
	GrManager* gr = createGrManager(cfg, win);
	PhysicsWorld* physics;
	ResourceFilesystem* fs;
	ResourceManager* resource = createResourceManager(cfg, gr, physics, fs);
	UiManager* ui = new UiManager();

	ANKI_TEST_EXPECT_NO_ERR(in->init(win));

	StagingGpuMemoryManager* stagingMem = new StagingGpuMemoryManager();
	ANKI_TEST_EXPECT_NO_ERR(stagingMem->init(gr, cfg));

	HeapAllocator<U8> alloc(allocAligned, nullptr);
	ANKI_TEST_EXPECT_NO_ERR(ui->init(allocAligned, nullptr, resource, gr, stagingMem, in));

	{
		FontPtr font;
		ANKI_TEST_EXPECT_NO_ERR(ui->newInstance(font, "UbuntuRegular.ttf", std::initializer_list<U32>{10, 20, 30, 60}));

		CanvasPtr canvas;
		ANKI_TEST_EXPECT_NO_ERR(ui->newInstance(canvas, font, 20, win->getWidth(), win->getHeight()));

		IntrusivePtr<Label> label;
		ANKI_TEST_EXPECT_NO_ERR(ui->newInstance(label));

		Bool done = false;
		while(!done)
		{
			ANKI_TEST_EXPECT_NO_ERR(in->handleEvents());
			HighRezTimer timer;
			timer.start();

			canvas->handleInput();
			if(in->getKey(KeyCode::ESCAPE))
			{
				done = true;
			}

			canvas->beginBuilding();
			label->build(canvas);

			TexturePtr presentTex = gr->acquireNextPresentableTexture();
			FramebufferPtr fb;
			{
				TextureViewInitInfo init;
				init.m_texture = presentTex;
				TextureViewPtr view = gr->newTextureView(init);

				FramebufferInitInfo fbinit;
				fbinit.m_colorAttachmentCount = 1;
				fbinit.m_colorAttachments[0].m_clearValue.m_colorf = {{1.0, 0.0, 1.0, 1.0}};
				fbinit.m_colorAttachments[0].m_textureView = view;

				fb = gr->newFramebuffer(fbinit);
			}

			CommandBufferInitInfo cinit;
			cinit.m_flags = CommandBufferFlag::GRAPHICS_WORK | CommandBufferFlag::SMALL_BATCH;
			CommandBufferPtr cmdb = gr->newCommandBuffer(cinit);

			cmdb->setTextureBarrier(presentTex,
				TextureUsageBit::NONE,
				TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE,
				TextureSubresourceInfo());

			cmdb->beginRenderPass(fb, {{TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE}}, {});
			canvas->appendToCommandBuffer(cmdb);
			cmdb->endRenderPass();

			cmdb->setTextureBarrier(presentTex,
				TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE,
				TextureUsageBit::PRESENT,
				TextureSubresourceInfo());

			cmdb->flush();

			gr->swapBuffers();
			stagingMem->endFrame();

			timer.stop();
			const F32 TICK = 1.0 / 30.0;
			if(timer.getElapsedTime() < TICK)
			{
				HighRezTimer::sleep(TICK - timer.getElapsedTime());
			}
		}
	}

	delete ui;
	delete stagingMem;
	delete resource;
	delete physics;
	delete fs;
	GrManager::deleteInstance(gr);
	delete in;
	delete win;
}
Ejemplo n.º 23
0
		Error operator()(CommandBufferImpl*)
		{
			return m_commands.get().executeAllCommands();
		}
Ejemplo n.º 24
0
//==============================================================================
void FramebufferPtr::bind(CommandBufferPtr& cmdb)
{
	cmdb.get().pushBackNewCommand<BindFramebufferCommand>(*this);
}
Ejemplo n.º 25
0
//==============================================================================
Error MeshLoadTask::operator()(AsyncLoaderTaskContext& ctx)
{
	GrManager& gr = m_manager->getGrManager();
	CommandBufferPtr cmdb;

	// Write vert buff
	if(m_vertBuff)
	{
		TransientMemoryToken token;
		Error err = ErrorCode::NONE;
		void* data = gr.allocateFrameTransientMemory(
			m_loader.getVertexDataSize(), BufferUsage::TRANSFER, token, &err);

		if(!err)
		{
			memcpy(
				data, m_loader.getVertexData(), m_loader.getVertexDataSize());
			cmdb = gr.newInstance<CommandBuffer>(CommandBufferInitInfo());
			cmdb->uploadBuffer(m_vertBuff, 0, token);
			m_vertBuff.reset(nullptr);
		}
		else
		{
			ctx.m_pause = true;
			ctx.m_resubmitTask = true;
			return ErrorCode::NONE;
		}
	}

	// Create index buffer
	{
		TransientMemoryToken token;
		Error err = ErrorCode::NONE;
		void* data = gr.allocateFrameTransientMemory(
			m_loader.getIndexDataSize(), BufferUsage::TRANSFER, token, &err);

		if(!err)
		{
			memcpy(data, m_loader.getIndexData(), m_loader.getIndexDataSize());

			if(!cmdb)
			{
				cmdb = gr.newInstance<CommandBuffer>(CommandBufferInitInfo());
			}

			cmdb->uploadBuffer(m_indicesBuff, 0, token);
			cmdb->flush();
		}
		else
		{
			// Submit prev work
			if(cmdb)
			{
				cmdb->flush();
			}

			ctx.m_pause = true;
			ctx.m_resubmitTask = true;
			return ErrorCode::NONE;
		}
	}

	return ErrorCode::NONE;
}