Commit 68fcfea3 by Tim Van Patten Committed by Commit Bot

Vulkan: support format aliasing in texture images

glBindImageTexture specifies the format which should be used to interpret the texture data and this format is independent from the texture's own internal format. This change allows the VkImage's format to be mutable to handle glBindImageTexture calls with different formats. Bug: angleproject:3885 Test: dEQP-GLES31.functional.image_load_store.*.format_reinterpret.* Change-Id: Ia1ad762b4ccae0f510c8b4918781234fcf51c5f1 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2222610Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarShahbaz Youssefi <syoussefi@chromium.org> Commit-Queue: Tim Van Patten <timvp@google.com>
parent 33c28e35
...@@ -1109,8 +1109,7 @@ angle::Result ProgramExecutableVk::updateImagesDescriptorSet( ...@@ -1109,8 +1109,7 @@ angle::Result ProgramExecutableVk::updateImagesDescriptorSet(
vk::ImageHelper *image = &textureVk->getImage(); vk::ImageHelper *image = &textureVk->getImage();
const vk::ImageView *imageView = nullptr; const vk::ImageView *imageView = nullptr;
ANGLE_TRY(textureVk->getStorageImageView(contextVk, (binding.layered == GL_TRUE), ANGLE_TRY(textureVk->getStorageImageView(contextVk, binding, &imageView));
binding.level, binding.layer, &imageView));
// Note: binding.access is unused because it is implied by the shader. // Note: binding.access is unused because it is implied by the shader.
......
...@@ -1632,6 +1632,8 @@ angle::Result TextureVk::syncState(const gl::Context *context, ...@@ -1632,6 +1632,8 @@ angle::Result TextureVk::syncState(const gl::Context *context,
// Create a new image if the storage state is enabled for the first time. // Create a new image if the storage state is enabled for the first time.
if (dirtyBits.test(gl::Texture::DIRTY_BIT_BOUND_AS_IMAGE)) if (dirtyBits.test(gl::Texture::DIRTY_BIT_BOUND_AS_IMAGE))
{ {
mImageCreateFlags |= VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT;
// Recreate the image to include storage bit if needed. // Recreate the image to include storage bit if needed.
if (!(mImageUsageFlags & VK_IMAGE_USAGE_STORAGE_BIT)) if (!(mImageUsageFlags & VK_IMAGE_USAGE_STORAGE_BIT))
{ {
...@@ -1806,20 +1808,23 @@ angle::Result TextureVk::getLevelLayerImageView(ContextVk *contextVk, ...@@ -1806,20 +1808,23 @@ angle::Result TextureVk::getLevelLayerImageView(ContextVk *contextVk,
} }
angle::Result TextureVk::getStorageImageView(ContextVk *contextVk, angle::Result TextureVk::getStorageImageView(ContextVk *contextVk,
bool allLayers, const gl::ImageUnit &binding,
size_t level,
size_t singleLayer,
const vk::ImageView **imageViewOut) const vk::ImageView **imageViewOut)
{ {
if (!allLayers) angle::FormatID formatID = angle::Format::InternalFormatToID(binding.format);
const vk::Format &format = contextVk->getRenderer()->getFormat(formatID);
if (binding.layered != GL_TRUE)
{ {
return getLevelLayerImageView(contextVk, level, singleLayer, imageViewOut); return getLevelLayerImageView(contextVk, binding.level, binding.layer, imageViewOut);
} }
uint32_t nativeLevel = getNativeImageLevel(static_cast<uint32_t>(level)); uint32_t nativeLevel = getNativeImageLevel(static_cast<uint32_t>(binding.level));
uint32_t nativeLayer = getNativeImageLayer(0); uint32_t nativeLayer = getNativeImageLayer(0);
return mImageViews.getLevelDrawImageView(contextVk, mState.getType(), *mImage, nativeLevel, return mImageViews.getLevelDrawImageView(
nativeLayer, imageViewOut); contextVk, mState.getType(), *mImage, nativeLevel, nativeLayer,
VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_STORAGE_BIT, format.vkImageFormat,
imageViewOut);
} }
angle::Result TextureVk::initImage(ContextVk *contextVk, angle::Result TextureVk::initImage(ContextVk *contextVk,
...@@ -1870,9 +1875,9 @@ angle::Result TextureVk::initImageViews(ContextVk *contextVk, ...@@ -1870,9 +1875,9 @@ angle::Result TextureVk::initImageViews(ContextVk *contextVk,
if ((mImageCreateFlags & VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT) != 0) if ((mImageCreateFlags & VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT) != 0)
{ {
ANGLE_TRY(mImageViews.initSRGBReadViews(contextVk, mState.getType(), *mImage, format, ANGLE_TRY(mImageViews.initSRGBReadViews(
formatSwizzle, readSwizzle, baseLevel, levelCount, contextVk, mState.getType(), *mImage, format, formatSwizzle, readSwizzle, baseLevel,
baseLayer, layerCount)); levelCount, baseLayer, layerCount, mImageUsageFlags & ~VK_IMAGE_USAGE_STORAGE_BIT));
} }
return angle::Result::Continue; return angle::Result::Continue;
......
...@@ -178,9 +178,7 @@ class TextureVk : public TextureImpl, public angle::ObserverInterface ...@@ -178,9 +178,7 @@ class TextureVk : public TextureImpl, public angle::ObserverInterface
// A special view used for texture copies that shouldn't perform swizzle. // A special view used for texture copies that shouldn't perform swizzle.
const vk::ImageView &getCopyImageViewAndRecordUse(ContextVk *contextVk) const; const vk::ImageView &getCopyImageViewAndRecordUse(ContextVk *contextVk) const;
angle::Result getStorageImageView(ContextVk *contextVk, angle::Result getStorageImageView(ContextVk *contextVk,
bool allLayers, const gl::ImageUnit &binding,
size_t level,
size_t singleLayer,
const vk::ImageView **imageViewOut); const vk::ImageView **imageViewOut);
const vk::Sampler &getSampler() const const vk::Sampler &getSampler() const
......
...@@ -2711,9 +2711,11 @@ angle::Result ImageHelper::initLayerImageView(Context *context, ...@@ -2711,9 +2711,11 @@ angle::Result ImageHelper::initLayerImageView(Context *context,
{ {
return initLayerImageViewImpl(context, textureType, aspectMask, swizzleMap, imageViewOut, return initLayerImageViewImpl(context, textureType, aspectMask, swizzleMap, imageViewOut,
baseMipLevel, levelCount, baseArrayLayer, layerCount, baseMipLevel, levelCount, baseArrayLayer, layerCount,
mFormat->vkImageFormat); mFormat->vkImageFormat, nullptr);
} }
angle::Result ImageHelper::initLayerImageViewImpl(Context *context,
angle::Result ImageHelper::initLayerImageViewImpl(
Context *context,
gl::TextureType textureType, gl::TextureType textureType,
VkImageAspectFlags aspectMask, VkImageAspectFlags aspectMask,
const gl::SwizzleState &swizzleMap, const gl::SwizzleState &swizzleMap,
...@@ -2722,7 +2724,8 @@ angle::Result ImageHelper::initLayerImageViewImpl(Context *context, ...@@ -2722,7 +2724,8 @@ angle::Result ImageHelper::initLayerImageViewImpl(Context *context,
uint32_t levelCount, uint32_t levelCount,
uint32_t baseArrayLayer, uint32_t baseArrayLayer,
uint32_t layerCount, uint32_t layerCount,
VkFormat imageFormat) const VkFormat imageFormat,
const VkImageViewUsageCreateInfo *imageViewUsageCreateInfo) const
{ {
VkImageViewCreateInfo viewInfo = {}; VkImageViewCreateInfo viewInfo = {};
viewInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; viewInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
...@@ -2752,10 +2755,34 @@ angle::Result ImageHelper::initLayerImageViewImpl(Context *context, ...@@ -2752,10 +2755,34 @@ angle::Result ImageHelper::initLayerImageViewImpl(Context *context,
viewInfo.subresourceRange.baseArrayLayer = baseArrayLayer; viewInfo.subresourceRange.baseArrayLayer = baseArrayLayer;
viewInfo.subresourceRange.layerCount = layerCount; viewInfo.subresourceRange.layerCount = layerCount;
viewInfo.pNext = imageViewUsageCreateInfo;
ANGLE_VK_TRY(context, imageViewOut->init(context->getDevice(), viewInfo)); ANGLE_VK_TRY(context, imageViewOut->init(context->getDevice(), viewInfo));
return angle::Result::Continue; return angle::Result::Continue;
} }
angle::Result ImageHelper::initAliasedLayerImageView(Context *context,
gl::TextureType textureType,
VkImageAspectFlags aspectMask,
const gl::SwizzleState &swizzleMap,
ImageView *imageViewOut,
uint32_t baseMipLevel,
uint32_t levelCount,
uint32_t baseArrayLayer,
uint32_t layerCount,
VkImageUsageFlags imageUsageFlags,
VkFormat imageViewFormat) const
{
VkImageViewUsageCreateInfo imageViewUsageCreateInfo = {};
imageViewUsageCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO;
imageViewUsageCreateInfo.usage =
imageUsageFlags & GetMaximalImageUsageFlags(context->getRenderer(), imageViewFormat);
return initLayerImageViewImpl(context, textureType, aspectMask, swizzleMap, imageViewOut,
baseMipLevel, levelCount, baseArrayLayer, layerCount,
imageViewFormat, &imageViewUsageCreateInfo);
}
void ImageHelper::destroy(RendererVk *renderer) void ImageHelper::destroy(RendererVk *renderer)
{ {
VkDevice device = renderer->getDevice(); VkDevice device = renderer->getDevice();
...@@ -4752,7 +4779,8 @@ angle::Result ImageViewHelper::initSRGBReadViews(ContextVk *contextVk, ...@@ -4752,7 +4779,8 @@ angle::Result ImageViewHelper::initSRGBReadViews(ContextVk *contextVk,
uint32_t baseLevel, uint32_t baseLevel,
uint32_t levelCount, uint32_t levelCount,
uint32_t baseLayer, uint32_t baseLayer,
uint32_t layerCount) uint32_t layerCount,
VkImageUsageFlags imageUsageFlags)
{ {
VkFormat nonLinearOverrideFormat = ConvertToNonLinear(image.getFormat().vkImageFormat); VkFormat nonLinearOverrideFormat = ConvertToNonLinear(image.getFormat().vkImageFormat);
VkFormat linearOverrideFormat = ConvertToLinear(image.getFormat().vkImageFormat); VkFormat linearOverrideFormat = ConvertToLinear(image.getFormat().vkImageFormat);
...@@ -4764,15 +4792,15 @@ angle::Result ImageViewHelper::initSRGBReadViews(ContextVk *contextVk, ...@@ -4764,15 +4792,15 @@ angle::Result ImageViewHelper::initSRGBReadViews(ContextVk *contextVk,
if (!mLinearReadImageView.valid()) if (!mLinearReadImageView.valid())
{ {
ANGLE_TRY(image.initLayerImageViewImpl(contextVk, viewType, aspectFlags, readSwizzle, ANGLE_TRY(image.initAliasedLayerImageView(
&mLinearReadImageView, baseLevel, levelCount, contextVk, viewType, aspectFlags, readSwizzle, &mLinearReadImageView, baseLevel,
baseLayer, layerCount, linearFormat)); levelCount, baseLayer, layerCount, imageUsageFlags, linearFormat));
} }
if (nonLinearOverrideFormat != VK_FORMAT_UNDEFINED && !mNonLinearReadImageView.valid()) if (nonLinearOverrideFormat != VK_FORMAT_UNDEFINED && !mNonLinearReadImageView.valid())
{ {
ANGLE_TRY(image.initLayerImageViewImpl(contextVk, viewType, aspectFlags, readSwizzle, ANGLE_TRY(image.initAliasedLayerImageView(
&mNonLinearReadImageView, baseLevel, levelCount, contextVk, viewType, aspectFlags, readSwizzle, &mNonLinearReadImageView, baseLevel,
baseLayer, layerCount, nonLinearOverrideFormat)); levelCount, baseLayer, layerCount, imageUsageFlags, nonLinearOverrideFormat));
} }
gl::TextureType fetchType = viewType; gl::TextureType fetchType = viewType;
...@@ -4785,29 +4813,30 @@ angle::Result ImageViewHelper::initSRGBReadViews(ContextVk *contextVk, ...@@ -4785,29 +4813,30 @@ angle::Result ImageViewHelper::initSRGBReadViews(ContextVk *contextVk,
if (!mLinearFetchImageView.valid()) if (!mLinearFetchImageView.valid())
{ {
ANGLE_TRY(image.initLayerImageViewImpl(contextVk, fetchType, aspectFlags, readSwizzle, ANGLE_TRY(image.initAliasedLayerImageView(
&mLinearFetchImageView, baseLevel, levelCount, contextVk, fetchType, aspectFlags, readSwizzle, &mLinearFetchImageView, baseLevel,
baseLayer, layerCount, linearFormat)); levelCount, baseLayer, layerCount, imageUsageFlags, linearFormat));
} }
if (nonLinearOverrideFormat != VK_FORMAT_UNDEFINED && !mNonLinearFetchImageView.valid()) if (nonLinearOverrideFormat != VK_FORMAT_UNDEFINED && !mNonLinearFetchImageView.valid())
{ {
ANGLE_TRY(image.initLayerImageViewImpl(contextVk, fetchType, aspectFlags, readSwizzle, ANGLE_TRY(image.initAliasedLayerImageView(contextVk, fetchType, aspectFlags,
&mNonLinearFetchImageView, baseLevel, levelCount, readSwizzle, &mNonLinearFetchImageView,
baseLayer, layerCount, nonLinearOverrideFormat)); baseLevel, levelCount, baseLayer, layerCount,
imageUsageFlags, nonLinearOverrideFormat));
} }
} }
if (!mLinearCopyImageView.valid()) if (!mLinearCopyImageView.valid())
{ {
ANGLE_TRY(image.initLayerImageViewImpl(contextVk, fetchType, aspectFlags, formatSwizzle, ANGLE_TRY(image.initAliasedLayerImageView(
&mLinearCopyImageView, baseLevel, levelCount, contextVk, fetchType, aspectFlags, formatSwizzle, &mLinearCopyImageView, baseLevel,
baseLayer, layerCount, linearFormat)); levelCount, baseLayer, layerCount, imageUsageFlags, linearFormat));
} }
if (nonLinearOverrideFormat != VK_FORMAT_UNDEFINED && !mNonLinearCopyImageView.valid()) if (nonLinearOverrideFormat != VK_FORMAT_UNDEFINED && !mNonLinearCopyImageView.valid())
{ {
ANGLE_TRY(image.initLayerImageViewImpl(contextVk, fetchType, aspectFlags, formatSwizzle, ANGLE_TRY(image.initAliasedLayerImageView(
&mNonLinearCopyImageView, baseLevel, levelCount, contextVk, fetchType, aspectFlags, formatSwizzle, &mNonLinearCopyImageView, baseLevel,
baseLayer, layerCount, nonLinearOverrideFormat)); levelCount, baseLayer, layerCount, imageUsageFlags, nonLinearOverrideFormat));
} }
return angle::Result::Continue; return angle::Result::Continue;
...@@ -4818,6 +4847,8 @@ angle::Result ImageViewHelper::getLevelDrawImageView(ContextVk *contextVk, ...@@ -4818,6 +4847,8 @@ angle::Result ImageViewHelper::getLevelDrawImageView(ContextVk *contextVk,
const ImageHelper &image, const ImageHelper &image,
uint32_t level, uint32_t level,
uint32_t layer, uint32_t layer,
VkImageUsageFlags imageUsageFlags,
VkFormat vkImageFormat,
const ImageView **imageViewOut) const ImageView **imageViewOut)
{ {
retain(&contextVk->getResourceUseList()); retain(&contextVk->getResourceUseList());
...@@ -4831,8 +4862,9 @@ angle::Result ImageViewHelper::getLevelDrawImageView(ContextVk *contextVk, ...@@ -4831,8 +4862,9 @@ angle::Result ImageViewHelper::getLevelDrawImageView(ContextVk *contextVk,
} }
// Create the view. Note that storage images are not affected by swizzle parameters. // Create the view. Note that storage images are not affected by swizzle parameters.
return image.initLayerImageView(contextVk, viewType, image.getAspectFlags(), gl::SwizzleState(), return image.initAliasedLayerImageView(contextVk, viewType, image.getAspectFlags(),
imageView, level, 1, layer, image.getLayerCount()); gl::SwizzleState(), imageView, level, 1, layer,
image.getLayerCount(), imageUsageFlags, vkImageFormat);
} }
angle::Result ImageViewHelper::getLevelLayerDrawImageView(ContextVk *contextVk, angle::Result ImageViewHelper::getLevelLayerDrawImageView(ContextVk *contextVk,
......
...@@ -1075,7 +1075,7 @@ class ImageHelper final : public Resource, public angle::Subject ...@@ -1075,7 +1075,7 @@ class ImageHelper final : public Resource, public angle::Subject
uint32_t levelCount, uint32_t levelCount,
uint32_t baseArrayLayer, uint32_t baseArrayLayer,
uint32_t layerCount) const; uint32_t layerCount) const;
angle::Result initLayerImageViewImpl(Context *context, angle::Result initAliasedLayerImageView(Context *context,
gl::TextureType textureType, gl::TextureType textureType,
VkImageAspectFlags aspectMask, VkImageAspectFlags aspectMask,
const gl::SwizzleState &swizzleMap, const gl::SwizzleState &swizzleMap,
...@@ -1084,7 +1084,8 @@ class ImageHelper final : public Resource, public angle::Subject ...@@ -1084,7 +1084,8 @@ class ImageHelper final : public Resource, public angle::Subject
uint32_t levelCount, uint32_t levelCount,
uint32_t baseArrayLayer, uint32_t baseArrayLayer,
uint32_t layerCount, uint32_t layerCount,
VkFormat imageFormat) const; VkImageUsageFlags imageUsageFlags,
VkFormat imageViewFormat) const;
angle::Result initImageView(Context *context, angle::Result initImageView(Context *context,
gl::TextureType textureType, gl::TextureType textureType,
VkImageAspectFlags aspectMask, VkImageAspectFlags aspectMask,
...@@ -1472,6 +1473,19 @@ class ImageHelper final : public Resource, public angle::Subject ...@@ -1472,6 +1473,19 @@ class ImageHelper final : public Resource, public angle::Subject
void prependSubresourceUpdate(SubresourceUpdate &&update); void prependSubresourceUpdate(SubresourceUpdate &&update);
void resetCachedProperties(); void resetCachedProperties();
angle::Result initLayerImageViewImpl(
Context *context,
gl::TextureType textureType,
VkImageAspectFlags aspectMask,
const gl::SwizzleState &swizzleMap,
ImageView *imageViewOut,
uint32_t baseMipLevel,
uint32_t levelCount,
uint32_t baseArrayLayer,
uint32_t layerCount,
VkFormat imageFormat,
const VkImageViewUsageCreateInfo *imageViewUsageCreateInfo) const;
// Vulkan objects. // Vulkan objects.
Image mImage; Image mImage;
DeviceMemory mDeviceMemory; DeviceMemory mDeviceMemory;
...@@ -1571,7 +1585,8 @@ class ImageViewHelper : angle::NonCopyable ...@@ -1571,7 +1585,8 @@ class ImageViewHelper : angle::NonCopyable
uint32_t baseLevel, uint32_t baseLevel,
uint32_t levelCount, uint32_t levelCount,
uint32_t baseLayer, uint32_t baseLayer,
uint32_t layerCount); uint32_t layerCount,
VkImageUsageFlags imageUsageFlags);
// Creates a view with all layers of the level. // Creates a view with all layers of the level.
angle::Result getLevelDrawImageView(ContextVk *contextVk, angle::Result getLevelDrawImageView(ContextVk *contextVk,
...@@ -1579,6 +1594,8 @@ class ImageViewHelper : angle::NonCopyable ...@@ -1579,6 +1594,8 @@ class ImageViewHelper : angle::NonCopyable
const ImageHelper &image, const ImageHelper &image,
uint32_t level, uint32_t level,
uint32_t layer, uint32_t layer,
VkImageUsageFlags imageUsageFlags,
VkFormat vkImageFormat,
const ImageView **imageViewOut); const ImageView **imageViewOut);
// Creates a view with a single layer of the level. // Creates a view with a single layer of the level.
......
...@@ -180,9 +180,6 @@ ...@@ -180,9 +180,6 @@
// Tessellation geometry interaction: // Tessellation geometry interaction:
3572 VULKAN : dEQP-GLES31.functional.tessellation_geometry_interaction.* = FAIL 3572 VULKAN : dEQP-GLES31.functional.tessellation_geometry_interaction.* = FAIL
// Vulkan creates the image view with the same format as the texture.
3885 VULKAN : dEQP-GLES31.functional.image_load_store.*.format_reinterpret.* = FAIL
// Cannot create 2D (array) view of 3D texture. // Cannot create 2D (array) view of 3D texture.
3886 VULKAN : dEQP-GLES31.functional.image_load_store.3d.*layer = FAIL 3886 VULKAN : dEQP-GLES31.functional.image_load_store.3d.*layer = FAIL
......
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