No border for compressed cube images
Cube images currently have a 1 pixel border around them for seamless
cubemaps. To add a border around a compressed image would require
adding an entire block's width/height around the image at each mip
level, which would take a lot of extra space and wouldn't be so
useful right now, since we'll perform both image decompression and
cubemap border update before sampling, so might as well do both at
the same time and only store a border in the decompressed image,
so that compressed cube images don't need to keep a border.
Bug b/119620767
Tests: dEQP-VK.pipeline.sampler.view_type.cube.format.*
Change-Id: I17974c0148fded37bca7c17a78d08d5e683a2afb
Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/28548
Tested-by: Alexis Hétu <sugoi@google.com>
Presubmit-Ready: Alexis Hétu <sugoi@google.com>
Kokoro-Presubmit: kokoro <noreply+kokoro@google.com>
Reviewed-by: Nicolas Capens <nicolascapens@google.com>
diff --git a/src/Vulkan/VkImage.cpp b/src/Vulkan/VkImage.cpp
index 06413e6..ba7cdad 100644
--- a/src/Vulkan/VkImage.cpp
+++ b/src/Vulkan/VkImage.cpp
@@ -431,13 +431,20 @@
return adjustedExtent;
}
+int Image::borderSize(VkImageAspectFlagBits aspect) const
+{
+ // We won't add a border to compressed cube textures, we'll add it when we decompress the texture
+ return (isCube() && !format.isCompressed()) ? 1 : 0;
+}
+
VkDeviceSize Image::texelOffsetBytesInStorage(const VkOffset3D& offset, const VkImageSubresourceLayers& subresource) const
{
VkImageAspectFlagBits aspect = static_cast<VkImageAspectFlagBits>(subresource.aspectMask);
VkOffset3D adjustedOffset = imageOffsetInBlocks(offset, aspect);
+ int border = borderSize(aspect);
return adjustedOffset.z * slicePitchBytes(aspect, subresource.mipLevel) +
- (adjustedOffset.y + (isCube() ? 1 : 0)) * rowPitchBytes(aspect, subresource.mipLevel) +
- (adjustedOffset.x + (isCube() ? 1 : 0)) * getFormat(aspect).bytesPerBlock();
+ (adjustedOffset.y + border) * rowPitchBytes(aspect, subresource.mipLevel) +
+ (adjustedOffset.x + border) * getFormat(aspect).bytesPerBlock();
}
VkExtent3D Image::getMipLevelExtent(uint32_t mipLevel) const
@@ -467,7 +474,7 @@
// Depth and Stencil pitch should be computed separately
ASSERT((aspect & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) !=
(VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT));
- return getFormat(aspect).pitchB(getMipLevelExtent(mipLevel).width, isCube() ? 1 : 0, true);
+ return getFormat(aspect).pitchB(getMipLevelExtent(mipLevel).width, borderSize(aspect), true);
}
int Image::slicePitchBytes(VkImageAspectFlagBits aspect, uint32_t mipLevel) const
@@ -482,7 +489,7 @@
sw::align(mipLevelExtent.width, usedFormat.blockWidth());
sw::align(mipLevelExtent.height, usedFormat.blockHeight());
}
- return getFormat(aspect).sliceB(mipLevelExtent.width, mipLevelExtent.height, isCube() ? 1 : 0, true);
+ return getFormat(aspect).sliceB(mipLevelExtent.width, mipLevelExtent.height, borderSize(aspect), true);
}
int Image::bytesPerTexel(VkImageAspectFlagBits aspect) const
diff --git a/src/Vulkan/VkImage.hpp b/src/Vulkan/VkImage.hpp
index 2d77e85..f9af23f 100644
--- a/src/Vulkan/VkImage.hpp
+++ b/src/Vulkan/VkImage.hpp
@@ -83,6 +83,7 @@
int bytesPerTexel(VkImageAspectFlagBits flags) const;
VkFormat getClearFormat() const;
void clear(void* pixelData, VkFormat format, const VkImageSubresourceRange& subresourceRange, const VkRect2D& renderArea);
+ int borderSize(VkImageAspectFlagBits aspect) const;
const Device *const device = nullptr;
DeviceMemory* deviceMemory = nullptr;