Commit 028df5f5 by Shahbaz Youssefi Committed by Commit Bot

Vulkan: Implement transfer path for texture copy

This is primarily in preparation for compressed texture copy, but has the following side effect: - When transfer is possible, it's faster than draw - When texture format does not support draw (but transfer is possible), it will avoid copying through CPU. Bug: angleproject:2670 Change-Id: I49e1b51e6ccec875db3f971106687c7d48c4916f Reviewed-on: https://chromium-review.googlesource.com/c/1470595 Commit-Queue: Shahbaz Youssefi <syoussefi@chromium.org> Reviewed-by: 's avatarYuly Novikov <ynovikov@chromium.org>
parent 8a64926e
...@@ -421,19 +421,30 @@ angle::Result FramebufferVk::blitWithCopy(ContextVk *contextVk, ...@@ -421,19 +421,30 @@ angle::Result FramebufferVk::blitWithCopy(ContextVk *contextVk,
bool blitDepthBuffer, bool blitDepthBuffer,
bool blitStencilBuffer) bool blitStencilBuffer)
{ {
vk::ImageHelper *writeImage = drawRenderTarget->getImageForWrite(&mFramebuffer); VkImageAspectFlags aspectMask =
vk::GetDepthStencilAspectFlagsForCopy(blitDepthBuffer, blitStencilBuffer);
vk::CommandBuffer *commandBuffer; vk::CommandBuffer *commandBuffer;
ANGLE_TRY(mFramebuffer.recordCommands(contextVk, &commandBuffer)); ANGLE_TRY(mFramebuffer.recordCommands(contextVk, &commandBuffer));
vk::ImageHelper *writeImage = drawRenderTarget->getImageForWrite(&mFramebuffer);
writeImage->changeLayout(writeImage->getAspectFlags(), vk::ImageLayout::TransferDst,
commandBuffer);
vk::ImageHelper *readImage = readRenderTarget->getImageForRead( vk::ImageHelper *readImage = readRenderTarget->getImageForRead(
&mFramebuffer, vk::ImageLayout::TransferSrc, commandBuffer); &mFramebuffer, vk::ImageLayout::TransferSrc, commandBuffer);
VkImageAspectFlags aspectMask = VkImageSubresourceLayers readSubresource = {};
vk::GetDepthStencilAspectFlagsForCopy(blitDepthBuffer, blitStencilBuffer); readSubresource.aspectMask = aspectMask;
readSubresource.mipLevel = 0;
readSubresource.baseArrayLayer = 0;
readSubresource.layerCount = 1;
VkImageSubresourceLayers writeSubresource = readSubresource;
vk::ImageHelper::Copy(readImage, writeImage, gl::Offset(), gl::Offset(), vk::ImageHelper::Copy(readImage, writeImage, gl::Offset(), gl::Offset(),
gl::Extents(copyArea.width, copyArea.height, 1), aspectMask, gl::Extents(copyArea.width, copyArea.height, 1), readSubresource,
commandBuffer); writeSubresource, commandBuffer);
return angle::Result::Continue; return angle::Result::Continue;
} }
......
...@@ -140,6 +140,20 @@ vk::ImageHelper *RenderTargetVk::getImageForRead(vk::CommandGraphResource *readi ...@@ -140,6 +140,20 @@ vk::ImageHelper *RenderTargetVk::getImageForRead(vk::CommandGraphResource *readi
ASSERT(mImage && mImage->valid()); ASSERT(mImage && mImage->valid());
// TODO(jmadill): Better simultaneous resource access. http://anglebug.com/2679 // TODO(jmadill): Better simultaneous resource access. http://anglebug.com/2679
//
// A better alternative would be:
//
// if (mImage->isLayoutChangeNecessary(layout)
// {
// vk::CommandBuffer *srcLayoutChange;
// ANGLE_TRY(mImage->recordCommands(contextVk, &srcLayoutChange));
// mImage->changeLayout(mImage->getAspectFlags(), layout, srcLayoutChange);
// }
// mImage->addReadDependency(readingResource);
//
// I.e. the transition should happen on a node generated from mImage itself.
// However, this needs context to be available here, or all call sites changed
// to perform the layout transition and set the dependency.
mImage->addWriteDependency(readingResource); mImage->addWriteDependency(readingResource);
mImage->changeLayout(mImage->getAspectFlags(), layout, commandBuffer); mImage->changeLayout(mImage->getAspectFlags(), layout, commandBuffer);
......
...@@ -207,6 +207,14 @@ class TextureVk : public TextureImpl ...@@ -207,6 +207,14 @@ class TextureVk : public TextureImpl
bool unpackUnmultiplyAlpha, bool unpackUnmultiplyAlpha,
TextureVk *source); TextureVk *source);
angle::Result copySubImageImplWithTransfer(ContextVk *contextVk,
const gl::ImageIndex &index,
const gl::Offset &destOffset,
const vk::Format &destFormat,
size_t sourceLevel,
const gl::Rectangle &sourceArea,
vk::ImageHelper *srcImage);
angle::Result copySubImageImplWithDraw(ContextVk *contextVk, angle::Result copySubImageImplWithDraw(ContextVk *contextVk,
const gl::ImageIndex &index, const gl::ImageIndex &index,
const gl::Offset &destOffset, const gl::Offset &destOffset,
......
...@@ -1401,12 +1401,12 @@ void ImageHelper::init2DWeakReference(VkImage handle, ...@@ -1401,12 +1401,12 @@ void ImageHelper::init2DWeakReference(VkImage handle,
{ {
ASSERT(!valid()); ASSERT(!valid());
mExtents = extents; mExtents = extents;
mFormat = &format; mFormat = &format;
mSamples = samples; mSamples = samples;
mCurrentLayout = ImageLayout::Undefined; mCurrentLayout = ImageLayout::Undefined;
mLayerCount = 1; mLayerCount = 1;
mLevelCount = 1; mLevelCount = 1;
mImage.setHandle(handle); mImage.setHandle(handle);
} }
...@@ -1607,32 +1607,27 @@ void ImageHelper::Copy(ImageHelper *srcImage, ...@@ -1607,32 +1607,27 @@ void ImageHelper::Copy(ImageHelper *srcImage,
const gl::Offset &srcOffset, const gl::Offset &srcOffset,
const gl::Offset &dstOffset, const gl::Offset &dstOffset,
const gl::Extents &copySize, const gl::Extents &copySize,
VkImageAspectFlags aspectMask, const VkImageSubresourceLayers &srcSubresource,
const VkImageSubresourceLayers &dstSubresource,
CommandBuffer *commandBuffer) CommandBuffer *commandBuffer)
{ {
ASSERT(commandBuffer->valid() && srcImage->valid() && dstImage->valid()); ASSERT(commandBuffer->valid() && srcImage->valid() && dstImage->valid());
srcImage->changeLayout(srcImage->getAspectFlags(), ImageLayout::TransferSrc, commandBuffer); ASSERT(srcImage->getCurrentLayout() == VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
dstImage->changeLayout(dstImage->getAspectFlags(), ImageLayout::TransferDst, commandBuffer); ASSERT(dstImage->getCurrentLayout() == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
VkImageCopy region = {}; VkImageCopy region = {};
region.srcSubresource.aspectMask = aspectMask; region.srcSubresource = srcSubresource;
region.srcSubresource.mipLevel = 0; region.srcOffset.x = srcOffset.x;
region.srcSubresource.baseArrayLayer = 0; region.srcOffset.y = srcOffset.y;
region.srcSubresource.layerCount = 1; region.srcOffset.z = srcOffset.z;
region.srcOffset.x = srcOffset.x; region.dstSubresource = dstSubresource;
region.srcOffset.y = srcOffset.y; region.dstOffset.x = dstOffset.x;
region.srcOffset.z = srcOffset.z; region.dstOffset.y = dstOffset.y;
region.dstSubresource.aspectMask = aspectMask; region.dstOffset.z = dstOffset.z;
region.dstSubresource.mipLevel = 0; region.extent.width = copySize.width;
region.dstSubresource.baseArrayLayer = 0; region.extent.height = copySize.height;
region.dstSubresource.layerCount = 1; region.extent.depth = copySize.depth;
region.dstOffset.x = dstOffset.x;
region.dstOffset.y = dstOffset.y;
region.dstOffset.z = dstOffset.z;
region.extent.width = copySize.width;
region.extent.height = copySize.height;
region.extent.depth = copySize.depth;
commandBuffer->copyImage(srcImage->getImage(), srcImage->getCurrentLayout(), commandBuffer->copyImage(srcImage->getImage(), srcImage->getCurrentLayout(),
dstImage->getImage(), dstImage->getCurrentLayout(), 1, &region); dstImage->getImage(), dstImage->getCurrentLayout(), 1, &region);
......
...@@ -614,7 +614,8 @@ class ImageHelper final : public CommandGraphResource ...@@ -614,7 +614,8 @@ class ImageHelper final : public CommandGraphResource
const gl::Offset &srcOffset, const gl::Offset &srcOffset,
const gl::Offset &dstOffset, const gl::Offset &dstOffset,
const gl::Extents &copySize, const gl::Extents &copySize,
VkImageAspectFlags aspectMask, const VkImageSubresourceLayers &srcSubresources,
const VkImageSubresourceLayers &dstSubresources,
CommandBuffer *commandBuffer); CommandBuffer *commandBuffer);
angle::Result generateMipmapsWithBlit(ContextVk *contextVk, GLuint maxLevel); angle::Result generateMipmapsWithBlit(ContextVk *contextVk, GLuint maxLevel);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment