Exemple #1
0
void Volumetric::setPostRunBarriers(RenderingContext& ctx)
{
	ctx.m_commandBuffer->setTextureSurfaceBarrier(m_rt,
		TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE,
		TextureUsageBit::SAMPLED_FRAGMENT,
		TextureSurfaceInfo(0, 0, 0, 0));
}
Exemple #2
0
void Is::setPreRunBarriers(RenderingContext& ctx)
{
	ctx.m_commandBuffer->setTextureSurfaceBarrier(m_rt,
		TextureUsageBit::NONE,
		TextureUsageBit::FRAMEBUFFER_ATTACHMENT_READ_WRITE,
		TextureSurfaceInfo(0, 0, 0, 0));
}
Exemple #3
0
void Volumetric::run(RenderingContext& ctx)
{
	CommandBufferPtr& cmdb = ctx.m_commandBuffer;
	const Frustum& frc = ctx.m_frustumComponent->getFrustum();

	// Update uniforms
	TransientMemoryInfo dyn = ctx.m_is.m_dynBufferInfo;
	Vec4* uniforms = static_cast<Vec4*>(getGrManager().allocateFrameTransientMemory(
		sizeof(Vec4) * 2, BufferUsageBit::UNIFORM_ALL, dyn.m_uniformBuffers[3]));
	computeLinearizeDepthOptimal(frc.getNear(), frc.getFar(), uniforms[0].x(), uniforms[0].y());
	uniforms[1] = Vec4(m_fogColor, m_fogFactor);

	// pass 0
	cmdb->setViewport(0, 0, m_r->getWidth() / VOLUMETRIC_FRACTION, m_r->getHeight() / VOLUMETRIC_FRACTION);
	cmdb->beginRenderPass(m_vblurFb);
	cmdb->bindPipeline(m_ppline);
	cmdb->bindResourceGroup(m_rc, 0, &dyn);
	m_r->drawQuad(cmdb);
	cmdb->endRenderPass();

	// hpass
	cmdb->setTextureSurfaceBarrier(m_rt,
		TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE,
		TextureUsageBit::SAMPLED_FRAGMENT,
		TextureSurfaceInfo(0, 0, 0, 0));
	cmdb->setTextureSurfaceBarrier(
		m_tmpRt, TextureUsageBit::NONE, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE, TextureSurfaceInfo(0, 0, 0, 0));
	cmdb->beginRenderPass(m_hblurFb);
	cmdb->bindPipeline(m_hblurPpline);
	cmdb->bindResourceGroup(m_hblurRc, 0, nullptr);
	m_r->drawQuad(cmdb);
	cmdb->endRenderPass();

	// vpass
	cmdb->setTextureSurfaceBarrier(m_tmpRt,
		TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE,
		TextureUsageBit::SAMPLED_FRAGMENT,
		TextureSurfaceInfo(0, 0, 0, 0));
	cmdb->setTextureSurfaceBarrier(
		m_rt, TextureUsageBit::NONE, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE, TextureSurfaceInfo(0, 0, 0, 0));
	cmdb->beginRenderPass(m_vblurFb);
	cmdb->bindPipeline(m_vblurPpline);
	cmdb->bindResourceGroup(m_vblurRc, 0, nullptr);
	m_r->drawQuad(cmdb);
	cmdb->endRenderPass();
}
Exemple #4
0
Error Pps::run(RenderingContext& ctx)
{
	CommandBufferPtr& cmdb = ctx.m_commandBuffer;

	// Get the drawing parameters
	Bool drawToDefaultFb = ctx.m_outFb.isCreated();
	Bool dbgEnabled = m_r->getDbg().getEnabled();

	// Get or create the ppline
	PipelinePtr& ppline = m_ppline[drawToDefaultFb][dbgEnabled];

	if(!ppline)
	{
		// Need to create it

		ShaderResourcePtr& frag = m_frag[drawToDefaultFb][dbgEnabled];
		if(!frag)
		{
			StringAuto pps(ctx.m_tempAllocator);

			pps.sprintf("#define BLOOM_ENABLED %u\n"
						"#define SHARPEN_ENABLED %u\n"
						"#define FBO_WIDTH %u\n"
						"#define FBO_HEIGHT %u\n"
						"#define LUT_SIZE %u.0\n"
						"#define DBG_ENABLED %u\n"
						"#define DRAW_TO_DEFAULT %u\n"
						"#define SMAA_ENABLED 1\n"
						"#define SMAA_RT_METRICS vec4(%f, %f, %f, %f)\n"
						"#define SMAA_PRESET_%s\n",
				true,
				m_sharpenEnabled,
				m_r->getWidth(),
				m_r->getHeight(),
				LUT_SIZE,
				dbgEnabled,
				drawToDefaultFb,
				1.0 / m_r->getWidth(),
				1.0 / m_r->getHeight(),
				F32(m_r->getWidth()),
				F32(m_r->getHeight()),
				&m_r->getSmaa().m_qualityPerset[0]);

			ANKI_CHECK(getResourceManager().loadResourceToCache(frag, "shaders/Pps.frag.glsl", pps.toCString(), "r_"));
		}

		if(!m_vert)
		{
			StringAuto pps(ctx.m_tempAllocator);

			pps.sprintf("#define SMAA_ENABLED 1\n"
						"#define SMAA_RT_METRICS vec4(%f, %f, %f, %f)\n"
						"#define SMAA_PRESET_%s\n",
				1.0 / m_r->getWidth(),
				1.0 / m_r->getHeight(),
				F32(m_r->getWidth()),
				F32(m_r->getHeight()),
				&m_r->getSmaa().m_qualityPerset[0]);

			ANKI_CHECK(
				getResourceManager().loadResourceToCache(m_vert, "shaders/Pps.vert.glsl", pps.toCString(), "r_"));
		}

		PixelFormat pfs = (drawToDefaultFb) ? PixelFormat(ComponentFormat::DEFAULT_FRAMEBUFFER, TransformFormat::NONE)
											: RT_PIXEL_FORMAT;

		PipelineInitInfo ppinit;

		ppinit.m_inputAssembler.m_topology = PrimitiveTopology::TRIANGLE_STRIP;

		ppinit.m_depthStencil.m_depthWriteEnabled = false;
		ppinit.m_depthStencil.m_depthCompareFunction = CompareOperation::ALWAYS;

		ppinit.m_color.m_attachmentCount = 1;
		ppinit.m_color.m_attachments[0].m_format = pfs;

		ppinit.m_shaders[ShaderType::VERTEX] = m_vert->getGrShader();
		ppinit.m_shaders[ShaderType::FRAGMENT] = frag->getGrShader();

		ppline = m_r->getGrManager().newInstance<Pipeline>(ppinit);
	}

	// Get or create the resource group
	ResourceGroupPtr& rsrc = m_rcGroup[dbgEnabled];
	if(!rsrc || m_lutDirty)
	{
		ResourceGroupInitInfo rcInit;
		rcInit.m_textures[0].m_texture = m_r->getIs().getRt();
		rcInit.m_textures[1].m_texture = m_r->getBloom().m_upscale.m_rt;
		rcInit.m_textures[2].m_texture = m_lut->getGrTexture();
		rcInit.m_textures[3].m_texture = m_r->getSmaa().m_weights.m_rt;
		if(dbgEnabled)
		{
			rcInit.m_textures[4].m_texture = m_r->getDbg().getRt();
		}

		rcInit.m_storageBuffers[0].m_buffer = m_r->getTm().getAverageLuminanceBuffer();
		rcInit.m_storageBuffers[0].m_usage = BufferUsageBit::STORAGE_FRAGMENT_READ;

		rsrc = getGrManager().newInstance<ResourceGroup>(rcInit);

		m_lutDirty = false;
	}

	// Get or create FB
	FramebufferPtr* fb = nullptr;
	U width, height;
	if(drawToDefaultFb)
	{
		fb = &ctx.m_outFb;
		width = ctx.m_outFbWidth;
		height = ctx.m_outFbHeight;
	}
	else
	{
		width = m_r->getWidth();
		height = m_r->getHeight();
		fb = &m_fb;
	}

	cmdb->beginRenderPass(*fb);
	cmdb->setViewport(0, 0, width, height);
	cmdb->bindPipeline(ppline);
	cmdb->bindResourceGroup(rsrc, 0, nullptr);
	m_r->drawQuad(cmdb);
	cmdb->endRenderPass();

	if(!drawToDefaultFb)
	{
		cmdb->setTextureSurfaceBarrier(m_rt,
			TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE,
			TextureUsageBit::SAMPLED_FRAGMENT,
			TextureSurfaceInfo(0, 0, 0, 0));
	}

	return ErrorCode::NONE;
}
//==============================================================================
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;
}
//==============================================================================
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;
}
//==============================================================================
void CommandBufferImpl::generateMipmaps(
	TexturePtr tex, U depth, U face, U layer)
{
	commandCommon();
	const TextureImpl& impl = tex->getImplementation();
	ANKI_ASSERT(impl.m_type != TextureType::_3D && "Not design for that ATM");

	U mipCount = computeMaxMipmapCount(impl.m_width, impl.m_height);

	for(U i = 0; i < mipCount - 1; ++i)
	{
		// Transition source
		if(i > 0)
		{
			VkImageSubresourceRange range;
			impl.computeSubResourceRange(
				TextureSurfaceInfo(i, depth, face, layer), range);

			setImageBarrier(VK_PIPELINE_STAGE_TRANSFER_BIT,
				VK_ACCESS_TRANSFER_WRITE_BIT,
				VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
				VK_PIPELINE_STAGE_TRANSFER_BIT,
				VK_ACCESS_TRANSFER_READ_BIT,
				VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
				impl.m_imageHandle,
				range);
		}

		// Transition destination
		{
			VkImageSubresourceRange range;
			impl.computeSubResourceRange(
				TextureSurfaceInfo(i + 1, depth, face, layer), range);

			setImageBarrier(VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
				0,
				VK_IMAGE_LAYOUT_UNDEFINED,
				VK_PIPELINE_STAGE_TRANSFER_BIT,
				VK_ACCESS_TRANSFER_WRITE_BIT,
				VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
				impl.m_imageHandle,
				range);
		}

		// Setup the blit struct
		I32 srcWidth = impl.m_width >> i;
		I32 srcHeight = impl.m_height >> i;

		I32 dstWidth = impl.m_width >> i;
		I32 dstHeight = impl.m_height >> i;

		ANKI_ASSERT(
			srcWidth > 0 && srcHeight > 0 && dstWidth > 0 && dstHeight > 0);

		VkImageBlit blit;
		blit.srcSubresource.aspectMask = impl.m_aspect;
		blit.srcSubresource.baseArrayLayer = layer;
		blit.srcSubresource.layerCount = 1;
		blit.srcSubresource.mipLevel = i;
		blit.srcOffsets[0] = {0, 0, 0};
		blit.srcOffsets[1] = {srcWidth, srcHeight, 1};

		blit.dstSubresource.aspectMask = impl.m_aspect;
		blit.dstSubresource.baseArrayLayer = layer;
		blit.dstSubresource.layerCount = 1;
		blit.dstSubresource.mipLevel = i + 1;
		blit.dstOffsets[0] = {0, 0, 0};
		blit.dstOffsets[1] = {dstWidth, dstHeight, 1};

		vkCmdBlitImage(m_handle,
			impl.m_imageHandle,
			VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
			impl.m_imageHandle,
			VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
			1,
			&blit,
			VK_FILTER_LINEAR);
	}

	// Hold the reference
	m_texList.pushBack(m_alloc, tex);
}