From 29c01176bf7e37c55fbf9fa232baebafc5ab9530 Mon Sep 17 00:00:00 2001 From: Dave Houlton Date: Fri, 19 Jan 2018 12:17:05 -0700 Subject: layers: Add GetImgSubrscLayout multi-planar VUIDs Adds new VUIDs defined in the VK_KHR_sampler_ycbcr_conversion extension to vkGetImageSubresourceLayouts(), and corrects the false positive error reported in GH issue #2350. Change-Id: Ia2814291291c7109fabd33af6119a9209e08dd51 --- layers/buffer_validation.cpp | 35 ++++++++++++++++++++++----------- layers/vk_format_utils.cpp | 34 +++++++++++++++++++++++++++++++- layers/vk_format_utils.h | 14 +++++++------ layers/vk_validation_error_database.txt | 4 ++-- 4 files changed, 67 insertions(+), 20 deletions(-) diff --git a/layers/buffer_validation.cpp b/layers/buffer_validation.cpp index b2268277..4cdeeaa4 100644 --- a/layers/buffer_validation.cpp +++ b/layers/buffer_validation.cpp @@ -4093,7 +4093,7 @@ bool PreCallValidateGetImageSubresourceLayout(layer_data *device_data, VkImage i bool skip = false; const VkImageAspectFlags sub_aspect = pSubresource->aspectMask; - // VU 00733: The aspectMask member of pSubresource must only have a single bit set + // The aspectMask member of pSubresource must only have a single bit set const int num_bits = sizeof(sub_aspect) * CHAR_BIT; std::bitset aspect_mask_bits(sub_aspect); if (aspect_mask_bits.count() != 1) { @@ -4108,7 +4108,7 @@ bool PreCallValidateGetImageSubresourceLayout(layer_data *device_data, VkImage i return skip; } - // VU 00732: image must have been created with tiling equal to VK_IMAGE_TILING_LINEAR + // image must have been created with tiling equal to VK_IMAGE_TILING_LINEAR if (image_entry->createInfo.tiling != VK_IMAGE_TILING_LINEAR) { skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, HandleToUint64(image), __LINE__, VALIDATION_ERROR_2a6007c8, "IMAGE", @@ -4116,7 +4116,7 @@ bool PreCallValidateGetImageSubresourceLayout(layer_data *device_data, VkImage i validation_error_map[VALIDATION_ERROR_2a6007c8]); } - // VU 00739: mipLevel must be less than the mipLevels specified in VkImageCreateInfo when the image was created + // mipLevel must be less than the mipLevels specified in VkImageCreateInfo when the image was created if (pSubresource->mipLevel >= image_entry->createInfo.mipLevels) { skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, HandleToUint64(image), __LINE__, VALIDATION_ERROR_0a4007cc, "IMAGE", @@ -4124,7 +4124,7 @@ bool PreCallValidateGetImageSubresourceLayout(layer_data *device_data, VkImage i pSubresource->mipLevel, image_entry->createInfo.mipLevels, validation_error_map[VALIDATION_ERROR_0a4007cc]); } - // VU 00740: arrayLayer must be less than the arrayLayers specified in VkImageCreateInfo when the image was created + // arrayLayer must be less than the arrayLayers specified in VkImageCreateInfo when the image was created if (pSubresource->arrayLayer >= image_entry->createInfo.arrayLayers) { skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, HandleToUint64(image), @@ -4133,15 +4133,28 @@ bool PreCallValidateGetImageSubresourceLayout(layer_data *device_data, VkImage i pSubresource->arrayLayer, image_entry->createInfo.arrayLayers, validation_error_map[VALIDATION_ERROR_0a4007ce]); } - // VU 00741: subresource's aspect must be compatible with image's format. + // subresource's aspect must be compatible with image's format. const VkFormat img_format = image_entry->createInfo.format; - if (FormatIsColor(img_format)) { + if (FormatIsMultiplane(img_format)) { + VkImageAspectFlags allowed_flags = (VK_IMAGE_ASPECT_PLANE_0_BIT_KHR | VK_IMAGE_ASPECT_PLANE_1_BIT_KHR); + UNIQUE_VALIDATION_ERROR_CODE vuid = VALIDATION_ERROR_2a600c5a; // 2-plane version + if (FormatPlaneCount(img_format) > 2u) { + allowed_flags |= VK_IMAGE_ASPECT_PLANE_2_BIT_KHR; + vuid = VALIDATION_ERROR_2a600c5c; // 3-plane version + } + if (sub_aspect != (sub_aspect & allowed_flags)) { + skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, + HandleToUint64(image), __LINE__, vuid, "IMAGE", + "vkGetImageSubresourceLayout(): For multi-planar images, VkImageSubresource.aspectMask (0x%" PRIx32 + ") must be a single-plane specifier flag. %s", + sub_aspect, validation_error_map[vuid]); + } + } else if (FormatIsColor(img_format)) { if (sub_aspect != VK_IMAGE_ASPECT_COLOR_BIT) { - skip |= log_msg( - report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, HandleToUint64(image), __LINE__, - VALIDATION_ERROR_0a400c01, "IMAGE", - "vkGetImageSubresourceLayout(): For color formats, VkImageSubresource.aspectMask must be VK_IMAGE_ASPECT_COLOR. %s", - validation_error_map[VALIDATION_ERROR_0a400c01]); + skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, + HandleToUint64(image), __LINE__, VALIDATION_ERROR_0a400c01, "IMAGE", + "vkGetImageSubresourceLayout(): For color formats, VkImageSubresource.aspectMask must be VK_IMAGE_ASPECT_COLOR. %s", + validation_error_map[VALIDATION_ERROR_0a400c01]); } } else if (FormatIsDepthOrStencil(img_format)) { if ((sub_aspect != VK_IMAGE_ASPECT_DEPTH_BIT) && (sub_aspect != VK_IMAGE_ASPECT_STENCIL_BIT)) { diff --git a/layers/vk_format_utils.cpp b/layers/vk_format_utils.cpp index f8bfdcf2..93481e85 100644 --- a/layers/vk_format_utils.cpp +++ b/layers/vk_format_utils.cpp @@ -866,6 +866,38 @@ VK_LAYER_EXPORT VkExtent3D FormatCompressedTexelBlockExtent(VkFormat format) { return block_size; } +VK_LAYER_EXPORT uint32_t FormatPlaneCount(VkFormat format) { + switch (format) { + case VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM_KHR: + case VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM_KHR: + case VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM_KHR: + case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16_KHR: + case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16_KHR: + case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16_KHR: + case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16_KHR: + case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16_KHR: + case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16_KHR: + case VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM_KHR: + case VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM_KHR: + case VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM_KHR: + return 3u; + break; + case VK_FORMAT_G8_B8R8_2PLANE_420_UNORM_KHR: + case VK_FORMAT_G8_B8R8_2PLANE_422_UNORM_KHR: + case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16_KHR: + case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16_KHR: + case VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16_KHR: + case VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16_KHR: + case VK_FORMAT_G16_B16R16_2PLANE_420_UNORM_KHR: + case VK_FORMAT_G16_B16R16_2PLANE_422_UNORM_KHR: + return 2u; + break; + default: + return 1u; + break; + } +} + // Return format class of the specified format VK_LAYER_EXPORT VkFormatCompatibilityClass FormatCompatibilityClass(VkFormat format) { auto item = vk_format_table.find(format); @@ -885,7 +917,7 @@ VK_LAYER_EXPORT size_t FormatSize(VkFormat format) { } // Return the number of channels for a given format -unsigned int FormatChannelCount(VkFormat format) { +uint32_t FormatChannelCount(VkFormat format) { auto item = vk_format_table.find(format); if (item != vk_format_table.end()) { return item->second.channel_count; diff --git a/layers/vk_format_utils.h b/layers/vk_format_utils.h index 7420a937..8ffa231c 100644 --- a/layers/vk_format_utils.h +++ b/layers/vk_format_utils.h @@ -111,17 +111,19 @@ VK_LAYER_EXPORT bool FormatIsUScaled(VkFormat format); VK_LAYER_EXPORT bool FormatIsSScaled(VkFormat format); VK_LAYER_EXPORT bool FormatIsCompressed(VkFormat format); -static inline bool FormatIsUndef(VkFormat format) { return (format == VK_FORMAT_UNDEFINED); } -static inline bool FormatIsColor(VkFormat format) { return !(FormatIsUndef(format) || FormatIsDepthOrStencil(format)); } -static inline bool FormatHasDepth(VkFormat format) { return (FormatIsDepthOnly(format) || FormatIsDepthAndStencil(format)); } -static inline bool FormatHasStencil(VkFormat format) { return (FormatIsStencilOnly(format) || FormatIsDepthAndStencil(format)); } - +VK_LAYER_EXPORT uint32_t FormatPlaneCount(VkFormat format); +VK_LAYER_EXPORT uint32_t FormatChannelCount(VkFormat format); VK_LAYER_EXPORT VkExtent3D FormatCompressedTexelBlockExtent(VkFormat format); VK_LAYER_EXPORT size_t FormatSize(VkFormat format); -VK_LAYER_EXPORT unsigned int FormatChannelCount(VkFormat format); VK_LAYER_EXPORT VkFormatCompatibilityClass FormatCompatibilityClass(VkFormat format); VK_LAYER_EXPORT VkDeviceSize SafeModulo(VkDeviceSize dividend, VkDeviceSize divisor); +static inline bool FormatIsUndef(VkFormat format) { return (format == VK_FORMAT_UNDEFINED); } +static inline bool FormatIsColor(VkFormat format) { return !(FormatIsUndef(format) || FormatIsDepthOrStencil(format)); } +static inline bool FormatHasDepth(VkFormat format) { return (FormatIsDepthOnly(format) || FormatIsDepthAndStencil(format)); } +static inline bool FormatHasStencil(VkFormat format) { return (FormatIsStencilOnly(format) || FormatIsDepthAndStencil(format)); } +static inline bool FormatIsMultiplane(VkFormat format) { return ((FormatPlaneCount(format)) > 1u); } + #ifdef __cplusplus } #endif diff --git a/layers/vk_validation_error_database.txt b/layers/vk_validation_error_database.txt index ed53c3ae..c13430a7 100644 --- a/layers/vk_validation_error_database.txt +++ b/layers/vk_validation_error_database.txt @@ -3074,8 +3074,8 @@ VALIDATION_ERROR_2a423601~^~N~^~Unknown~^~vkGetImageSparseMemoryRequirements~^~V VALIDATION_ERROR_2a423801~^~Y~^~Unknown~^~vkGetImageSparseMemoryRequirements~^~VUID-vkGetImageSparseMemoryRequirements-pSparseMemoryRequirements-parameter~^~core~^~The spec valid usage text states 'If the value referenced by pSparseMemoryRequirementCount is not 0, and pSparseMemoryRequirements is not NULL, pSparseMemoryRequirements must be a valid pointer to an array of pSparseMemoryRequirementCount VkSparseImageMemoryRequirements structures' (https://www.khronos.org/registry/vulkan/specs/1.0/html/vkspec.html#VUID-vkGetImageSparseMemoryRequirements-pSparseMemoryRequirements-parameter)~^~implicit VALIDATION_ERROR_2a6007c8~^~Y~^~Unknown~^~vkGetImageSubresourceLayout~^~VUID-vkGetImageSubresourceLayout-image-00996~^~core~^~The spec valid usage text states 'image must have been created with tiling equal to VK_IMAGE_TILING_LINEAR' (https://www.khronos.org/registry/vulkan/specs/1.0/html/vkspec.html#VUID-vkGetImageSubresourceLayout-image-00996)~^~ VALIDATION_ERROR_2a6007ca~^~Y~^~Unknown~^~vkGetImageSubresourceLayout~^~VUID-vkGetImageSubresourceLayout-aspectMask-00997~^~core~^~The spec valid usage text states 'The aspectMask member of pSubresource must only have a single bit set' (https://www.khronos.org/registry/vulkan/specs/1.0/html/vkspec.html#VUID-vkGetImageSubresourceLayout-aspectMask-00997)~^~ -VALIDATION_ERROR_2a600c5a~^~N~^~None~^~vkGetImageSubresourceLayout~^~VUID-vkGetImageSubresourceLayout-format-01581~^~(VK_KHR_sampler_ycbcr_conversion)~^~The spec valid usage text states 'If the format of image is a multi-planar format with two planes, the aspectMask member of pSubresource must be VK_IMAGE_ASPECT_PLANE_0_BIT_KHR or VK_IMAGE_ASPECT_PLANE_1_BIT_KHR' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/html/vkspec.html#VUID-vkGetImageSubresourceLayout-format-01581)~^~ -VALIDATION_ERROR_2a600c5c~^~N~^~None~^~vkGetImageSubresourceLayout~^~VUID-vkGetImageSubresourceLayout-format-01582~^~(VK_KHR_sampler_ycbcr_conversion)~^~The spec valid usage text states 'If the format of image is a multi-planar format with three planes, the aspectMask member of pSubresource must be VK_IMAGE_ASPECT_PLANE_0_BIT_KHR, VK_IMAGE_ASPECT_PLANE_1_BIT_KHR or VK_IMAGE_ASPECT_PLANE_2_BIT_KHR' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/html/vkspec.html#VUID-vkGetImageSubresourceLayout-format-01582)~^~ +VALIDATION_ERROR_2a600c5a~^~Y~^~None~^~vkGetImageSubresourceLayout~^~VUID-vkGetImageSubresourceLayout-format-01581~^~(VK_KHR_sampler_ycbcr_conversion)~^~The spec valid usage text states 'If the format of image is a multi-planar format with two planes, the aspectMask member of pSubresource must be VK_IMAGE_ASPECT_PLANE_0_BIT_KHR or VK_IMAGE_ASPECT_PLANE_1_BIT_KHR' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/html/vkspec.html#VUID-vkGetImageSubresourceLayout-format-01581)~^~ +VALIDATION_ERROR_2a600c5c~^~Y~^~None~^~vkGetImageSubresourceLayout~^~VUID-vkGetImageSubresourceLayout-format-01582~^~(VK_KHR_sampler_ycbcr_conversion)~^~The spec valid usage text states 'If the format of image is a multi-planar format with three planes, the aspectMask member of pSubresource must be VK_IMAGE_ASPECT_PLANE_0_BIT_KHR, VK_IMAGE_ASPECT_PLANE_1_BIT_KHR or VK_IMAGE_ASPECT_PLANE_2_BIT_KHR' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/html/vkspec.html#VUID-vkGetImageSubresourceLayout-format-01582)~^~ VALIDATION_ERROR_2a600d68~^~N~^~None~^~vkGetImageSubresourceLayout~^~VUID-vkGetImageSubresourceLayout-mipLevel-01716~^~core~^~The spec valid usage text states 'The mipLevel member of pSubresource must be less than the mipLevels specified in VkImageCreateInfo when image was created' (https://www.khronos.org/registry/vulkan/specs/1.0/html/vkspec.html#VUID-vkGetImageSubresourceLayout-mipLevel-01716)~^~ VALIDATION_ERROR_2a600d6a~^~N~^~None~^~vkGetImageSubresourceLayout~^~VUID-vkGetImageSubresourceLayout-arrayLayer-01717~^~core~^~The spec valid usage text states 'The arrayLayer member of pSubresource must be less than the arrayLayers specified in VkImageCreateInfo when image was created' (https://www.khronos.org/registry/vulkan/specs/1.0/html/vkspec.html#VUID-vkGetImageSubresourceLayout-arrayLayer-01717)~^~ VALIDATION_ERROR_2a605601~^~Y~^~None~^~vkGetImageSubresourceLayout~^~VUID-vkGetImageSubresourceLayout-device-parameter~^~core~^~The spec valid usage text states 'device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0/html/vkspec.html#VUID-vkGetImageSubresourceLayout-device-parameter)~^~implicit -- cgit v1.2.3