示例#1
0
Texture2D* FramebufferManager::ResolveEFBColorTexture(const VkRect2D& region)
{
	// Return the normal EFB texture if multisampling is off.
	if (m_efb_samples == VK_SAMPLE_COUNT_1_BIT)
		return m_efb_color_texture.get();

	// Can't resolve within a render pass.
	StateTracker::GetInstance()->EndRenderPass();

	// Resolving is considered to be a transfer operation.
	m_efb_color_texture->TransitionToLayout(g_command_buffer_mgr->GetCurrentCommandBuffer(),
		VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
	m_efb_resolve_color_texture->TransitionToLayout(g_command_buffer_mgr->GetCurrentCommandBuffer(),
		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);

	// Resolve to our already-created texture.
	VkImageResolve resolve = {
		{ VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, m_efb_layers },  // VkImageSubresourceLayers srcSubresource
		{ region.offset.x, region.offset.y, 0 },            // VkOffset3D                  srcOffset
		{ VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, m_efb_layers },  // VkImageSubresourceLayers dstSubresource
		{ region.offset.x, region.offset.y, 0 },            // VkOffset3D                  dstOffset
		{ region.extent.width, region.extent.height, m_efb_layers }  // VkExtent3D extent
	};
	vkCmdResolveImage(g_command_buffer_mgr->GetCurrentCommandBuffer(),
		m_efb_color_texture->GetImage(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
		m_efb_resolve_color_texture->GetImage(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
		1, &resolve);

	// Restore MSAA texture ready for rendering again
	m_efb_color_texture->TransitionToLayout(g_command_buffer_mgr->GetCurrentCommandBuffer(),
		VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
	return m_efb_resolve_color_texture.get();
}
示例#2
0
Texture2D* FramebufferManager::ResolveEFBColorTexture(const VkRect2D& region)
{
  // Return the normal EFB texture if multisampling is off.
  if (GetEFBSamples() == VK_SAMPLE_COUNT_1_BIT)
    return m_efb_color_texture.get();

  // Can't resolve within a render pass.
  StateTracker::GetInstance()->EndRenderPass();

  // It's not valid to resolve out-of-bounds coordinates.
  // Ensuring the region is within the image is the caller's responsibility.
  _assert_(region.offset.x >= 0 && region.offset.y >= 0 &&
           (static_cast<u32>(region.offset.x) + region.extent.width) <= GetEFBWidth() &&
           (static_cast<u32>(region.offset.y) + region.extent.height) <= GetEFBHeight());

  // Resolving is considered to be a transfer operation.
  m_efb_color_texture->TransitionToLayout(g_command_buffer_mgr->GetCurrentCommandBuffer(),
                                          VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
  m_efb_resolve_color_texture->TransitionToLayout(g_command_buffer_mgr->GetCurrentCommandBuffer(),
                                                  VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);

  // Resolve to our already-created texture.
  VkImageResolve resolve = {
      {VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, GetEFBLayers()},  // VkImageSubresourceLayers srcSubresource
      {region.offset.x, region.offset.y, 0},              // VkOffset3D                  srcOffset
      {VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, GetEFBLayers()},  // VkImageSubresourceLayers dstSubresource
      {region.offset.x, region.offset.y, 0},              // VkOffset3D                  dstOffset
      {region.extent.width, region.extent.height, GetEFBLayers()}  // VkExtent3D extent
  };
  vkCmdResolveImage(g_command_buffer_mgr->GetCurrentCommandBuffer(),
                    m_efb_color_texture->GetImage(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
                    m_efb_resolve_color_texture->GetImage(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
                    1, &resolve);

  // Restore MSAA texture ready for rendering again
  m_efb_color_texture->TransitionToLayout(g_command_buffer_mgr->GetCurrentCommandBuffer(),
                                          VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
  return m_efb_resolve_color_texture.get();
}
void vkeGameRendererDynamic::generateDrawCommands(){

	//Start generating draw commands.

	VulkanDC *dc = VulkanDC::Get();
	VulkanDC::Device *device = dc->getDefaultDevice();
	VkClearValue clearValues[3];

	colorClearValues(&clearValues[0], 1.0, 1.0, 1.0);
	depthStencilClearValues(&clearValues[1]);//default#
	colorClearValues(&clearValues[2], 0.0, 0.0, 0.0);

	/*
	Dispatch threads to create the secondary
	command buffers.
	*/
	m_calls_generated = 0;
	for (uint32_t i = 0; i < m_max_draw_calls; ++i){
		m_draw_calls[i]->initDrawCommands(m_node_data->count(), m_current_buffer_index);
	}

	/*
	Begin setting up the primary command buffer.
	*/
	VkCommandBufferBeginInfo cmdBeginInfo = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO };
	cmdBeginInfo.flags = VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT;

	VKA_CHECK_ERROR(vkResetCommandBuffer(m_primary_commands[m_current_buffer_index], 0),"Could not reset primary command buffer");
	VKA_CHECK_ERROR(vkBeginCommandBuffer(m_primary_commands[m_current_buffer_index], &cmdBeginInfo), "Could not begin primary command buffer.\n");


	uint32_t cnt = m_node_data->count();
	VkDeviceSize sz = (sizeof(VkeNodeUniform) * cnt) + (m_instance_count * 64);
	vkCmdUpdateBuffer(m_primary_commands[m_current_buffer_index], m_uniforms_buffer, 0, sz, (const uint32_t *)m_uniforms_local);
	m_camera->updateCameraCmd(m_primary_commands[m_current_buffer_index]);


	renderPassBegin(&m_primary_commands[m_current_buffer_index], m_render_pass, m_framebuffers[m_current_buffer_index], 0, 0, m_width, m_height, clearValues, 3, VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS);


	VkViewport vp;
	VkRect2D sc;
	vp.x = 0;
	vp.y = 0;
	vp.height = (float)(m_height);
	vp.width = (float)(m_width);
	vp.minDepth = 0.0f;
	vp.maxDepth = 1.0f;

	sc.offset.x = 0;
	sc.offset.y = 0;
	sc.extent.width = vp.width;
	sc.extent.height = vp.height;

	vkCmdSetViewport(m_primary_commands[m_current_buffer_index], 0, 1, &vp);
	vkCmdSetScissor(m_primary_commands[m_current_buffer_index], 0, 1, &sc);

	/*
	Wait here until the secondary commands are ready.
	*/

	VkCommandBuffer secondaryCommands[11];
	secondaryCommands[0] = m_terrain_command[m_current_buffer_index];
	for (uint32_t i = 0; i < m_max_draw_calls; ++i){
		secondaryCommands[i+1] = m_draw_calls[i]->getDrawCommand(m_current_buffer_index);
	}


	vkCmdExecuteCommands(m_primary_commands[m_current_buffer_index],  1+m_max_draw_calls, secondaryCommands);

	vkCmdEndRenderPass(m_primary_commands[m_current_buffer_index]);

	VkImageResolve blitInfo;
    blitInfo.srcOffset.x = 0;
	blitInfo.srcOffset.y = 0;
	blitInfo.srcOffset.z = 0;
	blitInfo.dstOffset.x = 0;
	blitInfo.dstOffset.y = 0;
	blitInfo.dstOffset.z = 0;
    blitInfo.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
    blitInfo.srcSubresource.mipLevel = 0;
    blitInfo.srcSubresource.baseArrayLayer = 0;
    blitInfo.srcSubresource.layerCount = 1;
    blitInfo.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
    blitInfo.dstSubresource.mipLevel = 0;
    blitInfo.dstSubresource.baseArrayLayer = 0;
    blitInfo.dstSubresource.layerCount = 1;
    blitInfo.extent.width = m_width;
    blitInfo.extent.height = m_height;
    blitInfo.extent.depth = 1;

	vkCmdResolveImage(
		m_primary_commands[m_current_buffer_index],
		m_color_attachment.image,
		VK_IMAGE_LAYOUT_GENERAL,
		m_resolve_attachment[m_current_buffer_index].image,
		VK_IMAGE_LAYOUT_GENERAL,
		1,
		&blitInfo);


	VKA_CHECK_ERROR(vkEndCommandBuffer(m_primary_commands[m_current_buffer_index]), "Could not end command buffer for draw command.\n");

}
void vkeGameRendererDynamic::generateDrawCommands(){

	//Start generating draw commands.

	VulkanDC *dc = VulkanDC::Get();
	VulkanDC::Device *device = dc->getDefaultDevice();
	VkClearValue clearValues[3];


	/*
	Dispatch threads to create the secondary
	command buffers.
	*/
	m_calls_generated = 0;
	for (uint32_t i = 0; i < m_max_draw_calls; ++i){
		m_draw_calls[i]->initDrawCommands(m_node_data->count(), m_current_buffer_index);
	}

	/*
	Begin setting up the primary command buffer.
	*/
	VkCommandBufferBeginInfo cmdBeginInfo = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO };
	cmdBeginInfo.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;

	vkResetCommandBuffer(m_primary_commands[m_current_buffer_index], 0);
	vkResetCommandBuffer(m_update_commands[m_current_buffer_index], 0);


	VKA_CHECK_ERROR(vkBeginCommandBuffer(m_update_commands[m_current_buffer_index], &cmdBeginInfo), "Could not begin primary command buffer.\n");

	VkBufferMemoryBarrier bufBarrier = { VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER };
	bufBarrier.dstAccessMask = VK_ACCESS_UNIFORM_READ_BIT;
	bufBarrier.srcAccessMask = VK_ACCESS_HOST_WRITE_BIT;
	bufBarrier.dstQueueFamilyIndex = 0;
	bufBarrier.offset = 0;
	bufBarrier.buffer = m_uniforms_buffer;
	bufBarrier.srcQueueFamilyIndex = 0;

	colorClearValues(&clearValues[0], 1.0, 1.0, 1.0);
	depthStencilClearValues(&clearValues[1]);//default#
	colorClearValues(&clearValues[2], 0.0, 0.0, 0.0);

	uint32_t sz = (sizeof(VkeNodeUniform) * 100) + (64 * 64);
	VkBufferCopy bufCopy;
	bufCopy.dstOffset = 0;
	bufCopy.srcOffset = 0;
	bufCopy.size = sz;

	vkCmdCopyBuffer(m_update_commands[m_current_buffer_index], m_uniforms_buffer_staging, m_uniforms_buffer, 1, &bufCopy);

	vkCmdPipelineBarrier(
		m_update_commands[m_current_buffer_index],
		VK_PIPELINE_STAGE_VERTEX_SHADER_BIT,
		VK_PIPELINE_STAGE_VERTEX_SHADER_BIT,
		0,
		0,
		NULL,
		1,
		&bufBarrier,
		0,
		NULL);

	VKA_CHECK_ERROR(vkEndCommandBuffer(m_update_commands[m_current_buffer_index]), "Could not end command buffer for draw command.\n");


	VKA_CHECK_ERROR(vkBeginCommandBuffer(m_primary_commands[m_current_buffer_index], &cmdBeginInfo), "Could not begin primary command buffer.\n");



	renderPassBegin(&m_primary_commands[m_current_buffer_index], m_render_pass, m_framebuffers[m_current_buffer_index], 0, 0, m_width, m_height, clearValues, 3, VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS);


	VkViewport vp;
	VkRect2D sc;
	vp.x = 0;
	vp.y = 0;
	vp.height = (float)(m_height);
	vp.width = (float)(m_width);
	vp.minDepth = 0.0f;
	vp.maxDepth = 1.0f;

	sc.offset.x = 0;
	sc.offset.y = 0;
	sc.extent.width = vp.width;
	sc.extent.height = vp.height;

	vkCmdSetViewport(m_primary_commands[m_current_buffer_index], 0, 1, &vp);
	vkCmdSetScissor(m_primary_commands[m_current_buffer_index], 0, 1, &sc);

	/*
	Wait here until the secondary commands are ready.
	*/

	VkCommandBuffer secondaryCommands[11];
	secondaryCommands[0] = m_terrain_command[m_current_buffer_index];
	for (uint32_t i = 0; i < m_max_draw_calls; ++i){
		secondaryCommands[i + 1] = m_draw_calls[i]->getDrawCommand(m_current_buffer_index);
	}

	vkCmdExecuteCommands(m_primary_commands[m_current_buffer_index], 1 + m_max_draw_calls, secondaryCommands);

	vkCmdEndRenderPass(m_primary_commands[m_current_buffer_index]);

	VkImageResolve blitInfo;
    blitInfo.srcOffset.x = 0;
	blitInfo.srcOffset.y = 0;
	blitInfo.srcOffset.z = 0;
	blitInfo.dstOffset.x = 0;
	blitInfo.dstOffset.y = 0;
	blitInfo.dstOffset.z = 0;
    blitInfo.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
    blitInfo.srcSubresource.mipLevel = 0;
    blitInfo.srcSubresource.baseArrayLayer = 0;
    blitInfo.srcSubresource.layerCount = 1;
    blitInfo.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
    blitInfo.dstSubresource.mipLevel = 0;
    blitInfo.dstSubresource.baseArrayLayer = 0;
    blitInfo.dstSubresource.layerCount = 1;
    blitInfo.extent.width = m_width;
    blitInfo.extent.height = m_height;
    blitInfo.extent.depth = 1;

	vkCmdResolveImage(
		m_primary_commands[m_current_buffer_index],
		m_color_attachment.image,
		VK_IMAGE_LAYOUT_GENERAL,
		m_resolve_attachment[m_current_buffer_index].image,
		VK_IMAGE_LAYOUT_GENERAL,
		1,
		&blitInfo);


	VKA_CHECK_ERROR(vkEndCommandBuffer(m_primary_commands[m_current_buffer_index]), "Could not end command buffer for draw command.\n");

}
示例#5
0
	void VulkanTexture::copyImpl(const SPtr<Texture>& target, const TEXTURE_COPY_DESC& desc, 
			const SPtr<CommandBuffer>& commandBuffer)
	{
		VulkanTexture* other = static_cast<VulkanTexture*>(target.get());

		const TextureProperties& srcProps = mProperties;
		const TextureProperties& dstProps = other->getProperties();

		bool srcHasMultisample = srcProps.getNumSamples() > 1;
		bool destHasMultisample = dstProps.getNumSamples() > 1;

		if ((srcProps.getUsage() & TU_DEPTHSTENCIL) != 0 || (dstProps.getUsage() & TU_DEPTHSTENCIL) != 0)
		{
			LOGERR("Texture copy/resolve isn't supported for depth-stencil textures.");
			return;
		}

		bool needsResolve = srcHasMultisample && !destHasMultisample;
		bool isMSCopy = srcHasMultisample || destHasMultisample;
		if (!needsResolve && isMSCopy)
		{
			if (srcProps.getNumSamples() != dstProps.getNumSamples())
			{
				LOGERR("When copying textures their multisample counts must match. Ignoring copy.");
				return;
			}
		}

		VkImageLayout transferSrcLayout = mDirectlyMappable ? VK_IMAGE_LAYOUT_GENERAL : VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
		VkImageLayout transferDstLayout = other->mDirectlyMappable ? VK_IMAGE_LAYOUT_GENERAL : VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;

		UINT32 mipWidth, mipHeight, mipDepth;

		bool copyEntireSurface = desc.srcVolume.getWidth() == 0 || 
			desc.srcVolume.getHeight() == 0 || 
			desc.srcVolume.getDepth() == 0;

		if(copyEntireSurface)
		{
			PixelUtil::getSizeForMipLevel(
				srcProps.getWidth(),
				srcProps.getHeight(),
				srcProps.getDepth(),
				desc.srcMip,
				mipWidth,
				mipHeight,
				mipDepth);
		}
		else
		{
			mipWidth = desc.srcVolume.getWidth();
			mipHeight = desc.srcVolume.getHeight();
			mipDepth = desc.srcVolume.getDepth();
		}

		VkImageResolve resolveRegion;
		resolveRegion.srcOffset = { (INT32)desc.srcVolume.left, (INT32)desc.srcVolume.top, (INT32)desc.srcVolume.front };
		resolveRegion.dstOffset = { desc.dstPosition.x, desc.dstPosition.y, desc.dstPosition.z };
		resolveRegion.extent = { mipWidth, mipHeight, mipDepth };
		resolveRegion.srcSubresource.baseArrayLayer = desc.srcFace;
		resolveRegion.srcSubresource.layerCount = 1;
		resolveRegion.srcSubresource.mipLevel = desc.srcMip;
		resolveRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
		resolveRegion.dstSubresource.baseArrayLayer = desc.dstFace;
		resolveRegion.dstSubresource.layerCount = 1;
		resolveRegion.dstSubresource.mipLevel = desc.dstMip;
		resolveRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;

		VkImageCopy imageRegion;
		imageRegion.srcOffset = { (INT32)desc.srcVolume.left, (INT32)desc.srcVolume.top, (INT32)desc.srcVolume.front };
		imageRegion.dstOffset = { desc.dstPosition.x, desc.dstPosition.y, desc.dstPosition.z };
		imageRegion.extent = { mipWidth, mipHeight, mipDepth };
		imageRegion.srcSubresource.baseArrayLayer = desc.srcFace;
		imageRegion.srcSubresource.layerCount = 1;
		imageRegion.srcSubresource.mipLevel = desc.srcMip;
		imageRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
		imageRegion.dstSubresource.baseArrayLayer = desc.dstFace;
		imageRegion.dstSubresource.layerCount = 1;
		imageRegion.dstSubresource.mipLevel = desc.dstMip;
		imageRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;

		VkImageSubresourceRange srcRange;
		srcRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
		srcRange.baseArrayLayer = desc.srcFace;
		srcRange.layerCount = 1;
		srcRange.baseMipLevel = desc.srcMip;
		srcRange.levelCount = 1;

		VkImageSubresourceRange dstRange;
		dstRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
		dstRange.baseArrayLayer = desc.dstFace;
		dstRange.layerCount = 1;
		dstRange.baseMipLevel = desc.dstMip;
		dstRange.levelCount = 1;

		VulkanRenderAPI& rapi = static_cast<VulkanRenderAPI&>(RenderAPI::instance());

		VulkanCmdBuffer* vkCB;
		if (commandBuffer != nullptr)
			vkCB = static_cast<VulkanCommandBuffer*>(commandBuffer.get())->getInternal();
		else
			vkCB = rapi._getMainCommandBuffer()->getInternal();

		UINT32 deviceIdx = vkCB->getDeviceIdx();

		VulkanImage* srcImage = mImages[deviceIdx];
		VulkanImage* dstImage = other->getResource(deviceIdx);

		if (srcImage == nullptr || dstImage == nullptr)
			return;

		VkImageLayout srcLayout = vkCB->getCurrentLayout(srcImage, srcRange, false);
		VkImageLayout dstLayout = vkCB->getCurrentLayout(dstImage, dstRange, false);

		VkCommandBuffer vkCmdBuf = vkCB->getHandle();

		VkAccessFlags srcAccessMask = srcImage->getAccessFlags(srcLayout);
		VkAccessFlags dstAccessMask = dstImage->getAccessFlags(dstLayout);

		if (vkCB->isInRenderPass())
			vkCB->endRenderPass();

		// Transfer textures to a valid layout
		vkCB->setLayout(srcImage->getHandle(), srcAccessMask, VK_ACCESS_TRANSFER_READ_BIT, srcLayout,
								transferSrcLayout, srcRange);

		vkCB->setLayout(dstImage->getHandle(), dstAccessMask, VK_ACCESS_TRANSFER_WRITE_BIT,
								dstLayout, transferDstLayout, dstRange);

		if (srcHasMultisample && !destHasMultisample) // Resolving from MS to non-MS texture
		{
			vkCmdResolveImage(vkCmdBuf, srcImage->getHandle(), transferSrcLayout, dstImage->getHandle(), transferDstLayout, 
				1, &resolveRegion);
		}
		else // Just a normal copy
		{
			vkCmdCopyImage(vkCmdBuf, srcImage->getHandle(), transferSrcLayout, dstImage->getHandle(), transferDstLayout, 
				1, &imageRegion);
		}

		// Transfer back to optimal layouts
		srcLayout = srcImage->getOptimalLayout();

		// Notify the command buffer that these resources are being used on it
		vkCB->registerResource(srcImage, srcRange, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, VulkanUseFlag::Read, ResourceUsage::Transfer);
		vkCB->registerResource(dstImage, dstRange, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VulkanUseFlag::Write, ResourceUsage::Transfer);
	}