diff options
Diffstat (limited to 'layers/buffer_validation.cpp')
| -rw-r--r-- | layers/buffer_validation.cpp | 238 |
1 files changed, 147 insertions, 91 deletions
diff --git a/layers/buffer_validation.cpp b/layers/buffer_validation.cpp index 44db3a6f..2cecf87c 100644 --- a/layers/buffer_validation.cpp +++ b/layers/buffer_validation.cpp @@ -620,7 +620,7 @@ void TransitionFinalSubpassLayouts(layer_data *device_data, GLOBAL_CB_NODE *pCB, } } } - + bool PreCallValidateCreateImage(layer_data *device_data, const VkImageCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkImage *pImage) { bool skip = false; @@ -634,141 +634,197 @@ bool PreCallValidateCreateImage(layer_data *device_data, const VkImageCreateInfo return skip; } + bool optimal_tiling = (VK_IMAGE_TILING_OPTIMAL == pCreateInfo->tiling); + const char *tiling_string = string_VkImageTiling(pCreateInfo->tiling); + const char *format_string = string_VkFormat(pCreateInfo->format); VkFormatProperties properties = GetFormatProperties(device_data, pCreateInfo->format); + VkFormatFeatureFlags features = (optimal_tiling ? properties.optimalTilingFeatures : properties.linearTilingFeatures); - if ((pCreateInfo->tiling == VK_IMAGE_TILING_LINEAR) && (properties.linearTilingFeatures == 0)) { + if (0 == features) { std::stringstream ss; - ss << "vkCreateImage format parameter (" << string_VkFormat(pCreateInfo->format) << ") is an unsupported format"; - skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, - VALIDATION_ERROR_09e007a2, "IMAGE", "%s. %s", ss.str().c_str(), - validation_error_map[VALIDATION_ERROR_09e007a2]); - + UNIQUE_VALIDATION_ERROR_CODE vuid = (optimal_tiling ? VALIDATION_ERROR_09e007ac : VALIDATION_ERROR_09e007a2); + ss << "vkCreateImage format parameter " << format_string << " is an unsupported format"; + skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, vuid, + "IMAGE", "%s. %s", ss.str().c_str(), validation_error_map[vuid]); return skip; } - if ((pCreateInfo->tiling == VK_IMAGE_TILING_OPTIMAL) && (properties.optimalTilingFeatures == 0)) { + if ((pCreateInfo->usage & VK_IMAGE_USAGE_SAMPLED_BIT) && !(features & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT)) { std::stringstream ss; - ss << "vkCreateImage format parameter (" << string_VkFormat(pCreateInfo->format) << ") is an unsupported format"; - skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, - VALIDATION_ERROR_09e007ac, "IMAGE", "%s. %s", ss.str().c_str(), - validation_error_map[VALIDATION_ERROR_09e007ac]); + UNIQUE_VALIDATION_ERROR_CODE vuid = (optimal_tiling ? VALIDATION_ERROR_09e007ae : VALIDATION_ERROR_09e007a4); + ss << "vkCreateImage: usage bit VK_IMAGE_USAGE_SAMPLED_BIT is not supported for format " << format_string << " with tiling " + << tiling_string; + skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, vuid, + "IMAGE", "%s. %s", ss.str().c_str(), validation_error_map[vuid]); + } - return skip; + if ((pCreateInfo->usage & VK_IMAGE_USAGE_STORAGE_BIT) && !(features & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT)) { + std::stringstream ss; + UNIQUE_VALIDATION_ERROR_CODE vuid = (optimal_tiling ? VALIDATION_ERROR_09e007b0 : VALIDATION_ERROR_09e007a6); + ss << "vkCreateImage: usage bit VK_IMAGE_USAGE_STORAGE_BIT is not supported for format " << format_string << " with tiling " + << tiling_string; + skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, vuid, + "IMAGE", "%s. %s", ss.str().c_str(), validation_error_map[vuid]); } // TODO: Add checks for EXTENDED_USAGE images to validate images are compatible // For EXTENDED_USAGE images, format can match any image COMPATIBLE with original image if (!GetDeviceExtensions(device_data)->vk_khr_maintenance2 || !(pCreateInfo->flags & VK_IMAGE_CREATE_EXTENDED_USAGE_BIT_KHR)) { // Validate that format supports usage as color attachment - if (pCreateInfo->usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) { - if ((pCreateInfo->tiling == VK_IMAGE_TILING_OPTIMAL) && - ((properties.optimalTilingFeatures & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT) == 0)) { - std::stringstream ss; - ss << "vkCreateImage: VkFormat for TILING_OPTIMAL image (" << string_VkFormat(pCreateInfo->format) - << ") does not support requested Image usage type VK_IMAGE_USAGE_COLOR_ATTACHMENT"; - skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, - VALIDATION_ERROR_09e007b2, "IMAGE", "%s. %s", ss.str().c_str(), - validation_error_map[VALIDATION_ERROR_09e007b2]); - } - if ((pCreateInfo->tiling == VK_IMAGE_TILING_LINEAR) && - ((properties.linearTilingFeatures & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT) == 0)) { - std::stringstream ss; - ss << "vkCreateImage: VkFormat for TILING_LINEAR image (" << string_VkFormat(pCreateInfo->format) - << ") does not support requested Image usage type VK_IMAGE_USAGE_COLOR_ATTACHMENT"; - skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, - VALIDATION_ERROR_09e007a8, "IMAGE", "%s. %s", ss.str().c_str(), - validation_error_map[VALIDATION_ERROR_09e007a8]); - } + if ((pCreateInfo->usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) && + (0 == (features & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT))) { + UNIQUE_VALIDATION_ERROR_CODE vuid = (optimal_tiling ? VALIDATION_ERROR_09e007b2 : VALIDATION_ERROR_09e007a8); + std::stringstream ss; + ss << "vkCreateImage: usage bit VK_IMAGE_USAGE_COLOR_ATTACHMENT is not supported for format " << format_string + << " with tiling " << tiling_string; + skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, vuid, + "IMAGE", "%s. %s", ss.str().c_str(), validation_error_map[vuid]); } // Validate that format supports usage as depth/stencil attachment - if (pCreateInfo->usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) { - if ((pCreateInfo->tiling == VK_IMAGE_TILING_OPTIMAL) && - ((properties.optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) == 0)) { + if ((pCreateInfo->usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) && + (0 == (features & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT))) { + UNIQUE_VALIDATION_ERROR_CODE vuid = (optimal_tiling ? VALIDATION_ERROR_09e007b4 : VALIDATION_ERROR_09e007aa); + std::stringstream ss; + ss << "vkCreateImage: usage bit VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT is not supported for format " << format_string + << " with tiling " << tiling_string; + skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, vuid, + "IMAGE", "%s. %s", ss.str().c_str(), validation_error_map[vuid]); + } + } + + if ((pCreateInfo->flags & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT) && (VK_IMAGE_TYPE_2D != pCreateInfo->imageType)) { + std::stringstream ss; + ss << "vkCreateImage: Image type must be VK_IMAGE_TYPE_2D when VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT flag bit is set"; + skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, + VALIDATION_ERROR_09e0076a, "IMAGE", "%s. %s", ss.str().c_str(), + validation_error_map[VALIDATION_ERROR_09e0076a]); + } + + const VkPhysicalDeviceLimits *device_limits = &(GetPhysicalDeviceProperties(device_data)->limits); + VkImageFormatProperties format_limits; // Format limits may exceed general device limits + VkResult err = GetImageFormatProperties(device_data, pCreateInfo, &format_limits); + if (VK_SUCCESS != err) { + std::stringstream ss; + ss << "vkCreateImage: The combination of format, type, tiling, usage and flags supplied in the VkImageCreateInfo struct is " + "reported by vkGetPhysicalDeviceImageFormatProperties() as unsupported"; + skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, + VALIDATION_ERROR_09e00758, "IMAGE", "%s. %s", ss.str().c_str(), + validation_error_map[VALIDATION_ERROR_09e00758]); + return skip; + } + + if ((VK_IMAGE_TYPE_1D == pCreateInfo->imageType) && + (pCreateInfo->extent.width > std::max(device_limits->maxImageDimension1D, format_limits.maxExtent.width))) { + std::stringstream ss; + ss << "vkCreateImage: 1D image width exceeds maximum supported width for format " << format_string; + skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, + VALIDATION_ERROR_09e0076e, "IMAGE", "%s. %s", ss.str().c_str(), + validation_error_map[VALIDATION_ERROR_09e0076e]); + } + + if (VK_IMAGE_TYPE_2D == pCreateInfo->imageType) { + if (0 == (pCreateInfo->flags & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT)) { + if (pCreateInfo->extent.width > std::max(device_limits->maxImageDimension2D, format_limits.maxExtent.width) || + pCreateInfo->extent.height > std::max(device_limits->maxImageDimension2D, format_limits.maxExtent.height)) { std::stringstream ss; - ss << "vkCreateImage: VkFormat for TILING_OPTIMAL image (" << string_VkFormat(pCreateInfo->format) - << ") does not support requested Image usage type VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT"; + ss << "vkCreateImage: 2D image extent exceeds maximum supported width or height for format " << format_string; skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, - VALIDATION_ERROR_09e007b4, "IMAGE", "%s. %s", ss.str().c_str(), - validation_error_map[VALIDATION_ERROR_09e007b4]); + VALIDATION_ERROR_09e00770, "IMAGE", "%s. %s", ss.str().c_str(), + validation_error_map[VALIDATION_ERROR_09e00770]); } - if ((pCreateInfo->tiling == VK_IMAGE_TILING_LINEAR) && - ((properties.linearTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) == 0)) { + } else { + if (pCreateInfo->extent.width > std::max(device_limits->maxImageDimensionCube, format_limits.maxExtent.width) || + pCreateInfo->extent.height > std::max(device_limits->maxImageDimensionCube, format_limits.maxExtent.height)) { std::stringstream ss; - ss << "vkCreateImage: VkFormat for TILING_LINEAR image (" << string_VkFormat(pCreateInfo->format) - << ") does not support requested Image usage type VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT"; + ss << "vkCreateImage: 2D image extent exceeds maximum supported width or height for cube-compatible images with " + "format " + << format_string; skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, - VALIDATION_ERROR_09e007aa, "IMAGE", "%s. %s", ss.str().c_str(), - validation_error_map[VALIDATION_ERROR_09e007aa]); + VALIDATION_ERROR_09e00772, "IMAGE", "%s. %s", ss.str().c_str(), + validation_error_map[VALIDATION_ERROR_09e00772]); } } } - VkImageFormatProperties ImageFormatProperties = GetImageFormatProperties( - device_data, pCreateInfo->format, pCreateInfo->imageType, pCreateInfo->tiling, pCreateInfo->usage, pCreateInfo->flags); + if (VK_IMAGE_TYPE_3D == pCreateInfo->imageType) { + if ((pCreateInfo->extent.width > std::max(device_limits->maxImageDimension3D, format_limits.maxExtent.width)) || + (pCreateInfo->extent.height > std::max(device_limits->maxImageDimension3D, format_limits.maxExtent.height)) || + (pCreateInfo->extent.depth > std::max(device_limits->maxImageDimension3D, format_limits.maxExtent.depth))) { + std::stringstream ss; + ss << "vkCreateImage: 3D image extent exceeds maximum supported width, height, or depth for format " << format_string; + skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, + VALIDATION_ERROR_09e00776, "IMAGE", "%s. %s", ss.str().c_str(), + validation_error_map[VALIDATION_ERROR_09e00776]); + } + } - VkDeviceSize imageGranularity = GetPhysicalDeviceProperties(device_data)->limits.bufferImageGranularity; - imageGranularity = imageGranularity == 1 ? 0 : imageGranularity; + // NOTE: As of 1/30/2018 the spec VU language is as in the commented code below. I believe this is an + // error in the spec, and have submitted Gitlab Vulkan issue #1151 to have it changed to match the + // implementation shown. DJH + // + // if ((pCreateInfo->mipLevels > format_limits.maxMipLevels) && + // (std::max({ pCreateInfo->extent.width, pCreateInfo->extent.height, pCreateInfo->extent.depth }) > + // device_limits->maxImageDimension3D)) { + if (pCreateInfo->mipLevels > format_limits.maxMipLevels) { + std::stringstream ss; + ss << "vkCreateImage: Image mip levels exceed image format maxMipLevels for format " << format_string; + skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, + VALIDATION_ERROR_09e0077e, "IMAGE", "%s. %s", ss.str().c_str(), + validation_error_map[VALIDATION_ERROR_09e0077e]); + } - // TODO: VALIDATION_ERROR_09e00770 VALIDATION_ERROR_09e00772 VALIDATION_ERROR_09e00776 VALIDATION_ERROR_09e0076e - // All these extent-related VUs should be checked here - if ((pCreateInfo->extent.depth > ImageFormatProperties.maxExtent.depth) || - (pCreateInfo->extent.width > ImageFormatProperties.maxExtent.width) || - (pCreateInfo->extent.height > ImageFormatProperties.maxExtent.height)) { - skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, 0, __LINE__, - IMAGE_INVALID_FORMAT_LIMITS_VIOLATION, "Image", - "CreateImage extents exceed allowable limits for format: " - "Width = %d Height = %d Depth = %d: Limits for Width = %d Height = %d Depth = %d for format %s.", - pCreateInfo->extent.width, pCreateInfo->extent.height, pCreateInfo->extent.depth, - ImageFormatProperties.maxExtent.width, ImageFormatProperties.maxExtent.height, - ImageFormatProperties.maxExtent.depth, string_VkFormat(pCreateInfo->format)); + VkImageUsageFlags attach_flags = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | + VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT; + if ((pCreateInfo->usage & attach_flags) && (pCreateInfo->extent.width > device_limits->maxFramebufferWidth)) { + std::stringstream ss; + ss << "vkCreateImage: Image usage flags include a frame buffer attachment bit and image width exceeds device " + "maxFramebufferWidth"; + skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, + VALIDATION_ERROR_09e00788, "IMAGE", "%s. %s", ss.str().c_str(), + validation_error_map[VALIDATION_ERROR_09e00788]); } - uint64_t totalSize = - ((uint64_t)pCreateInfo->extent.width * (uint64_t)pCreateInfo->extent.height * (uint64_t)pCreateInfo->extent.depth * - (uint64_t)pCreateInfo->arrayLayers * (uint64_t)pCreateInfo->samples * (uint64_t)FormatSize(pCreateInfo->format) + - (uint64_t)imageGranularity) & - ~(uint64_t)imageGranularity; + if ((pCreateInfo->usage & attach_flags) && (pCreateInfo->extent.height > device_limits->maxFramebufferHeight)) { + std::stringstream ss; + ss << "vkCreateImage: Image usage flags include a frame buffer attachment bit and image height exceeds device " + "maxFramebufferHeight"; + skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, + VALIDATION_ERROR_09e0078a, "IMAGE", "%s. %s", ss.str().c_str(), + validation_error_map[VALIDATION_ERROR_09e0078a]); + } + + uint64_t total_size = (uint64_t)pCreateInfo->extent.width * (uint64_t)pCreateInfo->extent.height * + (uint64_t)pCreateInfo->extent.depth * (uint64_t)pCreateInfo->arrayLayers * + (uint64_t)pCreateInfo->samples * (uint64_t)FormatSize(pCreateInfo->format); + + // Round up to imageGranularity boundary + VkDeviceSize imageGranularity = GetPhysicalDeviceProperties(device_data)->limits.bufferImageGranularity; + uint64_t ig_mask = imageGranularity - 1; + total_size = (total_size + ig_mask) & ~ig_mask; - if (totalSize > ImageFormatProperties.maxResourceSize) { + if (total_size > format_limits.maxResourceSize) { skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, 0, __LINE__, IMAGE_INVALID_FORMAT_LIMITS_VIOLATION, "Image", "CreateImage resource size exceeds allowable maximum " "Image resource size = 0x%" PRIxLEAST64 ", maximum resource size = 0x%" PRIxLEAST64 " ", - totalSize, ImageFormatProperties.maxResourceSize); + total_size, format_limits.maxResourceSize); } - // TODO: VALIDATION_ERROR_09e0077e - if (pCreateInfo->mipLevels > ImageFormatProperties.maxMipLevels) { + if (pCreateInfo->arrayLayers > format_limits.maxArrayLayers) { skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, 0, __LINE__, - IMAGE_INVALID_FORMAT_LIMITS_VIOLATION, "Image", - "CreateImage mipLevels=%d exceeds allowable maximum supported by format of %d", pCreateInfo->mipLevels, - ImageFormatProperties.maxMipLevels); - } - - if (pCreateInfo->arrayLayers > ImageFormatProperties.maxArrayLayers) { - skip |= - log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, 0, __LINE__, - VALIDATION_ERROR_09e00780, "Image", - "CreateImage arrayLayers=%d exceeds allowable maximum supported by format of %d. %s", pCreateInfo->arrayLayers, - ImageFormatProperties.maxArrayLayers, validation_error_map[VALIDATION_ERROR_09e00780]); + VALIDATION_ERROR_09e00780, "Image", + "CreateImage arrayLayers=%d exceeds allowable maximum supported by format of %d. %s", + pCreateInfo->arrayLayers, format_limits.maxArrayLayers, validation_error_map[VALIDATION_ERROR_09e00780]); } - if ((pCreateInfo->samples & ImageFormatProperties.sampleCounts) == 0) { + if ((pCreateInfo->samples & format_limits.sampleCounts) == 0) { skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, 0, __LINE__, VALIDATION_ERROR_09e0078e, "Image", "CreateImage samples %s is not supported by format 0x%.8X. %s", - string_VkSampleCountFlagBits(pCreateInfo->samples), ImageFormatProperties.sampleCounts, + string_VkSampleCountFlagBits(pCreateInfo->samples), format_limits.sampleCounts, validation_error_map[VALIDATION_ERROR_09e0078e]); } - if (pCreateInfo->initialLayout != VK_IMAGE_LAYOUT_UNDEFINED && pCreateInfo->initialLayout != VK_IMAGE_LAYOUT_PREINITIALIZED) { - skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, 0, __LINE__, - VALIDATION_ERROR_09e0b801, "Image", - "vkCreateImage parameter, pCreateInfo->initialLayout, must be VK_IMAGE_LAYOUT_UNDEFINED or " - "VK_IMAGE_LAYOUT_PREINITIALIZED. %s", - validation_error_map[VALIDATION_ERROR_09e0b801]); - } - if ((pCreateInfo->flags & VK_IMAGE_CREATE_SPARSE_BINDING_BIT) && (!GetEnabledFeatures(device_data)->sparseBinding)) { skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, VALIDATION_ERROR_09e00792, "DS", |
