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

vkGetPhysicalDeviceImageFormatProperties2 assumes color and depth stencil attachments #8673

Open bl4ckb0ne opened 4 weeks ago

bl4ckb0ne commented 4 weeks ago

Environment:

Describe the Issue

I was debugging a VK_ERROR_FORMAT_NOT_SUPPORTED from vkGetPhysicalDeviceImageFormatProperties2 which was also ringin the validation layer

10-09 13:27:56.828 24928 24948 I VALIDATION: VUID-VkImageCreateInfo-pNext-00990(ERROR / SPEC): msgNum: 1181525669 - Validation Error: [ VUID-VkImageCreateInfo-pNext-00990 ] | MessageID = 0x466ca6a5 | vkCreateImage(): pCreateInfo The handle type (VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID), format (VK_FORMAT_R8G8B8A8_UNORM), type (VK_IMAGE_TYPE_2D), tiling (VK_IMAGE_TILING_OPTIMAL), usage (VK_IMAGE_USAGE_SAMPLED_BIT|VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT|VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT|VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT), flags (VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT) is not supported combination of parameters and vkGetPhysicalDeviceImageFormatProperties2 returned back VK_ERROR_FORMAT_NOT_SUPPORTED. The Vulkan spec states: If the pNext chain includes a VkExternalMemoryImageCreateInfo structure, its handleTypes member must only contain bits that are also in VkExternalImageFormatProperties::externalMemoryProperties.compatibleHandleTypes, as returned by vkGetPhysicalDeviceImageFormatProperties2 with format, imageType, tiling, 

I caught this in the emulator output window

E1009 11:45:09.143845  556205 VkDecoderGlobalState.cpp:5839] The VkImageCreateInfo to import AHardwareBuffer contains unsupported VkImageUsageFlags. All supported VkImageUsageFlags are VK_IMAGE_USAGE_TRANSFER_SRC_BIT|VK_IMAGE_USAGE_TRANSFER_DST_BIT|VK_IMAGE_USAGE_SAMPLED_BIT|VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT|VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT, the input VkImageCreateInfo requires support for VK_IMAGE_USAGE_SAMPLED_BIT|VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT|VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT|VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT.

The AHardwareBuffer format AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM doesn't support VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT as a usage flag. Removing it from my code made vkGetPhysicalDeviceImageFormatProperties2 return VK_SUCCESS, but the layer unconditionally assumes (VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) for the AHARDWAREBUFFER_USAGE_GPU_FRAMEBUFFER here 1.

Expected behavior

I'm not sure yet if this is simply an error from my side, a driver issue or a hole in the spec. Nevertheless, the validation message is popping on my side even though my AHardwareBuffer has the VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT flag set.

Valid Usage ID

VUID-VkImageCreateInfo-pNext-00990 & VUID-VkImportAndroidHardwareBufferInfoANDROID-buffer-01880

Additional context

This was caught on the Android emulator with the Android 14 profile on the Pixel 6. I've had reports of the same issue on real HW but I can't reproduce on my side to conclude.

spencer-lunarg commented 4 weeks ago

I'm not sure yet if this is simply an error from my side, a driver issue or a hole in the spec.

That is what I think everytime I have to deal with Android Hardware Buffers :laughing:

The spec has a section that says

image

bl4ckb0ne commented 4 weeks ago

Ha so I'm not crazy! Thanks!

I made this function to pick the proper VkImageUsageFlagBits

static VkImageUsageFlagBits
ahb_format_usage(uint32_t fmt)
{
    switch (fmt) {
    case AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM:
    case AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM:
    case AHARDWAREBUFFER_FORMAT_R8G8B8_UNORM:
    case AHARDWAREBUFFER_FORMAT_R5G6B5_UNORM:
    case AHARDWAREBUFFER_FORMAT_R16G16B16A16_FLOAT:
    case AHARDWAREBUFFER_FORMAT_R10G10B10A2_UNORM: return VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
    case AHARDWAREBUFFER_FORMAT_D16_UNORM:
    case AHARDWAREBUFFER_FORMAT_D24_UNORM:
    case AHARDWAREBUFFER_FORMAT_D24_UNORM_S8_UINT:
    case AHARDWAREBUFFER_FORMAT_D32_FLOAT:
    case AHARDWAREBUFFER_FORMAT_D32_FLOAT_S8_UINT:
    case AHARDWAREBUFFER_FORMAT_S8_UINT: return VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
    default: return 0;
    }
}