Commit 64ed1218 by Nicolas Capens Committed by Nicolas Capens

Make multisample resolve a Blitter method

The Vulkan spec explicitly states that "vkCmdBlitImage must not be used for multisampled source or destination images. Use vkCmdResolveImage for this purpose." And the only other way to obtain resolve multisample results is by using resolve attachments as part of a subpass. This split between blit operations and resolve operations should be reflected by the Blitter interface so we have less confusion about its blit() method being used to perform resolves. It will also facilitate adding a fast path for common resolve operations. Bug: b/147802090 Change-Id: I2549a5e7acd7ef9ec3f70f8ceb88ff5fc65a0d17 Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/47988 Presubmit-Ready: Nicolas Capens <nicolascapens@google.com> Kokoro-Result: kokoro <noreply+kokoro@google.com> Tested-by: 's avatarNicolas Capens <nicolascapens@google.com> Reviewed-by: 's avatarAlexis Hétu <sugoi@google.com>
parent 2014e7b9
......@@ -1741,31 +1741,10 @@ Blitter::CornerUpdateRoutineType Blitter::getCornerUpdateRoutine(const State &st
return cornerUpdateRoutine;
}
void Blitter::copy(const vk::Image *src, uint8_t *dst, unsigned int dstPitch)
{
const VkExtent3D &extent = src->getExtent();
size_t rowBytes = src->getFormat(VK_IMAGE_ASPECT_COLOR_BIT).bytes() * extent.width;
unsigned int srcPitch = src->rowPitchBytes(VK_IMAGE_ASPECT_COLOR_BIT, 0);
ASSERT(dstPitch >= rowBytes && srcPitch >= rowBytes);
const uint8_t *s = (uint8_t *)src->getTexelPointer({ 0, 0, 0 }, { VK_IMAGE_ASPECT_COLOR_BIT, 0, 0 });
uint8_t *d = dst;
for(uint32_t y = 0; y < extent.height; y++)
{
memcpy(d, s, rowBytes);
s += srcPitch;
d += dstPitch;
}
}
void Blitter::blit(const vk::Image *src, vk::Image *dst, VkImageBlit region, VkFilter filter)
{
if(dst->getFormat() == VK_FORMAT_UNDEFINED)
{
return;
}
ASSERT(src->getFormat() != VK_FORMAT_UNDEFINED);
ASSERT(dst->getFormat() != VK_FORMAT_UNDEFINED);
// Vulkan 1.2 section 18.5. Image Copies with Scaling:
// "The layerCount member of srcSubresource and dstSubresource must match"
......@@ -1874,7 +1853,7 @@ void Blitter::blit(const vk::Image *src, vk::Image *dst, VkImageBlit region, VkF
VkImageSubresourceRange dstSubresRange = {
region.dstSubresource.aspectMask,
region.dstSubresource.mipLevel,
1,
1, // levelCount
region.dstSubresource.baseArrayLayer,
region.dstSubresource.layerCount
};
......@@ -1895,6 +1874,45 @@ void Blitter::blit(const vk::Image *src, vk::Image *dst, VkImageBlit region, VkF
dst->contentsChanged(dstSubresRange);
}
void Blitter::resolve(const vk::Image *src, vk::Image *dst, VkImageResolve region)
{
VkImageBlit blitRegion;
blitRegion.srcOffsets[0] = blitRegion.srcOffsets[1] = region.srcOffset;
blitRegion.srcOffsets[1].x += region.extent.width;
blitRegion.srcOffsets[1].y += region.extent.height;
blitRegion.srcOffsets[1].z += region.extent.depth;
blitRegion.dstOffsets[0] = blitRegion.dstOffsets[1] = region.dstOffset;
blitRegion.dstOffsets[1].x += region.extent.width;
blitRegion.dstOffsets[1].y += region.extent.height;
blitRegion.dstOffsets[1].z += region.extent.depth;
blitRegion.srcSubresource = region.srcSubresource;
blitRegion.dstSubresource = region.dstSubresource;
blit(src, dst, blitRegion, VK_FILTER_NEAREST);
}
void Blitter::copy(const vk::Image *src, uint8_t *dst, unsigned int dstPitch)
{
VkExtent3D extent = src->getExtent();
size_t rowBytes = src->getFormat(VK_IMAGE_ASPECT_COLOR_BIT).bytes() * extent.width;
unsigned int srcPitch = src->rowPitchBytes(VK_IMAGE_ASPECT_COLOR_BIT, 0);
ASSERT(dstPitch >= rowBytes && srcPitch >= rowBytes && src->getMipLevelExtent(VK_IMAGE_ASPECT_COLOR_BIT, 0).height >= extent.height);
const uint8_t *s = (uint8_t *)src->getTexelPointer({ 0, 0, 0 }, { VK_IMAGE_ASPECT_COLOR_BIT, 0, 0 });
uint8_t *d = dst;
for(uint32_t y = 0; y < extent.height; y++)
{
memcpy(d, s, rowBytes);
s += srcPitch;
d += dstPitch;
}
}
void Blitter::computeCubeCorner(Pointer<Byte> &layer, Int &x0, Int &x1, Int &y0, Int &y1, Int &pitchB, const State &state)
{
int bytes = state.sourceFormat.bytes();
......
......@@ -144,6 +144,7 @@ public:
void clear(void *clearValue, vk::Format clearFormat, vk::Image *dest, const vk::Format &viewFormat, const VkImageSubresourceRange &subresourceRange, const VkRect2D *renderArea = nullptr);
void blit(const vk::Image *src, vk::Image *dst, VkImageBlit region, VkFilter filter);
void resolve(const vk::Image *src, vk::Image *dst, VkImageResolve region);
void copy(const vk::Image *src, uint8_t *dst, unsigned int dstPitch);
void updateBorders(vk::Image *image, const VkImageSubresource &subresource);
......
......@@ -942,22 +942,7 @@ void Image::copyTo(uint8_t *dst, unsigned int dstPitch) const
void Image::resolveTo(Image *dstImage, const VkImageResolve &region) const
{
VkImageBlit blitRegion;
blitRegion.srcOffsets[0] = blitRegion.srcOffsets[1] = region.srcOffset;
blitRegion.srcOffsets[1].x += region.extent.width;
blitRegion.srcOffsets[1].y += region.extent.height;
blitRegion.srcOffsets[1].z += region.extent.depth;
blitRegion.dstOffsets[0] = blitRegion.dstOffsets[1] = region.dstOffset;
blitRegion.dstOffsets[1].x += region.extent.width;
blitRegion.dstOffsets[1].y += region.extent.height;
blitRegion.dstOffsets[1].z += region.extent.depth;
blitRegion.srcSubresource = region.srcSubresource;
blitRegion.dstSubresource = region.dstSubresource;
device->getBlitter()->blit(this, dstImage, blitRegion, VK_FILTER_NEAREST);
device->getBlitter()->resolve(this, dstImage, region);
}
VkFormat Image::getClearFormat() const
......
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