From 3013625ffe951526673c5b6f3d20bedf3b62cf69 Mon Sep 17 00:00:00 2001 From: Mark Lobodzinski Date: Wed, 15 Feb 2017 12:59:00 -0700 Subject: layers: Move image layer image-buffer-copy to CV Moved the image layer validation for buffer-image copies to the buffer validation module. Change-Id: If8ff8aa183f88560dc5db9d59c92346ee47b01e9 --- layers/image.cpp | 184 ++----------------------------------------------------- 1 file changed, 4 insertions(+), 180 deletions(-) (limited to 'layers/image.cpp') diff --git a/layers/image.cpp b/layers/image.cpp index cec9e7b4..af24c568 100644 --- a/layers/image.cpp +++ b/layers/image.cpp @@ -242,195 +242,19 @@ VKAPI_ATTR void VKAPI_CALL DestroyImage(VkDevice device, VkImage image, const Vk device_data->device_dispatch_table->DestroyImage(device, image, pAllocator); } -static bool ValidateBufferImageCopyData(layer_data *dev_data, uint32_t regionCount, const VkBufferImageCopy *pRegions, - VkImage image, const char *function) { - bool skip = false; - - for (uint32_t i = 0; i < regionCount; i++) { - auto image_info = GetImageState(dev_data, image); - if (image_info) { - if (image_info->imageType == VK_IMAGE_TYPE_1D) { - if ((pRegions[i].imageOffset.y != 0) || (pRegions[i].imageExtent.height != 1)) { - skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, - reinterpret_cast(image), __LINE__, VALIDATION_ERROR_01746, "IMAGE", - "%s(): pRegion[%d] imageOffset.y is %d and imageExtent.height is %d. For 1D images these " - "must be 0 and 1, respectively. %s", - function, i, pRegions[i].imageOffset.y, pRegions[i].imageExtent.height, - validation_error_map[VALIDATION_ERROR_01746]); - } - } - - if ((image_info->imageType == VK_IMAGE_TYPE_1D) || (image_info->imageType == VK_IMAGE_TYPE_2D)) { - if ((pRegions[i].imageOffset.z != 0) || (pRegions[i].imageExtent.depth != 1)) { - skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, - reinterpret_cast(image), __LINE__, VALIDATION_ERROR_01747, "IMAGE", - "%s(): pRegion[%d] imageOffset.z is %d and imageExtent.depth is %d. For 1D and 2D images these " - "must be 0 and 1, respectively. %s", - function, i, pRegions[i].imageOffset.z, pRegions[i].imageExtent.depth, - validation_error_map[VALIDATION_ERROR_01747]); - } - } - - if (image_info->imageType == VK_IMAGE_TYPE_3D) { - if ((0 != pRegions[i].imageSubresource.baseArrayLayer) || (1 != pRegions[i].imageSubresource.layerCount)) { - skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, - reinterpret_cast(image), __LINE__, VALIDATION_ERROR_01281, "IMAGE", - "%s(): pRegion[%d] imageSubresource.baseArrayLayer is %d and imageSubresource.layerCount is " - "%d. For 3D images these must be 0 and 1, respectively. %s", - function, i, pRegions[i].imageSubresource.baseArrayLayer, - pRegions[i].imageSubresource.layerCount, validation_error_map[VALIDATION_ERROR_01281]); - } - } - - // If the the calling command's VkImage parameter's format is not a depth/stencil format, - // then bufferOffset must be a multiple of the calling command's VkImage parameter's texel size - auto texel_size = vk_format_get_size(image_info->format); - if (!vk_format_is_depth_and_stencil(image_info->format) && vk_safe_modulo(pRegions[i].bufferOffset, texel_size) != 0) { - skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, - reinterpret_cast(image), __LINE__, VALIDATION_ERROR_01263, "IMAGE", - "%s(): pRegion[%d] bufferOffset 0x%" PRIxLEAST64 - " must be a multiple of this format's texel size (" PRINTF_SIZE_T_SPECIFIER "). %s", - function, i, pRegions[i].bufferOffset, texel_size, validation_error_map[VALIDATION_ERROR_01263]); - } - - // BufferOffset must be a multiple of 4 - if (vk_safe_modulo(pRegions[i].bufferOffset, 4) != 0) { - skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, - reinterpret_cast(image), __LINE__, VALIDATION_ERROR_01264, "IMAGE", - "%s(): pRegion[%d] bufferOffset 0x%" PRIxLEAST64 " must be a multiple of 4. %s", function, i, - pRegions[i].bufferOffset, validation_error_map[VALIDATION_ERROR_01264]); - } - - // BufferRowLength must be 0, or greater than or equal to the width member of imageExtent - if ((pRegions[i].bufferRowLength != 0) && (pRegions[i].bufferRowLength < pRegions[i].imageExtent.width)) { - skip |= log_msg( - dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, - reinterpret_cast(image), __LINE__, VALIDATION_ERROR_01265, "IMAGE", - "%s(): pRegion[%d] bufferRowLength (%d) must be zero or greater-than-or-equal-to imageExtent.width (%d). %s", - function, i, pRegions[i].bufferRowLength, pRegions[i].imageExtent.width, - validation_error_map[VALIDATION_ERROR_01265]); - } - - // BufferImageHeight must be 0, or greater than or equal to the height member of imageExtent - if ((pRegions[i].bufferImageHeight != 0) && (pRegions[i].bufferImageHeight < pRegions[i].imageExtent.height)) { - skip |= log_msg( - dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, - reinterpret_cast(image), __LINE__, VALIDATION_ERROR_01266, "IMAGE", - "%s(): pRegion[%d] bufferImageHeight (%d) must be zero or greater-than-or-equal-to imageExtent.height (%d). %s", - function, i, pRegions[i].bufferImageHeight, pRegions[i].imageExtent.height, - validation_error_map[VALIDATION_ERROR_01266]); - } - - // subresource aspectMask must have exactly 1 bit set - const int num_bits = sizeof(VkFlags) * CHAR_BIT; - std::bitset aspect_mask_bits(pRegions[i].imageSubresource.aspectMask); - if (aspect_mask_bits.count() != 1) { - skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, - reinterpret_cast(image), __LINE__, VALIDATION_ERROR_01280, "IMAGE", - "%s: aspectMasks for imageSubresource in each region must have only a single bit set. %s", function, - validation_error_map[VALIDATION_ERROR_01280]); - } - - // image subresource aspect bit must match format - if (((0 != (pRegions[i].imageSubresource.aspectMask & VK_IMAGE_ASPECT_COLOR_BIT)) && - (!vk_format_is_color(image_info->format))) || - ((0 != (pRegions[i].imageSubresource.aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT)) && - (!vk_format_has_depth(image_info->format))) || - ((0 != (pRegions[i].imageSubresource.aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT)) && - (!vk_format_has_stencil(image_info->format)))) { - skip |= log_msg( - dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, - reinterpret_cast(image), __LINE__, VALIDATION_ERROR_01279, "IMAGE", - "%s(): pRegion[%d] subresource aspectMask 0x%x specifies aspects that are not present in image format 0x%x. %s", - function, i, pRegions[i].imageSubresource.aspectMask, image_info->format, - validation_error_map[VALIDATION_ERROR_01279]); - } - - // Checks that apply only to compressed images - // TODO: there is a comment in ValidateCopyBufferImageTransferGranularityRequirements() in core_validation.cpp that - // reserves a place for these compressed image checks. This block of code could move there once the image - // stuff is moved into core validation. - if (vk_format_is_compressed(image_info->format)) { - VkExtent2D block_size = vk_format_compressed_block_size(image_info->format); - - // BufferRowLength must be a multiple of block width - if (vk_safe_modulo(pRegions[i].bufferRowLength, block_size.width) != 0) { - skip |= log_msg( - dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, - reinterpret_cast(image), __LINE__, VALIDATION_ERROR_01271, "IMAGE", - "%s(): pRegion[%d] bufferRowLength (%d) must be a multiple of the compressed image's texel width (%d). %s.", - function, i, pRegions[i].bufferRowLength, block_size.width, validation_error_map[VALIDATION_ERROR_01271]); - } - - // BufferRowHeight must be a multiple of block height - if (vk_safe_modulo(pRegions[i].bufferImageHeight, block_size.height) != 0) { - skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, - reinterpret_cast(image), __LINE__, VALIDATION_ERROR_01272, "IMAGE", - "%s(): pRegion[%d] bufferImageHeight (%d) must be a multiple of the compressed image's texel " - "height (%d). %s.", - function, i, pRegions[i].bufferImageHeight, block_size.height, - validation_error_map[VALIDATION_ERROR_01272]); - } - - // image offsets must be multiples of block dimensions - if ((vk_safe_modulo(pRegions[i].imageOffset.x, block_size.width) != 0) || - (vk_safe_modulo(pRegions[i].imageOffset.y, block_size.height) != 0)) { - skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, - reinterpret_cast(image), __LINE__, VALIDATION_ERROR_01273, "IMAGE", - "%s(): pRegion[%d] imageOffset(x,y) (%d, %d) must be multiples of the compressed image's texel " - "width & height (%d, %d). %s.", - function, i, pRegions[i].imageOffset.x, pRegions[i].imageOffset.y, block_size.width, - block_size.height, validation_error_map[VALIDATION_ERROR_01273]); - } - - // bufferOffset must be a multiple of block size (linear bytes) - int block_size_in_bytes = block_size.width * block_size.height; - if (vk_safe_modulo(pRegions[i].bufferOffset, block_size_in_bytes) != 0) { - skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, - reinterpret_cast(image), __LINE__, VALIDATION_ERROR_01274, "IMAGE", - "%s(): pRegion[%d] bufferOffset (0x%" PRIxLEAST64 ") must be a multiple of the compressed image's texel block " - "size (0x%x). %s.", - function, i, pRegions[i].bufferOffset, block_size_in_bytes, - validation_error_map[VALIDATION_ERROR_01274]); - } - } - } - } - - return skip; -} - -static bool PreCallValidateCmdCopyImageToBuffer(layer_data *dev_data, VkImage srcImage, uint32_t regionCount, - const VkBufferImageCopy *pRegions, const char *func_name) { - bool skip = ValidateBufferImageCopyData(dev_data, regionCount, pRegions, srcImage, "vkCmdCopyImageToBuffer"); - return skip; -} - VKAPI_ATTR void VKAPI_CALL CmdCopyImageToBuffer(VkCommandBuffer commandBuffer, VkImage srcImage, VkImageLayout srcImageLayout, VkBuffer dstBuffer, uint32_t regionCount, const VkBufferImageCopy *pRegions) { layer_data *device_data = GetLayerDataPtr(get_dispatch_key(commandBuffer), layer_data_map); - - if (!PreCallValidateCmdCopyImageToBuffer(device_data, srcImage, regionCount, pRegions, "vkCmdCopyImageToBuffer()")) { - device_data->device_dispatch_table->CmdCopyImageToBuffer(commandBuffer, srcImage, srcImageLayout, dstBuffer, regionCount, - pRegions); - } -} - -static bool PreCallValidateCmdCopyBufferToImage(layer_data *dev_data, VkImage dstImage, uint32_t regionCount, - const VkBufferImageCopy *pRegions, const char *func_name) { - bool skip = ValidateBufferImageCopyData(dev_data, regionCount, pRegions, dstImage, "vkCmdCopyBufferToImage"); - return skip; + device_data->device_dispatch_table->CmdCopyImageToBuffer(commandBuffer, srcImage, srcImageLayout, dstBuffer, regionCount, + pRegions); } VKAPI_ATTR void VKAPI_CALL CmdCopyBufferToImage(VkCommandBuffer commandBuffer, VkBuffer srcBuffer, VkImage dstImage, VkImageLayout dstImageLayout, uint32_t regionCount, const VkBufferImageCopy *pRegions) { layer_data *device_data = GetLayerDataPtr(get_dispatch_key(commandBuffer), layer_data_map); - - if (!PreCallValidateCmdCopyBufferToImage(device_data, dstImage, regionCount, pRegions, "vkCmdCopyBufferToImage()")) { - device_data->device_dispatch_table->CmdCopyBufferToImage(commandBuffer, srcBuffer, dstImage, dstImageLayout, regionCount, - pRegions); - } + device_data->device_dispatch_table->CmdCopyBufferToImage(commandBuffer, srcBuffer, dstImage, dstImageLayout, regionCount, + pRegions); } VKAPI_ATTR void VKAPI_CALL GetPhysicalDeviceProperties(VkPhysicalDevice physicalDevice, VkPhysicalDeviceProperties *pProperties) { -- cgit v1.2.3