aboutsummaryrefslogtreecommitdiff
path: root/layers/buffer_validation.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'layers/buffer_validation.cpp')
-rw-r--r--layers/buffer_validation.cpp320
1 files changed, 218 insertions, 102 deletions
diff --git a/layers/buffer_validation.cpp b/layers/buffer_validation.cpp
index 6f4440b4..cafa37e5 100644
--- a/layers/buffer_validation.cpp
+++ b/layers/buffer_validation.cpp
@@ -43,7 +43,7 @@ std::string to_string(T var) {
ss << var;
return ss.str();
}
-}
+} // namespace std
#endif
void SetLayout(layer_data *device_data, GLOBAL_CB_NODE *pCB, ImageSubresourcePair imgpair, const VkImageLayout &layout) {
@@ -496,7 +496,8 @@ bool ValidateBarriersToImages(layer_data *device_data, VkCommandBuffer cmdBuffer
// Make sure layout is able to be transitioned, currently only presented shared presentable images are locked
if (image_state->layout_locked) {
// TODO: Add unique id for error when available
- skip |= log_msg(core_validation::GetReportData(device_data), VK_DEBUG_REPORT_ERROR_BIT_EXT,
+ skip |= log_msg(
+ core_validation::GetReportData(device_data), VK_DEBUG_REPORT_ERROR_BIT_EXT,
VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, 0, "DS",
"Attempting to transition shared presentable image 0x%" PRIxLEAST64
" from layout %s to layout %s, but image has already been presented and cannot have its layout transitioned.",
@@ -921,9 +922,9 @@ bool VerifyClearImageLayout(layer_data *device_data, GLOBAL_CB_NODE *cb_node, IM
if (!GetDeviceExtensions(device_data)->vk_khr_shared_presentable_image) {
// TODO: Add unique error id when available.
skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT,
- HandleToUint64(image_state->image), __LINE__, 0, "DS",
- "Must enable VK_KHR_shared_presentable_image extension before creating images with a layout type "
- "of VK_IMAGE_LAYOUT_SHARED_PRESENT_KHR.");
+ HandleToUint64(image_state->image), __LINE__, 0, "DS",
+ "Must enable VK_KHR_shared_presentable_image extension before creating images with a layout type "
+ "of VK_IMAGE_LAYOUT_SHARED_PRESENT_KHR.");
} else {
if (image_state->shared_presentable) {
@@ -2213,6 +2214,149 @@ bool PreCallValidateCmdBlitImage(layer_data *device_data, GLOBAL_CB_NODE *cb_nod
skip |= insideRenderPass(device_data, cb_node, "vkCmdBlitImage()", VALIDATION_ERROR_18400017);
// TODO: Need to validate image layouts, which will include layout validation for shared presentable images
+ VkFormat src_format = src_image_state->createInfo.format;
+ VkFormat dst_format = dst_image_state->createInfo.format;
+ VkImageType src_type = src_image_state->createInfo.imageType;
+ VkImageType dst_type = dst_image_state->createInfo.imageType;
+
+ const VkFormatProperties *props = GetFormatProperties(device_data, src_format);
+ VkImageTiling tiling = src_image_state->createInfo.tiling;
+ VkFormatFeatureFlags flags =
+ (tiling == VK_IMAGE_TILING_LINEAR ? props->linearTilingFeatures : props->optimalTilingFeatures);
+ if (VK_FORMAT_FEATURE_BLIT_SRC_BIT != (flags & VK_FORMAT_FEATURE_BLIT_SRC_BIT)) {
+ skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
+ HandleToUint64(cb_node->commandBuffer), __LINE__, VALIDATION_ERROR_184001b4, "IMAGE",
+ "vkCmdBlitImage: source image format %s does not support VK_FORMAT_FEATURE_BLIT_SRC_BIT feature. %s",
+ string_VkFormat(src_format), validation_error_map[VALIDATION_ERROR_184001b4]);
+ }
+
+ if ((VK_FILTER_LINEAR == filter) &&
+ (VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT != (flags & VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT))) {
+ skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
+ HandleToUint64(cb_node->commandBuffer), __LINE__, VALIDATION_ERROR_184001d6, "IMAGE",
+ "vkCmdBlitImage: source image format %s does not support linear filtering. %s",
+ string_VkFormat(src_format), validation_error_map[VALIDATION_ERROR_184001d6]);
+ }
+
+ if ((VK_FILTER_CUBIC_IMG == filter) && (VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_CUBIC_BIT_IMG !=
+ (flags & VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_CUBIC_BIT_IMG))) {
+ skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
+ HandleToUint64(cb_node->commandBuffer), __LINE__, VALIDATION_ERROR_184001d8, "IMAGE",
+ "vkCmdBlitImage: source image format %s does not support cubic filtering. %s",
+ string_VkFormat(src_format), validation_error_map[VALIDATION_ERROR_184001d8]);
+ }
+
+ if ((VK_FILTER_CUBIC_IMG == filter) && (VK_IMAGE_TYPE_3D != src_type)) {
+ skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
+ HandleToUint64(cb_node->commandBuffer), __LINE__, VALIDATION_ERROR_184001da, "IMAGE",
+ "vkCmdBlitImage: source image type must be VK_IMAGE_TYPE_3D when cubic filtering is specified. %s",
+ validation_error_map[VALIDATION_ERROR_184001da]);
+ }
+
+ props = GetFormatProperties(device_data, dst_format);
+ tiling = dst_image_state->createInfo.tiling;
+ flags = (tiling == VK_IMAGE_TILING_LINEAR ? props->linearTilingFeatures : props->optimalTilingFeatures);
+ if (VK_FORMAT_FEATURE_BLIT_DST_BIT != (flags & VK_FORMAT_FEATURE_BLIT_DST_BIT)) {
+ skip |=
+ log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
+ HandleToUint64(cb_node->commandBuffer), __LINE__, VALIDATION_ERROR_184001be, "IMAGE",
+ "vkCmdBlitImage: destination image format %s does not support VK_FORMAT_FEATURE_BLIT_DST_BIT feature. %s",
+ string_VkFormat(dst_format), validation_error_map[VALIDATION_ERROR_184001be]);
+ }
+
+ if ((VK_SAMPLE_COUNT_1_BIT != src_image_state->createInfo.samples) ||
+ (VK_SAMPLE_COUNT_1_BIT != dst_image_state->createInfo.samples)) {
+ skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
+ HandleToUint64(cb_node->commandBuffer), __LINE__, VALIDATION_ERROR_184001c8, "IMAGE",
+ "vkCmdBlitImage: source or dest image has sample count other than VK_SAMPLE_COUNT_1_BIT. %s",
+ validation_error_map[VALIDATION_ERROR_184001c8]);
+ }
+
+ // Validate consistency for unsigned formats
+ if (FormatIsUInt(src_format) != FormatIsUInt(dst_format)) {
+ std::stringstream ss;
+ ss << "vkCmdBlitImage: If one of srcImage and dstImage images has unsigned integer format, "
+ << "the other one must also have unsigned integer format. "
+ << "Source format is " << string_VkFormat(src_format) << " Destination format is " << string_VkFormat(dst_format);
+ skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
+ HandleToUint64(cb_node->commandBuffer), __LINE__, VALIDATION_ERROR_184001cc, "IMAGE", "%s. %s",
+ ss.str().c_str(), validation_error_map[VALIDATION_ERROR_184001cc]);
+ }
+
+ // Validate consistency for signed formats
+ if (FormatIsSInt(src_format) != FormatIsSInt(dst_format)) {
+ std::stringstream ss;
+ ss << "vkCmdBlitImage: If one of srcImage and dstImage images has signed integer format, "
+ << "the other one must also have signed integer format. "
+ << "Source format is " << string_VkFormat(src_format) << " Destination format is " << string_VkFormat(dst_format);
+ skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
+ HandleToUint64(cb_node->commandBuffer), __LINE__, VALIDATION_ERROR_184001ca, "IMAGE", "%s. %s",
+ ss.str().c_str(), validation_error_map[VALIDATION_ERROR_184001ca]);
+ }
+
+ // Validate filter for Depth/Stencil formats
+ if (FormatIsDepthOrStencil(src_format) && (filter != VK_FILTER_NEAREST)) {
+ std::stringstream ss;
+ ss << "vkCmdBlitImage: If the format of srcImage is a depth, stencil, or depth stencil "
+ << "then filter must be VK_FILTER_NEAREST.";
+ skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
+ HandleToUint64(cb_node->commandBuffer), __LINE__, VALIDATION_ERROR_184001d0, "IMAGE", "%s. %s",
+ ss.str().c_str(), validation_error_map[VALIDATION_ERROR_184001d0]);
+ }
+
+ // Validate aspect bits and formats for depth/stencil images
+ if (FormatIsDepthOrStencil(src_format) || FormatIsDepthOrStencil(dst_format)) {
+ if (src_format != dst_format) {
+ std::stringstream ss;
+ ss << "vkCmdBlitImage: If one of srcImage and dstImage images has a format of depth, stencil or depth "
+ << "stencil, the other one must have exactly the same format. "
+ << "Source format is " << string_VkFormat(src_format) << " Destination format is "
+ << string_VkFormat(dst_format);
+ skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
+ HandleToUint64(cb_node->commandBuffer), __LINE__, VALIDATION_ERROR_184001ce, "IMAGE", "%s. %s",
+ ss.str().c_str(), validation_error_map[VALIDATION_ERROR_184001ce]);
+ }
+
+#if 0 // TODO: Cannot find VU statements or spec language for these in CmdBlitImage. Verify or remove.
+ for (uint32_t i = 0; i < regionCount; i++) {
+ VkImageAspectFlags srcAspect = pRegions[i].srcSubresource.aspectMask;
+
+ if (FormatIsDepthAndStencil(src_format)) {
+ if ((srcAspect != VK_IMAGE_ASPECT_DEPTH_BIT) && (srcAspect != VK_IMAGE_ASPECT_STENCIL_BIT)) {
+ std::stringstream ss;
+ ss << "vkCmdBlitImage: Combination depth/stencil image formats must have only one of "
+ "VK_IMAGE_ASPECT_DEPTH_BIT "
+ << "and VK_IMAGE_ASPECT_STENCIL_BIT set in srcImage and dstImage";
+ skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
+ HandleToUint64(cb_node->commandBuffer), __LINE__, DRAWSTATE_INVALID_IMAGE_ASPECT, "IMAGE",
+ "%s", ss.str().c_str());
+ }
+ }
+ else if (FormatIsStencilOnly(src_format)) {
+ if (srcAspect != VK_IMAGE_ASPECT_STENCIL_BIT) {
+ std::stringstream ss;
+ ss << "vkCmdBlitImage: Stencil-only image formats must have only the VK_IMAGE_ASPECT_STENCIL_BIT "
+ << "set in both the srcImage and dstImage";
+ skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
+ HandleToUint64(cb_node->commandBuffer), __LINE__, DRAWSTATE_INVALID_IMAGE_ASPECT, "IMAGE",
+ "%s", ss.str().c_str());
+ }
+ }
+ else if (FormatIsDepthOnly(src_format)) {
+ if (srcAspect != VK_IMAGE_ASPECT_DEPTH_BIT) {
+ std::stringstream ss;
+ ss << "vkCmdBlitImage: Depth-only image formats must have only the VK_IMAGE_ASPECT_DEPTH "
+ << "set in both the srcImage and dstImage";
+ skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
+ HandleToUint64(cb_node->commandBuffer), __LINE__, DRAWSTATE_INVALID_IMAGE_ASPECT, "IMAGE",
+ "%s", ss.str().c_str());
+ }
+ }
+ }
+#endif
+ } // Depth or Stencil
+
+ // Do per-region checks
for (uint32_t i = 0; i < regionCount; i++) {
VkImageBlit rgn = pRegions[i];
@@ -2260,9 +2404,26 @@ bool PreCallValidateCmdBlitImage(layer_data *device_data, GLOBAL_CB_NODE *cb_nod
validation_error_map[VALIDATION_ERROR_09a001dc]);
}
+ if (!VerifyAspectsPresent(rgn.srcSubresource.aspectMask, src_format)) {
+ skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
+ HandleToUint64(cb_node->commandBuffer), __LINE__, VALIDATION_ERROR_09a001e2, "IMAGE",
+ "vkCmdBlitImage: region [%d] source aspectMask (0x%x) specifies aspects not present in source "
+ "image format %s. %s",
+ i, rgn.srcSubresource.aspectMask, string_VkFormat(src_format),
+ validation_error_map[VALIDATION_ERROR_09a001e2]);
+ }
+
+ if (!VerifyAspectsPresent(rgn.dstSubresource.aspectMask, dst_format)) {
+ skip |= log_msg(
+ report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
+ HandleToUint64(cb_node->commandBuffer), __LINE__, VALIDATION_ERROR_09a001e4, "IMAGE",
+ "vkCmdBlitImage: region [%d] dest aspectMask (0x%x) specifies aspects not present in dest image format %s. %s",
+ i, rgn.dstSubresource.aspectMask, string_VkFormat(dst_format), validation_error_map[VALIDATION_ERROR_09a001e4]);
+ }
+
// Validate source image offsets
VkExtent3D src_extent = GetImageSubresourceExtent(src_image_state, &(rgn.srcSubresource));
- if (VK_IMAGE_TYPE_1D == src_image_state->createInfo.imageType) {
+ if (VK_IMAGE_TYPE_1D == src_type) {
if ((0 != rgn.srcOffsets[0].y) || (1 != rgn.srcOffsets[1].y)) {
skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
HandleToUint64(cb_node->commandBuffer), __LINE__, VALIDATION_ERROR_09a001ea, "IMAGE",
@@ -2272,8 +2433,7 @@ bool PreCallValidateCmdBlitImage(layer_data *device_data, GLOBAL_CB_NODE *cb_nod
}
}
- if ((VK_IMAGE_TYPE_1D == src_image_state->createInfo.imageType) ||
- (VK_IMAGE_TYPE_2D == src_image_state->createInfo.imageType)) {
+ if ((VK_IMAGE_TYPE_1D == src_type) || (VK_IMAGE_TYPE_2D == src_type)) {
if ((0 != rgn.srcOffsets[0].z) || (1 != rgn.srcOffsets[1].z)) {
skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
HandleToUint64(cb_node->commandBuffer), __LINE__, VALIDATION_ERROR_09a001ee, "IMAGE",
@@ -2283,8 +2443,10 @@ bool PreCallValidateCmdBlitImage(layer_data *device_data, GLOBAL_CB_NODE *cb_nod
}
}
+ bool oob = false;
if ((rgn.srcOffsets[0].x < 0) || (rgn.srcOffsets[0].x > static_cast<int32_t>(src_extent.width)) ||
(rgn.srcOffsets[1].x < 0) || (rgn.srcOffsets[1].x > static_cast<int32_t>(src_extent.width))) {
+ oob = true;
skip |= log_msg(
report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
HandleToUint64(cb_node->commandBuffer), __LINE__, VALIDATION_ERROR_09a001e6, "IMAGE",
@@ -2293,6 +2455,7 @@ bool PreCallValidateCmdBlitImage(layer_data *device_data, GLOBAL_CB_NODE *cb_nod
}
if ((rgn.srcOffsets[0].y < 0) || (rgn.srcOffsets[0].y > static_cast<int32_t>(src_extent.height)) ||
(rgn.srcOffsets[1].y < 0) || (rgn.srcOffsets[1].y > static_cast<int32_t>(src_extent.height))) {
+ oob = true;
skip |= log_msg(
report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
HandleToUint64(cb_node->commandBuffer), __LINE__, VALIDATION_ERROR_09a001e8, "IMAGE",
@@ -2301,16 +2464,28 @@ bool PreCallValidateCmdBlitImage(layer_data *device_data, GLOBAL_CB_NODE *cb_nod
}
if ((rgn.srcOffsets[0].z < 0) || (rgn.srcOffsets[0].z > static_cast<int32_t>(src_extent.depth)) ||
(rgn.srcOffsets[1].z < 0) || (rgn.srcOffsets[1].z > static_cast<int32_t>(src_extent.depth))) {
+ oob = true;
skip |= log_msg(
report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
HandleToUint64(cb_node->commandBuffer), __LINE__, VALIDATION_ERROR_09a001ec, "IMAGE",
"vkCmdBlitImage: region [%d] srcOffset[].z values (%1d, %1d) exceed srcSubresource depth extent (%1d). %s", i,
rgn.srcOffsets[0].z, rgn.srcOffsets[1].z, src_extent.depth, validation_error_map[VALIDATION_ERROR_09a001ec]);
}
+ if (rgn.srcSubresource.mipLevel >= src_image_state->createInfo.mipLevels) {
+ skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
+ HandleToUint64(cb_node->commandBuffer), __LINE__, VALIDATION_ERROR_184001ae, "IMAGE",
+ "vkCmdBlitImage: region [%d] source image, attempt to access a non-existant mip level %1d. %s", i,
+ rgn.srcSubresource.mipLevel, validation_error_map[VALIDATION_ERROR_184001ae]);
+ } else if (oob) {
+ skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
+ HandleToUint64(cb_node->commandBuffer), __LINE__, VALIDATION_ERROR_184001ae, "IMAGE",
+ "vkCmdBlitImage: region [%d] source image blit region exceeds image dimensions. %s", i,
+ validation_error_map[VALIDATION_ERROR_184001ae]);
+ }
// Validate dest image offsets
VkExtent3D dst_extent = GetImageSubresourceExtent(dst_image_state, &(rgn.dstSubresource));
- if (VK_IMAGE_TYPE_1D == dst_image_state->createInfo.imageType) {
+ if (VK_IMAGE_TYPE_1D == dst_type) {
if ((0 != rgn.dstOffsets[0].y) || (1 != rgn.dstOffsets[1].y)) {
skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
HandleToUint64(cb_node->commandBuffer), __LINE__, VALIDATION_ERROR_09a001f4, "IMAGE",
@@ -2320,8 +2495,7 @@ bool PreCallValidateCmdBlitImage(layer_data *device_data, GLOBAL_CB_NODE *cb_nod
}
}
- if ((VK_IMAGE_TYPE_1D == dst_image_state->createInfo.imageType) ||
- (VK_IMAGE_TYPE_2D == dst_image_state->createInfo.imageType)) {
+ if ((VK_IMAGE_TYPE_1D == dst_type) || (VK_IMAGE_TYPE_2D == dst_type)) {
if ((0 != rgn.dstOffsets[0].z) || (1 != rgn.dstOffsets[1].z)) {
skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
HandleToUint64(cb_node->commandBuffer), __LINE__, VALIDATION_ERROR_09a001f8, "IMAGE",
@@ -2331,8 +2505,10 @@ bool PreCallValidateCmdBlitImage(layer_data *device_data, GLOBAL_CB_NODE *cb_nod
}
}
+ oob = false;
if ((rgn.dstOffsets[0].x < 0) || (rgn.dstOffsets[0].x > static_cast<int32_t>(dst_extent.width)) ||
(rgn.dstOffsets[1].x < 0) || (rgn.dstOffsets[1].x > static_cast<int32_t>(dst_extent.width))) {
+ oob = true;
skip |= log_msg(
report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
HandleToUint64(cb_node->commandBuffer), __LINE__, VALIDATION_ERROR_09a001f0, "IMAGE",
@@ -2341,6 +2517,7 @@ bool PreCallValidateCmdBlitImage(layer_data *device_data, GLOBAL_CB_NODE *cb_nod
}
if ((rgn.dstOffsets[0].y < 0) || (rgn.dstOffsets[0].y > static_cast<int32_t>(dst_extent.height)) ||
(rgn.dstOffsets[1].y < 0) || (rgn.dstOffsets[1].y > static_cast<int32_t>(dst_extent.height))) {
+ oob = true;
skip |= log_msg(
report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
HandleToUint64(cb_node->commandBuffer), __LINE__, VALIDATION_ERROR_09a001f2, "IMAGE",
@@ -2349,98 +2526,36 @@ bool PreCallValidateCmdBlitImage(layer_data *device_data, GLOBAL_CB_NODE *cb_nod
}
if ((rgn.dstOffsets[0].z < 0) || (rgn.dstOffsets[0].z > static_cast<int32_t>(dst_extent.depth)) ||
(rgn.dstOffsets[1].z < 0) || (rgn.dstOffsets[1].z > static_cast<int32_t>(dst_extent.depth))) {
+ oob = true;
skip |= log_msg(
report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
HandleToUint64(cb_node->commandBuffer), __LINE__, VALIDATION_ERROR_09a001f6, "IMAGE",
"vkCmdBlitImage: region [%d] dstOffset[].z values (%1d, %1d) exceed dstSubresource depth extent (%1d). %s", i,
rgn.dstOffsets[0].z, rgn.dstOffsets[1].z, dst_extent.depth, validation_error_map[VALIDATION_ERROR_09a001f6]);
}
- }
-
- VkFormat src_format = src_image_state->createInfo.format;
- VkFormat dst_format = dst_image_state->createInfo.format;
-
- // Validate consistency for unsigned formats
- if (FormatIsUInt(src_format) != FormatIsUInt(dst_format)) {
- std::stringstream ss;
- ss << "vkCmdBlitImage: If one of srcImage and dstImage images has unsigned integer format, "
- << "the other one must also have unsigned integer format. "
- << "Source format is " << string_VkFormat(src_format) << " Destination format is " << string_VkFormat(dst_format);
- skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
- HandleToUint64(cb_node->commandBuffer), __LINE__, VALIDATION_ERROR_184001cc, "IMAGE", "%s. %s",
- ss.str().c_str(), validation_error_map[VALIDATION_ERROR_184001cc]);
- }
-
- // Validate consistency for signed formats
- if (FormatIsSInt(src_format) != FormatIsSInt(dst_format)) {
- std::stringstream ss;
- ss << "vkCmdBlitImage: If one of srcImage and dstImage images has signed integer format, "
- << "the other one must also have signed integer format. "
- << "Source format is " << string_VkFormat(src_format) << " Destination format is " << string_VkFormat(dst_format);
- skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
- HandleToUint64(cb_node->commandBuffer), __LINE__, VALIDATION_ERROR_184001ca, "IMAGE", "%s. %s",
- ss.str().c_str(), validation_error_map[VALIDATION_ERROR_184001ca]);
- }
-
- // Validate aspect bits and formats for depth/stencil images
- if (FormatIsDepthOrStencil(src_format) || FormatIsDepthOrStencil(dst_format)) {
- if (src_format != dst_format) {
- std::stringstream ss;
- ss << "vkCmdBlitImage: If one of srcImage and dstImage images has a format of depth, stencil or depth "
- << "stencil, the other one must have exactly the same format. "
- << "Source format is " << string_VkFormat(src_format) << " Destination format is "
- << string_VkFormat(dst_format);
+ if (rgn.dstSubresource.mipLevel >= dst_image_state->createInfo.mipLevels) {
skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
- HandleToUint64(cb_node->commandBuffer), __LINE__, VALIDATION_ERROR_184001ce, "IMAGE", "%s. %s",
- ss.str().c_str(), validation_error_map[VALIDATION_ERROR_184001ce]);
+ HandleToUint64(cb_node->commandBuffer), __LINE__, VALIDATION_ERROR_184001b0, "IMAGE",
+ "vkCmdBlitImage: region [%d] destination image, attempt to access a non-existant mip level %1d. %s",
+ i, rgn.dstSubresource.mipLevel, validation_error_map[VALIDATION_ERROR_184001b0]);
+ } else if (oob) {
+ skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
+ HandleToUint64(cb_node->commandBuffer), __LINE__, VALIDATION_ERROR_184001b0, "IMAGE",
+ "vkCmdBlitImage: region [%d] destination image blit region exceeds image dimensions. %s", i,
+ validation_error_map[VALIDATION_ERROR_184001b0]);
}
-#if 0 // TODO: Cannot find VU statements or spec language for these in CmdBlitImage. Verify or remove.
- for (uint32_t i = 0; i < regionCount; i++) {
- VkImageAspectFlags srcAspect = pRegions[i].srcSubresource.aspectMask;
-
- if (FormatIsDepthAndStencil(src_format)) {
- if ((srcAspect != VK_IMAGE_ASPECT_DEPTH_BIT) && (srcAspect != VK_IMAGE_ASPECT_STENCIL_BIT)) {
- std::stringstream ss;
- ss << "vkCmdBlitImage: Combination depth/stencil image formats must have only one of "
- "VK_IMAGE_ASPECT_DEPTH_BIT "
- << "and VK_IMAGE_ASPECT_STENCIL_BIT set in srcImage and dstImage";
- skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
- HandleToUint64(cb_node->commandBuffer), __LINE__, DRAWSTATE_INVALID_IMAGE_ASPECT, "IMAGE",
- "%s", ss.str().c_str());
- }
- } else if (FormatIsStencilOnly(src_format)) {
- if (srcAspect != VK_IMAGE_ASPECT_STENCIL_BIT) {
- std::stringstream ss;
- ss << "vkCmdBlitImage: Stencil-only image formats must have only the VK_IMAGE_ASPECT_STENCIL_BIT "
- << "set in both the srcImage and dstImage";
- skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
- HandleToUint64(cb_node->commandBuffer), __LINE__, DRAWSTATE_INVALID_IMAGE_ASPECT, "IMAGE",
- "%s", ss.str().c_str());
- }
- } else if (FormatIsDepthOnly(src_format)) {
- if (srcAspect != VK_IMAGE_ASPECT_DEPTH_BIT) {
- std::stringstream ss;
- ss << "vkCmdBlitImage: Depth-only image formats must have only the VK_IMAGE_ASPECT_DEPTH "
- << "set in both the srcImage and dstImage";
- skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
- HandleToUint64(cb_node->commandBuffer), __LINE__, DRAWSTATE_INVALID_IMAGE_ASPECT, "IMAGE",
- "%s", ss.str().c_str());
- }
+ if ((VK_IMAGE_TYPE_3D == src_type) || (VK_IMAGE_TYPE_3D == dst_type)) {
+ if ((0 != rgn.srcSubresource.baseArrayLayer) || (1 != rgn.srcSubresource.layerCount) ||
+ (0 != rgn.dstSubresource.baseArrayLayer) || (1 != rgn.dstSubresource.layerCount)) {
+ skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
+ HandleToUint64(cb_node->commandBuffer), __LINE__, VALIDATION_ERROR_09a001e0, "IMAGE",
+ "vkCmdBlitImage: region [%d] blit to/from a 3D image type with a non-zero baseArrayLayer, or a "
+ "layerCount other than 1. %s",
+ i, validation_error_map[VALIDATION_ERROR_09a001e0]);
}
}
-#endif
- } // Depth/Stencil
-
- // Validate filter
- if (FormatIsDepthOrStencil(src_format) && (filter != VK_FILTER_NEAREST)) {
- std::stringstream ss;
- ss << "vkCmdBlitImage: If the format of srcImage is a depth, stencil, or depth stencil "
- << "then filter must be VK_FILTER_NEAREST.";
- skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
- HandleToUint64(cb_node->commandBuffer), __LINE__, VALIDATION_ERROR_184001d0, "IMAGE", "%s. %s",
- ss.str().c_str(), validation_error_map[VALIDATION_ERROR_184001d0]);
- }
+ } // per-region checks
} else {
assert(0);
}
@@ -2743,7 +2858,7 @@ bool ValidateLayouts(core_validation::layer_data *device_data, VkDevice device,
// as an acceptable layout, but need to make sure shared presentable images ONLY use that layout
switch (subpass.pColorAttachments[j].layout) {
case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL:
- // This is ideal.
+ // This is ideal.
case VK_IMAGE_LAYOUT_SHARED_PRESENT_KHR:
// TODO: See note above, just assuming that attachment is shared presentable and allowing this for now.
break;
@@ -3019,7 +3134,8 @@ bool ValidateImageSubresourceRange(const layer_data *device_data, const IMAGE_ST
if (subresourceRange.baseMipLevel >= image_mip_count) {
skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT,
HandleToUint64(image_state->image), __LINE__, DRAWSTATE_INVALID_IMAGE_SUBRANGE, "IMAGE",
- "%s: %s.baseMipLevel (= %" PRIu32 ") is greater or equal to the mip level count of the image (i.e. "
+ "%s: %s.baseMipLevel (= %" PRIu32
+ ") is greater or equal to the mip level count of the image (i.e. "
"greater or equal to %" PRIu32 ").",
cmd_name, param_name, subresourceRange.baseMipLevel, image_mip_count);
}
@@ -3056,7 +3172,8 @@ bool ValidateImageSubresourceRange(const layer_data *device_data, const IMAGE_ST
if (subresourceRange.baseArrayLayer >= image_layer_count) {
skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT,
HandleToUint64(image_state->image), __LINE__, DRAWSTATE_INVALID_IMAGE_SUBRANGE, "IMAGE",
- "%s: %s.baseArrayLayer (= %" PRIu32 ") is greater or equal to the %s of the image when it was created "
+ "%s: %s.baseArrayLayer (= %" PRIu32
+ ") is greater or equal to the %s of the image when it was created "
"(i.e. greater or equal to %" PRIu32 ").",
cmd_name, param_name, subresourceRange.baseArrayLayer, image_layer_count_var_name, image_layer_count);
}
@@ -3067,7 +3184,8 @@ bool ValidateImageSubresourceRange(const layer_data *device_data, const IMAGE_ST
skip |=
log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT,
HandleToUint64(image_state->image), __LINE__, invalid_layer_code, "IMAGE",
- "%s: %s.baseArrayLayer + .layerCount (= %" PRIu32 " + %" PRIu32 " = %" PRIu64 ") is greater than the "
+ "%s: %s.baseArrayLayer + .layerCount (= %" PRIu32 " + %" PRIu32 " = %" PRIu64
+ ") is greater than the "
"%s of the image when it was created (i.e. greater than %" PRIu32 "). %s",
cmd_name, param_name, subresourceRange.baseArrayLayer, subresourceRange.layerCount, necessary_layer_count,
image_layer_count_var_name, image_layer_count, validation_error_map[invalid_layer_code]);
@@ -3509,8 +3627,8 @@ static bool ValidateImageBounds(const debug_report_data *report_data, const IMAG
}
static inline bool ValidateBufferBounds(const debug_report_data *report_data, IMAGE_STATE *image_state, BUFFER_STATE *buff_state,
- uint32_t regionCount, const VkBufferImageCopy *pRegions, const char *func_name,
- UNIQUE_VALIDATION_ERROR_CODE msg_code) {
+ uint32_t regionCount, const VkBufferImageCopy *pRegions, const char *func_name,
+ UNIQUE_VALIDATION_ERROR_CODE msg_code) {
bool skip = false;
VkDeviceSize buffer_size = buff_state->createInfo.size;
@@ -3606,7 +3724,7 @@ bool PreCallValidateCmdCopyImageToBuffer(layer_data *device_data, VkImageLayout
skip |= ValidateImageBounds(report_data, src_image_state, regionCount, pRegions, "vkCmdCopyBufferToImage()",
VALIDATION_ERROR_1920016c);
skip |= ValidateBufferBounds(report_data, src_image_state, dst_buffer_state, regionCount, pRegions, "vkCmdCopyImageToBuffer()",
- VALIDATION_ERROR_1920016e);
+ VALIDATION_ERROR_1920016e);
skip |= ValidateImageSampleCount(device_data, src_image_state, VK_SAMPLE_COUNT_1_BIT, "vkCmdCopyImageToBuffer(): srcImage",
VALIDATION_ERROR_19200178);
@@ -3650,7 +3768,6 @@ void PreCallRecordCmdCopyImageToBuffer(layer_data *device_data, GLOBAL_CB_NODE *
return false;
};
cb_node->validate_functions.push_back(function);
-
}
bool PreCallValidateCmdCopyBufferToImage(layer_data *device_data, VkImageLayout dstImageLayout, GLOBAL_CB_NODE *cb_node,
@@ -3682,7 +3799,7 @@ bool PreCallValidateCmdCopyBufferToImage(layer_data *device_data, VkImageLayout
skip |= ValidateImageBounds(report_data, dst_image_state, regionCount, pRegions, "vkCmdCopyBufferToImage()",
VALIDATION_ERROR_18e00158);
skip |= ValidateBufferBounds(report_data, dst_image_state, src_buffer_state, regionCount, pRegions, "vkCmdCopyBufferToImage()",
- VALIDATION_ERROR_18e00156);
+ VALIDATION_ERROR_18e00156);
skip |= ValidateImageSampleCount(device_data, dst_image_state, VK_SAMPLE_COUNT_1_BIT, "vkCmdCopyBufferToImage(): dstImage",
VALIDATION_ERROR_18e00166);
skip |= ValidateMemoryIsBoundToBuffer(device_data, src_buffer_state, "vkCmdCopyBufferToImage()", VALIDATION_ERROR_18e00160);
@@ -3719,7 +3836,6 @@ void PreCallRecordCmdCopyBufferToImage(layer_data *device_data, GLOBAL_CB_NODE *
cb_node->validate_functions.push_back(function);
function = [=]() { return ValidateBufferMemoryIsValid(device_data, src_buffer_state, "vkCmdCopyBufferToImage()"); };
cb_node->validate_functions.push_back(function);
-
}
bool PreCallValidateGetImageSubresourceLayout(layer_data *device_data, VkImage image, const VkImageSubresource *pSubresource) {