KhronosGroup / Vulkan-ValidationLayers

Vulkan Validation Layers (VVL)
https://vulkan.lunarg.com/doc/sdk/latest/linux/khronos_validation_layer.html
Other
768 stars 404 forks source link

Validation seems to be ignoring VK_KHR_image_format_list and VK_KHR_maintenance2 #4520

Open manas-kulkarni opened 2 years ago

manas-kulkarni commented 2 years ago

Describe the Issue Trying to create an ETC2_RGB_UNORM image with RG32_UINT as the uncompressed format using VK_KHR_image_format_list.

static VkFormat bpp64[] =
{
    VK_FORMAT_R32G32_UINT,
    VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK,
    VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK,
};
VkImageFormatListCreateInfoKHR formatList = { VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO_KHR };
formatList.pViewFormats = bpp64;
formatList.viewFormatCount = 3;

VkImageCreateInfo createInfo = { VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO };
createInfo.pNext  = &formatList;
createInfo.flags  = VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT | VK_IMAGE_CREATE_BLOCK_TEXEL_VIEW_COMPATIBLE_BIT_KHR;
createInfo.usage  = VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_SAMPLED_BIT;
createInfo.format = VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK;

Validation errors:

[ VUID_Undefined ] Object: VK_NULL_HANDLE (Type = 0) | vkCreateImage(): Format VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK is not supported for this combination of parameters.

[ VUID-VkImageViewCreateInfo-usage-02275 ] Object: 0x9522 (Type = 10) | vkCreateImageView(): pCreateInfo->format VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK with tiling VK_IMAGE_TILING_OPTIMAL does not support usage that includes VK_IMAGE_USAGE_STORAGE_BIT. The Vulkan spec states: If usage contains VK_IMAGE_USAGE_STORAGE_BIT, then the image view's format features must contain VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT. (https://www.khronos.org/registry/vulkan/specs/1.1-extensions/html/vkspec.html#VUID-VkImageViewCreateInfo-usage-02275)

VK_KHR_maintenance2 states

Allow creating images with usage flags that may not be supported for the base image’s format, but are supported for image views of the image that have a different but compatible format.

RG32_UINT is compatible with ETC2_RGB_UNORM (both are 64-bit) and supports VK_IMAGE_USAGE_STORAGE_BIT. Should the error get triggered in this case or am I missing something?

Valid Usage ID There should be no validation error

Environment:

Additional context

sjfricke commented 2 years ago

Looking at a Pixel 6 with Mali-G78 on Android 13 https://vulkan.gpuinfo.org/displayreport.php?id=15551#formats_optimal

it seems ETC2_R8G8B8_UNORM_BLOCK does not support VK_IMAGE_USAGE_STORAGE_BIT on that driver therefore this Validation Error seems to be doing its job and catching that for you

So yes the formats are compatible, but they both still need to be supported by the driver

manas-kulkarni commented 2 years ago

Isn't VK_KHR_maintenance2 supposed to tackle this exact limitation? The extension page says

Allow creating images with usage flags that may not be supported for the base image’s format, but are supported for image views of the image that have a different but compatible format.

Doesn't this mean that validation should no longer complain if VK_IMAGE_USAGE_STORAGE_BIT is not supported for ETC2_RGB_UNORM (base image format) but is supported by a compatible format (specified in the image format list)

sjfricke commented 2 years ago

Ok, so sorry for any confusion, what exactly does your VkImageViewCreateInfo contain because the error says

vkCreateImageView(): pCreateInfo->format VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK

which makes it seem like your application at Image View time is ETC2_R8G8B8_UNORM which I mentioned above doesn't seem to have the STORAGE_BIT

VK_KHR_maintenance2

So yes, the extensions let you in this case use ETC2_R8G8B8_UNORM (not supported) for the VkImage::format but then you need to still have a supported VkImageView::format format. The VkImageFormatListCreateInfoKHR is for the VkImage not the VkImageView

but are supported for image views of the image that have a different but compatible format.

My guess is you ment to use VK_FORMAT_R32G32_UINT in your VkImageViewCreateInfo but are using the ETC2 format instead

manas-kulkarni commented 2 years ago

I dont understand. This would make it impossible to alias compressed and uncompressed textures making things like compute shader virtual texture compression not possible on Vulkan (possible on PC DX12). The code works perfectly fine on all Adreno 6xx, and Mali G-7x GPUs as well as all the desktop GPUs we test on. The only issue is the validation layer complaining.

My guess is you meant to use VK_FORMAT_R32G32_UINT in your VkImageViewCreateInfo but are using the ETC2 format instead

We need both views (ETC2 to sample in the pixel shader and RG32 for writing as UAV in compute shader)

janharaldfredriksen-arm commented 2 years ago

Out of curiosity - what happens to the VU errors if you create the image as VK_FORMAT_R32G32_UINT, but with the same entries in formatList?

manas-kulkarni commented 2 years ago

We decided to go another way. Use RG32 intermediate texture and copy into ETC2 texture whenever necessary. Error seems to go away with RG32 as base format but then it doesnt alias correctly as some drivers use base format to determine the swizzle (if base format is not ETC2, driver will not use correct swizzle and texture sampling is broken in the shader)

ncesario-lunarg commented 2 years ago

I thought VK_IMAGE_CREATE_EXTENDED_USAGE_BIT (from maintenance2) was required for this type of usage, but I might be getting this mixed up with a different use case. I think @aitor-lunarg looked at this (or a closely related issue) extensively here in #1495, and I think created a test case that is similar to what you are doing here.

manas-kulkarni commented 2 years ago

That would make sense. Thanks! We were missing VkImageViewUsageCreateInfo for vkCreateImageView. But it still throws a validation error for vkCreateImage even with VK_IMAGE_CREATE_EXTENDED_USAGE_BIT_KHR. Using latest Android binaries release

ncesario-lunarg commented 2 years ago

Is the validation error you're hitting 02251 (I see VUID_Undefined in the original description above, but the VUID description matches 02251)? If that is the case and your image tiling is set to VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT, you might be running into https://github.com/KhronosGroup/Vulkan-ValidationLayers/issues/4435.

If you are hitting 02251 but your image tiling is not set to VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT, then it would be interesting to see what vkGetPhysicalDeviceImageFormatProperties returns before creating the image, as that is effectively what the validation layers are checking before producing 02251: https://github.com/KhronosGroup/Vulkan-ValidationLayers/blob/825dd8a8902b1005434016951f636f759d4bdcfb/layers/buffer_validation.cpp#L1913-L1915 https://github.com/KhronosGroup/Vulkan-ValidationLayers/blob/825dd8a8902b1005434016951f636f759d4bdcfb/layers/buffer_validation.cpp#L1959

manas-kulkarni commented 2 years ago

Just using OPTIMAL tiling

ncesario-lunarg commented 2 years ago

In that case, can you call vkGetPhysicalDeviceImageformatProperties before creating the image and see what the result is? If VK_ERROR_FORMAT_NOT_SUPPORTED is returned, then it would seem the image you are attempting to create is not valid, at least not on that driver, unless I'm missing something else.