From af006f57700efaab33e4fd2fe50a8017b3e25c01 Mon Sep 17 00:00:00 2001 From: Mark Lobodzinski Date: Thu, 26 Jan 2017 15:23:11 -0700 Subject: [PATCH] layers: Move CreateImage validation into core_val Was in Image layer. Added layer_data accessor functions. Change-Id: I55b7896cfc9de81210c9fba4d332998c827f5d44 --- layers/buffer_validation.cpp | 185 +++++++++++++++++++++++++++++++++++ layers/buffer_validation.h | 5 + layers/core_validation.cpp | 25 ++++- layers/core_validation_error_enums.h | 4 + layers/core_validation_types.h | 8 ++ layers/image.cpp | 176 +-------------------------------- layers/image.h | 1 - 7 files changed, 225 insertions(+), 179 deletions(-) diff --git a/layers/buffer_validation.cpp b/layers/buffer_validation.cpp index 4094b0a..1b650aa 100644 --- a/layers/buffer_validation.cpp +++ b/layers/buffer_validation.cpp @@ -21,8 +21,193 @@ // Allow use of STL min and max functions in Windows #define NOMINMAX +#include + +#include "vk_enum_string_helper.h" +#include "vk_layer_data.h" +#include "vk_layer_utils.h" +#include "vk_layer_logging.h" + + #include "buffer_validation.h" +bool PreCallValidateCreateImage(core_validation::layer_data *device_data, const VkImageCreateInfo *pCreateInfo, + const VkAllocationCallbacks *pAllocator, VkImage *pImage) { + bool skip_call = false; + VkImageFormatProperties ImageFormatProperties; + const VkPhysicalDevice physical_device = core_validation::GetPhysicalDevice(device_data); + const debug_report_data *report_data = core_validation::GetReportData(device_data); + + if (pCreateInfo->format != VK_FORMAT_UNDEFINED) { + VkFormatProperties properties; + core_validation::GetFormatPropertiesPointer(device_data)(physical_device, pCreateInfo->format, &properties); + + if ((pCreateInfo->tiling == VK_IMAGE_TILING_LINEAR) && (properties.linearTilingFeatures == 0)) { + std::stringstream ss; + ss << "vkCreateImage format parameter (" << string_VkFormat(pCreateInfo->format) << ") is an unsupported format"; + skip_call |= + log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, + VALIDATION_ERROR_02150, "IMAGE", "%s. %s", ss.str().c_str(), validation_error_map[VALIDATION_ERROR_02150]); + } + + if ((pCreateInfo->tiling == VK_IMAGE_TILING_OPTIMAL) && (properties.optimalTilingFeatures == 0)) { + std::stringstream ss; + ss << "vkCreateImage format parameter (" << string_VkFormat(pCreateInfo->format) << ") is an unsupported format"; + skip_call |= + log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, + VALIDATION_ERROR_02155, "IMAGE", "%s. %s", ss.str().c_str(), validation_error_map[VALIDATION_ERROR_02155]); + } + + // 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_call |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, + __LINE__, VALIDATION_ERROR_02158, "IMAGE", "%s. %s", ss.str().c_str(), + validation_error_map[VALIDATION_ERROR_02158]); + } + 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_call |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, + __LINE__, VALIDATION_ERROR_02153, "IMAGE", "%s. %s", ss.str().c_str(), + validation_error_map[VALIDATION_ERROR_02153]); + } + } + // 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)) { + 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"; + skip_call |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, + __LINE__, VALIDATION_ERROR_02159, "IMAGE", "%s. %s", ss.str().c_str(), + validation_error_map[VALIDATION_ERROR_02159]); + } + if ((pCreateInfo->tiling == VK_IMAGE_TILING_LINEAR) && + ((properties.linearTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_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_DEPTH_STENCIL_ATTACHMENT"; + skip_call |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, + __LINE__, VALIDATION_ERROR_02154, "IMAGE", "%s. %s", ss.str().c_str(), + validation_error_map[VALIDATION_ERROR_02154]); + } + } + } else { + skip_call |= + log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, + VALIDATION_ERROR_00715, "IMAGE", "vkCreateImage: VkFormat for image must not be VK_FORMAT_UNDEFINED. %s", + validation_error_map[VALIDATION_ERROR_00715]); + } + + // Internal call to get format info. Still goes through layers, could potentially go directly to ICD. + core_validation::GetImageFormatPropertiesPointer(device_data)(physical_device, pCreateInfo->format, pCreateInfo->imageType, + pCreateInfo->tiling, pCreateInfo->usage, pCreateInfo->flags, + &ImageFormatProperties); + + VkDeviceSize imageGranularity = core_validation::GetPhysicalDeviceProperties(device_data)->limits.bufferImageGranularity; + imageGranularity = imageGranularity == 1 ? 0 : imageGranularity; + + // Make sure all required dimension are non-zero at least. + bool failedMinSize = false; + switch (pCreateInfo->imageType) { + case VK_IMAGE_TYPE_3D: + if (pCreateInfo->extent.depth == 0) { + failedMinSize = true; + } + // Intentional fall-through + case VK_IMAGE_TYPE_2D: + if (pCreateInfo->extent.height == 0) { + failedMinSize = true; + } + // Intentional fall-through + case VK_IMAGE_TYPE_1D: + if (pCreateInfo->extent.width == 0) { + failedMinSize = true; + } + break; + default: + break; + } + // TODO: VALIDATION_ERROR_00716 + // this is *almost* VU 00716, except should not be condidtional on image type - all extents must be non-zero for all types + if (failedMinSize) { + skip_call |= + 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 is 0 for at least one required dimension for image of type %d: " + "Width = %d Height = %d Depth = %d.", + pCreateInfo->imageType, pCreateInfo->extent.width, pCreateInfo->extent.height, pCreateInfo->extent.depth); + } + + // TODO: VALIDATION_ERROR_02125 VALIDATION_ERROR_02126 VALIDATION_ERROR_02128 VALIDATION_ERROR_00720 + // 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_call |= 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)); + } + + 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)vk_format_get_size(pCreateInfo->format) + + (uint64_t)imageGranularity) & + ~(uint64_t)imageGranularity; + + if (totalSize > ImageFormatProperties.maxResourceSize) { + skip_call |= 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); + } + + // TODO: VALIDATION_ERROR_02132 + if (pCreateInfo->mipLevels > ImageFormatProperties.maxMipLevels) { + skip_call |= 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_call |= log_msg( + report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, 0, __LINE__, VALIDATION_ERROR_02133, + "Image", "CreateImage arrayLayers=%d exceeds allowable maximum supported by format of %d. %s", pCreateInfo->arrayLayers, + ImageFormatProperties.maxArrayLayers, validation_error_map[VALIDATION_ERROR_02133]); + } + + if ((pCreateInfo->samples & ImageFormatProperties.sampleCounts) == 0) { + skip_call |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, 0, __LINE__, + VALIDATION_ERROR_02138, "Image", "CreateImage samples %s is not supported by format 0x%.8X. %s", + string_VkSampleCountFlagBits(pCreateInfo->samples), ImageFormatProperties.sampleCounts, + validation_error_map[VALIDATION_ERROR_02138]); + } + + if (pCreateInfo->initialLayout != VK_IMAGE_LAYOUT_UNDEFINED && pCreateInfo->initialLayout != VK_IMAGE_LAYOUT_PREINITIALIZED) { + skip_call |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, 0, __LINE__, + VALIDATION_ERROR_00731, "Image", + "vkCreateImage parameter, pCreateInfo->initialLayout, must be VK_IMAGE_LAYOUT_UNDEFINED or " + "VK_IMAGE_LAYOUT_PREINITIALIZED. %s", + validation_error_map[VALIDATION_ERROR_00731]); + } + + return skip_call; +} + void PostCallRecordCreateImage(std::unordered_map> *imageMap, std::unordered_map> *imageSubresourceMap, std::unordered_map *imageLayoutMap, diff --git a/layers/buffer_validation.h b/layers/buffer_validation.h index a5fd396..88342a1 100644 --- a/layers/buffer_validation.h +++ b/layers/buffer_validation.h @@ -21,11 +21,16 @@ #define CORE_VALIDATION_BUFFER_VALIDATION_H_ #include "core_validation_types.h" +#include "core_validation_error_enums.h" #include "vulkan/vk_layer.h" #include #include #include + +bool PreCallValidateCreateImage(core_validation::layer_data *device_data, const VkImageCreateInfo *pCreateInfo, + const VkAllocationCallbacks *pAllocator, VkImage *pImage); + void PostCallRecordCreateImage(std::unordered_map> *imageMap, std::unordered_map> *imageSubresourceMap, std::unordered_map *imageLayoutMap, diff --git a/layers/core_validation.cpp b/layers/core_validation.cpp index d342afa..4d1e30e 100644 --- a/layers/core_validation.cpp +++ b/layers/core_validation.cpp @@ -6394,12 +6394,31 @@ VKAPI_ATTR VkResult VKAPI_CALL CreateBufferView(VkDevice device, const VkBufferV return result; } +// Access helper functions for external modules +PFN_vkGetPhysicalDeviceFormatProperties GetFormatPropertiesPointer(core_validation::layer_data *device_data) { + return device_data->instance_data->dispatch_table.GetPhysicalDeviceFormatProperties; +} + +PFN_vkGetPhysicalDeviceImageFormatProperties GetImageFormatPropertiesPointer(core_validation::layer_data *device_data) { + return device_data->instance_data->dispatch_table.GetPhysicalDeviceImageFormatProperties; +} + +VkPhysicalDevice GetPhysicalDevice(core_validation::layer_data *device_data) { return device_data->physical_device; } + +const debug_report_data *GetReportData(core_validation::layer_data *device_data) { return device_data->report_data; } + +const VkPhysicalDeviceProperties *GetPhysicalDeviceProperties(core_validation::layer_data *device_data) { + return &device_data->phys_dev_props; +} + VKAPI_ATTR VkResult VKAPI_CALL CreateImage(VkDevice device, const VkImageCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkImage *pImage) { + VkResult result = VK_ERROR_VALIDATION_FAILED_EXT; layer_data *dev_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map); - - VkResult result = dev_data->dispatch_table.CreateImage(device, pCreateInfo, pAllocator, pImage); - + bool skip = PreCallValidateCreateImage(dev_data, pCreateInfo, pAllocator, pImage); + if (!skip) { + result = dev_data->dispatch_table.CreateImage(device, pCreateInfo, pAllocator, pImage); + } if (VK_SUCCESS == result) { std::lock_guard lock(global_lock); PostCallRecordCreateImage(&dev_data->imageMap, &dev_data->imageSubresourceMap, &dev_data->imageLayoutMap, pCreateInfo, diff --git a/layers/core_validation_error_enums.h b/layers/core_validation_error_enums.h index e4dd0bb..4efd778 100644 --- a/layers/core_validation_error_enums.h +++ b/layers/core_validation_error_enums.h @@ -189,4 +189,8 @@ enum DEV_LIMITS_ERROR { DEVLIMITS_COUNT_MISMATCH, DEVLIMITS_INVALID_QUEUE_CREATE_REQUEST, }; + +enum IMAGE_ERROR { + IMAGE_INVALID_FORMAT_LIMITS_VIOLATION, +}; #endif // CORE_VALIDATION_ERROR_ENUMS_H_ diff --git a/layers/core_validation_types.h b/layers/core_validation_types.h index e2b95f5..22090a8 100644 --- a/layers/core_validation_types.h +++ b/layers/core_validation_types.h @@ -49,6 +49,7 @@ #include "vk_safe_struct.h" #include "vulkan/vulkan.h" #include "vk_validation_error_messages.h" +#include "vk_layer_logging.h" #include #include #include @@ -692,6 +693,13 @@ void AddCommandBufferBindingImage(const layer_data *, GLOBAL_CB_NODE *, IMAGE_ST void AddCommandBufferBindingImageView(const layer_data *, GLOBAL_CB_NODE *, IMAGE_VIEW_STATE *); void AddCommandBufferBindingBuffer(const layer_data *, GLOBAL_CB_NODE *, BUFFER_STATE *); void AddCommandBufferBindingBufferView(const layer_data *, GLOBAL_CB_NODE *, BUFFER_VIEW_STATE *); + +// Prototypes for layer_data accessor functions. These should be in their own header file at some point +PFN_vkGetPhysicalDeviceFormatProperties GetFormatPropertiesPointer(layer_data *); +PFN_vkGetPhysicalDeviceImageFormatProperties GetImageFormatPropertiesPointer(layer_data *); +VkPhysicalDevice GetPhysicalDevice(layer_data *); +const debug_report_data *GetReportData(layer_data *); +const VkPhysicalDeviceProperties *GetPhysicalDeviceProperties(layer_data *); } #endif // CORE_VALIDATION_TYPES_H_ diff --git a/layers/image.cpp b/layers/image.cpp index ddc0738..c823eed 100644 --- a/layers/image.cpp +++ b/layers/image.cpp @@ -221,185 +221,11 @@ static const VkLayerProperties global_layer = { VKAPI_ATTR VkResult VKAPI_CALL CreateImage(VkDevice device, const VkImageCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkImage *pImage) { - bool skip_call = false; VkResult result = VK_ERROR_VALIDATION_FAILED_EXT; - VkImageFormatProperties ImageFormatProperties; - layer_data *device_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map); - VkPhysicalDevice physicalDevice = device_data->physicalDevice; - layer_data *phy_dev_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map); - - if (pCreateInfo->format != VK_FORMAT_UNDEFINED) { - VkFormatProperties properties; - phy_dev_data->instance_dispatch_table->GetPhysicalDeviceFormatProperties(device_data->physicalDevice, pCreateInfo->format, - &properties); - if ((pCreateInfo->tiling == VK_IMAGE_TILING_LINEAR) && (properties.linearTilingFeatures == 0)) { - std::stringstream ss; - ss << "vkCreateImage format parameter (" << string_VkFormat(pCreateInfo->format) << ") is an unsupported format"; - skip_call |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, - 0, __LINE__, VALIDATION_ERROR_02150, "IMAGE", "%s. %s", ss.str().c_str(), - validation_error_map[VALIDATION_ERROR_02150]); - } - - if ((pCreateInfo->tiling == VK_IMAGE_TILING_OPTIMAL) && (properties.optimalTilingFeatures == 0)) { - std::stringstream ss; - ss << "vkCreateImage format parameter (" << string_VkFormat(pCreateInfo->format) << ") is an unsupported format"; - skip_call |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, - 0, __LINE__, VALIDATION_ERROR_02155, "IMAGE", "%s. %s", ss.str().c_str(), - validation_error_map[VALIDATION_ERROR_02155]); - } - - // 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_call |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, - VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, VALIDATION_ERROR_02158, "IMAGE", - "%s. %s", ss.str().c_str(), validation_error_map[VALIDATION_ERROR_02158]); - } - 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_call |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, - VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, VALIDATION_ERROR_02153, "IMAGE", - "%s. %s", ss.str().c_str(), validation_error_map[VALIDATION_ERROR_02153]); - } - } - // 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)) { - 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"; - skip_call |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, - VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, VALIDATION_ERROR_02159, "IMAGE", - "%s. %s", ss.str().c_str(), validation_error_map[VALIDATION_ERROR_02159]); - } - if ((pCreateInfo->tiling == VK_IMAGE_TILING_LINEAR) && - ((properties.linearTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_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_DEPTH_STENCIL_ATTACHMENT"; - skip_call |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, - VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, VALIDATION_ERROR_02154, "IMAGE", - "%s. %s", ss.str().c_str(), validation_error_map[VALIDATION_ERROR_02154]); - } - } - } else { - skip_call |= - log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, - VALIDATION_ERROR_00715, "IMAGE", "vkCreateImage: VkFormat for image must not be VK_FORMAT_UNDEFINED. %s", - validation_error_map[VALIDATION_ERROR_00715]); - } - - // Internal call to get format info. Still goes through layers, could potentially go directly to ICD. - phy_dev_data->instance_dispatch_table->GetPhysicalDeviceImageFormatProperties( - physicalDevice, pCreateInfo->format, pCreateInfo->imageType, pCreateInfo->tiling, pCreateInfo->usage, pCreateInfo->flags, - &ImageFormatProperties); - VkDeviceSize imageGranularity = device_data->physicalDeviceProperties.limits.bufferImageGranularity; - imageGranularity = imageGranularity == 1 ? 0 : imageGranularity; + result = device_data->device_dispatch_table->CreateImage(device, pCreateInfo, pAllocator, pImage); - // Make sure all required dimension are non-zero at least. - bool failedMinSize = false; - switch (pCreateInfo->imageType) { - case VK_IMAGE_TYPE_3D: - if (pCreateInfo->extent.depth == 0) { - failedMinSize = true; - } - // Intentional fall-through - case VK_IMAGE_TYPE_2D: - if (pCreateInfo->extent.height == 0) { - failedMinSize = true; - } - // Intentional fall-through - case VK_IMAGE_TYPE_1D: - if (pCreateInfo->extent.width == 0) { - failedMinSize = true; - } - break; - default: - break; - } - // TODO: VALIDATION_ERROR_00716 - // this is *almost* VU 00716, except should not be condidtional on image type - all extents must be non-zero for all types - if (failedMinSize) { - skip_call |= - log_msg(phy_dev_data->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 is 0 for at least one required dimension for image of type %d: " - "Width = %d Height = %d Depth = %d.", - pCreateInfo->imageType, pCreateInfo->extent.width, pCreateInfo->extent.height, pCreateInfo->extent.depth); - } - - // TODO: VALIDATION_ERROR_02125 VALIDATION_ERROR_02126 VALIDATION_ERROR_02128 VALIDATION_ERROR_00720 - // 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_call |= log_msg(phy_dev_data->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)); - } - - 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)vk_format_get_size(pCreateInfo->format) + - (uint64_t)imageGranularity) & - ~(uint64_t)imageGranularity; - - if (totalSize > ImageFormatProperties.maxResourceSize) { - skip_call |= log_msg(phy_dev_data->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); - } - - // TODO: VALIDATION_ERROR_02132 - if (pCreateInfo->mipLevels > ImageFormatProperties.maxMipLevels) { - skip_call |= log_msg(phy_dev_data->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_call |= log_msg( - phy_dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, 0, __LINE__, - VALIDATION_ERROR_02133, "Image", "CreateImage arrayLayers=%d exceeds allowable maximum supported by format of %d. %s", - pCreateInfo->arrayLayers, ImageFormatProperties.maxArrayLayers, validation_error_map[VALIDATION_ERROR_02133]); - } - - if ((pCreateInfo->samples & ImageFormatProperties.sampleCounts) == 0) { - skip_call |= - log_msg(phy_dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, 0, __LINE__, - VALIDATION_ERROR_02138, "Image", "CreateImage samples %s is not supported by format 0x%.8X. %s", - string_VkSampleCountFlagBits(pCreateInfo->samples), ImageFormatProperties.sampleCounts, - validation_error_map[VALIDATION_ERROR_02138]); - } - - if (pCreateInfo->initialLayout != VK_IMAGE_LAYOUT_UNDEFINED && pCreateInfo->initialLayout != VK_IMAGE_LAYOUT_PREINITIALIZED) { - skip_call |= log_msg(phy_dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, 0, - __LINE__, VALIDATION_ERROR_00731, "Image", - "vkCreateImage parameter, pCreateInfo->initialLayout, must be VK_IMAGE_LAYOUT_UNDEFINED or " - "VK_IMAGE_LAYOUT_PREINITIALIZED. %s", - validation_error_map[VALIDATION_ERROR_00731]); - } - - if (!skip_call) { - result = device_data->device_dispatch_table->CreateImage(device, pCreateInfo, pAllocator, pImage); - } if (result == VK_SUCCESS) { std::lock_guard lock(global_lock); device_data->imageMap[*pImage] = IMAGE_STATE(pCreateInfo); diff --git a/layers/image.h b/layers/image.h index 727980a..002b981 100644 --- a/layers/image.h +++ b/layers/image.h @@ -41,7 +41,6 @@ enum IMAGE_ERROR { IMAGE_INVALID_FORMAT, // Operation specifies an invalid format, or there is a format mismatch IMAGE_INVALID_FILTER, // Operation specifies an invalid filter setting IMAGE_INVALID_IMAGE_RESOURCE, // Image resource/subresource called with invalid setting - IMAGE_INVALID_FORMAT_LIMITS_VIOLATION, // Device limits for this format have been exceeded IMAGE_INVALID_LAYOUT, // Operation specifies an invalid layout IMAGE_INVALID_EXTENTS, // Operation specifies invalid image extents IMAGE_INVALID_USAGE, // Image was created without necessary usage for operation -- 2.7.4