Allow ImageView to cast compressed texture into other formats If an image is created with flags including the VK_IMAGE_CREATE_BLOCK_TEXEL_VIEW_COMPATIBLE_BIT bit, then the compressed image may be used with an image view which has an uncompressed format that is size-compatible with the image's compressed format. Tests: dEQP-VK.image.texel_view_compatible.*.texture_read.e* Bug b/119620767 Change-Id: Ia1af959780af12e9014f7852aaf991d313f75bf1 Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/31620 Tested-by: Alexis Hétu <sugoi@google.com> Presubmit-Ready: Alexis Hétu <sugoi@google.com> Reviewed-by: Nicolas Capens <nicolascapens@google.com> Kokoro-Presubmit: kokoro <noreply+kokoro@google.com>
diff --git a/src/Vulkan/VkImage.cpp b/src/Vulkan/VkImage.cpp index 9ac5ea6..cf44d68 100644 --- a/src/Vulkan/VkImage.cpp +++ b/src/Vulkan/VkImage.cpp
@@ -706,6 +706,21 @@ return arrayLayers * getLayerSize(static_cast<VkImageAspectFlagBits>(aspectMask)); } +const Image* Image::getSampledImage(const vk::Format& imageViewFormat) const +{ + bool isImageViewCompressed = imageViewFormat.isCompressed(); + if(decompressedImage && !isImageViewCompressed) + { + ASSERT(flags & VK_IMAGE_CREATE_BLOCK_TEXEL_VIEW_COMPATIBLE_BIT); + ASSERT(format.bytesPerBlock() == imageViewFormat.bytesPerBlock()); + } + // If the ImageView's format is compressed, then we do need to decompress the image so that + // it may be sampled properly by texture sampling functions, which don't support compressed + // textures. If the ImageView's format is NOT compressed, then we reinterpret cast the + // compressed image into the ImageView's format, so we must return the compressed image as is. + return (decompressedImage && isImageViewCompressed) ? decompressedImage : this; +} + void Image::blit(VkImage dstImage, const VkImageBlit& region, VkFilter filter) { device->getBlitter()->blit(this, Cast(dstImage), region, filter);
diff --git a/src/Vulkan/VkImage.hpp b/src/Vulkan/VkImage.hpp index 86dae4c..b44332e 100644 --- a/src/Vulkan/VkImage.hpp +++ b/src/Vulkan/VkImage.hpp
@@ -71,7 +71,7 @@ VkDeviceSize getLayerSize(VkImageAspectFlagBits aspect) const; void prepareForSampling(const VkImageSubresourceRange& subresourceRange); - const Image* getSampledImage() const { return decompressedImage ? decompressedImage : this; } + const Image* getSampledImage(const vk::Format& imageViewFormat) const; static Format GetFormat(const vk::Format& format, VkImageAspectFlagBits aspect);
diff --git a/src/Vulkan/VkImageView.cpp b/src/Vulkan/VkImageView.cpp index 1cdad2b..512743c 100644 --- a/src/Vulkan/VkImageView.cpp +++ b/src/Vulkan/VkImageView.cpp
@@ -192,7 +192,7 @@ case RAW: return image; case SAMPLING: - return image->getSampledImage(); + return image->getSampledImage(format); default: UNIMPLEMENTED("usage %d", int(usage)); return nullptr;