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
Format srcFormat = getFormat(srcAspect);
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();
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 }));
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
VkExtent3D dstExtent = dstImage->getMipLevelExtent(dstAspect, region.dstSubresource.mipLevel);
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;
// 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
......@@ -397,7 +382,7 @@ void Image::copyTo(Image *dstImage, const VkImageCopy &region) const
}
else if(isEntireSlice) // Copy multiple slices
{
size_t copySize = copyExtent.depth * srcSlicePitchBytes;
size_t copySize = sliceCount * srcSlicePitchBytes;
ASSERT((srcMem + copySize) < end());
ASSERT((dstMem + copySize) < dstImage->end());
memcpy(dstMem, srcMem, copySize);
......@@ -406,7 +391,7 @@ void Image::copyTo(Image *dstImage, const VkImageCopy &region) const
{
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((dstMem + copySize) < dstImage->end());
......@@ -417,7 +402,7 @@ void Image::copyTo(Image *dstImage, const VkImageCopy &region) const
{
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;
uint8_t *dstSlice = dstMem;
......@@ -458,6 +443,7 @@ void Image::copy(Buffer *buffer, const VkBufferImageCopy &region, bool bufferIsS
int bytesPerBlock = copyFormat.bytesPerBlock();
int bufferRowPitchBytes = bufferExtent.width * bytesPerBlock;
int bufferSlicePitchBytes = bufferExtent.height * bufferRowPitchBytes;
ASSERT(samples == 1);
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 }));
......
......@@ -181,7 +181,7 @@ void ImageView::resolve(ImageView *resolveAttachment, int layer)
UNIMPLEMENTED("b/148242443: levelCount != 1"); // FIXME(b/148242443)
}
VkImageCopy region;
VkImageResolve region;
region.srcSubresource = {
subresourceRange.aspectMask,
subresourceRange.baseMipLevel,
......@@ -199,7 +199,7 @@ void ImageView::resolve(ImageView *resolveAttachment, int layer)
region.extent = image->getMipLevelExtent(static_cast<VkImageAspectFlagBits>(subresourceRange.aspectMask),
subresourceRange.baseMipLevel);
image->copyTo(resolveAttachment->image, region);
image->resolveTo(resolveAttachment->image, region);
}
void ImageView::resolve(ImageView *resolveAttachment)
......@@ -209,7 +209,7 @@ void ImageView::resolve(ImageView *resolveAttachment)
UNIMPLEMENTED("b/148242443: levelCount != 1"); // FIXME(b/148242443)
}
VkImageCopy region;
VkImageResolve region;
region.srcSubresource = {
subresourceRange.aspectMask,
subresourceRange.baseMipLevel,
......@@ -227,7 +227,7 @@ void ImageView::resolve(ImageView *resolveAttachment)
region.extent = image->getMipLevelExtent(static_cast<VkImageAspectFlagBits>(subresourceRange.aspectMask),
subresourceRange.baseMipLevel);
image->copyTo(resolveAttachment->image, region);
image->resolveTo(resolveAttachment->image, region);
}
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