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(
vk::ImageHelper *image = &textureVk->getImage();
const vk::ImageView *imageView = nullptr;
ANGLE_TRY(textureVk->getStorageImageView(contextVk, (binding.layered == GL_TRUE),
binding.level, binding.layer, &imageView));
ANGLE_TRY(textureVk->getStorageImageView(contextVk, binding, &imageView));
// Note: binding.access is unused because it is implied by the shader.
......
......@@ -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.
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.
if (!(mImageUsageFlags & VK_IMAGE_USAGE_STORAGE_BIT))
{
......@@ -1806,20 +1808,23 @@ angle::Result TextureVk::getLevelLayerImageView(ContextVk *contextVk,
}
angle::Result TextureVk::getStorageImageView(ContextVk *contextVk,
bool allLayers,
size_t level,
size_t singleLayer,
const gl::ImageUnit &binding,
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);
return mImageViews.getLevelDrawImageView(contextVk, mState.getType(), *mImage, nativeLevel,
nativeLayer, imageViewOut);
return mImageViews.getLevelDrawImageView(
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,
......@@ -1870,9 +1875,9 @@ angle::Result TextureVk::initImageViews(ContextVk *contextVk,
if ((mImageCreateFlags & VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT) != 0)
{
ANGLE_TRY(mImageViews.initSRGBReadViews(contextVk, mState.getType(), *mImage, format,
formatSwizzle, readSwizzle, baseLevel, levelCount,
baseLayer, layerCount));
ANGLE_TRY(mImageViews.initSRGBReadViews(
contextVk, mState.getType(), *mImage, format, formatSwizzle, readSwizzle, baseLevel,
levelCount, baseLayer, layerCount, mImageUsageFlags & ~VK_IMAGE_USAGE_STORAGE_BIT));
}
return angle::Result::Continue;
......
......@@ -178,9 +178,7 @@ class TextureVk : public TextureImpl, public angle::ObserverInterface
// A special view used for texture copies that shouldn't perform swizzle.
const vk::ImageView &getCopyImageViewAndRecordUse(ContextVk *contextVk) const;
angle::Result getStorageImageView(ContextVk *contextVk,
bool allLayers,
size_t level,
size_t singleLayer,
const gl::ImageUnit &binding,
const vk::ImageView **imageViewOut);
const vk::Sampler &getSampler() const
......
......@@ -2711,18 +2711,21 @@ angle::Result ImageHelper::initLayerImageView(Context *context,
{
return initLayerImageViewImpl(context, textureType, aspectMask, swizzleMap, imageViewOut,
baseMipLevel, levelCount, baseArrayLayer, layerCount,
mFormat->vkImageFormat);
}
angle::Result ImageHelper::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
mFormat->vkImageFormat, nullptr);
}
angle::Result ImageHelper::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
{
VkImageViewCreateInfo viewInfo = {};
viewInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
......@@ -2752,10 +2755,34 @@ angle::Result ImageHelper::initLayerImageViewImpl(Context *context,
viewInfo.subresourceRange.baseArrayLayer = baseArrayLayer;
viewInfo.subresourceRange.layerCount = layerCount;
viewInfo.pNext = imageViewUsageCreateInfo;
ANGLE_VK_TRY(context, imageViewOut->init(context->getDevice(), viewInfo));
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)
{
VkDevice device = renderer->getDevice();
......@@ -4752,7 +4779,8 @@ angle::Result ImageViewHelper::initSRGBReadViews(ContextVk *contextVk,
uint32_t baseLevel,
uint32_t levelCount,
uint32_t baseLayer,
uint32_t layerCount)
uint32_t layerCount,
VkImageUsageFlags imageUsageFlags)
{
VkFormat nonLinearOverrideFormat = ConvertToNonLinear(image.getFormat().vkImageFormat);
VkFormat linearOverrideFormat = ConvertToLinear(image.getFormat().vkImageFormat);
......@@ -4764,15 +4792,15 @@ angle::Result ImageViewHelper::initSRGBReadViews(ContextVk *contextVk,
if (!mLinearReadImageView.valid())
{
ANGLE_TRY(image.initLayerImageViewImpl(contextVk, viewType, aspectFlags, readSwizzle,
&mLinearReadImageView, baseLevel, levelCount,
baseLayer, layerCount, linearFormat));
ANGLE_TRY(image.initAliasedLayerImageView(
contextVk, viewType, aspectFlags, readSwizzle, &mLinearReadImageView, baseLevel,
levelCount, baseLayer, layerCount, imageUsageFlags, linearFormat));
}
if (nonLinearOverrideFormat != VK_FORMAT_UNDEFINED && !mNonLinearReadImageView.valid())
{
ANGLE_TRY(image.initLayerImageViewImpl(contextVk, viewType, aspectFlags, readSwizzle,
&mNonLinearReadImageView, baseLevel, levelCount,
baseLayer, layerCount, nonLinearOverrideFormat));
ANGLE_TRY(image.initAliasedLayerImageView(
contextVk, viewType, aspectFlags, readSwizzle, &mNonLinearReadImageView, baseLevel,
levelCount, baseLayer, layerCount, imageUsageFlags, nonLinearOverrideFormat));
}
gl::TextureType fetchType = viewType;
......@@ -4785,29 +4813,30 @@ angle::Result ImageViewHelper::initSRGBReadViews(ContextVk *contextVk,
if (!mLinearFetchImageView.valid())
{
ANGLE_TRY(image.initLayerImageViewImpl(contextVk, fetchType, aspectFlags, readSwizzle,
&mLinearFetchImageView, baseLevel, levelCount,
baseLayer, layerCount, linearFormat));
ANGLE_TRY(image.initAliasedLayerImageView(
contextVk, fetchType, aspectFlags, readSwizzle, &mLinearFetchImageView, baseLevel,
levelCount, baseLayer, layerCount, imageUsageFlags, linearFormat));
}
if (nonLinearOverrideFormat != VK_FORMAT_UNDEFINED && !mNonLinearFetchImageView.valid())
{
ANGLE_TRY(image.initLayerImageViewImpl(contextVk, fetchType, aspectFlags, readSwizzle,
&mNonLinearFetchImageView, baseLevel, levelCount,
baseLayer, layerCount, nonLinearOverrideFormat));
ANGLE_TRY(image.initAliasedLayerImageView(contextVk, fetchType, aspectFlags,
readSwizzle, &mNonLinearFetchImageView,
baseLevel, levelCount, baseLayer, layerCount,
imageUsageFlags, nonLinearOverrideFormat));
}
}
if (!mLinearCopyImageView.valid())
{
ANGLE_TRY(image.initLayerImageViewImpl(contextVk, fetchType, aspectFlags, formatSwizzle,
&mLinearCopyImageView, baseLevel, levelCount,
baseLayer, layerCount, linearFormat));
ANGLE_TRY(image.initAliasedLayerImageView(
contextVk, fetchType, aspectFlags, formatSwizzle, &mLinearCopyImageView, baseLevel,
levelCount, baseLayer, layerCount, imageUsageFlags, linearFormat));
}
if (nonLinearOverrideFormat != VK_FORMAT_UNDEFINED && !mNonLinearCopyImageView.valid())
{
ANGLE_TRY(image.initLayerImageViewImpl(contextVk, fetchType, aspectFlags, formatSwizzle,
&mNonLinearCopyImageView, baseLevel, levelCount,
baseLayer, layerCount, nonLinearOverrideFormat));
ANGLE_TRY(image.initAliasedLayerImageView(
contextVk, fetchType, aspectFlags, formatSwizzle, &mNonLinearCopyImageView, baseLevel,
levelCount, baseLayer, layerCount, imageUsageFlags, nonLinearOverrideFormat));
}
return angle::Result::Continue;
......@@ -4818,6 +4847,8 @@ angle::Result ImageViewHelper::getLevelDrawImageView(ContextVk *contextVk,
const ImageHelper &image,
uint32_t level,
uint32_t layer,
VkImageUsageFlags imageUsageFlags,
VkFormat vkImageFormat,
const ImageView **imageViewOut)
{
retain(&contextVk->getResourceUseList());
......@@ -4831,8 +4862,9 @@ angle::Result ImageViewHelper::getLevelDrawImageView(ContextVk *contextVk,
}
// Create the view. Note that storage images are not affected by swizzle parameters.
return image.initLayerImageView(contextVk, viewType, image.getAspectFlags(), gl::SwizzleState(),
imageView, level, 1, layer, image.getLayerCount());
return image.initAliasedLayerImageView(contextVk, viewType, image.getAspectFlags(),
gl::SwizzleState(), imageView, level, 1, layer,
image.getLayerCount(), imageUsageFlags, vkImageFormat);
}
angle::Result ImageViewHelper::getLevelLayerDrawImageView(ContextVk *contextVk,
......
......@@ -1075,16 +1075,17 @@ class ImageHelper final : public Resource, public angle::Subject
uint32_t levelCount,
uint32_t baseArrayLayer,
uint32_t layerCount) const;
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;
angle::Result 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;
angle::Result initImageView(Context *context,
gl::TextureType textureType,
VkImageAspectFlags aspectMask,
......@@ -1472,6 +1473,19 @@ class ImageHelper final : public Resource, public angle::Subject
void prependSubresourceUpdate(SubresourceUpdate &&update);
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.
Image mImage;
DeviceMemory mDeviceMemory;
......@@ -1571,7 +1585,8 @@ class ImageViewHelper : angle::NonCopyable
uint32_t baseLevel,
uint32_t levelCount,
uint32_t baseLayer,
uint32_t layerCount);
uint32_t layerCount,
VkImageUsageFlags imageUsageFlags);
// Creates a view with all layers of the level.
angle::Result getLevelDrawImageView(ContextVk *contextVk,
......@@ -1579,6 +1594,8 @@ class ImageViewHelper : angle::NonCopyable
const ImageHelper &image,
uint32_t level,
uint32_t layer,
VkImageUsageFlags imageUsageFlags,
VkFormat vkImageFormat,
const ImageView **imageViewOut);
// Creates a view with a single layer of the level.
......
......@@ -180,9 +180,6 @@
// Tessellation geometry interaction:
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.
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