Skip to content

Commit

Permalink
layers: Add validation for VkHostImageLayoutTransitionInfoEXT
Browse files Browse the repository at this point in the history
  • Loading branch information
TonyBarbour committed Aug 1, 2023
1 parent 47d3717 commit eb7d011
Show file tree
Hide file tree
Showing 3 changed files with 122 additions and 2 deletions.
2 changes: 1 addition & 1 deletion layers/core_checks/cc_copy_blit_resolve.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2917,7 +2917,7 @@ bool CoreChecks::ValidateHostCopyImageLayout(const VkDevice device, const VkImag
if (!found) {
LogObjectList objlist(device, image);
skip |= LogError(objlist, vuid,
"%s(): %s is %s which is not one of the layouts retuned in "
"%s(): %s is %s which is not one of the layouts returned in "
"VkPhysicalDeviceHostImageCopyPropertiesEXT::%s",
func_name, field_name, string_VkImageLayout(image_layout), supported_name);
}
Expand Down
120 changes: 119 additions & 1 deletion layers/core_checks/cc_image.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2275,13 +2275,131 @@ bool CoreChecks::PreCallValidateGetImageSubresourceLayout2EXT(VkDevice device, V
return skip;
}

static const SubresourceRangeErrorCodes TransitionImageLayoutVUIDs{
"VUID-VkHostImageLayoutTransitionInfoEXT-subresourceRange-01486",
"VUID-VkHostImageLayoutTransitionInfoEXT-subresourceRange-01724",
"VUID-VkHostImageLayoutTransitionInfoEXT-subresourceRange-01488",
"VUID-VkHostImageLayoutTransitionInfoEXT-subresourceRange-01725",
};

bool CoreChecks::PreCallValidateTransitionImageLayoutEXT(VkDevice device, uint32_t transitionCount,
const VkHostImageLayoutTransitionInfoEXT *pTransitions) const {
bool skip = false;

const char *func_name = "vkTransitionImageLayoutEXT()";

for (uint32_t i = 0; i < transitionCount; ++i) {
auto transition = pTransitions[i];
auto image_state = Get<IMAGE_STATE>(transition.image);
auto image_format = image_state->createInfo.format;
auto aspect_mask = transition.subresourceRange.aspectMask;
const bool has_depth_mask = (aspect_mask & VK_IMAGE_ASPECT_DEPTH_BIT) != 0;
const bool has_stencil_mask = (aspect_mask & VK_IMAGE_ASPECT_STENCIL_BIT) != 0;

if ((image_state->createInfo.usage & VK_IMAGE_USAGE_HOST_TRANSFER_BIT_EXT) == 0) {
const LogObjectList objlist(device, image_state->Handle());
skip |= LogError(objlist, "VUID-VkHostImageLayoutTransitionInfoEXT-image-09055",
"%s: image in transition %d was not created with VK_IMAGE_USAGE_HOST_TRANSFER_BIT_EXT", func_name, i);
}

skip |= ValidateImageSubresourceRange(image_state->createInfo.mipLevels, image_state->createInfo.arrayLayers,
transition.subresourceRange, func_name, "subresourceRange", "arrayLayers",
image_state->image(), TransitionImageLayoutVUIDs);
skip |=
ValidateMemoryIsBoundToImage(device, *image_state, func_name, "VUID-VkHostImageLayoutTransitionInfoEXT-image-01932");

if (((FormatIsColor(image_format) == true) && (FormatIsMultiplane(image_format) == false)) ||
(image_state->disjoint == false)) {
if (aspect_mask != VK_IMAGE_ASPECT_COLOR_BIT) {
const LogObjectList objlist(device, image_state->Handle());
skip |= LogError(
objlist, "VUID-VkHostImageLayoutTransitionInfoEXT-image-01671",
"%s: image in transition %d requires subresourceRange.aspectMask to be VK_IMAGE_ASPECT_COLOR_BIT, but it is %s",
func_name, i, string_VkImageAspectFlags(aspect_mask).c_str());
}
}
if ((FormatIsMultiplane(image_format)) && (image_state->disjoint == true)) {
if (!IsValidPlaneAspect(image_format, aspect_mask) && ((aspect_mask & VK_IMAGE_ASPECT_COLOR_BIT) == 0)) {
const LogObjectList objlist(device, image_state->Handle());
skip |= LogError(objlist, "VUID-VkHostImageLayoutTransitionInfoEXT-image-01671",
"%s: image in transition %d requires subresourceRange.aspectMask to include at least one "
"multi-planar aspect mask or to be VK_IMAGE_ASPECT_COLOR_BIT, but it is %s",
func_name, i, string_VkImageAspectFlags(aspect_mask).c_str());
}
}
if (FormatIsDepthAndStencil(image_format)) {
if (enabled_features.core12.separateDepthStencilLayouts) {
if (!has_depth_mask && !has_stencil_mask) {
const LogObjectList objlist(device, image_state->Handle());
skip |= LogError(objlist, "VUID-VkHostImageLayoutTransitionInfoEXT-image-03319",
"%s: image in transition %d of format %s requires subresourceRange.aspectMask to have either "
"the depth or stencil "
"aspects set, but its aspectMask is %s",
func_name, i, string_VkFormat(image_format), string_VkImageAspectFlags(aspect_mask).c_str());
}
} else {
if (!has_depth_mask || !has_stencil_mask) {
const LogObjectList objlist(device, image_state->Handle());
skip |= LogError(objlist, "VUID-VkHostImageLayoutTransitionInfoEXT-image-03320",
"%s: image in transition %d of format %s requires subresourceRange.aspectMask to have both "
"the depth and stencil "
"aspects set, but its aspectMask is %s",
func_name, i, string_VkFormat(image_format), string_VkImageAspectFlags(aspect_mask).c_str());
}
}
}
if (aspect_mask & VK_IMAGE_ASPECT_DEPTH_BIT) {
if ((transition.oldLayout == VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL) ||
(transition.oldLayout == VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL) ||
(transition.newLayout == VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL) ||
(transition.newLayout == VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL)) {
const LogObjectList objlist(device, image_state->Handle());
skip |= LogError(objlist, "VUID-VkHostImageLayoutTransitionInfoEXT-aspectMask-08702",
"%s: the aspect mask in transition %i is %s meaning that neither oldLayout nor newLayout can be "
"VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL or VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL"
"oldLayout = %s and newLayout = %s",
func_name, i, string_VkImageAspectFlags(aspect_mask).c_str(),
string_VkImageLayout(transition.oldLayout), string_VkImageLayout(transition.oldLayout));
}
}
if (aspect_mask & VK_IMAGE_ASPECT_STENCIL_BIT) {
if ((transition.oldLayout == VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL) ||
(transition.oldLayout == VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL) ||
(transition.newLayout == VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL) ||
(transition.newLayout == VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL)) {
const LogObjectList objlist(device, image_state->Handle());
skip |= LogError(objlist, "VUID-VkHostImageLayoutTransitionInfoEXT-aspectMask-08703",
"%s: the aspect mask in transition %i is %s meaning that neither oldLayout nor newLayout can be "
"VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL or VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL"
"oldLayout = %s and newLayout = %s",
func_name, i, string_VkImageAspectFlags(aspect_mask).c_str(),
string_VkImageLayout(transition.oldLayout), string_VkImageLayout(transition.oldLayout));
}
}
if ((transition.oldLayout != VK_IMAGE_LAYOUT_UNDEFINED) && (transition.oldLayout != VK_IMAGE_LAYOUT_PREINITIALIZED)) {
auto *props = &phys_dev_ext_props.host_image_copy_properties;
skip |= ValidateHostCopyImageLayout(device, transition.image, props->copySrcLayoutCount, props->pCopySrcLayouts,
transition.oldLayout, func_name, "oldLayout", "pCopySrcLayouts",
"VUID-VkHostImageLayoutTransitionInfoEXT-oldLayout-09056");
}

auto *props = &phys_dev_ext_props.host_image_copy_properties;
skip |= ValidateHostCopyImageLayout(device, transition.image, props->copyDstLayoutCount, props->pCopyDstLayouts,
transition.newLayout, func_name, "newLayout", "pCopyDstLayouts",
"VUID-VkHostImageLayoutTransitionInfoEXT-newLayout-09057");
}
return skip;
};

void CoreChecks::PostCallRecordTransitionImageLayoutEXT(VkDevice device, uint32_t transitionCount,
const VkHostImageLayoutTransitionInfoEXT *pTransitions, VkResult result) {
ValidationStateTracker::PostCallRecordTransitionImageLayoutEXT(device, transitionCount, pTransitions, result);
//for (uint32_t i = 0; i < transitionCount; ++i) {
// auto transition = pTransitions[i];
// auto image_state = GetWrite<IMAGE_STATE>(transition.image);
// Todo Update image's layout_range_map in transition.subresourceRange
//}
}

// Validates the image is allowed to be protected
bool CoreChecks::ValidateProtectedImage(const CMD_BUFFER_STATE &cb_state, const IMAGE_STATE &image_state, const char *cmd_name,
const char *vuid, const char *more_message) const {
Expand Down
2 changes: 2 additions & 0 deletions layers/core_checks/core_validation.h
Original file line number Diff line number Diff line change
Expand Up @@ -2288,6 +2288,8 @@ class CoreChecks : public ValidationStateTracker {
VkSubresourceLayout& layout, bool is_ext) const;
bool PreCallValidateTransitionImageLayoutEXT(VkDevice device, uint32_t transitionCount,
const VkHostImageLayoutTransitionInfoEXT* pTransitions) const override;
void PostCallRecordTransitionImageLayoutEXT(VkDevice device, uint32_t transitionCount,
const VkHostImageLayoutTransitionInfoEXT* pTransitions, VkResult result) override;
bool PreCallValidateGetImageSubresourceLayout(VkDevice device, VkImage image, const VkImageSubresource* pSubresource,
VkSubresourceLayout* pLayout) const override;
bool PreCallValidateGetImageSubresourceLayout2EXT(VkDevice device, VkImage image, const VkImageSubresource2EXT* pSubresource,
Expand Down

0 comments on commit eb7d011

Please sign in to comment.