Vulkan: Texture 3D and 2DArray layers as framebuffer attachments
Support glFramebufferTextureLayer by correctly handling layers
from 3D and 2DArray textures. Modeled after CubeMap layers support.
Bug: angleproject:3188
Bug: angleproject:3189
Change-Id: Ic73a6017134e9d2b49beed103487454397a97167
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/1738436
Reviewed-by: Tim Van Patten <timvp@google.com>
Commit-Queue: Cody Northrop <cnorthrop@google.com>
diff --git a/src/libANGLE/renderer/vulkan/FramebufferVk.cpp b/src/libANGLE/renderer/vulkan/FramebufferVk.cpp
index eee1d58..dae582c 100644
--- a/src/libANGLE/renderer/vulkan/FramebufferVk.cpp
+++ b/src/libANGLE/renderer/vulkan/FramebufferVk.cpp
@@ -1439,9 +1439,23 @@
size_t level = renderTarget->getLevelIndex();
size_t layer = renderTarget->getLayerIndex();
VkOffset3D srcOffset = {area.x, area.y, 0};
+
+ VkImageSubresourceLayers srcSubresource = {};
+ srcSubresource.aspectMask = copyAspectFlags;
+ srcSubresource.mipLevel = level;
+ srcSubresource.baseArrayLayer = layer;
+ srcSubresource.layerCount = 1;
+
VkExtent3D srcExtent = {static_cast<uint32_t>(area.width), static_cast<uint32_t>(area.height),
1};
+ if (srcImage->getExtents().depth > 1)
+ {
+ // Depth > 1 means this is a 3D texture and we need special handling
+ srcOffset.z = layer;
+ srcSubresource.baseArrayLayer = 0;
+ }
+
// If the source image is multisampled, we need to resolve it into a temporary image before
// performing a readback.
bool isMultisampled = srcImage->getSamples() > 1;
@@ -1461,10 +1475,7 @@
ASSERT(copyAspectFlags == VK_IMAGE_ASPECT_COLOR_BIT);
VkImageResolve resolveRegion = {};
- resolveRegion.srcSubresource.aspectMask = copyAspectFlags;
- resolveRegion.srcSubresource.mipLevel = level;
- resolveRegion.srcSubresource.baseArrayLayer = layer;
- resolveRegion.srcSubresource.layerCount = 1;
+ resolveRegion.srcSubresource = srcSubresource;
resolveRegion.srcOffset = srcOffset;
resolveRegion.dstSubresource.aspectMask = copyAspectFlags;
resolveRegion.dstSubresource.mipLevel = 0;
@@ -1483,6 +1494,9 @@
level = 0;
layer = 0;
srcOffset = {0, 0, 0};
+ srcSubresource.baseArrayLayer = 0;
+ srcSubresource.layerCount = 1;
+ srcSubresource.mipLevel = 0;
}
VkBuffer bufferHandle = VK_NULL_HANDLE;
@@ -1493,16 +1507,13 @@
ANGLE_TRY(mReadPixelBuffer.allocate(contextVk, allocationSize, &readPixelBuffer, &bufferHandle,
&stagingOffset, nullptr));
- VkBufferImageCopy region = {};
- region.bufferImageHeight = srcExtent.height;
- region.bufferOffset = stagingOffset;
- region.bufferRowLength = srcExtent.width;
- region.imageExtent = srcExtent;
- region.imageOffset = srcOffset;
- region.imageSubresource.aspectMask = copyAspectFlags;
- region.imageSubresource.baseArrayLayer = layer;
- region.imageSubresource.layerCount = 1;
- region.imageSubresource.mipLevel = level;
+ VkBufferImageCopy region = {};
+ region.bufferImageHeight = srcExtent.height;
+ region.bufferOffset = stagingOffset;
+ region.bufferRowLength = srcExtent.width;
+ region.imageExtent = srcExtent;
+ region.imageOffset = srcOffset;
+ region.imageSubresource = srcSubresource;
commandBuffer->copyImageToBuffer(srcImage->getImage(), srcImage->getCurrentLayout(),
bufferHandle, 1, ®ion);