Commit 2aace0d7 by Nicolas Capens Committed by Nicolas Capens

Fix copying of multisample images

Multisample images can be copied to other multisample images with the same number of samples, without undergoing multisample resolve. We were using the Blitter::copy() code path both for vkCmdCopyImage and attachment resolve operations at the end of subpasses, leading to resolve operations happening on copy commands. They are now detangled and copy() is able to handle multiple samples the same way as 3D slices. Bug: b/159210008 Change-Id: I4c285ca7ca58e9f8c6cf7bd942041e038b042cb9 Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/46129 Presubmit-Ready: Nicolas Capens <nicolascapens@google.com> Tested-by: 's avatarNicolas Capens <nicolascapens@google.com> Kokoro-Result: kokoro <noreply+kokoro@google.com> Reviewed-by: 's avatarAntonio Maiorano <amaiorano@google.com>
parent c55fd97b
...@@ -322,28 +322,9 @@ void Image::copyTo(Image *dstImage, const VkImageCopy &region) const ...@@ -322,28 +322,9 @@ void Image::copyTo(Image *dstImage, const VkImageCopy &region) const
Format srcFormat = getFormat(srcAspect); Format srcFormat = getFormat(srcAspect);
Format dstFormat = dstImage->getFormat(dstAspect); Format dstFormat = dstImage->getFormat(dstAspect);
if((samples > VK_SAMPLE_COUNT_1_BIT) && (imageType == VK_IMAGE_TYPE_2D) && !format.isUnnormalizedInteger())
{
// Requires multisampling resolve
VkImageBlit blitRegion;
blitRegion.srcSubresource = region.srcSubresource;
blitRegion.srcOffsets[0] = region.srcOffset;
blitRegion.srcOffsets[1].x = blitRegion.srcOffsets[0].x + region.extent.width;
blitRegion.srcOffsets[1].y = blitRegion.srcOffsets[0].y + region.extent.height;
blitRegion.srcOffsets[1].z = blitRegion.srcOffsets[0].z + region.extent.depth;
blitRegion.dstSubresource = region.dstSubresource;
blitRegion.dstOffsets[0] = region.dstOffset;
blitRegion.dstOffsets[1].x = blitRegion.dstOffsets[0].x + region.extent.width;
blitRegion.dstOffsets[1].y = blitRegion.dstOffsets[0].y + region.extent.height;
blitRegion.dstOffsets[1].z = blitRegion.dstOffsets[0].z + region.extent.depth;
return device->getBlitter()->blit(this, dstImage, blitRegion, VK_FILTER_NEAREST);
}
int bytesPerBlock = srcFormat.bytesPerBlock(); int bytesPerBlock = srcFormat.bytesPerBlock();
ASSERT(bytesPerBlock == dstFormat.bytesPerBlock()); ASSERT(bytesPerBlock == dstFormat.bytesPerBlock());
ASSERT(samples == dstImage->samples);
const uint8_t *srcMem = static_cast<const uint8_t *>(getTexelPointer(region.srcOffset, { region.srcSubresource.aspectMask, region.srcSubresource.mipLevel, region.srcSubresource.baseArrayLayer })); const uint8_t *srcMem = static_cast<const uint8_t *>(getTexelPointer(region.srcOffset, { region.srcSubresource.aspectMask, region.srcSubresource.mipLevel, region.srcSubresource.baseArrayLayer }));
uint8_t *dstMem = static_cast<uint8_t *>(dstImage->getTexelPointer(region.dstOffset, { region.dstSubresource.aspectMask, region.dstSubresource.mipLevel, region.dstSubresource.baseArrayLayer })); uint8_t *dstMem = static_cast<uint8_t *>(dstImage->getTexelPointer(region.dstOffset, { region.dstSubresource.aspectMask, region.dstSubresource.mipLevel, region.dstSubresource.baseArrayLayer }));
...@@ -357,7 +338,11 @@ void Image::copyTo(Image *dstImage, const VkImageCopy &region) const ...@@ -357,7 +338,11 @@ void Image::copyTo(Image *dstImage, const VkImageCopy &region) const
VkExtent3D dstExtent = dstImage->getMipLevelExtent(dstAspect, region.dstSubresource.mipLevel); VkExtent3D dstExtent = dstImage->getMipLevelExtent(dstAspect, region.dstSubresource.mipLevel);
VkExtent3D copyExtent = imageExtentInBlocks(region.extent, srcAspect); VkExtent3D copyExtent = imageExtentInBlocks(region.extent, srcAspect);
bool isSingleSlice = (copyExtent.depth == 1); // Multisample images are currently implemented similar to 3D images by storing one sample per slice.
// TODO(b/160600347): Store samples consecutively.
uint32_t sliceCount = copyExtent.depth * samples;
bool isSingleSlice = (sliceCount == 1);
bool isSingleLine = (copyExtent.height == 1) && isSingleSlice; bool isSingleLine = (copyExtent.height == 1) && isSingleSlice;
// In order to copy multiple lines using a single memcpy call, we // In order to copy multiple lines using a single memcpy call, we
// have to make sure that we need to copy the entire line and that // have to make sure that we need to copy the entire line and that
...@@ -397,7 +382,7 @@ void Image::copyTo(Image *dstImage, const VkImageCopy &region) const ...@@ -397,7 +382,7 @@ void Image::copyTo(Image *dstImage, const VkImageCopy &region) const
} }
else if(isEntireSlice) // Copy multiple slices else if(isEntireSlice) // Copy multiple slices
{ {
size_t copySize = copyExtent.depth * srcSlicePitchBytes; size_t copySize = sliceCount * srcSlicePitchBytes;
ASSERT((srcMem + copySize) < end()); ASSERT((srcMem + copySize) < end());
ASSERT((dstMem + copySize) < dstImage->end()); ASSERT((dstMem + copySize) < dstImage->end());
memcpy(dstMem, srcMem, copySize); memcpy(dstMem, srcMem, copySize);
...@@ -406,7 +391,7 @@ void Image::copyTo(Image *dstImage, const VkImageCopy &region) const ...@@ -406,7 +391,7 @@ void Image::copyTo(Image *dstImage, const VkImageCopy &region) const
{ {
size_t copySize = copyExtent.height * srcRowPitchBytes; size_t copySize = copyExtent.height * srcRowPitchBytes;
for(uint32_t z = 0; z < copyExtent.depth; z++, dstMem += dstSlicePitchBytes, srcMem += srcSlicePitchBytes) for(uint32_t z = 0; z < sliceCount; z++, dstMem += dstSlicePitchBytes, srcMem += srcSlicePitchBytes)
{ {
ASSERT((srcMem + copySize) < end()); ASSERT((srcMem + copySize) < end());
ASSERT((dstMem + copySize) < dstImage->end()); ASSERT((dstMem + copySize) < dstImage->end());
...@@ -417,7 +402,7 @@ void Image::copyTo(Image *dstImage, const VkImageCopy &region) const ...@@ -417,7 +402,7 @@ void Image::copyTo(Image *dstImage, const VkImageCopy &region) const
{ {
size_t copySize = copyExtent.width * bytesPerBlock; size_t copySize = copyExtent.width * bytesPerBlock;
for(uint32_t z = 0; z < copyExtent.depth; z++, dstMem += dstSlicePitchBytes, srcMem += srcSlicePitchBytes) for(uint32_t z = 0; z < sliceCount; z++, dstMem += dstSlicePitchBytes, srcMem += srcSlicePitchBytes)
{ {
const uint8_t *srcSlice = srcMem; const uint8_t *srcSlice = srcMem;
uint8_t *dstSlice = dstMem; uint8_t *dstSlice = dstMem;
...@@ -458,6 +443,7 @@ void Image::copy(Buffer *buffer, const VkBufferImageCopy &region, bool bufferIsS ...@@ -458,6 +443,7 @@ void Image::copy(Buffer *buffer, const VkBufferImageCopy &region, bool bufferIsS
int bytesPerBlock = copyFormat.bytesPerBlock(); int bytesPerBlock = copyFormat.bytesPerBlock();
int bufferRowPitchBytes = bufferExtent.width * bytesPerBlock; int bufferRowPitchBytes = bufferExtent.width * bytesPerBlock;
int bufferSlicePitchBytes = bufferExtent.height * bufferRowPitchBytes; int bufferSlicePitchBytes = bufferExtent.height * bufferRowPitchBytes;
ASSERT(samples == 1);
uint8_t *bufferMemory = static_cast<uint8_t *>(buffer->getOffsetPointer(region.bufferOffset)); uint8_t *bufferMemory = static_cast<uint8_t *>(buffer->getOffsetPointer(region.bufferOffset));
uint8_t *imageMemory = static_cast<uint8_t *>(getTexelPointer(region.imageOffset, { region.imageSubresource.aspectMask, region.imageSubresource.mipLevel, region.imageSubresource.baseArrayLayer })); uint8_t *imageMemory = static_cast<uint8_t *>(getTexelPointer(region.imageOffset, { region.imageSubresource.aspectMask, region.imageSubresource.mipLevel, region.imageSubresource.baseArrayLayer }));
......
...@@ -181,7 +181,7 @@ void ImageView::resolve(ImageView *resolveAttachment, int layer) ...@@ -181,7 +181,7 @@ void ImageView::resolve(ImageView *resolveAttachment, int layer)
UNIMPLEMENTED("b/148242443: levelCount != 1"); // FIXME(b/148242443) UNIMPLEMENTED("b/148242443: levelCount != 1"); // FIXME(b/148242443)
} }
VkImageCopy region; VkImageResolve region;
region.srcSubresource = { region.srcSubresource = {
subresourceRange.aspectMask, subresourceRange.aspectMask,
subresourceRange.baseMipLevel, subresourceRange.baseMipLevel,
...@@ -199,7 +199,7 @@ void ImageView::resolve(ImageView *resolveAttachment, int layer) ...@@ -199,7 +199,7 @@ void ImageView::resolve(ImageView *resolveAttachment, int layer)
region.extent = image->getMipLevelExtent(static_cast<VkImageAspectFlagBits>(subresourceRange.aspectMask), region.extent = image->getMipLevelExtent(static_cast<VkImageAspectFlagBits>(subresourceRange.aspectMask),
subresourceRange.baseMipLevel); subresourceRange.baseMipLevel);
image->copyTo(resolveAttachment->image, region); image->resolveTo(resolveAttachment->image, region);
} }
void ImageView::resolve(ImageView *resolveAttachment) void ImageView::resolve(ImageView *resolveAttachment)
...@@ -209,7 +209,7 @@ void ImageView::resolve(ImageView *resolveAttachment) ...@@ -209,7 +209,7 @@ void ImageView::resolve(ImageView *resolveAttachment)
UNIMPLEMENTED("b/148242443: levelCount != 1"); // FIXME(b/148242443) UNIMPLEMENTED("b/148242443: levelCount != 1"); // FIXME(b/148242443)
} }
VkImageCopy region; VkImageResolve region;
region.srcSubresource = { region.srcSubresource = {
subresourceRange.aspectMask, subresourceRange.aspectMask,
subresourceRange.baseMipLevel, subresourceRange.baseMipLevel,
...@@ -227,7 +227,7 @@ void ImageView::resolve(ImageView *resolveAttachment) ...@@ -227,7 +227,7 @@ void ImageView::resolve(ImageView *resolveAttachment)
region.extent = image->getMipLevelExtent(static_cast<VkImageAspectFlagBits>(subresourceRange.aspectMask), region.extent = image->getMipLevelExtent(static_cast<VkImageAspectFlagBits>(subresourceRange.aspectMask),
subresourceRange.baseMipLevel); subresourceRange.baseMipLevel);
image->copyTo(resolveAttachment->image, region); image->resolveTo(resolveAttachment->image, region);
} }
void ImageView::resolveWithLayerMask(ImageView *resolveAttachment, uint32_t layerMask) void ImageView::resolveWithLayerMask(ImageView *resolveAttachment, uint32_t layerMask)
......
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