diff options
| author | Dustin Graves <dustin@lunarg.com> | 2016-05-11 18:31:44 -0600 |
|---|---|---|
| committer | Dustin Graves <dustin@lunarg.com> | 2016-05-12 11:30:00 -0600 |
| commit | 37c4c06347ad58d2a259b693e17efc7d646449fc (patch) | |
| tree | 5fb6748f6b20f6ba51f5061c473defc1d39f8985 /layers/parameter_validation.cpp | |
| parent | 243c5fb0b0d4237f9bd5c8fed01dfd87c126dc2e (diff) | |
| download | usermoji-37c4c06347ad58d2a259b693e17efc7d646449fc.tar.xz | |
layers: Additional vkCreateImage param validation
Add more vkCreateImage parameter validation, based on the valid usage
section for VkImageCreateInfo.
Issues-Addressed: GitHub #354
Change-Id: Ia978a64f6c03c3cf115a07e707099253104e04a1
Diffstat (limited to 'layers/parameter_validation.cpp')
| -rw-r--r-- | layers/parameter_validation.cpp | 100 |
1 files changed, 84 insertions, 16 deletions
diff --git a/layers/parameter_validation.cpp b/layers/parameter_validation.cpp index d556c3c8..c8b70406 100644 --- a/layers/parameter_validation.cpp +++ b/layers/parameter_validation.cpp @@ -21,6 +21,9 @@ * Author: Dustin Graves <dustin@lunarg.com> */ +#define NOMINMAX + +#include <math.h> #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -2358,32 +2361,97 @@ vkDestroyBufferView(VkDevice device, VkBufferView bufferView, const VkAllocation } } -bool PreCreateImage(layer_data *device_data, const VkImageCreateInfo *pCreateInfo) { +VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateImage(VkDevice device, const VkImageCreateInfo *pCreateInfo, + const VkAllocationCallbacks *pAllocator, VkImage *pImage) { + VkResult result = VK_ERROR_VALIDATION_FAILED_EXT; + bool skip_call = false; + layer_data *device_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map); + assert(device_data != NULL); + debug_report_data *report_data = device_data->report_data; + + skip_call |= parameter_validation_vkCreateImage(report_data, pCreateInfo, pAllocator, pImage); + if (pCreateInfo != nullptr) { if (pCreateInfo->sharingMode == VK_SHARING_MODE_CONCURRENT) { - validate_queue_family_indices(device_data, "vkCreateImage", "pCreateInfo->pQueueFamilyIndices", - pCreateInfo->queueFamilyIndexCount, pCreateInfo->pQueueFamilyIndices); + // pQueueFamilyIndices must not be NULL + skip_call |= validate_required_pointer(report_data, "vkCreateImage", "pCreateInfo->pQueueFamilyIndices", + pCreateInfo->pQueueFamilyIndices); + + // queueFamilyIndexCount must be greater than 1 + skip_call |= ValidateGreaterThan(report_data, "vkCreateImage", "pCreateInfo->pQueueFamilyIndices", + pCreateInfo->queueFamilyIndexCount, 1u); + + skip_call |= validate_queue_family_indices(device_data, "vkCreateImage", "pCreateInfo->pQueueFamilyIndices", + pCreateInfo->queueFamilyIndexCount, pCreateInfo->pQueueFamilyIndices); } - } - return true; -} + // width, height, and depth members of extent must be greater than 0 + skip_call |= ValidateGreaterThan(report_data, "vkCreateImage", "pCreateInfo->extent.width", pCreateInfo->extent.width, + 0u); + skip_call |= ValidateGreaterThan(report_data, "vkCreateImage", "pCreateInfo->extent.height", pCreateInfo->extent.height, + 0u); + skip_call |= ValidateGreaterThan(report_data, "vkCreateImage", "pCreateInfo->extent.depth", pCreateInfo->extent.depth, + 0u); -VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL -vkCreateImage(VkDevice device, const VkImageCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkImage *pImage) { - VkResult result = VK_ERROR_VALIDATION_FAILED_EXT; - bool skipCall = false; - layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map); - assert(my_data != NULL); + // mipLevels must be greater than 0 + skip_call |= ValidateGreaterThan(report_data, "vkCreateImage", "pCreateInfo->mipLevels", pCreateInfo->mipLevels, + 0u); - skipCall |= parameter_validation_vkCreateImage(my_data->report_data, pCreateInfo, pAllocator, pImage); + // arrayLayers must be greater than 0 + skip_call |= ValidateGreaterThan(report_data, "vkCreateImage", "pCreateInfo->arrayLayers", pCreateInfo->arrayLayers, + 0u); - if (!skipCall) { - PreCreateImage(my_data, pCreateInfo); + // If imageType is VK_IMAGE_TYPE_1D, both extent.height and extent.depth must be 1 + if ((pCreateInfo->imageType == VK_IMAGE_TYPE_1D) && (pCreateInfo->extent.height != 1) && (pCreateInfo->extent.depth != 1)) { + skip_call |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__, 1, + LayerName, "vkCreateImage: if pCreateInfo->imageType is VK_IMAGE_TYPE_1D, both " + "pCreateInfo->extent.height and pCreateInfo->extent.depth must be 1"); + } + if (pCreateInfo->imageType == VK_IMAGE_TYPE_2D) { + // If imageType is VK_IMAGE_TYPE_2D and flags contains VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT, extent.width and + // extent.height must be equal + if ((pCreateInfo->flags & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT) && + (pCreateInfo->extent.width != pCreateInfo->extent.height)) { + skip_call |= + log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__, 1, + LayerName, "vkCreateImage: if pCreateInfo->imageType is VK_IMAGE_TYPE_2D and " + "pCreateInfo->flags contains VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT, " + "pCreateInfo->extent.width and pCreateInfo->extent.height must be equal"); + } + + if (pCreateInfo->extent.depth != 1) { + skip_call |= + log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__, 1, + LayerName, + "vkCreateImage: if pCreateInfo->imageType is VK_IMAGE_TYPE_2D, pCreateInfo->extent.depth must be 1"); + } + } + + // mipLevels must be less than or equal to floor(log2(max(extent.width,extent.height,extent.depth)))+1 + uint32_t maxDim = std::max(std::max(pCreateInfo->extent.width, pCreateInfo->extent.height), pCreateInfo->extent.depth); + if (pCreateInfo->mipLevels > (floor(log2(maxDim)) + 1)) { + skip_call |= log_msg( + report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__, 1, LayerName, + "vkCreateImage: pCreateInfo->mipLevels must be less than or equal to " + "floor(log2(max(pCreateInfo->extent.width, pCreateInfo->extent.height, pCreateInfo->extent.depth)))+1"); + } + + // If flags contains VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT or VK_IMAGE_CREATE_SPARSE_ALIASED_BIT, it must also contain + // VK_IMAGE_CREATE_SPARSE_BINDING_BIT + if (((pCreateInfo->flags & (VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT | VK_IMAGE_CREATE_SPARSE_ALIASED_BIT)) != 0) && + ((pCreateInfo->flags & VK_IMAGE_CREATE_SPARSE_BINDING_BIT) != VK_IMAGE_CREATE_SPARSE_BINDING_BIT)) { + skip_call |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__, 1, + LayerName, + "vkCreateImage: pCreateInfo->flags contains VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT or " + "VK_IMAGE_CREATE_SPARSE_ALIASED_BIT, it must also contain VK_IMAGE_CREATE_SPARSE_BINDING_BIT"); + } + } + + if (!skip_call) { result = get_dispatch_table(pc_device_table_map, device)->CreateImage(device, pCreateInfo, pAllocator, pImage); - validate_result(my_data->report_data, "vkCreateImage", result); + validate_result(report_data, "vkCreateImage", result); } return result; |
