buffer_validation.cpp revision cf2ce8673669ca1111e333bdea272c4dd57cb5c2
1584b2b6a66e3069a66727639e5a0b7ef9ebf13b6Mark Lobodzinski/* Copyright (c) 2015-2017 The Khronos Group Inc. 2584b2b6a66e3069a66727639e5a0b7ef9ebf13b6Mark Lobodzinski * Copyright (c) 2015-2017 Valve Corporation 3584b2b6a66e3069a66727639e5a0b7ef9ebf13b6Mark Lobodzinski * Copyright (c) 2015-2017 LunarG, Inc. 4584b2b6a66e3069a66727639e5a0b7ef9ebf13b6Mark Lobodzinski * Copyright (C) 2015-2017 Google Inc. 5584b2b6a66e3069a66727639e5a0b7ef9ebf13b6Mark Lobodzinski * 6584b2b6a66e3069a66727639e5a0b7ef9ebf13b6Mark Lobodzinski * Licensed under the Apache License, Version 2.0 (the "License"); 7584b2b6a66e3069a66727639e5a0b7ef9ebf13b6Mark Lobodzinski * you may not use this file except in compliance with the License. 8584b2b6a66e3069a66727639e5a0b7ef9ebf13b6Mark Lobodzinski * You may obtain a copy of the License at 9584b2b6a66e3069a66727639e5a0b7ef9ebf13b6Mark Lobodzinski * 10584b2b6a66e3069a66727639e5a0b7ef9ebf13b6Mark Lobodzinski * http://www.apache.org/licenses/LICENSE-2.0 11584b2b6a66e3069a66727639e5a0b7ef9ebf13b6Mark Lobodzinski * 12584b2b6a66e3069a66727639e5a0b7ef9ebf13b6Mark Lobodzinski * Unless required by applicable law or agreed to in writing, software 13584b2b6a66e3069a66727639e5a0b7ef9ebf13b6Mark Lobodzinski * distributed under the License is distributed on an "AS IS" BASIS, 14584b2b6a66e3069a66727639e5a0b7ef9ebf13b6Mark Lobodzinski * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15584b2b6a66e3069a66727639e5a0b7ef9ebf13b6Mark Lobodzinski * See the License for the specific language governing permissions and 16584b2b6a66e3069a66727639e5a0b7ef9ebf13b6Mark Lobodzinski * limitations under the License. 17584b2b6a66e3069a66727639e5a0b7ef9ebf13b6Mark Lobodzinski * 18584b2b6a66e3069a66727639e5a0b7ef9ebf13b6Mark Lobodzinski * Author: Mark Lobodzinski <mark@lunarg.com> 19e9d74ac8e13687c1be3ee147efce42e8215a049eDave Houlton * Author: Dave Houlton <daveh@lunarg.com> 20584b2b6a66e3069a66727639e5a0b7ef9ebf13b6Mark Lobodzinski */ 21584b2b6a66e3069a66727639e5a0b7ef9ebf13b6Mark Lobodzinski 22584b2b6a66e3069a66727639e5a0b7ef9ebf13b6Mark Lobodzinski// Allow use of STL min and max functions in Windows 23584b2b6a66e3069a66727639e5a0b7ef9ebf13b6Mark Lobodzinski#define NOMINMAX 24584b2b6a66e3069a66727639e5a0b7ef9ebf13b6Mark Lobodzinski 258dea300c362f709ad26886548ea46eb4c315e401Mark Lobodzinski#include <sstream> 268dea300c362f709ad26886548ea46eb4c315e401Mark Lobodzinski 278dea300c362f709ad26886548ea46eb4c315e401Mark Lobodzinski#include "vk_enum_string_helper.h" 288dea300c362f709ad26886548ea46eb4c315e401Mark Lobodzinski#include "vk_layer_data.h" 298dea300c362f709ad26886548ea46eb4c315e401Mark Lobodzinski#include "vk_layer_utils.h" 308dea300c362f709ad26886548ea46eb4c315e401Mark Lobodzinski#include "vk_layer_logging.h" 318dea300c362f709ad26886548ea46eb4c315e401Mark Lobodzinski 32584b2b6a66e3069a66727639e5a0b7ef9ebf13b6Mark Lobodzinski#include "buffer_validation.h" 33c06c9b88f5f5bcc7033ba41d5547b048fa6015a4Mark Lobodzinski 34e40189d4deab674240cd9baf4c063bab4567c212Tobin Ehlisvoid SetLayout(layer_data *device_data, GLOBAL_CB_NODE *pCB, ImageSubresourcePair imgpair, const VkImageLayout &layout) { 350d2fd381af11d2202d3856cb2da2c7122a0294efChris Forbes if (pCB->imageLayoutMap.find(imgpair) != pCB->imageLayoutMap.end()) { 3655867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski pCB->imageLayoutMap[imgpair].layout = layout; 3755867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski } else { 3855867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski assert(imgpair.hasSubresource); 3955867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski IMAGE_CMD_BUF_LAYOUT_NODE node; 4055867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski if (!FindCmdBufLayout(device_data, pCB, imgpair.image, imgpair.subresource, node)) { 4155867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski node.initialLayout = layout; 4255867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski } 4355867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski SetLayout(device_data, pCB, imgpair, {node.initialLayout, layout}); 4455867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski } 4555867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski} 4655867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinskitemplate <class OBJECT, class LAYOUT> 47e40189d4deab674240cd9baf4c063bab4567c212Tobin Ehlisvoid SetLayout(layer_data *device_data, OBJECT *pObject, VkImage image, VkImageSubresource range, const LAYOUT &layout) { 4855867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski ImageSubresourcePair imgpair = {image, true, range}; 4955867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski SetLayout(device_data, pObject, imgpair, layout, VK_IMAGE_ASPECT_COLOR_BIT); 5055867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski SetLayout(device_data, pObject, imgpair, layout, VK_IMAGE_ASPECT_DEPTH_BIT); 5155867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski SetLayout(device_data, pObject, imgpair, layout, VK_IMAGE_ASPECT_STENCIL_BIT); 5255867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski SetLayout(device_data, pObject, imgpair, layout, VK_IMAGE_ASPECT_METADATA_BIT); 5355867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski} 5455867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski 5555867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinskitemplate <class OBJECT, class LAYOUT> 56e40189d4deab674240cd9baf4c063bab4567c212Tobin Ehlisvoid SetLayout(layer_data *device_data, OBJECT *pObject, ImageSubresourcePair imgpair, const LAYOUT &layout, 5755867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski VkImageAspectFlags aspectMask) { 5855867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski if (imgpair.subresource.aspectMask & aspectMask) { 5955867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski imgpair.subresource.aspectMask = aspectMask; 6055867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski SetLayout(device_data, pObject, imgpair, layout); 6155867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski } 6255867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski} 6355867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski 6451920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour// Set the layout in supplied map 65440bdd357701497c3442e3515f12ac1cfffc180aTony Barbourvoid SetLayout(std::unordered_map<ImageSubresourcePair, IMAGE_LAYOUT_NODE> &imageLayoutMap, ImageSubresourcePair imgpair, 66440bdd357701497c3442e3515f12ac1cfffc180aTony Barbour VkImageLayout layout) { 6751920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour imageLayoutMap[imgpair].layout = layout; 6851920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour} 6951920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour 700db18ab1345f9e10907913b22ea5d57bd48077ebTobin Ehlisbool FindLayoutVerifyNode(layer_data const *device_data, GLOBAL_CB_NODE const *pCB, ImageSubresourcePair imgpair, 7155867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski IMAGE_CMD_BUF_LAYOUT_NODE &node, const VkImageAspectFlags aspectMask) { 7255867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski const debug_report_data *report_data = core_validation::GetReportData(device_data); 7355867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski 7455867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski if (!(imgpair.subresource.aspectMask & aspectMask)) { 7555867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski return false; 7655867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski } 7755867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski VkImageAspectFlags oldAspectMask = imgpair.subresource.aspectMask; 7855867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski imgpair.subresource.aspectMask = aspectMask; 7955867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski auto imgsubIt = pCB->imageLayoutMap.find(imgpair); 8055867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski if (imgsubIt == pCB->imageLayoutMap.end()) { 8155867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski return false; 8255867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski } 8355867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski if (node.layout != VK_IMAGE_LAYOUT_MAX_ENUM && node.layout != imgsubIt->second.layout) { 8455867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, 8555867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski reinterpret_cast<uint64_t &>(imgpair.image), __LINE__, DRAWSTATE_INVALID_LAYOUT, "DS", 8655867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski "Cannot query for VkImage 0x%" PRIx64 " layout when combined aspect mask %d has multiple layout types: %s and %s", 8755867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski reinterpret_cast<uint64_t &>(imgpair.image), oldAspectMask, string_VkImageLayout(node.layout), 8855867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski string_VkImageLayout(imgsubIt->second.layout)); 8955867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski } 9055867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski if (node.initialLayout != VK_IMAGE_LAYOUT_MAX_ENUM && node.initialLayout != imgsubIt->second.initialLayout) { 9155867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, 9255867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski reinterpret_cast<uint64_t &>(imgpair.image), __LINE__, DRAWSTATE_INVALID_LAYOUT, "DS", 9355867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski "Cannot query for VkImage 0x%" PRIx64 9455867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski " layout when combined aspect mask %d has multiple initial layout types: %s and %s", 9555867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski reinterpret_cast<uint64_t &>(imgpair.image), oldAspectMask, string_VkImageLayout(node.initialLayout), 9655867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski string_VkImageLayout(imgsubIt->second.initialLayout)); 9755867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski } 9855867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski node = imgsubIt->second; 9955867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski return true; 10055867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski} 10155867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski 1020db18ab1345f9e10907913b22ea5d57bd48077ebTobin Ehlisbool FindLayoutVerifyLayout(layer_data const *device_data, ImageSubresourcePair imgpair, VkImageLayout &layout, 10355867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski const VkImageAspectFlags aspectMask) { 10455867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski if (!(imgpair.subresource.aspectMask & aspectMask)) { 10555867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski return false; 10655867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski } 10755867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski const debug_report_data *report_data = core_validation::GetReportData(device_data); 10855867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski VkImageAspectFlags oldAspectMask = imgpair.subresource.aspectMask; 10955867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski imgpair.subresource.aspectMask = aspectMask; 11055867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski auto imgsubIt = (*core_validation::GetImageLayoutMap(device_data)).find(imgpair); 11155867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski if (imgsubIt == (*core_validation::GetImageLayoutMap(device_data)).end()) { 11255867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski return false; 11355867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski } 11455867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski if (layout != VK_IMAGE_LAYOUT_MAX_ENUM && layout != imgsubIt->second.layout) { 11555867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, 11655867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski reinterpret_cast<uint64_t &>(imgpair.image), __LINE__, DRAWSTATE_INVALID_LAYOUT, "DS", 11755867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski "Cannot query for VkImage 0x%" PRIx64 " layout when combined aspect mask %d has multiple layout types: %s and %s", 11855867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski reinterpret_cast<uint64_t &>(imgpair.image), oldAspectMask, string_VkImageLayout(layout), 11955867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski string_VkImageLayout(imgsubIt->second.layout)); 12055867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski } 12155867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski layout = imgsubIt->second.layout; 12255867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski return true; 12355867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski} 12455867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski 12555867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski// Find layout(s) on the command buffer level 1260db18ab1345f9e10907913b22ea5d57bd48077ebTobin Ehlisbool FindCmdBufLayout(layer_data const *device_data, GLOBAL_CB_NODE const *pCB, VkImage image, VkImageSubresource range, 12755867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski IMAGE_CMD_BUF_LAYOUT_NODE &node) { 12855867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski ImageSubresourcePair imgpair = {image, true, range}; 12955867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski node = IMAGE_CMD_BUF_LAYOUT_NODE(VK_IMAGE_LAYOUT_MAX_ENUM, VK_IMAGE_LAYOUT_MAX_ENUM); 13055867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski FindLayoutVerifyNode(device_data, pCB, imgpair, node, VK_IMAGE_ASPECT_COLOR_BIT); 13155867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski FindLayoutVerifyNode(device_data, pCB, imgpair, node, VK_IMAGE_ASPECT_DEPTH_BIT); 13255867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski FindLayoutVerifyNode(device_data, pCB, imgpair, node, VK_IMAGE_ASPECT_STENCIL_BIT); 13355867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski FindLayoutVerifyNode(device_data, pCB, imgpair, node, VK_IMAGE_ASPECT_METADATA_BIT); 13455867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski if (node.layout == VK_IMAGE_LAYOUT_MAX_ENUM) { 13555867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski imgpair = {image, false, VkImageSubresource()}; 13655867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski auto imgsubIt = pCB->imageLayoutMap.find(imgpair); 13755867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski if (imgsubIt == pCB->imageLayoutMap.end()) return false; 13855867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski // TODO: This is ostensibly a find function but it changes state here 13955867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski node = imgsubIt->second; 14055867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski } 14155867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski return true; 14255867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski} 14355867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski 14455867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski// Find layout(s) on the global level 145e40189d4deab674240cd9baf4c063bab4567c212Tobin Ehlisbool FindGlobalLayout(layer_data *device_data, ImageSubresourcePair imgpair, VkImageLayout &layout) { 14655867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski layout = VK_IMAGE_LAYOUT_MAX_ENUM; 14755867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski FindLayoutVerifyLayout(device_data, imgpair, layout, VK_IMAGE_ASPECT_COLOR_BIT); 14855867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski FindLayoutVerifyLayout(device_data, imgpair, layout, VK_IMAGE_ASPECT_DEPTH_BIT); 14955867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski FindLayoutVerifyLayout(device_data, imgpair, layout, VK_IMAGE_ASPECT_STENCIL_BIT); 15055867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski FindLayoutVerifyLayout(device_data, imgpair, layout, VK_IMAGE_ASPECT_METADATA_BIT); 15155867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski if (layout == VK_IMAGE_LAYOUT_MAX_ENUM) { 15255867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski imgpair = {imgpair.image, false, VkImageSubresource()}; 15355867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski auto imgsubIt = (*core_validation::GetImageLayoutMap(device_data)).find(imgpair); 15455867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski if (imgsubIt == (*core_validation::GetImageLayoutMap(device_data)).end()) return false; 15555867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski layout = imgsubIt->second.layout; 15655867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski } 15755867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski return true; 15855867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski} 15955867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski 160e40189d4deab674240cd9baf4c063bab4567c212Tobin Ehlisbool FindLayouts(layer_data *device_data, VkImage image, std::vector<VkImageLayout> &layouts) { 16155867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski auto sub_data = (*core_validation::GetImageSubresourceMap(device_data)).find(image); 16255867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski if (sub_data == (*core_validation::GetImageSubresourceMap(device_data)).end()) return false; 1639a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto image_state = GetImageState(device_data, image); 16455867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski if (!image_state) return false; 16555867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski bool ignoreGlobal = false; 16655867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski // TODO: Make this robust for >1 aspect mask. Now it will just say ignore potential errors in this case. 16755867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski if (sub_data->second.size() >= (image_state->createInfo.arrayLayers * image_state->createInfo.mipLevels + 1)) { 16855867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski ignoreGlobal = true; 16955867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski } 17055867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski for (auto imgsubpair : sub_data->second) { 17155867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski if (ignoreGlobal && !imgsubpair.hasSubresource) continue; 17255867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski auto img_data = (*core_validation::GetImageLayoutMap(device_data)).find(imgsubpair); 17355867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski if (img_data != (*core_validation::GetImageLayoutMap(device_data)).end()) { 17455867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski layouts.push_back(img_data->second.layout); 17555867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski } 17655867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski } 17755867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski return true; 17855867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski} 179440bdd357701497c3442e3515f12ac1cfffc180aTony Barbourbool FindLayout(const std::unordered_map<ImageSubresourcePair, IMAGE_LAYOUT_NODE> &imageLayoutMap, ImageSubresourcePair imgpair, 180440bdd357701497c3442e3515f12ac1cfffc180aTony Barbour VkImageLayout &layout, const VkImageAspectFlags aspectMask) { 18151920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour if (!(imgpair.subresource.aspectMask & aspectMask)) { 18251920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour return false; 18351920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour } 18451920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour imgpair.subresource.aspectMask = aspectMask; 18551920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour auto imgsubIt = imageLayoutMap.find(imgpair); 18651920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour if (imgsubIt == imageLayoutMap.end()) { 18751920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour return false; 18851920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour } 18951920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour layout = imgsubIt->second.layout; 19051920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour return true; 191440bdd357701497c3442e3515f12ac1cfffc180aTony Barbour} 19251920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour 19351920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour// find layout in supplied map 194440bdd357701497c3442e3515f12ac1cfffc180aTony Barbourbool FindLayout(const std::unordered_map<ImageSubresourcePair, IMAGE_LAYOUT_NODE> &imageLayoutMap, ImageSubresourcePair imgpair, 195440bdd357701497c3442e3515f12ac1cfffc180aTony Barbour VkImageLayout &layout) { 19651920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour layout = VK_IMAGE_LAYOUT_MAX_ENUM; 19751920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour FindLayout(imageLayoutMap, imgpair, layout, VK_IMAGE_ASPECT_COLOR_BIT); 19851920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour FindLayout(imageLayoutMap, imgpair, layout, VK_IMAGE_ASPECT_DEPTH_BIT); 19951920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour FindLayout(imageLayoutMap, imgpair, layout, VK_IMAGE_ASPECT_STENCIL_BIT); 20051920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour FindLayout(imageLayoutMap, imgpair, layout, VK_IMAGE_ASPECT_METADATA_BIT); 20151920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour if (layout == VK_IMAGE_LAYOUT_MAX_ENUM) { 20251920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour imgpair = {imgpair.image, false, VkImageSubresource()}; 20351920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour auto imgsubIt = imageLayoutMap.find(imgpair); 20451920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour if (imgsubIt == imageLayoutMap.end()) return false; 20551920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour layout = imgsubIt->second.layout; 20651920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour } 20751920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour return true; 20851920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour} 20955867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski 21055867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski// Set the layout on the global level 211e40189d4deab674240cd9baf4c063bab4567c212Tobin Ehlisvoid SetGlobalLayout(layer_data *device_data, ImageSubresourcePair imgpair, const VkImageLayout &layout) { 21255867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski VkImage &image = imgpair.image; 21355867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski (*core_validation::GetImageLayoutMap(device_data))[imgpair].layout = layout; 21455867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski auto &image_subresources = (*core_validation::GetImageSubresourceMap(device_data))[image]; 21555867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski auto subresource = std::find(image_subresources.begin(), image_subresources.end(), imgpair); 21655867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski if (subresource == image_subresources.end()) { 21755867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski image_subresources.push_back(imgpair); 21855867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski } 21955867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski} 22055867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski 22155867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski// Set the layout on the cmdbuf level 222e40189d4deab674240cd9baf4c063bab4567c212Tobin Ehlisvoid SetLayout(layer_data *device_data, GLOBAL_CB_NODE *pCB, ImageSubresourcePair imgpair, const IMAGE_CMD_BUF_LAYOUT_NODE &node) { 22355867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski pCB->imageLayoutMap[imgpair] = node; 22455867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski} 225a07ae8bd5f566eb9b073498dd4280efdb0b838b9Tobin Ehlis// Set image layout for given VkImageSubresourceRange struct 226a07ae8bd5f566eb9b073498dd4280efdb0b838b9Tobin Ehlisvoid SetImageLayout(layer_data *device_data, GLOBAL_CB_NODE *cb_node, const IMAGE_STATE *image_state, 227a07ae8bd5f566eb9b073498dd4280efdb0b838b9Tobin Ehlis VkImageSubresourceRange image_subresource_range, const VkImageLayout &layout) { 228a07ae8bd5f566eb9b073498dd4280efdb0b838b9Tobin Ehlis assert(image_state); 229a07ae8bd5f566eb9b073498dd4280efdb0b838b9Tobin Ehlis for (uint32_t level_index = 0; level_index < image_subresource_range.levelCount; ++level_index) { 230a07ae8bd5f566eb9b073498dd4280efdb0b838b9Tobin Ehlis uint32_t level = image_subresource_range.baseMipLevel + level_index; 231a07ae8bd5f566eb9b073498dd4280efdb0b838b9Tobin Ehlis for (uint32_t layer_index = 0; layer_index < image_subresource_range.layerCount; layer_index++) { 232a07ae8bd5f566eb9b073498dd4280efdb0b838b9Tobin Ehlis uint32_t layer = image_subresource_range.baseArrayLayer + layer_index; 233a07ae8bd5f566eb9b073498dd4280efdb0b838b9Tobin Ehlis VkImageSubresource sub = {image_subresource_range.aspectMask, level, layer}; 23455867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski // TODO: If ImageView was created with depth or stencil, transition both layouts as the aspectMask is ignored and both 23555867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski // are used. Verify that the extra implicit layout is OK for descriptor set layout validation 236a07ae8bd5f566eb9b073498dd4280efdb0b838b9Tobin Ehlis if (image_subresource_range.aspectMask & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) { 23716769f6b2a7721e391952a97f010cbb530e4f211Dave Houlton if (FormatIsDepthAndStencil(image_state->createInfo.format)) { 23855867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski sub.aspectMask |= (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT); 23955867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski } 24055867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski } 241a07ae8bd5f566eb9b073498dd4280efdb0b838b9Tobin Ehlis SetLayout(device_data, cb_node, image_state->image, sub, layout); 24255867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski } 24355867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski } 24455867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski} 245a07ae8bd5f566eb9b073498dd4280efdb0b838b9Tobin Ehlis// Set image layout for given VkImageSubresourceLayers struct 246a07ae8bd5f566eb9b073498dd4280efdb0b838b9Tobin Ehlisvoid SetImageLayout(layer_data *device_data, GLOBAL_CB_NODE *cb_node, const IMAGE_STATE *image_state, 247a07ae8bd5f566eb9b073498dd4280efdb0b838b9Tobin Ehlis VkImageSubresourceLayers image_subresource_layers, const VkImageLayout &layout) { 248a07ae8bd5f566eb9b073498dd4280efdb0b838b9Tobin Ehlis // Transfer VkImageSubresourceLayers into VkImageSubresourceRange struct 249a07ae8bd5f566eb9b073498dd4280efdb0b838b9Tobin Ehlis VkImageSubresourceRange image_subresource_range; 250a07ae8bd5f566eb9b073498dd4280efdb0b838b9Tobin Ehlis image_subresource_range.aspectMask = image_subresource_layers.aspectMask; 251a07ae8bd5f566eb9b073498dd4280efdb0b838b9Tobin Ehlis image_subresource_range.baseArrayLayer = image_subresource_layers.baseArrayLayer; 252a07ae8bd5f566eb9b073498dd4280efdb0b838b9Tobin Ehlis image_subresource_range.layerCount = image_subresource_layers.layerCount; 253a07ae8bd5f566eb9b073498dd4280efdb0b838b9Tobin Ehlis image_subresource_range.baseMipLevel = image_subresource_layers.mipLevel; 254a07ae8bd5f566eb9b073498dd4280efdb0b838b9Tobin Ehlis image_subresource_range.levelCount = 1; 255a07ae8bd5f566eb9b073498dd4280efdb0b838b9Tobin Ehlis SetImageLayout(device_data, cb_node, image_state, image_subresource_range, layout); 256a07ae8bd5f566eb9b073498dd4280efdb0b838b9Tobin Ehlis} 257a07ae8bd5f566eb9b073498dd4280efdb0b838b9Tobin Ehlis// Set image layout for all slices of an image view 258a07ae8bd5f566eb9b073498dd4280efdb0b838b9Tobin Ehlisvoid SetImageViewLayout(layer_data *device_data, GLOBAL_CB_NODE *cb_node, VkImageView imageView, const VkImageLayout &layout) { 259a07ae8bd5f566eb9b073498dd4280efdb0b838b9Tobin Ehlis auto view_state = GetImageViewState(device_data, imageView); 260a07ae8bd5f566eb9b073498dd4280efdb0b838b9Tobin Ehlis assert(view_state); 261a07ae8bd5f566eb9b073498dd4280efdb0b838b9Tobin Ehlis 262a07ae8bd5f566eb9b073498dd4280efdb0b838b9Tobin Ehlis SetImageLayout(device_data, cb_node, GetImageState(device_data, view_state->create_info.image), 263a07ae8bd5f566eb9b073498dd4280efdb0b838b9Tobin Ehlis view_state->create_info.subresourceRange, layout); 264a07ae8bd5f566eb9b073498dd4280efdb0b838b9Tobin Ehlis} 26555867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski 266e40189d4deab674240cd9baf4c063bab4567c212Tobin Ehlisbool VerifyFramebufferAndRenderPassLayouts(layer_data *device_data, GLOBAL_CB_NODE *pCB, 26755867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski const VkRenderPassBeginInfo *pRenderPassBegin, 26855867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski const FRAMEBUFFER_STATE *framebuffer_state) { 2693251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = false; 2709a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto const pRenderPassInfo = GetRenderPassState(device_data, pRenderPassBegin->renderPass)->createInfo.ptr(); 27155867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski auto const &framebufferInfo = framebuffer_state->createInfo; 27255867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski const auto report_data = core_validation::GetReportData(device_data); 27355867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski if (pRenderPassInfo->attachmentCount != framebufferInfo.attachmentCount) { 2743251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 2753251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski reinterpret_cast<uint64_t>(pCB->commandBuffer), __LINE__, DRAWSTATE_INVALID_RENDERPASS, "DS", 2763251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "You cannot start a render pass using a framebuffer " 2773251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "with a different number of attachments."); 27855867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski } 27955867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski for (uint32_t i = 0; i < pRenderPassInfo->attachmentCount; ++i) { 28055867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski const VkImageView &image_view = framebufferInfo.pAttachments[i]; 2819a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto view_state = GetImageViewState(device_data, image_view); 28255867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski assert(view_state); 28355867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski const VkImage &image = view_state->create_info.image; 28455867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski const VkImageSubresourceRange &subRange = view_state->create_info.subresourceRange; 2855f025a7d647e3257e12a816fa1db078b5fc8ed49Tobin Ehlis auto initial_layout = pRenderPassInfo->pAttachments[i].initialLayout; 28655867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski // TODO: Do not iterate over every possibility - consolidate where possible 28755867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski for (uint32_t j = 0; j < subRange.levelCount; j++) { 28855867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski uint32_t level = subRange.baseMipLevel + j; 28955867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski for (uint32_t k = 0; k < subRange.layerCount; k++) { 29055867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski uint32_t layer = subRange.baseArrayLayer + k; 29155867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski VkImageSubresource sub = {subRange.aspectMask, level, layer}; 29255867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski IMAGE_CMD_BUF_LAYOUT_NODE node; 29355867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski if (!FindCmdBufLayout(device_data, pCB, image, sub, node)) { 2945f025a7d647e3257e12a816fa1db078b5fc8ed49Tobin Ehlis // Missing layouts will be added during state update 29555867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski continue; 29655867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski } 2975f025a7d647e3257e12a816fa1db078b5fc8ed49Tobin Ehlis if (initial_layout != VK_IMAGE_LAYOUT_UNDEFINED && initial_layout != node.layout) { 2983251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, 2993251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski __LINE__, DRAWSTATE_INVALID_RENDERPASS, "DS", 3003251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "You cannot start a render pass using attachment %u " 3013251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "where the render pass initial layout is %s and the previous " 3023251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "known layout of the attachment is %s. The layouts must match, or " 3033251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "the render pass initial layout for the attachment must be " 3043251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "VK_IMAGE_LAYOUT_UNDEFINED", 3053251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski i, string_VkImageLayout(initial_layout), string_VkImageLayout(node.layout)); 30655867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski } 30755867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski } 30855867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski } 30955867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski } 3103251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski return skip; 31155867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski} 31255867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski 313e40189d4deab674240cd9baf4c063bab4567c212Tobin Ehlisvoid TransitionAttachmentRefLayout(layer_data *device_data, GLOBAL_CB_NODE *pCB, FRAMEBUFFER_STATE *pFramebuffer, 31455867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski VkAttachmentReference ref) { 31555867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski if (ref.attachment != VK_ATTACHMENT_UNUSED) { 31655867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski auto image_view = pFramebuffer->createInfo.pAttachments[ref.attachment]; 31755867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski SetImageViewLayout(device_data, pCB, image_view, ref.layout); 31855867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski } 31955867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski} 32055867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski 3215f025a7d647e3257e12a816fa1db078b5fc8ed49Tobin Ehlisvoid TransitionSubpassLayouts(layer_data *device_data, GLOBAL_CB_NODE *pCB, const RENDER_PASS_STATE *render_pass_state, 322e40189d4deab674240cd9baf4c063bab4567c212Tobin Ehlis const int subpass_index, FRAMEBUFFER_STATE *framebuffer_state) { 3235f025a7d647e3257e12a816fa1db078b5fc8ed49Tobin Ehlis assert(render_pass_state); 32455867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski 32555867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski if (framebuffer_state) { 3265f025a7d647e3257e12a816fa1db078b5fc8ed49Tobin Ehlis auto const &subpass = render_pass_state->createInfo.pSubpasses[subpass_index]; 32755867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski for (uint32_t j = 0; j < subpass.inputAttachmentCount; ++j) { 32855867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski TransitionAttachmentRefLayout(device_data, pCB, framebuffer_state, subpass.pInputAttachments[j]); 32955867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski } 33055867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski for (uint32_t j = 0; j < subpass.colorAttachmentCount; ++j) { 33155867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski TransitionAttachmentRefLayout(device_data, pCB, framebuffer_state, subpass.pColorAttachments[j]); 33255867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski } 33355867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski if (subpass.pDepthStencilAttachment) { 33455867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski TransitionAttachmentRefLayout(device_data, pCB, framebuffer_state, *subpass.pDepthStencilAttachment); 33555867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski } 33655867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski } 33755867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski} 33855867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski 339e659c986db0f3146726d6c744c75772316c3e0c6Mark Lobodzinskibool ValidateImageAspectLayout(layer_data *device_data, GLOBAL_CB_NODE *pCB, const VkImageMemoryBarrier *mem_barrier, 340e659c986db0f3146726d6c744c75772316c3e0c6Mark Lobodzinski uint32_t level, uint32_t layer, VkImageAspectFlags aspect) { 34155867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski if (!(mem_barrier->subresourceRange.aspectMask & aspect)) { 34255867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski return false; 34355867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski } 34455867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski VkImageSubresource sub = {aspect, level, layer}; 34555867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski IMAGE_CMD_BUF_LAYOUT_NODE node; 34655867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski if (!FindCmdBufLayout(device_data, pCB, mem_barrier->image, sub, node)) { 34755867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski return false; 34855867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski } 34955867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski bool skip = false; 35055867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski if (mem_barrier->oldLayout == VK_IMAGE_LAYOUT_UNDEFINED) { 35155867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski // TODO: Set memory invalid which is in mem_tracker currently 35255867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski } else if (node.layout != mem_barrier->oldLayout) { 3530620f54d857b76b4866f3835bc1aea96e525699cMark Lobodzinski skip |= 3540620f54d857b76b4866f3835bc1aea96e525699cMark Lobodzinski log_msg(core_validation::GetReportData(device_data), VK_DEBUG_REPORT_ERROR_BIT_EXT, 3550620f54d857b76b4866f3835bc1aea96e525699cMark Lobodzinski VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, reinterpret_cast<uint64_t>(pCB->commandBuffer), __LINE__, 3560620f54d857b76b4866f3835bc1aea96e525699cMark Lobodzinski DRAWSTATE_INVALID_IMAGE_LAYOUT, "DS", 3570620f54d857b76b4866f3835bc1aea96e525699cMark Lobodzinski "For image 0x%" PRIxLEAST64 " you cannot transition the layout of aspect %d from %s when current layout is %s.", 3580620f54d857b76b4866f3835bc1aea96e525699cMark Lobodzinski reinterpret_cast<const uint64_t &>(mem_barrier->image), aspect, string_VkImageLayout(mem_barrier->oldLayout), 3590620f54d857b76b4866f3835bc1aea96e525699cMark Lobodzinski string_VkImageLayout(node.layout)); 36055867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski } 36155867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski return skip; 36255867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski} 36355867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski 3645f025a7d647e3257e12a816fa1db078b5fc8ed49Tobin Ehlis// Transition the layout state for renderpass attachments based on the BeginRenderPass() call. This includes: 3655f025a7d647e3257e12a816fa1db078b5fc8ed49Tobin Ehlis// 1. Transition into initialLayout state 3665f025a7d647e3257e12a816fa1db078b5fc8ed49Tobin Ehlis// 2. Transition from initialLayout to layout used in subpass 0 3675f025a7d647e3257e12a816fa1db078b5fc8ed49Tobin Ehlisvoid TransitionBeginRenderPassLayouts(layer_data *device_data, GLOBAL_CB_NODE *cb_state, const RENDER_PASS_STATE *render_pass_state, 3685f025a7d647e3257e12a816fa1db078b5fc8ed49Tobin Ehlis FRAMEBUFFER_STATE *framebuffer_state) { 3695f025a7d647e3257e12a816fa1db078b5fc8ed49Tobin Ehlis // First transition into initialLayout 3705f025a7d647e3257e12a816fa1db078b5fc8ed49Tobin Ehlis auto const rpci = render_pass_state->createInfo.ptr(); 3715f025a7d647e3257e12a816fa1db078b5fc8ed49Tobin Ehlis for (uint32_t i = 0; i < rpci->attachmentCount; ++i) { 3725f025a7d647e3257e12a816fa1db078b5fc8ed49Tobin Ehlis VkImageView image_view = framebuffer_state->createInfo.pAttachments[i]; 3735f025a7d647e3257e12a816fa1db078b5fc8ed49Tobin Ehlis SetImageViewLayout(device_data, cb_state, image_view, rpci->pAttachments[i].initialLayout); 3745f025a7d647e3257e12a816fa1db078b5fc8ed49Tobin Ehlis } 3755f025a7d647e3257e12a816fa1db078b5fc8ed49Tobin Ehlis // Now transition for first subpass (index 0) 3765f025a7d647e3257e12a816fa1db078b5fc8ed49Tobin Ehlis TransitionSubpassLayouts(device_data, cb_state, render_pass_state, 0, framebuffer_state); 3775f025a7d647e3257e12a816fa1db078b5fc8ed49Tobin Ehlis} 3785f025a7d647e3257e12a816fa1db078b5fc8ed49Tobin Ehlis 379e659c986db0f3146726d6c744c75772316c3e0c6Mark Lobodzinskivoid TransitionImageAspectLayout(layer_data *device_data, GLOBAL_CB_NODE *pCB, const VkImageMemoryBarrier *mem_barrier, 380e659c986db0f3146726d6c744c75772316c3e0c6Mark Lobodzinski uint32_t level, uint32_t layer, VkImageAspectFlags aspect) { 381e659c986db0f3146726d6c744c75772316c3e0c6Mark Lobodzinski if (!(mem_barrier->subresourceRange.aspectMask & aspect)) { 382e659c986db0f3146726d6c744c75772316c3e0c6Mark Lobodzinski return; 383e659c986db0f3146726d6c744c75772316c3e0c6Mark Lobodzinski } 384e659c986db0f3146726d6c744c75772316c3e0c6Mark Lobodzinski VkImageSubresource sub = {aspect, level, layer}; 385e659c986db0f3146726d6c744c75772316c3e0c6Mark Lobodzinski IMAGE_CMD_BUF_LAYOUT_NODE node; 386e659c986db0f3146726d6c744c75772316c3e0c6Mark Lobodzinski if (!FindCmdBufLayout(device_data, pCB, mem_barrier->image, sub, node)) { 387e659c986db0f3146726d6c744c75772316c3e0c6Mark Lobodzinski SetLayout(device_data, pCB, mem_barrier->image, sub, 388e659c986db0f3146726d6c744c75772316c3e0c6Mark Lobodzinski IMAGE_CMD_BUF_LAYOUT_NODE(mem_barrier->oldLayout, mem_barrier->newLayout)); 389e659c986db0f3146726d6c744c75772316c3e0c6Mark Lobodzinski return; 390e659c986db0f3146726d6c744c75772316c3e0c6Mark Lobodzinski } 391e659c986db0f3146726d6c744c75772316c3e0c6Mark Lobodzinski if (mem_barrier->oldLayout == VK_IMAGE_LAYOUT_UNDEFINED) { 392e659c986db0f3146726d6c744c75772316c3e0c6Mark Lobodzinski // TODO: Set memory invalid 393e659c986db0f3146726d6c744c75772316c3e0c6Mark Lobodzinski } 394e659c986db0f3146726d6c744c75772316c3e0c6Mark Lobodzinski SetLayout(device_data, pCB, mem_barrier->image, sub, mem_barrier->newLayout); 395e659c986db0f3146726d6c744c75772316c3e0c6Mark Lobodzinski} 396e659c986db0f3146726d6c744c75772316c3e0c6Mark Lobodzinski 39765b2f2c31703462c8ad1fcf4543c459df8a028ccDave Houltonbool VerifyAspectsPresent(VkImageAspectFlags aspect_mask, VkFormat format) { 398e9d74ac8e13687c1be3ee147efce42e8215a049eDave Houlton if ((aspect_mask & VK_IMAGE_ASPECT_COLOR_BIT) != 0) { 39916769f6b2a7721e391952a97f010cbb530e4f211Dave Houlton if (!FormatIsColor(format)) return false; 400e9d74ac8e13687c1be3ee147efce42e8215a049eDave Houlton } 401e9d74ac8e13687c1be3ee147efce42e8215a049eDave Houlton if ((aspect_mask & VK_IMAGE_ASPECT_DEPTH_BIT) != 0) { 40216769f6b2a7721e391952a97f010cbb530e4f211Dave Houlton if (!FormatHasDepth(format)) return false; 403e9d74ac8e13687c1be3ee147efce42e8215a049eDave Houlton } 404e9d74ac8e13687c1be3ee147efce42e8215a049eDave Houlton if ((aspect_mask & VK_IMAGE_ASPECT_STENCIL_BIT) != 0) { 40516769f6b2a7721e391952a97f010cbb530e4f211Dave Houlton if (!FormatHasStencil(format)) return false; 406e9d74ac8e13687c1be3ee147efce42e8215a049eDave Houlton } 407e9d74ac8e13687c1be3ee147efce42e8215a049eDave Houlton return true; 408e9d74ac8e13687c1be3ee147efce42e8215a049eDave Houlton} 409e9d74ac8e13687c1be3ee147efce42e8215a049eDave Houlton 410a90f5fa414aa0994e67cdb911938e6ae48f2ad6aMike Weiblen// Verify an ImageMemoryBarrier's old/new ImageLayouts are compatible with the Image's ImageUsageFlags. 411a90f5fa414aa0994e67cdb911938e6ae48f2ad6aMike Weiblenbool ValidateBarrierLayoutToImageUsage(layer_data *device_data, const VkImageMemoryBarrier *img_barrier, bool new_not_old, 412a90f5fa414aa0994e67cdb911938e6ae48f2ad6aMike Weiblen VkImageUsageFlags usage_flags, const char *func_name) { 413a90f5fa414aa0994e67cdb911938e6ae48f2ad6aMike Weiblen const auto report_data = core_validation::GetReportData(device_data); 414a90f5fa414aa0994e67cdb911938e6ae48f2ad6aMike Weiblen bool skip = false; 415a90f5fa414aa0994e67cdb911938e6ae48f2ad6aMike Weiblen const VkImageLayout layout = (new_not_old) ? img_barrier->newLayout : img_barrier->oldLayout; 416a90f5fa414aa0994e67cdb911938e6ae48f2ad6aMike Weiblen UNIQUE_VALIDATION_ERROR_CODE msg_code = VALIDATION_ERROR_UNDEFINED; // sentinel value meaning "no error" 417a90f5fa414aa0994e67cdb911938e6ae48f2ad6aMike Weiblen 418a90f5fa414aa0994e67cdb911938e6ae48f2ad6aMike Weiblen switch (layout) { 419a90f5fa414aa0994e67cdb911938e6ae48f2ad6aMike Weiblen case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL: 420a90f5fa414aa0994e67cdb911938e6ae48f2ad6aMike Weiblen if ((usage_flags & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) == 0) { 421a90f5fa414aa0994e67cdb911938e6ae48f2ad6aMike Weiblen msg_code = VALIDATION_ERROR_00303; 422a90f5fa414aa0994e67cdb911938e6ae48f2ad6aMike Weiblen } 423a90f5fa414aa0994e67cdb911938e6ae48f2ad6aMike Weiblen break; 424a90f5fa414aa0994e67cdb911938e6ae48f2ad6aMike Weiblen case VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL: 425a90f5fa414aa0994e67cdb911938e6ae48f2ad6aMike Weiblen if ((usage_flags & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) == 0) { 426a90f5fa414aa0994e67cdb911938e6ae48f2ad6aMike Weiblen msg_code = VALIDATION_ERROR_00304; 427a90f5fa414aa0994e67cdb911938e6ae48f2ad6aMike Weiblen } 428a90f5fa414aa0994e67cdb911938e6ae48f2ad6aMike Weiblen break; 429a90f5fa414aa0994e67cdb911938e6ae48f2ad6aMike Weiblen case VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL: 430a90f5fa414aa0994e67cdb911938e6ae48f2ad6aMike Weiblen if ((usage_flags & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) == 0) { 431a90f5fa414aa0994e67cdb911938e6ae48f2ad6aMike Weiblen msg_code = VALIDATION_ERROR_00305; 432a90f5fa414aa0994e67cdb911938e6ae48f2ad6aMike Weiblen } 433a90f5fa414aa0994e67cdb911938e6ae48f2ad6aMike Weiblen break; 434a90f5fa414aa0994e67cdb911938e6ae48f2ad6aMike Weiblen case VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL: 435a90f5fa414aa0994e67cdb911938e6ae48f2ad6aMike Weiblen if ((usage_flags & (VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT)) == 0) { 436a90f5fa414aa0994e67cdb911938e6ae48f2ad6aMike Weiblen msg_code = VALIDATION_ERROR_00306; 437a90f5fa414aa0994e67cdb911938e6ae48f2ad6aMike Weiblen } 438a90f5fa414aa0994e67cdb911938e6ae48f2ad6aMike Weiblen break; 439a90f5fa414aa0994e67cdb911938e6ae48f2ad6aMike Weiblen case VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL: 440a90f5fa414aa0994e67cdb911938e6ae48f2ad6aMike Weiblen if ((usage_flags & VK_IMAGE_USAGE_TRANSFER_SRC_BIT) == 0) { 441a90f5fa414aa0994e67cdb911938e6ae48f2ad6aMike Weiblen msg_code = VALIDATION_ERROR_00307; 442a90f5fa414aa0994e67cdb911938e6ae48f2ad6aMike Weiblen } 443a90f5fa414aa0994e67cdb911938e6ae48f2ad6aMike Weiblen break; 444a90f5fa414aa0994e67cdb911938e6ae48f2ad6aMike Weiblen case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL: 445a90f5fa414aa0994e67cdb911938e6ae48f2ad6aMike Weiblen if ((usage_flags & VK_IMAGE_USAGE_TRANSFER_DST_BIT) == 0) { 446a90f5fa414aa0994e67cdb911938e6ae48f2ad6aMike Weiblen msg_code = VALIDATION_ERROR_00308; 447a90f5fa414aa0994e67cdb911938e6ae48f2ad6aMike Weiblen } 448a90f5fa414aa0994e67cdb911938e6ae48f2ad6aMike Weiblen break; 449a90f5fa414aa0994e67cdb911938e6ae48f2ad6aMike Weiblen default: 450a90f5fa414aa0994e67cdb911938e6ae48f2ad6aMike Weiblen // Other VkImageLayout values do not have VUs defined in this context. 451a90f5fa414aa0994e67cdb911938e6ae48f2ad6aMike Weiblen break; 452a90f5fa414aa0994e67cdb911938e6ae48f2ad6aMike Weiblen } 453a90f5fa414aa0994e67cdb911938e6ae48f2ad6aMike Weiblen 454a90f5fa414aa0994e67cdb911938e6ae48f2ad6aMike Weiblen if (msg_code != VALIDATION_ERROR_UNDEFINED) { 455fdc75c21ced997fbbc180734bef87bf6d5811d4bMark Lobodzinski skip |= 456fdc75c21ced997fbbc180734bef87bf6d5811d4bMark Lobodzinski log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, 457fdc75c21ced997fbbc180734bef87bf6d5811d4bMark Lobodzinski reinterpret_cast<const uint64_t &>(img_barrier->image), __LINE__, msg_code, "DS", 458fdc75c21ced997fbbc180734bef87bf6d5811d4bMark Lobodzinski "%s: Image barrier 0x%p %sLayout=%s is not compatible with image 0x%" PRIx64 " usage flags 0x%" PRIx32 ". %s", 459fdc75c21ced997fbbc180734bef87bf6d5811d4bMark Lobodzinski func_name, img_barrier, ((new_not_old) ? "new" : "old"), string_VkImageLayout(layout), 460fdc75c21ced997fbbc180734bef87bf6d5811d4bMark Lobodzinski reinterpret_cast<const uint64_t &>(img_barrier->image), usage_flags, validation_error_map[msg_code]); 461a90f5fa414aa0994e67cdb911938e6ae48f2ad6aMike Weiblen } 462a90f5fa414aa0994e67cdb911938e6ae48f2ad6aMike Weiblen return skip; 463a90f5fa414aa0994e67cdb911938e6ae48f2ad6aMike Weiblen} 464a90f5fa414aa0994e67cdb911938e6ae48f2ad6aMike Weiblen 465a90f5fa414aa0994e67cdb911938e6ae48f2ad6aMike Weiblen// Verify image barriers are compatible with the images they reference. 466a90f5fa414aa0994e67cdb911938e6ae48f2ad6aMike Weiblenbool ValidateBarriersToImages(layer_data *device_data, VkCommandBuffer cmdBuffer, uint32_t imageMemoryBarrierCount, 467a90f5fa414aa0994e67cdb911938e6ae48f2ad6aMike Weiblen const VkImageMemoryBarrier *pImageMemoryBarriers, const char *func_name) { 4689a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis GLOBAL_CB_NODE *pCB = GetCBNode(device_data, cmdBuffer); 46955867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski bool skip = false; 470a90f5fa414aa0994e67cdb911938e6ae48f2ad6aMike Weiblen 471a90f5fa414aa0994e67cdb911938e6ae48f2ad6aMike Weiblen for (uint32_t i = 0; i < imageMemoryBarrierCount; ++i) { 472a90f5fa414aa0994e67cdb911938e6ae48f2ad6aMike Weiblen auto img_barrier = &pImageMemoryBarriers[i]; 473a90f5fa414aa0994e67cdb911938e6ae48f2ad6aMike Weiblen if (!img_barrier) continue; 47455867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski 47595b7894efd5e101e410da92fc697429aec3ffa7bMark Lobodzinski VkImageCreateInfo *image_create_info = &(GetImageState(device_data, img_barrier->image)->createInfo); 476c7455116cef9c14f8405aae43bc0247f2c256f96Tobin Ehlis // For a Depth/Stencil image both aspects MUST be set 477c7455116cef9c14f8405aae43bc0247f2c256f96Tobin Ehlis if (FormatIsDepthAndStencil(image_create_info->format)) { 478c7455116cef9c14f8405aae43bc0247f2c256f96Tobin Ehlis auto const aspect_mask = img_barrier->subresourceRange.aspectMask; 479c7455116cef9c14f8405aae43bc0247f2c256f96Tobin Ehlis auto const ds_mask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT; 480c7455116cef9c14f8405aae43bc0247f2c256f96Tobin Ehlis if ((aspect_mask & ds_mask) != (ds_mask)) { 481c7455116cef9c14f8405aae43bc0247f2c256f96Tobin Ehlis skip |= 482c7455116cef9c14f8405aae43bc0247f2c256f96Tobin Ehlis log_msg(core_validation::GetReportData(device_data), VK_DEBUG_REPORT_ERROR_BIT_EXT, 483c7455116cef9c14f8405aae43bc0247f2c256f96Tobin Ehlis VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, reinterpret_cast<const uint64_t &>(img_barrier->image), __LINE__, 484c7455116cef9c14f8405aae43bc0247f2c256f96Tobin Ehlis VALIDATION_ERROR_00302, "DS", 485c7455116cef9c14f8405aae43bc0247f2c256f96Tobin Ehlis "%s: Image barrier 0x%p references image 0x%" PRIx64 486c7455116cef9c14f8405aae43bc0247f2c256f96Tobin Ehlis " of format %s that must have the depth and stencil aspects set, but its " 487c7455116cef9c14f8405aae43bc0247f2c256f96Tobin Ehlis "aspectMask is 0x%" PRIx32 ". %s", 488c7455116cef9c14f8405aae43bc0247f2c256f96Tobin Ehlis func_name, img_barrier, reinterpret_cast<const uint64_t &>(img_barrier->image), 489c7455116cef9c14f8405aae43bc0247f2c256f96Tobin Ehlis string_VkFormat(image_create_info->format), aspect_mask, validation_error_map[VALIDATION_ERROR_00302]); 490c7455116cef9c14f8405aae43bc0247f2c256f96Tobin Ehlis } 491c7455116cef9c14f8405aae43bc0247f2c256f96Tobin Ehlis } 49295b7894efd5e101e410da92fc697429aec3ffa7bMark Lobodzinski uint32_t level_count = ResolveRemainingLevels(&img_barrier->subresourceRange, image_create_info->mipLevels); 49395b7894efd5e101e410da92fc697429aec3ffa7bMark Lobodzinski uint32_t layer_count = ResolveRemainingLayers(&img_barrier->subresourceRange, image_create_info->arrayLayers); 494a90f5fa414aa0994e67cdb911938e6ae48f2ad6aMike Weiblen 495a90f5fa414aa0994e67cdb911938e6ae48f2ad6aMike Weiblen for (uint32_t j = 0; j < level_count; j++) { 496a90f5fa414aa0994e67cdb911938e6ae48f2ad6aMike Weiblen uint32_t level = img_barrier->subresourceRange.baseMipLevel + j; 497a90f5fa414aa0994e67cdb911938e6ae48f2ad6aMike Weiblen for (uint32_t k = 0; k < layer_count; k++) { 498a90f5fa414aa0994e67cdb911938e6ae48f2ad6aMike Weiblen uint32_t layer = img_barrier->subresourceRange.baseArrayLayer + k; 499a90f5fa414aa0994e67cdb911938e6ae48f2ad6aMike Weiblen skip |= ValidateImageAspectLayout(device_data, pCB, img_barrier, level, layer, VK_IMAGE_ASPECT_COLOR_BIT); 500a90f5fa414aa0994e67cdb911938e6ae48f2ad6aMike Weiblen skip |= ValidateImageAspectLayout(device_data, pCB, img_barrier, level, layer, VK_IMAGE_ASPECT_DEPTH_BIT); 501a90f5fa414aa0994e67cdb911938e6ae48f2ad6aMike Weiblen skip |= ValidateImageAspectLayout(device_data, pCB, img_barrier, level, layer, VK_IMAGE_ASPECT_STENCIL_BIT); 502a90f5fa414aa0994e67cdb911938e6ae48f2ad6aMike Weiblen skip |= ValidateImageAspectLayout(device_data, pCB, img_barrier, level, layer, VK_IMAGE_ASPECT_METADATA_BIT); 50355867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski } 50455867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski } 505a90f5fa414aa0994e67cdb911938e6ae48f2ad6aMike Weiblen 506a90f5fa414aa0994e67cdb911938e6ae48f2ad6aMike Weiblen IMAGE_STATE *image_state = GetImageState(device_data, img_barrier->image); 507a90f5fa414aa0994e67cdb911938e6ae48f2ad6aMike Weiblen if (image_state) { 508a90f5fa414aa0994e67cdb911938e6ae48f2ad6aMike Weiblen VkImageUsageFlags usage_flags = image_state->createInfo.usage; 509a90f5fa414aa0994e67cdb911938e6ae48f2ad6aMike Weiblen skip |= ValidateBarrierLayoutToImageUsage(device_data, img_barrier, false, usage_flags, func_name); 510a90f5fa414aa0994e67cdb911938e6ae48f2ad6aMike Weiblen skip |= ValidateBarrierLayoutToImageUsage(device_data, img_barrier, true, usage_flags, func_name); 511a90f5fa414aa0994e67cdb911938e6ae48f2ad6aMike Weiblen } 51255867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski } 51355867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski return skip; 51455867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski} 51555867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski 516e659c986db0f3146726d6c744c75772316c3e0c6Mark Lobodzinskivoid TransitionImageLayouts(layer_data *device_data, VkCommandBuffer cmdBuffer, uint32_t memBarrierCount, 517e659c986db0f3146726d6c744c75772316c3e0c6Mark Lobodzinski const VkImageMemoryBarrier *pImgMemBarriers) { 518e659c986db0f3146726d6c744c75772316c3e0c6Mark Lobodzinski GLOBAL_CB_NODE *pCB = GetCBNode(device_data, cmdBuffer); 519e659c986db0f3146726d6c744c75772316c3e0c6Mark Lobodzinski 520e659c986db0f3146726d6c744c75772316c3e0c6Mark Lobodzinski for (uint32_t i = 0; i < memBarrierCount; ++i) { 521e659c986db0f3146726d6c744c75772316c3e0c6Mark Lobodzinski auto mem_barrier = &pImgMemBarriers[i]; 522e659c986db0f3146726d6c744c75772316c3e0c6Mark Lobodzinski if (!mem_barrier) continue; 523e659c986db0f3146726d6c744c75772316c3e0c6Mark Lobodzinski 52495b7894efd5e101e410da92fc697429aec3ffa7bMark Lobodzinski VkImageCreateInfo *image_create_info = &(GetImageState(device_data, mem_barrier->image)->createInfo); 52595b7894efd5e101e410da92fc697429aec3ffa7bMark Lobodzinski uint32_t level_count = ResolveRemainingLevels(&mem_barrier->subresourceRange, image_create_info->mipLevels); 52695b7894efd5e101e410da92fc697429aec3ffa7bMark Lobodzinski uint32_t layer_count = ResolveRemainingLayers(&mem_barrier->subresourceRange, image_create_info->arrayLayers); 52795b7894efd5e101e410da92fc697429aec3ffa7bMark Lobodzinski 52895b7894efd5e101e410da92fc697429aec3ffa7bMark Lobodzinski for (uint32_t j = 0; j < level_count; j++) { 529e659c986db0f3146726d6c744c75772316c3e0c6Mark Lobodzinski uint32_t level = mem_barrier->subresourceRange.baseMipLevel + j; 53095b7894efd5e101e410da92fc697429aec3ffa7bMark Lobodzinski for (uint32_t k = 0; k < layer_count; k++) { 531e659c986db0f3146726d6c744c75772316c3e0c6Mark Lobodzinski uint32_t layer = mem_barrier->subresourceRange.baseArrayLayer + k; 532e659c986db0f3146726d6c744c75772316c3e0c6Mark Lobodzinski TransitionImageAspectLayout(device_data, pCB, mem_barrier, level, layer, VK_IMAGE_ASPECT_COLOR_BIT); 533e659c986db0f3146726d6c744c75772316c3e0c6Mark Lobodzinski TransitionImageAspectLayout(device_data, pCB, mem_barrier, level, layer, VK_IMAGE_ASPECT_DEPTH_BIT); 534e659c986db0f3146726d6c744c75772316c3e0c6Mark Lobodzinski TransitionImageAspectLayout(device_data, pCB, mem_barrier, level, layer, VK_IMAGE_ASPECT_STENCIL_BIT); 535e659c986db0f3146726d6c744c75772316c3e0c6Mark Lobodzinski TransitionImageAspectLayout(device_data, pCB, mem_barrier, level, layer, VK_IMAGE_ASPECT_METADATA_BIT); 536e659c986db0f3146726d6c744c75772316c3e0c6Mark Lobodzinski } 537e659c986db0f3146726d6c744c75772316c3e0c6Mark Lobodzinski } 538e659c986db0f3146726d6c744c75772316c3e0c6Mark Lobodzinski } 539e659c986db0f3146726d6c744c75772316c3e0c6Mark Lobodzinski} 540e659c986db0f3146726d6c744c75772316c3e0c6Mark Lobodzinski 5410db18ab1345f9e10907913b22ea5d57bd48077ebTobin Ehlisbool VerifyImageLayout(layer_data const *device_data, GLOBAL_CB_NODE const *cb_node, IMAGE_STATE *image_state, 542fab4fd84d0d187bc73b5bc6709d8ed6370bb7cc3Tobin Ehlis VkImageSubresourceLayers subLayers, VkImageLayout explicit_layout, VkImageLayout optimal_layout, 5430db18ab1345f9e10907913b22ea5d57bd48077ebTobin Ehlis const char *caller, UNIQUE_VALIDATION_ERROR_CODE msg_code, bool *error) { 54455867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski const auto report_data = core_validation::GetReportData(device_data); 545fab4fd84d0d187bc73b5bc6709d8ed6370bb7cc3Tobin Ehlis const auto image = image_state->image; 5463251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = false; 54755867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski 54855867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski for (uint32_t i = 0; i < subLayers.layerCount; ++i) { 54955867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski uint32_t layer = i + subLayers.baseArrayLayer; 55055867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski VkImageSubresource sub = {subLayers.aspectMask, subLayers.mipLevel, layer}; 55155867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski IMAGE_CMD_BUF_LAYOUT_NODE node; 552a07ae8bd5f566eb9b073498dd4280efdb0b838b9Tobin Ehlis if (FindCmdBufLayout(device_data, cb_node, image, sub, node)) { 553a07ae8bd5f566eb9b073498dd4280efdb0b838b9Tobin Ehlis if (node.layout != explicit_layout) { 5540db18ab1345f9e10907913b22ea5d57bd48077ebTobin Ehlis *error = true; 555a07ae8bd5f566eb9b073498dd4280efdb0b838b9Tobin Ehlis // TODO: Improve log message in the next pass 5563251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 5573251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski reinterpret_cast<uint64_t>(cb_node->commandBuffer), __LINE__, DRAWSTATE_INVALID_IMAGE_LAYOUT, "DS", 5583251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "%s: Cannot use image 0x%" PRIxLEAST64 5593251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski " with specific layout %s that doesn't match the actual current layout %s.", 5603251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski caller, reinterpret_cast<const uint64_t &>(image), string_VkImageLayout(explicit_layout), 5613251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski string_VkImageLayout(node.layout)); 562a07ae8bd5f566eb9b073498dd4280efdb0b838b9Tobin Ehlis } 56355867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski } 56455867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski } 565fab4fd84d0d187bc73b5bc6709d8ed6370bb7cc3Tobin Ehlis // If optimal_layout is not UNDEFINED, check that layout matches optimal for this case 566fab4fd84d0d187bc73b5bc6709d8ed6370bb7cc3Tobin Ehlis if ((VK_IMAGE_LAYOUT_UNDEFINED != optimal_layout) && (explicit_layout != optimal_layout)) { 567fab4fd84d0d187bc73b5bc6709d8ed6370bb7cc3Tobin Ehlis if (VK_IMAGE_LAYOUT_GENERAL == explicit_layout) { 56855867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski if (image_state->createInfo.tiling != VK_IMAGE_TILING_LINEAR) { 56955867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski // LAYOUT_GENERAL is allowed, but may not be performance optimal, flag as perf warning. 5703251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT, 5713251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, reinterpret_cast<uint64_t>(cb_node->commandBuffer), 5723251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski __LINE__, DRAWSTATE_INVALID_IMAGE_LAYOUT, "DS", 5733251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "%s: For optimal performance image 0x%" PRIxLEAST64 " layout should be %s instead of GENERAL.", 5743251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski caller, reinterpret_cast<const uint64_t &>(image), string_VkImageLayout(optimal_layout)); 57555867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski } 57655867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski } else { 5770db18ab1345f9e10907913b22ea5d57bd48077ebTobin Ehlis *error = true; 5783251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 5793251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski reinterpret_cast<uint64_t>(cb_node->commandBuffer), __LINE__, msg_code, "DS", 5803251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "%s: Layout for image 0x%" PRIxLEAST64 " is %s but can only be %s or VK_IMAGE_LAYOUT_GENERAL. %s", 5813251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski caller, reinterpret_cast<const uint64_t &>(image), string_VkImageLayout(explicit_layout), 5823251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski string_VkImageLayout(optimal_layout), validation_error_map[msg_code]); 58355867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski } 58455867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski } 5853251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski return skip; 58655867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski} 58755867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski 588e40189d4deab674240cd9baf4c063bab4567c212Tobin Ehlisvoid TransitionFinalSubpassLayouts(layer_data *device_data, GLOBAL_CB_NODE *pCB, const VkRenderPassBeginInfo *pRenderPassBegin, 589e40189d4deab674240cd9baf4c063bab4567c212Tobin Ehlis FRAMEBUFFER_STATE *framebuffer_state) { 5909a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto renderPass = GetRenderPassState(device_data, pRenderPassBegin->renderPass); 59155867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski if (!renderPass) return; 59255867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski 59355867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski const VkRenderPassCreateInfo *pRenderPassInfo = renderPass->createInfo.ptr(); 59455867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski if (framebuffer_state) { 59555867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski for (uint32_t i = 0; i < pRenderPassInfo->attachmentCount; ++i) { 59655867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski auto image_view = framebuffer_state->createInfo.pAttachments[i]; 59755867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski SetImageViewLayout(device_data, pCB, image_view, pRenderPassInfo->pAttachments[i].finalLayout); 59855867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski } 59955867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski } 60055867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski} 60155867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski 602e40189d4deab674240cd9baf4c063bab4567c212Tobin Ehlisbool PreCallValidateCreateImage(layer_data *device_data, const VkImageCreateInfo *pCreateInfo, 6038dea300c362f709ad26886548ea46eb4c315e401Mark Lobodzinski const VkAllocationCallbacks *pAllocator, VkImage *pImage) { 6043251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = false; 6058dea300c362f709ad26886548ea46eb4c315e401Mark Lobodzinski const debug_report_data *report_data = core_validation::GetReportData(device_data); 6068dea300c362f709ad26886548ea46eb4c315e401Mark Lobodzinski 6073c4d73267a033429a5b49318cdfd743432518761Jeremy Hayes if (pCreateInfo->format == VK_FORMAT_UNDEFINED) { 6083251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, 6093251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski VALIDATION_ERROR_00715, "IMAGE", "vkCreateImage: VkFormat for image must not be VK_FORMAT_UNDEFINED. %s", 6103251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski validation_error_map[VALIDATION_ERROR_00715]); 6113c4d73267a033429a5b49318cdfd743432518761Jeremy Hayes 6123251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski return skip; 6133c4d73267a033429a5b49318cdfd743432518761Jeremy Hayes } 6143c4d73267a033429a5b49318cdfd743432518761Jeremy Hayes 6153c4d73267a033429a5b49318cdfd743432518761Jeremy Hayes const VkFormatProperties *properties = GetFormatProperties(device_data, pCreateInfo->format); 6163c4d73267a033429a5b49318cdfd743432518761Jeremy Hayes 6173c4d73267a033429a5b49318cdfd743432518761Jeremy Hayes if ((pCreateInfo->tiling == VK_IMAGE_TILING_LINEAR) && (properties->linearTilingFeatures == 0)) { 6183c4d73267a033429a5b49318cdfd743432518761Jeremy Hayes std::stringstream ss; 6193c4d73267a033429a5b49318cdfd743432518761Jeremy Hayes ss << "vkCreateImage format parameter (" << string_VkFormat(pCreateInfo->format) << ") is an unsupported format"; 6203251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, 6213251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski VALIDATION_ERROR_02150, "IMAGE", "%s. %s", ss.str().c_str(), validation_error_map[VALIDATION_ERROR_02150]); 6223c4d73267a033429a5b49318cdfd743432518761Jeremy Hayes 6233251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski return skip; 6243c4d73267a033429a5b49318cdfd743432518761Jeremy Hayes } 6253c4d73267a033429a5b49318cdfd743432518761Jeremy Hayes 6263c4d73267a033429a5b49318cdfd743432518761Jeremy Hayes if ((pCreateInfo->tiling == VK_IMAGE_TILING_OPTIMAL) && (properties->optimalTilingFeatures == 0)) { 6273c4d73267a033429a5b49318cdfd743432518761Jeremy Hayes std::stringstream ss; 6283c4d73267a033429a5b49318cdfd743432518761Jeremy Hayes ss << "vkCreateImage format parameter (" << string_VkFormat(pCreateInfo->format) << ") is an unsupported format"; 6293251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, 6303251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski VALIDATION_ERROR_02155, "IMAGE", "%s. %s", ss.str().c_str(), validation_error_map[VALIDATION_ERROR_02155]); 6313c4d73267a033429a5b49318cdfd743432518761Jeremy Hayes 6323251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski return skip; 6333c4d73267a033429a5b49318cdfd743432518761Jeremy Hayes } 6348dea300c362f709ad26886548ea46eb4c315e401Mark Lobodzinski 6353c4d73267a033429a5b49318cdfd743432518761Jeremy Hayes // Validate that format supports usage as color attachment 6363c4d73267a033429a5b49318cdfd743432518761Jeremy Hayes if (pCreateInfo->usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) { 6373c4d73267a033429a5b49318cdfd743432518761Jeremy Hayes if ((pCreateInfo->tiling == VK_IMAGE_TILING_OPTIMAL) && 6383c4d73267a033429a5b49318cdfd743432518761Jeremy Hayes ((properties->optimalTilingFeatures & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT) == 0)) { 6398dea300c362f709ad26886548ea46eb4c315e401Mark Lobodzinski std::stringstream ss; 6403c4d73267a033429a5b49318cdfd743432518761Jeremy Hayes ss << "vkCreateImage: VkFormat for TILING_OPTIMAL image (" << string_VkFormat(pCreateInfo->format) 6413c4d73267a033429a5b49318cdfd743432518761Jeremy Hayes << ") does not support requested Image usage type VK_IMAGE_USAGE_COLOR_ATTACHMENT"; 6423251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= 6438dea300c362f709ad26886548ea46eb4c315e401Mark Lobodzinski log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, 6443c4d73267a033429a5b49318cdfd743432518761Jeremy Hayes VALIDATION_ERROR_02158, "IMAGE", "%s. %s", ss.str().c_str(), validation_error_map[VALIDATION_ERROR_02158]); 6458dea300c362f709ad26886548ea46eb4c315e401Mark Lobodzinski } 6463c4d73267a033429a5b49318cdfd743432518761Jeremy Hayes if ((pCreateInfo->tiling == VK_IMAGE_TILING_LINEAR) && 6473c4d73267a033429a5b49318cdfd743432518761Jeremy Hayes ((properties->linearTilingFeatures & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT) == 0)) { 6488dea300c362f709ad26886548ea46eb4c315e401Mark Lobodzinski std::stringstream ss; 6493c4d73267a033429a5b49318cdfd743432518761Jeremy Hayes ss << "vkCreateImage: VkFormat for TILING_LINEAR image (" << string_VkFormat(pCreateInfo->format) 6503c4d73267a033429a5b49318cdfd743432518761Jeremy Hayes << ") does not support requested Image usage type VK_IMAGE_USAGE_COLOR_ATTACHMENT"; 6513251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= 6528dea300c362f709ad26886548ea46eb4c315e401Mark Lobodzinski log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, 6533c4d73267a033429a5b49318cdfd743432518761Jeremy Hayes VALIDATION_ERROR_02153, "IMAGE", "%s. %s", ss.str().c_str(), validation_error_map[VALIDATION_ERROR_02153]); 6548dea300c362f709ad26886548ea46eb4c315e401Mark Lobodzinski } 6553c4d73267a033429a5b49318cdfd743432518761Jeremy Hayes } 6568dea300c362f709ad26886548ea46eb4c315e401Mark Lobodzinski 6573c4d73267a033429a5b49318cdfd743432518761Jeremy Hayes // Validate that format supports usage as depth/stencil attachment 6583c4d73267a033429a5b49318cdfd743432518761Jeremy Hayes if (pCreateInfo->usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) { 6593c4d73267a033429a5b49318cdfd743432518761Jeremy Hayes if ((pCreateInfo->tiling == VK_IMAGE_TILING_OPTIMAL) && 6603c4d73267a033429a5b49318cdfd743432518761Jeremy Hayes ((properties->optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) == 0)) { 6613c4d73267a033429a5b49318cdfd743432518761Jeremy Hayes std::stringstream ss; 6623c4d73267a033429a5b49318cdfd743432518761Jeremy Hayes ss << "vkCreateImage: VkFormat for TILING_OPTIMAL image (" << string_VkFormat(pCreateInfo->format) 6633c4d73267a033429a5b49318cdfd743432518761Jeremy Hayes << ") does not support requested Image usage type VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT"; 6643251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= 6653c4d73267a033429a5b49318cdfd743432518761Jeremy Hayes log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, 6663c4d73267a033429a5b49318cdfd743432518761Jeremy Hayes VALIDATION_ERROR_02159, "IMAGE", "%s. %s", ss.str().c_str(), validation_error_map[VALIDATION_ERROR_02159]); 6678dea300c362f709ad26886548ea46eb4c315e401Mark Lobodzinski } 6683c4d73267a033429a5b49318cdfd743432518761Jeremy Hayes if ((pCreateInfo->tiling == VK_IMAGE_TILING_LINEAR) && 6693c4d73267a033429a5b49318cdfd743432518761Jeremy Hayes ((properties->linearTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) == 0)) { 6703c4d73267a033429a5b49318cdfd743432518761Jeremy Hayes std::stringstream ss; 6713c4d73267a033429a5b49318cdfd743432518761Jeremy Hayes ss << "vkCreateImage: VkFormat for TILING_LINEAR image (" << string_VkFormat(pCreateInfo->format) 6723c4d73267a033429a5b49318cdfd743432518761Jeremy Hayes << ") does not support requested Image usage type VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT"; 6733251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= 6743c4d73267a033429a5b49318cdfd743432518761Jeremy Hayes log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, 6753c4d73267a033429a5b49318cdfd743432518761Jeremy Hayes VALIDATION_ERROR_02154, "IMAGE", "%s. %s", ss.str().c_str(), validation_error_map[VALIDATION_ERROR_02154]); 6768dea300c362f709ad26886548ea46eb4c315e401Mark Lobodzinski } 6778dea300c362f709ad26886548ea46eb4c315e401Mark Lobodzinski } 6788dea300c362f709ad26886548ea46eb4c315e401Mark Lobodzinski 679d0b59d0aabea9048c518840e762c7a510927c132Mark Lobodzinski const VkImageFormatProperties *ImageFormatProperties = GetImageFormatProperties( 680d0b59d0aabea9048c518840e762c7a510927c132Mark Lobodzinski device_data, pCreateInfo->format, pCreateInfo->imageType, pCreateInfo->tiling, pCreateInfo->usage, pCreateInfo->flags); 6818dea300c362f709ad26886548ea46eb4c315e401Mark Lobodzinski 682d0b59d0aabea9048c518840e762c7a510927c132Mark Lobodzinski VkDeviceSize imageGranularity = GetPhysicalDeviceProperties(device_data)->limits.bufferImageGranularity; 6838dea300c362f709ad26886548ea46eb4c315e401Mark Lobodzinski imageGranularity = imageGranularity == 1 ? 0 : imageGranularity; 68460f59be7ded9ccf2d57c36b2e0974cc2798cf844Tobin Ehlis // TODO : This is also covering 2918 & 2919. Break out into separate checks 685a9991b9f53d0be4fecc63bdbdf3de9950070a3a5Mark Lobodzinski if ((pCreateInfo->extent.width <= 0) || (pCreateInfo->extent.height <= 0) || (pCreateInfo->extent.depth <= 0)) { 6863251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, 0, __LINE__, 6873251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski VALIDATION_ERROR_02917, "Image", 6883251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "CreateImage extent is 0 for at least one required dimension for image: " 6893251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "Width = %d Height = %d Depth = %d. %s", 6903251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski pCreateInfo->extent.width, pCreateInfo->extent.height, pCreateInfo->extent.depth, 6913251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski validation_error_map[VALIDATION_ERROR_02917]); 6928dea300c362f709ad26886548ea46eb4c315e401Mark Lobodzinski } 6938dea300c362f709ad26886548ea46eb4c315e401Mark Lobodzinski 6948dea300c362f709ad26886548ea46eb4c315e401Mark Lobodzinski // TODO: VALIDATION_ERROR_02125 VALIDATION_ERROR_02126 VALIDATION_ERROR_02128 VALIDATION_ERROR_00720 6958dea300c362f709ad26886548ea46eb4c315e401Mark Lobodzinski // All these extent-related VUs should be checked here 696d0b59d0aabea9048c518840e762c7a510927c132Mark Lobodzinski if ((pCreateInfo->extent.depth > ImageFormatProperties->maxExtent.depth) || 697d0b59d0aabea9048c518840e762c7a510927c132Mark Lobodzinski (pCreateInfo->extent.width > ImageFormatProperties->maxExtent.width) || 698d0b59d0aabea9048c518840e762c7a510927c132Mark Lobodzinski (pCreateInfo->extent.height > ImageFormatProperties->maxExtent.height)) { 6993251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, 0, __LINE__, 7003251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski IMAGE_INVALID_FORMAT_LIMITS_VIOLATION, "Image", 7013251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "CreateImage extents exceed allowable limits for format: " 7023251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "Width = %d Height = %d Depth = %d: Limits for Width = %d Height = %d Depth = %d for format %s.", 7033251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski pCreateInfo->extent.width, pCreateInfo->extent.height, pCreateInfo->extent.depth, 7043251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski ImageFormatProperties->maxExtent.width, ImageFormatProperties->maxExtent.height, 7053251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski ImageFormatProperties->maxExtent.depth, string_VkFormat(pCreateInfo->format)); 7068dea300c362f709ad26886548ea46eb4c315e401Mark Lobodzinski } 7078dea300c362f709ad26886548ea46eb4c315e401Mark Lobodzinski 708cf2ce8673669ca1111e333bdea272c4dd57cb5c2Dave Houlton uint64_t totalSize = 709cf2ce8673669ca1111e333bdea272c4dd57cb5c2Dave Houlton ((uint64_t)pCreateInfo->extent.width * (uint64_t)pCreateInfo->extent.height * (uint64_t)pCreateInfo->extent.depth * 710cf2ce8673669ca1111e333bdea272c4dd57cb5c2Dave Houlton (uint64_t)pCreateInfo->arrayLayers * (uint64_t)pCreateInfo->samples * (uint64_t)FormatSize(pCreateInfo->format) + 711cf2ce8673669ca1111e333bdea272c4dd57cb5c2Dave Houlton (uint64_t)imageGranularity) & 712cf2ce8673669ca1111e333bdea272c4dd57cb5c2Dave Houlton ~(uint64_t)imageGranularity; 7138dea300c362f709ad26886548ea46eb4c315e401Mark Lobodzinski 714d0b59d0aabea9048c518840e762c7a510927c132Mark Lobodzinski if (totalSize > ImageFormatProperties->maxResourceSize) { 7153251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, 0, __LINE__, 7163251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski IMAGE_INVALID_FORMAT_LIMITS_VIOLATION, "Image", 7173251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "CreateImage resource size exceeds allowable maximum " 7183251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "Image resource size = 0x%" PRIxLEAST64 ", maximum resource size = 0x%" PRIxLEAST64 " ", 7193251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski totalSize, ImageFormatProperties->maxResourceSize); 7208dea300c362f709ad26886548ea46eb4c315e401Mark Lobodzinski } 7218dea300c362f709ad26886548ea46eb4c315e401Mark Lobodzinski 7228dea300c362f709ad26886548ea46eb4c315e401Mark Lobodzinski // TODO: VALIDATION_ERROR_02132 723d0b59d0aabea9048c518840e762c7a510927c132Mark Lobodzinski if (pCreateInfo->mipLevels > ImageFormatProperties->maxMipLevels) { 7243251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, 0, __LINE__, 7253251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski IMAGE_INVALID_FORMAT_LIMITS_VIOLATION, "Image", 7263251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "CreateImage mipLevels=%d exceeds allowable maximum supported by format of %d", pCreateInfo->mipLevels, 7273251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski ImageFormatProperties->maxMipLevels); 7288dea300c362f709ad26886548ea46eb4c315e401Mark Lobodzinski } 7298dea300c362f709ad26886548ea46eb4c315e401Mark Lobodzinski 730d0b59d0aabea9048c518840e762c7a510927c132Mark Lobodzinski if (pCreateInfo->arrayLayers > ImageFormatProperties->maxArrayLayers) { 7313251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg( 7328dea300c362f709ad26886548ea46eb4c315e401Mark Lobodzinski report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, 0, __LINE__, VALIDATION_ERROR_02133, 7338dea300c362f709ad26886548ea46eb4c315e401Mark Lobodzinski "Image", "CreateImage arrayLayers=%d exceeds allowable maximum supported by format of %d. %s", pCreateInfo->arrayLayers, 734d0b59d0aabea9048c518840e762c7a510927c132Mark Lobodzinski ImageFormatProperties->maxArrayLayers, validation_error_map[VALIDATION_ERROR_02133]); 7358dea300c362f709ad26886548ea46eb4c315e401Mark Lobodzinski } 7368dea300c362f709ad26886548ea46eb4c315e401Mark Lobodzinski 737d0b59d0aabea9048c518840e762c7a510927c132Mark Lobodzinski if ((pCreateInfo->samples & ImageFormatProperties->sampleCounts) == 0) { 7383251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, 0, __LINE__, 7393251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski VALIDATION_ERROR_02138, "Image", "CreateImage samples %s is not supported by format 0x%.8X. %s", 7403251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski string_VkSampleCountFlagBits(pCreateInfo->samples), ImageFormatProperties->sampleCounts, 7413251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski validation_error_map[VALIDATION_ERROR_02138]); 7428dea300c362f709ad26886548ea46eb4c315e401Mark Lobodzinski } 7438dea300c362f709ad26886548ea46eb4c315e401Mark Lobodzinski 7448dea300c362f709ad26886548ea46eb4c315e401Mark Lobodzinski if (pCreateInfo->initialLayout != VK_IMAGE_LAYOUT_UNDEFINED && pCreateInfo->initialLayout != VK_IMAGE_LAYOUT_PREINITIALIZED) { 7453251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, 0, __LINE__, 7463251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski VALIDATION_ERROR_00731, "Image", 7473251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "vkCreateImage parameter, pCreateInfo->initialLayout, must be VK_IMAGE_LAYOUT_UNDEFINED or " 7483251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "VK_IMAGE_LAYOUT_PREINITIALIZED. %s", 7493251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski validation_error_map[VALIDATION_ERROR_00731]); 7508dea300c362f709ad26886548ea46eb4c315e401Mark Lobodzinski } 7518dea300c362f709ad26886548ea46eb4c315e401Mark Lobodzinski 75201363bf3d84ba5841a6870b40c041c2f53d76583Mark Lobodzinski if ((pCreateInfo->flags & VK_IMAGE_CREATE_SPARSE_BINDING_BIT) && (!GetEnabledFeatures(device_data)->sparseBinding)) { 7533251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, 7543251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski VALIDATION_ERROR_02143, "DS", 7553251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "vkCreateImage(): the sparseBinding device feature is disabled: Images cannot be created with the " 7563251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "VK_IMAGE_CREATE_SPARSE_BINDING_BIT set. %s", 7573251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski validation_error_map[VALIDATION_ERROR_02143]); 75801363bf3d84ba5841a6870b40c041c2f53d76583Mark Lobodzinski } 75901363bf3d84ba5841a6870b40c041c2f53d76583Mark Lobodzinski 7607e105b26dcb40aff4f9776b8f5b5f1326aa1e36cMark Lobodzinski if ((pCreateInfo->flags & VK_IMAGE_CREATE_SPARSE_ALIASED_BIT) && (!GetEnabledFeatures(device_data)->sparseResidencyAliased)) { 7613251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, 7623251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski DRAWSTATE_INVALID_FEATURE, "DS", 7633251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "vkCreateImage(): the sparseResidencyAliased device feature is disabled: Images cannot be created with the " 7643251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "VK_IMAGE_CREATE_SPARSE_ALIASED_BIT set."); 7657e105b26dcb40aff4f9776b8f5b5f1326aa1e36cMark Lobodzinski } 7667e105b26dcb40aff4f9776b8f5b5f1326aa1e36cMark Lobodzinski 7673251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski return skip; 7688dea300c362f709ad26886548ea46eb4c315e401Mark Lobodzinski} 7698dea300c362f709ad26886548ea46eb4c315e401Mark Lobodzinski 770e40189d4deab674240cd9baf4c063bab4567c212Tobin Ehlisvoid PostCallRecordCreateImage(layer_data *device_data, const VkImageCreateInfo *pCreateInfo, VkImage *pImage) { 771c06c9b88f5f5bcc7033ba41d5547b048fa6015a4Mark Lobodzinski IMAGE_LAYOUT_NODE image_state; 772c06c9b88f5f5bcc7033ba41d5547b048fa6015a4Mark Lobodzinski image_state.layout = pCreateInfo->initialLayout; 773c06c9b88f5f5bcc7033ba41d5547b048fa6015a4Mark Lobodzinski image_state.format = pCreateInfo->format; 774920311b6aa5614a545cad59521770d0898a75d65Mark Lobodzinski GetImageMap(device_data)->insert(std::make_pair(*pImage, std::unique_ptr<IMAGE_STATE>(new IMAGE_STATE(*pImage, pCreateInfo)))); 775c06c9b88f5f5bcc7033ba41d5547b048fa6015a4Mark Lobodzinski ImageSubresourcePair subpair{*pImage, false, VkImageSubresource()}; 776920311b6aa5614a545cad59521770d0898a75d65Mark Lobodzinski (*core_validation::GetImageSubresourceMap(device_data))[*pImage].push_back(subpair); 777920311b6aa5614a545cad59521770d0898a75d65Mark Lobodzinski (*core_validation::GetImageLayoutMap(device_data))[subpair] = image_state; 778c06c9b88f5f5bcc7033ba41d5547b048fa6015a4Mark Lobodzinski} 7798c59133586421be878d393799b30044497f77727Mark Lobodzinski 780e40189d4deab674240cd9baf4c063bab4567c212Tobin Ehlisbool PreCallValidateDestroyImage(layer_data *device_data, VkImage image, IMAGE_STATE **image_state, VK_OBJECT *obj_struct) { 7818c59133586421be878d393799b30044497f77727Mark Lobodzinski const CHECK_DISABLED *disabled = core_validation::GetDisables(device_data); 7829a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis *image_state = core_validation::GetImageState(device_data, image); 783cf2ce8673669ca1111e333bdea272c4dd57cb5c2Dave Houlton *obj_struct = {reinterpret_cast<uint64_t &>(image), kVulkanObjectTypeImage}; 7848c59133586421be878d393799b30044497f77727Mark Lobodzinski if (disabled->destroy_image) return false; 7858c59133586421be878d393799b30044497f77727Mark Lobodzinski bool skip = false; 7868c59133586421be878d393799b30044497f77727Mark Lobodzinski if (*image_state) { 7878c59133586421be878d393799b30044497f77727Mark Lobodzinski skip |= core_validation::ValidateObjectNotInUse(device_data, *image_state, *obj_struct, VALIDATION_ERROR_00743); 7888c59133586421be878d393799b30044497f77727Mark Lobodzinski } 7898c59133586421be878d393799b30044497f77727Mark Lobodzinski return skip; 7908c59133586421be878d393799b30044497f77727Mark Lobodzinski} 7918c59133586421be878d393799b30044497f77727Mark Lobodzinski 792e40189d4deab674240cd9baf4c063bab4567c212Tobin Ehlisvoid PostCallRecordDestroyImage(layer_data *device_data, VkImage image, IMAGE_STATE *image_state, VK_OBJECT obj_struct) { 7938c59133586421be878d393799b30044497f77727Mark Lobodzinski core_validation::invalidateCommandBuffers(device_data, image_state->cb_bindings, obj_struct); 7948c59133586421be878d393799b30044497f77727Mark Lobodzinski // Clean up memory mapping, bindings and range references for image 7958c59133586421be878d393799b30044497f77727Mark Lobodzinski for (auto mem_binding : image_state->GetBoundMemory()) { 7969a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto mem_info = core_validation::GetMemObjInfo(device_data, mem_binding); 7978c59133586421be878d393799b30044497f77727Mark Lobodzinski if (mem_info) { 7988c59133586421be878d393799b30044497f77727Mark Lobodzinski core_validation::RemoveImageMemoryRange(obj_struct.handle, mem_info); 7998c59133586421be878d393799b30044497f77727Mark Lobodzinski } 8008c59133586421be878d393799b30044497f77727Mark Lobodzinski } 8017a9423788398dbeb6d1fe0354a66123b61afda96Mark Lobodzinski core_validation::ClearMemoryObjectBindings(device_data, obj_struct.handle, kVulkanObjectTypeImage); 8028c59133586421be878d393799b30044497f77727Mark Lobodzinski // Remove image from imageMap 8038c59133586421be878d393799b30044497f77727Mark Lobodzinski core_validation::GetImageMap(device_data)->erase(image); 8048c59133586421be878d393799b30044497f77727Mark Lobodzinski std::unordered_map<VkImage, std::vector<ImageSubresourcePair>> *imageSubresourceMap = 8058c59133586421be878d393799b30044497f77727Mark Lobodzinski core_validation::GetImageSubresourceMap(device_data); 8068c59133586421be878d393799b30044497f77727Mark Lobodzinski 8078c59133586421be878d393799b30044497f77727Mark Lobodzinski const auto &sub_entry = imageSubresourceMap->find(image); 8088c59133586421be878d393799b30044497f77727Mark Lobodzinski if (sub_entry != imageSubresourceMap->end()) { 8098c59133586421be878d393799b30044497f77727Mark Lobodzinski for (const auto &pair : sub_entry->second) { 8108c59133586421be878d393799b30044497f77727Mark Lobodzinski core_validation::GetImageLayoutMap(device_data)->erase(pair); 8118c59133586421be878d393799b30044497f77727Mark Lobodzinski } 8128c59133586421be878d393799b30044497f77727Mark Lobodzinski imageSubresourceMap->erase(sub_entry); 8138c59133586421be878d393799b30044497f77727Mark Lobodzinski } 8148c59133586421be878d393799b30044497f77727Mark Lobodzinski} 815509e427aa732fc714b9aa01a175ca5f57b2d7a07Mark Lobodzinski 816e40189d4deab674240cd9baf4c063bab4567c212Tobin Ehlisbool ValidateImageAttributes(layer_data *device_data, IMAGE_STATE *image_state, VkImageSubresourceRange range) { 817509e427aa732fc714b9aa01a175ca5f57b2d7a07Mark Lobodzinski bool skip = false; 818509e427aa732fc714b9aa01a175ca5f57b2d7a07Mark Lobodzinski const debug_report_data *report_data = core_validation::GetReportData(device_data); 819509e427aa732fc714b9aa01a175ca5f57b2d7a07Mark Lobodzinski 820509e427aa732fc714b9aa01a175ca5f57b2d7a07Mark Lobodzinski if (range.aspectMask != VK_IMAGE_ASPECT_COLOR_BIT) { 821509e427aa732fc714b9aa01a175ca5f57b2d7a07Mark Lobodzinski char const str[] = "vkCmdClearColorImage aspectMasks for all subresource ranges must be set to VK_IMAGE_ASPECT_COLOR_BIT"; 822509e427aa732fc714b9aa01a175ca5f57b2d7a07Mark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, 823509e427aa732fc714b9aa01a175ca5f57b2d7a07Mark Lobodzinski reinterpret_cast<uint64_t &>(image_state->image), __LINE__, DRAWSTATE_INVALID_IMAGE_ASPECT, "IMAGE", str); 824509e427aa732fc714b9aa01a175ca5f57b2d7a07Mark Lobodzinski } 825509e427aa732fc714b9aa01a175ca5f57b2d7a07Mark Lobodzinski 82616769f6b2a7721e391952a97f010cbb530e4f211Dave Houlton if (FormatIsDepthOrStencil(image_state->createInfo.format)) { 827509e427aa732fc714b9aa01a175ca5f57b2d7a07Mark Lobodzinski char const str[] = "vkCmdClearColorImage called with depth/stencil image."; 828509e427aa732fc714b9aa01a175ca5f57b2d7a07Mark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, 829509e427aa732fc714b9aa01a175ca5f57b2d7a07Mark Lobodzinski reinterpret_cast<uint64_t &>(image_state->image), __LINE__, VALIDATION_ERROR_01088, "IMAGE", "%s. %s", str, 830509e427aa732fc714b9aa01a175ca5f57b2d7a07Mark Lobodzinski validation_error_map[VALIDATION_ERROR_01088]); 83116769f6b2a7721e391952a97f010cbb530e4f211Dave Houlton } else if (FormatIsCompressed(image_state->createInfo.format)) { 832509e427aa732fc714b9aa01a175ca5f57b2d7a07Mark Lobodzinski char const str[] = "vkCmdClearColorImage called with compressed image."; 833509e427aa732fc714b9aa01a175ca5f57b2d7a07Mark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, 834509e427aa732fc714b9aa01a175ca5f57b2d7a07Mark Lobodzinski reinterpret_cast<uint64_t &>(image_state->image), __LINE__, VALIDATION_ERROR_01088, "IMAGE", "%s. %s", str, 835509e427aa732fc714b9aa01a175ca5f57b2d7a07Mark Lobodzinski validation_error_map[VALIDATION_ERROR_01088]); 836509e427aa732fc714b9aa01a175ca5f57b2d7a07Mark Lobodzinski } 837509e427aa732fc714b9aa01a175ca5f57b2d7a07Mark Lobodzinski 838509e427aa732fc714b9aa01a175ca5f57b2d7a07Mark Lobodzinski if (!(image_state->createInfo.usage & VK_IMAGE_USAGE_TRANSFER_DST_BIT)) { 839509e427aa732fc714b9aa01a175ca5f57b2d7a07Mark Lobodzinski char const str[] = "vkCmdClearColorImage called with image created without VK_IMAGE_USAGE_TRANSFER_DST_BIT."; 840509e427aa732fc714b9aa01a175ca5f57b2d7a07Mark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, 841509e427aa732fc714b9aa01a175ca5f57b2d7a07Mark Lobodzinski reinterpret_cast<uint64_t &>(image_state->image), __LINE__, VALIDATION_ERROR_01084, "IMAGE", "%s. %s", str, 842509e427aa732fc714b9aa01a175ca5f57b2d7a07Mark Lobodzinski validation_error_map[VALIDATION_ERROR_01084]); 843509e427aa732fc714b9aa01a175ca5f57b2d7a07Mark Lobodzinski } 844509e427aa732fc714b9aa01a175ca5f57b2d7a07Mark Lobodzinski return skip; 845509e427aa732fc714b9aa01a175ca5f57b2d7a07Mark Lobodzinski} 846623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski 84795b7894efd5e101e410da92fc697429aec3ffa7bMark Lobodzinskiuint32_t ResolveRemainingLevels(const VkImageSubresourceRange *range, uint32_t mip_levels) { 84895b7894efd5e101e410da92fc697429aec3ffa7bMark Lobodzinski // Return correct number of mip levels taking into account VK_REMAINING_MIP_LEVELS 84995b7894efd5e101e410da92fc697429aec3ffa7bMark Lobodzinski uint32_t mip_level_count = range->levelCount; 85008c7aae3177092f8567e2b5a946457be61616e9aMark Lobodzinski if (range->levelCount == VK_REMAINING_MIP_LEVELS) { 85195b7894efd5e101e410da92fc697429aec3ffa7bMark Lobodzinski mip_level_count = mip_levels - range->baseMipLevel; 852623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski } 85395b7894efd5e101e410da92fc697429aec3ffa7bMark Lobodzinski return mip_level_count; 854623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski} 855623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski 85695b7894efd5e101e410da92fc697429aec3ffa7bMark Lobodzinskiuint32_t ResolveRemainingLayers(const VkImageSubresourceRange *range, uint32_t layers) { 85795b7894efd5e101e410da92fc697429aec3ffa7bMark Lobodzinski // Return correct number of layers taking into account VK_REMAINING_ARRAY_LAYERS 85895b7894efd5e101e410da92fc697429aec3ffa7bMark Lobodzinski uint32_t array_layer_count = range->layerCount; 85995b7894efd5e101e410da92fc697429aec3ffa7bMark Lobodzinski if (range->layerCount == VK_REMAINING_ARRAY_LAYERS) { 86095b7894efd5e101e410da92fc697429aec3ffa7bMark Lobodzinski array_layer_count = layers - range->baseArrayLayer; 861623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski } 86295b7894efd5e101e410da92fc697429aec3ffa7bMark Lobodzinski return array_layer_count; 863623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski} 864623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski 865e40189d4deab674240cd9baf4c063bab4567c212Tobin Ehlisbool VerifyClearImageLayout(layer_data *device_data, GLOBAL_CB_NODE *cb_node, IMAGE_STATE *image_state, 866623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski VkImageSubresourceRange range, VkImageLayout dest_image_layout, const char *func_name) { 867623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski bool skip = false; 868623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski const debug_report_data *report_data = core_validation::GetReportData(device_data); 869623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski 87095b7894efd5e101e410da92fc697429aec3ffa7bMark Lobodzinski uint32_t level_count = ResolveRemainingLevels(&range, image_state->createInfo.mipLevels); 87195b7894efd5e101e410da92fc697429aec3ffa7bMark Lobodzinski uint32_t layer_count = ResolveRemainingLayers(&range, image_state->createInfo.arrayLayers); 872623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski 873623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski if (dest_image_layout != VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL) { 874623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski if (dest_image_layout == VK_IMAGE_LAYOUT_GENERAL) { 875623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski if (image_state->createInfo.tiling != VK_IMAGE_TILING_LINEAR) { 876623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski // LAYOUT_GENERAL is allowed, but may not be performance optimal, flag as perf warning. 877fdc75c21ced997fbbc180734bef87bf6d5811d4bMark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, 878fdc75c21ced997fbbc180734bef87bf6d5811d4bMark Lobodzinski reinterpret_cast<uint64_t &>(image_state->image), __LINE__, DRAWSTATE_INVALID_IMAGE_LAYOUT, "DS", 879623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski "%s: Layout for cleared image should be TRANSFER_DST_OPTIMAL instead of GENERAL.", func_name); 880623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski } 881623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski } else { 882623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski UNIQUE_VALIDATION_ERROR_CODE error_code = VALIDATION_ERROR_01086; 883623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski if (strcmp(func_name, "vkCmdClearDepthStencilImage()") == 0) { 884623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski error_code = VALIDATION_ERROR_01101; 885623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski } else { 886623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski assert(strcmp(func_name, "vkCmdClearColorImage()") == 0); 887623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski } 888fdc75c21ced997fbbc180734bef87bf6d5811d4bMark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, 889fdc75c21ced997fbbc180734bef87bf6d5811d4bMark Lobodzinski reinterpret_cast<uint64_t &>(image_state->image), __LINE__, error_code, "DS", 890fdc75c21ced997fbbc180734bef87bf6d5811d4bMark Lobodzinski "%s: Layout for cleared image is %s but can only be " 891fdc75c21ced997fbbc180734bef87bf6d5811d4bMark Lobodzinski "TRANSFER_DST_OPTIMAL or GENERAL. %s", 892fdc75c21ced997fbbc180734bef87bf6d5811d4bMark Lobodzinski func_name, string_VkImageLayout(dest_image_layout), validation_error_map[error_code]); 893623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski } 894623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski } 895623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski 89695b7894efd5e101e410da92fc697429aec3ffa7bMark Lobodzinski for (uint32_t level_index = 0; level_index < level_count; ++level_index) { 89795b7894efd5e101e410da92fc697429aec3ffa7bMark Lobodzinski uint32_t level = level_index + range.baseMipLevel; 89895b7894efd5e101e410da92fc697429aec3ffa7bMark Lobodzinski for (uint32_t layer_index = 0; layer_index < layer_count; ++layer_index) { 89995b7894efd5e101e410da92fc697429aec3ffa7bMark Lobodzinski uint32_t layer = layer_index + range.baseArrayLayer; 90095b7894efd5e101e410da92fc697429aec3ffa7bMark Lobodzinski VkImageSubresource sub = {range.aspectMask, level, layer}; 901623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski IMAGE_CMD_BUF_LAYOUT_NODE node; 90255867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski if (FindCmdBufLayout(device_data, cb_node, image_state->image, sub, node)) { 903623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski if (node.layout != dest_image_layout) { 904623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski UNIQUE_VALIDATION_ERROR_CODE error_code = VALIDATION_ERROR_01085; 905623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski if (strcmp(func_name, "vkCmdClearDepthStencilImage()") == 0) { 906623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski error_code = VALIDATION_ERROR_01100; 907623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski } else { 908623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski assert(strcmp(func_name, "vkCmdClearColorImage()") == 0); 909623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski } 910623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 0, 911623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski __LINE__, error_code, "DS", 912623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski "%s: Cannot clear an image whose layout is %s and " 913623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski "doesn't match the current layout %s. %s", 914623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski func_name, string_VkImageLayout(dest_image_layout), string_VkImageLayout(node.layout), 915623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski validation_error_map[error_code]); 916623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski } 917623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski } 918623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski } 919623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski } 920623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski 921623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski return skip; 922623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski} 923623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski 924e40189d4deab674240cd9baf4c063bab4567c212Tobin Ehlisvoid RecordClearImageLayout(layer_data *device_data, GLOBAL_CB_NODE *cb_node, VkImage image, VkImageSubresourceRange range, 925e40189d4deab674240cd9baf4c063bab4567c212Tobin Ehlis VkImageLayout dest_image_layout) { 92695b7894efd5e101e410da92fc697429aec3ffa7bMark Lobodzinski VkImageCreateInfo *image_create_info = &(GetImageState(device_data, image)->createInfo); 92795b7894efd5e101e410da92fc697429aec3ffa7bMark Lobodzinski uint32_t level_count = ResolveRemainingLevels(&range, image_create_info->mipLevels); 92895b7894efd5e101e410da92fc697429aec3ffa7bMark Lobodzinski uint32_t layer_count = ResolveRemainingLayers(&range, image_create_info->arrayLayers); 92995b7894efd5e101e410da92fc697429aec3ffa7bMark Lobodzinski 93095b7894efd5e101e410da92fc697429aec3ffa7bMark Lobodzinski for (uint32_t level_index = 0; level_index < level_count; ++level_index) { 93195b7894efd5e101e410da92fc697429aec3ffa7bMark Lobodzinski uint32_t level = level_index + range.baseMipLevel; 93295b7894efd5e101e410da92fc697429aec3ffa7bMark Lobodzinski for (uint32_t layer_index = 0; layer_index < layer_count; ++layer_index) { 93395b7894efd5e101e410da92fc697429aec3ffa7bMark Lobodzinski uint32_t layer = layer_index + range.baseArrayLayer; 93495b7894efd5e101e410da92fc697429aec3ffa7bMark Lobodzinski VkImageSubresource sub = {range.aspectMask, level, layer}; 935623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski IMAGE_CMD_BUF_LAYOUT_NODE node; 93655867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski if (!FindCmdBufLayout(device_data, cb_node, image, sub, node)) { 93755867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski SetLayout(device_data, cb_node, image, sub, IMAGE_CMD_BUF_LAYOUT_NODE(dest_image_layout, dest_image_layout)); 938623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski } 939623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski } 940623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski } 941623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski} 942623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski 943e40189d4deab674240cd9baf4c063bab4567c212Tobin Ehlisbool PreCallValidateCmdClearColorImage(layer_data *dev_data, VkCommandBuffer commandBuffer, VkImage image, 944623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski VkImageLayout imageLayout, uint32_t rangeCount, const VkImageSubresourceRange *pRanges) { 945623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski bool skip = false; 946623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski // TODO : Verify memory is in VK_IMAGE_STATE_CLEAR state 9479a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto cb_node = GetCBNode(dev_data, commandBuffer); 9489a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto image_state = GetImageState(dev_data, image); 949623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski if (cb_node && image_state) { 950623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski skip |= ValidateMemoryIsBoundToImage(dev_data, image_state, "vkCmdClearColorImage()", VALIDATION_ERROR_02527); 951baa50ccc5a8cf7a6f7474148f301802c5480e715Mike Schuchardt skip |= ValidateCmdQueueFlags(dev_data, cb_node, "vkCmdClearColorImage()", VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT, 952baa50ccc5a8cf7a6f7474148f301802c5480e715Mike Schuchardt VALIDATION_ERROR_01095); 953623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski skip |= ValidateCmd(dev_data, cb_node, CMD_CLEARCOLORIMAGE, "vkCmdClearColorImage()"); 954623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski skip |= insideRenderPass(dev_data, cb_node, "vkCmdClearColorImage()", VALIDATION_ERROR_01096); 955623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski for (uint32_t i = 0; i < rangeCount; ++i) { 956623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski skip |= ValidateImageAttributes(dev_data, image_state, pRanges[i]); 95708c7aae3177092f8567e2b5a946457be61616e9aMark Lobodzinski skip |= VerifyClearImageLayout(dev_data, cb_node, image_state, pRanges[i], imageLayout, "vkCmdClearColorImage()"); 958623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski } 959623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski } 960623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski return skip; 961623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski} 962623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski 963623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski// This state recording routine is shared between ClearColorImage and ClearDepthStencilImage 964e40189d4deab674240cd9baf4c063bab4567c212Tobin Ehlisvoid PreCallRecordCmdClearImage(layer_data *dev_data, VkCommandBuffer commandBuffer, VkImage image, VkImageLayout imageLayout, 965e40189d4deab674240cd9baf4c063bab4567c212Tobin Ehlis uint32_t rangeCount, const VkImageSubresourceRange *pRanges, CMD_TYPE cmd_type) { 9669a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto cb_node = GetCBNode(dev_data, commandBuffer); 9679a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto image_state = GetImageState(dev_data, image); 968623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski if (cb_node && image_state) { 969623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski AddCommandBufferBindingImage(dev_data, cb_node, image_state); 970623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski std::function<bool()> function = [=]() { 971623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski SetImageMemoryValid(dev_data, image_state, true); 972623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski return false; 973623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski }; 974623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski cb_node->validate_functions.push_back(function); 9759a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis core_validation::UpdateCmdBufferLastCmd(cb_node, cmd_type); 976623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski for (uint32_t i = 0; i < rangeCount; ++i) { 977623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski RecordClearImageLayout(dev_data, cb_node, image, pRanges[i], imageLayout); 978623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski } 979623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski } 980623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski} 981623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski 982e40189d4deab674240cd9baf4c063bab4567c212Tobin Ehlisbool PreCallValidateCmdClearDepthStencilImage(layer_data *device_data, VkCommandBuffer commandBuffer, VkImage image, 983e40189d4deab674240cd9baf4c063bab4567c212Tobin Ehlis VkImageLayout imageLayout, uint32_t rangeCount, 984623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski const VkImageSubresourceRange *pRanges) { 985623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski bool skip = false; 9867244435437260842ba43b67bb7d008e161736c31Mark Lobodzinski const debug_report_data *report_data = core_validation::GetReportData(device_data); 9877244435437260842ba43b67bb7d008e161736c31Mark Lobodzinski 988623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski // TODO : Verify memory is in VK_IMAGE_STATE_CLEAR state 9899a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto cb_node = GetCBNode(device_data, commandBuffer); 9909a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto image_state = GetImageState(device_data, image); 991623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski if (cb_node && image_state) { 9927244435437260842ba43b67bb7d008e161736c31Mark Lobodzinski skip |= ValidateMemoryIsBoundToImage(device_data, image_state, "vkCmdClearDepthStencilImage()", VALIDATION_ERROR_02528); 993baa50ccc5a8cf7a6f7474148f301802c5480e715Mike Schuchardt skip |= ValidateCmdQueueFlags(device_data, cb_node, "vkCmdClearDepthStencilImage()", VK_QUEUE_GRAPHICS_BIT, 994baa50ccc5a8cf7a6f7474148f301802c5480e715Mike Schuchardt VALIDATION_ERROR_01110); 9957244435437260842ba43b67bb7d008e161736c31Mark Lobodzinski skip |= ValidateCmd(device_data, cb_node, CMD_CLEARDEPTHSTENCILIMAGE, "vkCmdClearDepthStencilImage()"); 9967244435437260842ba43b67bb7d008e161736c31Mark Lobodzinski skip |= insideRenderPass(device_data, cb_node, "vkCmdClearDepthStencilImage()", VALIDATION_ERROR_01111); 997623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski for (uint32_t i = 0; i < rangeCount; ++i) { 99808c7aae3177092f8567e2b5a946457be61616e9aMark Lobodzinski skip |= 99908c7aae3177092f8567e2b5a946457be61616e9aMark Lobodzinski VerifyClearImageLayout(device_data, cb_node, image_state, pRanges[i], imageLayout, "vkCmdClearDepthStencilImage()"); 10007244435437260842ba43b67bb7d008e161736c31Mark Lobodzinski // Image aspect must be depth or stencil or both 10017244435437260842ba43b67bb7d008e161736c31Mark Lobodzinski if (((pRanges[i].aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT) != VK_IMAGE_ASPECT_DEPTH_BIT) && 10027244435437260842ba43b67bb7d008e161736c31Mark Lobodzinski ((pRanges[i].aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT) != VK_IMAGE_ASPECT_STENCIL_BIT)) { 10037244435437260842ba43b67bb7d008e161736c31Mark Lobodzinski char const str[] = 10047244435437260842ba43b67bb7d008e161736c31Mark Lobodzinski "vkCmdClearDepthStencilImage aspectMasks for all subresource ranges must be " 10057244435437260842ba43b67bb7d008e161736c31Mark Lobodzinski "set to VK_IMAGE_ASPECT_DEPTH_BIT and/or VK_IMAGE_ASPECT_STENCIL_BIT"; 10067244435437260842ba43b67bb7d008e161736c31Mark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 10077244435437260842ba43b67bb7d008e161736c31Mark Lobodzinski (uint64_t)commandBuffer, __LINE__, DRAWSTATE_INVALID_IMAGE_ASPECT, "IMAGE", str); 10087244435437260842ba43b67bb7d008e161736c31Mark Lobodzinski } 10097244435437260842ba43b67bb7d008e161736c31Mark Lobodzinski } 101016769f6b2a7721e391952a97f010cbb530e4f211Dave Houlton if (image_state && !FormatIsDepthOrStencil(image_state->createInfo.format)) { 10117244435437260842ba43b67bb7d008e161736c31Mark Lobodzinski char const str[] = "vkCmdClearDepthStencilImage called without a depth/stencil image."; 10127244435437260842ba43b67bb7d008e161736c31Mark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, 10137244435437260842ba43b67bb7d008e161736c31Mark Lobodzinski reinterpret_cast<uint64_t &>(image), __LINE__, VALIDATION_ERROR_01103, "IMAGE", "%s. %s", str, 10147244435437260842ba43b67bb7d008e161736c31Mark Lobodzinski validation_error_map[VALIDATION_ERROR_01103]); 1015623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski } 1016623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski } 1017623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski return skip; 1018623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski} 1019ff309c48cf48eec4599c9bf83f5b5cd802fa2db0Mark Lobodzinski 1020ff309c48cf48eec4599c9bf83f5b5cd802fa2db0Mark Lobodzinski// Returns true if [x, xoffset] and [y, yoffset] overlap 1021ff309c48cf48eec4599c9bf83f5b5cd802fa2db0Mark Lobodzinskistatic bool RangesIntersect(int32_t start, uint32_t start_offset, int32_t end, uint32_t end_offset) { 1022ff309c48cf48eec4599c9bf83f5b5cd802fa2db0Mark Lobodzinski bool result = false; 1023ff309c48cf48eec4599c9bf83f5b5cd802fa2db0Mark Lobodzinski uint32_t intersection_min = std::max(static_cast<uint32_t>(start), static_cast<uint32_t>(end)); 1024ff309c48cf48eec4599c9bf83f5b5cd802fa2db0Mark Lobodzinski uint32_t intersection_max = std::min(static_cast<uint32_t>(start) + start_offset, static_cast<uint32_t>(end) + end_offset); 1025ff309c48cf48eec4599c9bf83f5b5cd802fa2db0Mark Lobodzinski 1026ff309c48cf48eec4599c9bf83f5b5cd802fa2db0Mark Lobodzinski if (intersection_max > intersection_min) { 1027ff309c48cf48eec4599c9bf83f5b5cd802fa2db0Mark Lobodzinski result = true; 1028ff309c48cf48eec4599c9bf83f5b5cd802fa2db0Mark Lobodzinski } 1029ff309c48cf48eec4599c9bf83f5b5cd802fa2db0Mark Lobodzinski return result; 1030ff309c48cf48eec4599c9bf83f5b5cd802fa2db0Mark Lobodzinski} 1031ff309c48cf48eec4599c9bf83f5b5cd802fa2db0Mark Lobodzinski 1032ff309c48cf48eec4599c9bf83f5b5cd802fa2db0Mark Lobodzinski// Returns true if two VkImageCopy structures overlap 1033ff309c48cf48eec4599c9bf83f5b5cd802fa2db0Mark Lobodzinskistatic bool RegionIntersects(const VkImageCopy *src, const VkImageCopy *dst, VkImageType type) { 1034ff309c48cf48eec4599c9bf83f5b5cd802fa2db0Mark Lobodzinski bool result = false; 1035ff309c48cf48eec4599c9bf83f5b5cd802fa2db0Mark Lobodzinski if ((src->srcSubresource.mipLevel == dst->dstSubresource.mipLevel) && 1036ff309c48cf48eec4599c9bf83f5b5cd802fa2db0Mark Lobodzinski (RangesIntersect(src->srcSubresource.baseArrayLayer, src->srcSubresource.layerCount, dst->dstSubresource.baseArrayLayer, 1037ff309c48cf48eec4599c9bf83f5b5cd802fa2db0Mark Lobodzinski dst->dstSubresource.layerCount))) { 1038ff309c48cf48eec4599c9bf83f5b5cd802fa2db0Mark Lobodzinski result = true; 1039ff309c48cf48eec4599c9bf83f5b5cd802fa2db0Mark Lobodzinski switch (type) { 1040ff309c48cf48eec4599c9bf83f5b5cd802fa2db0Mark Lobodzinski case VK_IMAGE_TYPE_3D: 1041ff309c48cf48eec4599c9bf83f5b5cd802fa2db0Mark Lobodzinski result &= RangesIntersect(src->srcOffset.z, src->extent.depth, dst->dstOffset.z, dst->extent.depth); 1042ff309c48cf48eec4599c9bf83f5b5cd802fa2db0Mark Lobodzinski // Intentionally fall through to 2D case 1043ff309c48cf48eec4599c9bf83f5b5cd802fa2db0Mark Lobodzinski case VK_IMAGE_TYPE_2D: 1044ff309c48cf48eec4599c9bf83f5b5cd802fa2db0Mark Lobodzinski result &= RangesIntersect(src->srcOffset.y, src->extent.height, dst->dstOffset.y, dst->extent.height); 1045ff309c48cf48eec4599c9bf83f5b5cd802fa2db0Mark Lobodzinski // Intentionally fall through to 1D case 1046ff309c48cf48eec4599c9bf83f5b5cd802fa2db0Mark Lobodzinski case VK_IMAGE_TYPE_1D: 1047ff309c48cf48eec4599c9bf83f5b5cd802fa2db0Mark Lobodzinski result &= RangesIntersect(src->srcOffset.x, src->extent.width, dst->dstOffset.x, dst->extent.width); 1048ff309c48cf48eec4599c9bf83f5b5cd802fa2db0Mark Lobodzinski break; 1049ff309c48cf48eec4599c9bf83f5b5cd802fa2db0Mark Lobodzinski default: 1050ff309c48cf48eec4599c9bf83f5b5cd802fa2db0Mark Lobodzinski // Unrecognized or new IMAGE_TYPE enums will be caught in parameter_validation 1051ff309c48cf48eec4599c9bf83f5b5cd802fa2db0Mark Lobodzinski assert(false); 1052ff309c48cf48eec4599c9bf83f5b5cd802fa2db0Mark Lobodzinski } 1053ff309c48cf48eec4599c9bf83f5b5cd802fa2db0Mark Lobodzinski } 1054ff309c48cf48eec4599c9bf83f5b5cd802fa2db0Mark Lobodzinski return result; 1055ff309c48cf48eec4599c9bf83f5b5cd802fa2db0Mark Lobodzinski} 1056ff309c48cf48eec4599c9bf83f5b5cd802fa2db0Mark Lobodzinski 10573fb79e4c87829ef090622d69a117f33ec7d4ded5Dave Houlton// Returns non-zero if offset and extent exceed image extents 10583fb79e4c87829ef090622d69a117f33ec7d4ded5Dave Houltonstatic const uint32_t x_bit = 1; 10593fb79e4c87829ef090622d69a117f33ec7d4ded5Dave Houltonstatic const uint32_t y_bit = 2; 10603fb79e4c87829ef090622d69a117f33ec7d4ded5Dave Houltonstatic const uint32_t z_bit = 4; 1061cf2ce8673669ca1111e333bdea272c4dd57cb5c2Dave Houltonstatic uint32_t ExceedsBounds(const VkOffset3D *offset, const VkExtent3D *extent, const VkExtent3D *image_extent) { 10623fb79e4c87829ef090622d69a117f33ec7d4ded5Dave Houlton uint32_t result = 0; 1063ff309c48cf48eec4599c9bf83f5b5cd802fa2db0Mark Lobodzinski // Extents/depths cannot be negative but checks left in for clarity 10645971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton if ((offset->z + extent->depth > image_extent->depth) || (offset->z < 0) || 10655971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton ((offset->z + static_cast<int32_t>(extent->depth)) < 0)) { 10663fb79e4c87829ef090622d69a117f33ec7d4ded5Dave Houlton result |= z_bit; 10675971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton } 10685971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton if ((offset->y + extent->height > image_extent->height) || (offset->y < 0) || 10695971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton ((offset->y + static_cast<int32_t>(extent->height)) < 0)) { 10703fb79e4c87829ef090622d69a117f33ec7d4ded5Dave Houlton result |= y_bit; 10715971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton } 10725971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton if ((offset->x + extent->width > image_extent->width) || (offset->x < 0) || 10735971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton ((offset->x + static_cast<int32_t>(extent->width)) < 0)) { 10743fb79e4c87829ef090622d69a117f33ec7d4ded5Dave Houlton result |= x_bit; 1075ff309c48cf48eec4599c9bf83f5b5cd802fa2db0Mark Lobodzinski } 1076ff309c48cf48eec4599c9bf83f5b5cd802fa2db0Mark Lobodzinski return result; 1077ff309c48cf48eec4599c9bf83f5b5cd802fa2db0Mark Lobodzinski} 1078ff309c48cf48eec4599c9bf83f5b5cd802fa2db0Mark Lobodzinski 10796a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski// Test if two VkExtent3D structs are equivalent 10806a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinskistatic inline bool IsExtentEqual(const VkExtent3D *extent, const VkExtent3D *other_extent) { 10816a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski bool result = true; 10826a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski if ((extent->width != other_extent->width) || (extent->height != other_extent->height) || 10836a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski (extent->depth != other_extent->depth)) { 10846a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski result = false; 10856a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski } 10866a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski return result; 10876a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski} 10886a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski 10896a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski// Returns the image extent of a specific subresource. 10906a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinskistatic inline VkExtent3D GetImageSubresourceExtent(const IMAGE_STATE *img, const VkImageSubresourceLayers *subresource) { 10916a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski const uint32_t mip = subresource->mipLevel; 10923fb79e4c87829ef090622d69a117f33ec7d4ded5Dave Houlton 10933fb79e4c87829ef090622d69a117f33ec7d4ded5Dave Houlton // Return zero extent if mip level doesn't exist 1094cf2ce8673669ca1111e333bdea272c4dd57cb5c2Dave Houlton if (mip >= img->createInfo.mipLevels) { 1095cf2ce8673669ca1111e333bdea272c4dd57cb5c2Dave Houlton return VkExtent3D{0, 0, 0}; 10963fb79e4c87829ef090622d69a117f33ec7d4ded5Dave Houlton } 1097cf2ce8673669ca1111e333bdea272c4dd57cb5c2Dave Houlton 10985971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton // Don't allow mip adjustment to create 0 dim, but pass along a 0 if that's what subresource specified 10993fb79e4c87829ef090622d69a117f33ec7d4ded5Dave Houlton VkExtent3D extent = img->createInfo.extent; 11005971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton extent.width = (0 == extent.width ? 0 : std::max(1U, extent.width >> mip)); 11015971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton extent.height = (0 == extent.height ? 0 : std::max(1U, extent.height >> mip)); 11025971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton extent.depth = (0 == extent.depth ? 0 : std::max(1U, extent.depth >> mip)); 11033fb79e4c87829ef090622d69a117f33ec7d4ded5Dave Houlton 11043fb79e4c87829ef090622d69a117f33ec7d4ded5Dave Houlton // For 2D images, the number of layers present becomes the effective depth (for 2D <-> 3D copies) 11053fb79e4c87829ef090622d69a117f33ec7d4ded5Dave Houlton // In this case the depth extent is not diminished with mip level 1106cf2ce8673669ca1111e333bdea272c4dd57cb5c2Dave Houlton if (VK_IMAGE_TYPE_2D == img->createInfo.imageType) { 11073fb79e4c87829ef090622d69a117f33ec7d4ded5Dave Houlton extent.depth = img->createInfo.arrayLayers; 11083fb79e4c87829ef090622d69a117f33ec7d4ded5Dave Houlton } 11093fb79e4c87829ef090622d69a117f33ec7d4ded5Dave Houlton 11106a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski return extent; 11116a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski} 11126a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski 11136a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski// Test if the extent argument has all dimensions set to 0. 11145971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houltonstatic inline bool IsExtentAllZeroes(const VkExtent3D *extent) { 11156a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski return ((extent->width == 0) && (extent->height == 0) && (extent->depth == 0)); 11166a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski} 11176a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski 11185971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton// Test if the extent argument has any dimensions set to 0. 11195971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houltonstatic inline bool IsExtentSizeZero(const VkExtent3D *extent) { 11205971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton return ((extent->width == 0) || (extent->height == 0) || (extent->depth == 0)); 11215971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton} 11225971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton 11236a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski// Returns the image transfer granularity for a specific image scaled by compressed block size if necessary. 11246a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinskistatic inline VkExtent3D GetScaledItg(layer_data *device_data, const GLOBAL_CB_NODE *cb_node, const IMAGE_STATE *img) { 11256a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski // Default to (0, 0, 0) granularity in case we can't find the real granularity for the physical device. 11266a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski VkExtent3D granularity = {0, 0, 0}; 11276a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski auto pPool = GetCommandPoolNode(device_data, cb_node->createInfo.commandPool); 11286a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski if (pPool) { 11296a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski granularity = 11306a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski GetPhysDevProperties(device_data)->queue_family_properties[pPool->queueFamilyIndex].minImageTransferGranularity; 113116769f6b2a7721e391952a97f010cbb530e4f211Dave Houlton if (FormatIsCompressed(img->createInfo.format)) { 113216769f6b2a7721e391952a97f010cbb530e4f211Dave Houlton auto block_size = FormatCompressedTexelBlockExtent(img->createInfo.format); 11336a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski granularity.width *= block_size.width; 11346a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski granularity.height *= block_size.height; 11356a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski } 11366a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski } 11376a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski return granularity; 11386a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski} 11396a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski 11406a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski// Test elements of a VkExtent3D structure against alignment constraints contained in another VkExtent3D structure 11416a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinskistatic inline bool IsExtentAligned(const VkExtent3D *extent, const VkExtent3D *granularity) { 11426a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski bool valid = true; 114316769f6b2a7721e391952a97f010cbb530e4f211Dave Houlton if ((SafeModulo(extent->depth, granularity->depth) != 0) || (SafeModulo(extent->width, granularity->width) != 0) || 114416769f6b2a7721e391952a97f010cbb530e4f211Dave Houlton (SafeModulo(extent->height, granularity->height) != 0)) { 11456a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski valid = false; 11466a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski } 11476a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski return valid; 11486a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski} 11496a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski 11506a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski// Check elements of a VkOffset3D structure against a queue family's Image Transfer Granularity values 11516a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinskistatic inline bool CheckItgOffset(layer_data *device_data, const GLOBAL_CB_NODE *cb_node, const VkOffset3D *offset, 11526a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski const VkExtent3D *granularity, const uint32_t i, const char *function, const char *member) { 11536a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski const debug_report_data *report_data = core_validation::GetReportData(device_data); 11546a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski bool skip = false; 11556a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski VkExtent3D offset_extent = {}; 11566a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski offset_extent.width = static_cast<uint32_t>(abs(offset->x)); 11576a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski offset_extent.height = static_cast<uint32_t>(abs(offset->y)); 11586a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski offset_extent.depth = static_cast<uint32_t>(abs(offset->z)); 11595971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton if (IsExtentAllZeroes(granularity)) { 11606a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski // If the queue family image transfer granularity is (0, 0, 0), then the offset must always be (0, 0, 0) 11615971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton if (IsExtentAllZeroes(&offset_extent) == false) { 1162fdc75c21ced997fbbc180734bef87bf6d5811d4bMark Lobodzinski skip |= 1163fdc75c21ced997fbbc180734bef87bf6d5811d4bMark Lobodzinski log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 1164fdc75c21ced997fbbc180734bef87bf6d5811d4bMark Lobodzinski reinterpret_cast<uint64_t>(cb_node->commandBuffer), __LINE__, DRAWSTATE_IMAGE_TRANSFER_GRANULARITY, "DS", 1165fdc75c21ced997fbbc180734bef87bf6d5811d4bMark Lobodzinski "%s: pRegion[%d].%s (x=%d, y=%d, z=%d) must be (x=0, y=0, z=0) " 1166fdc75c21ced997fbbc180734bef87bf6d5811d4bMark Lobodzinski "when the command buffer's queue family image transfer granularity is (w=0, h=0, d=0).", 1167fdc75c21ced997fbbc180734bef87bf6d5811d4bMark Lobodzinski function, i, member, offset->x, offset->y, offset->z); 11686a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski } 11696a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski } else { 11706a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski // If the queue family image transfer granularity is not (0, 0, 0), then the offset dimensions must always be even 11716a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski // integer multiples of the image transfer granularity. 11726a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski if (IsExtentAligned(&offset_extent, granularity) == false) { 1173fdc75c21ced997fbbc180734bef87bf6d5811d4bMark Lobodzinski skip |= log_msg( 1174fdc75c21ced997fbbc180734bef87bf6d5811d4bMark Lobodzinski report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 1175fdc75c21ced997fbbc180734bef87bf6d5811d4bMark Lobodzinski reinterpret_cast<uint64_t>(cb_node->commandBuffer), __LINE__, DRAWSTATE_IMAGE_TRANSFER_GRANULARITY, "DS", 1176fdc75c21ced997fbbc180734bef87bf6d5811d4bMark Lobodzinski "%s: pRegion[%d].%s (x=%d, y=%d, z=%d) dimensions must be even integer " 1177fdc75c21ced997fbbc180734bef87bf6d5811d4bMark Lobodzinski "multiples of this command buffer's queue family image transfer granularity (w=%d, h=%d, d=%d).", 1178fdc75c21ced997fbbc180734bef87bf6d5811d4bMark Lobodzinski function, i, member, offset->x, offset->y, offset->z, granularity->width, granularity->height, granularity->depth); 11796a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski } 11806a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski } 11816a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski return skip; 11826a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski} 11836a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski 11846a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski// Check elements of a VkExtent3D structure against a queue family's Image Transfer Granularity values 11856a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinskistatic inline bool CheckItgExtent(layer_data *device_data, const GLOBAL_CB_NODE *cb_node, const VkExtent3D *extent, 11866a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski const VkOffset3D *offset, const VkExtent3D *granularity, const VkExtent3D *subresource_extent, 11876a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski const uint32_t i, const char *function, const char *member) { 11886a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski const debug_report_data *report_data = core_validation::GetReportData(device_data); 11896a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski bool skip = false; 11905971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton if (IsExtentAllZeroes(granularity)) { 11916a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski // If the queue family image transfer granularity is (0, 0, 0), then the extent must always match the image 11926a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski // subresource extent. 11936a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski if (IsExtentEqual(extent, subresource_extent) == false) { 1194fdc75c21ced997fbbc180734bef87bf6d5811d4bMark Lobodzinski skip |= 1195fdc75c21ced997fbbc180734bef87bf6d5811d4bMark Lobodzinski log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 1196fdc75c21ced997fbbc180734bef87bf6d5811d4bMark Lobodzinski reinterpret_cast<uint64_t>(cb_node->commandBuffer), __LINE__, DRAWSTATE_IMAGE_TRANSFER_GRANULARITY, "DS", 1197fdc75c21ced997fbbc180734bef87bf6d5811d4bMark Lobodzinski "%s: pRegion[%d].%s (w=%d, h=%d, d=%d) must match the image subresource extents (w=%d, h=%d, d=%d) " 1198fdc75c21ced997fbbc180734bef87bf6d5811d4bMark Lobodzinski "when the command buffer's queue family image transfer granularity is (w=0, h=0, d=0).", 1199fdc75c21ced997fbbc180734bef87bf6d5811d4bMark Lobodzinski function, i, member, extent->width, extent->height, extent->depth, subresource_extent->width, 1200fdc75c21ced997fbbc180734bef87bf6d5811d4bMark Lobodzinski subresource_extent->height, subresource_extent->depth); 12016a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski } 12026a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski } else { 12036a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski // If the queue family image transfer granularity is not (0, 0, 0), then the extent dimensions must always be even 12046a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski // integer multiples of the image transfer granularity or the offset + extent dimensions must always match the image 12056a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski // subresource extent dimensions. 12066a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski VkExtent3D offset_extent_sum = {}; 12076a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski offset_extent_sum.width = static_cast<uint32_t>(abs(offset->x)) + extent->width; 12086a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski offset_extent_sum.height = static_cast<uint32_t>(abs(offset->y)) + extent->height; 12096a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski offset_extent_sum.depth = static_cast<uint32_t>(abs(offset->z)) + extent->depth; 12106a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski if ((IsExtentAligned(extent, granularity) == false) && (IsExtentEqual(&offset_extent_sum, subresource_extent) == false)) { 12116a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski skip |= 1212fdc75c21ced997fbbc180734bef87bf6d5811d4bMark Lobodzinski log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 1213fdc75c21ced997fbbc180734bef87bf6d5811d4bMark Lobodzinski reinterpret_cast<uint64_t>(cb_node->commandBuffer), __LINE__, DRAWSTATE_IMAGE_TRANSFER_GRANULARITY, "DS", 12146a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski "%s: pRegion[%d].%s (w=%d, h=%d, d=%d) dimensions must be even integer multiples of this command buffer's " 12156a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski "queue family image transfer granularity (w=%d, h=%d, d=%d) or offset (x=%d, y=%d, z=%d) + " 12166a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski "extent (w=%d, h=%d, d=%d) must match the image subresource extents (w=%d, h=%d, d=%d).", 12176a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski function, i, member, extent->width, extent->height, extent->depth, granularity->width, granularity->height, 12186a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski granularity->depth, offset->x, offset->y, offset->z, extent->width, extent->height, extent->depth, 12196a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski subresource_extent->width, subresource_extent->height, subresource_extent->depth); 12206a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski } 12216a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski } 12226a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski return skip; 12236a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski} 12246a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski 12256a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski// Check a uint32_t width or stride value against a queue family's Image Transfer Granularity width value 12266a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinskistatic inline bool CheckItgInt(layer_data *device_data, const GLOBAL_CB_NODE *cb_node, const uint32_t value, 12276a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski const uint32_t granularity, const uint32_t i, const char *function, const char *member) { 12286a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski const debug_report_data *report_data = core_validation::GetReportData(device_data); 12296a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski 12306a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski bool skip = false; 123116769f6b2a7721e391952a97f010cbb530e4f211Dave Houlton if (SafeModulo(value, granularity) != 0) { 1232fdc75c21ced997fbbc180734bef87bf6d5811d4bMark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 1233fdc75c21ced997fbbc180734bef87bf6d5811d4bMark Lobodzinski reinterpret_cast<uint64_t>(cb_node->commandBuffer), __LINE__, DRAWSTATE_IMAGE_TRANSFER_GRANULARITY, "DS", 12346a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski "%s: pRegion[%d].%s (%d) must be an even integer multiple of this command buffer's queue family image " 12356a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski "transfer granularity width (%d).", 12366a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski function, i, member, value, granularity); 12376a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski } 12386a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski return skip; 12396a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski} 12406a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski 12416a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski// Check a VkDeviceSize value against a queue family's Image Transfer Granularity width value 12426a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinskistatic inline bool CheckItgSize(layer_data *device_data, const GLOBAL_CB_NODE *cb_node, const VkDeviceSize value, 12436a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski const uint32_t granularity, const uint32_t i, const char *function, const char *member) { 12446a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski const debug_report_data *report_data = core_validation::GetReportData(device_data); 12456a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski bool skip = false; 124616769f6b2a7721e391952a97f010cbb530e4f211Dave Houlton if (SafeModulo(value, granularity) != 0) { 1247fdc75c21ced997fbbc180734bef87bf6d5811d4bMark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 1248fdc75c21ced997fbbc180734bef87bf6d5811d4bMark Lobodzinski reinterpret_cast<uint64_t>(cb_node->commandBuffer), __LINE__, DRAWSTATE_IMAGE_TRANSFER_GRANULARITY, "DS", 12496a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski "%s: pRegion[%d].%s (%" PRIdLEAST64 12506a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski ") must be an even integer multiple of this command buffer's queue family image transfer " 12516a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski "granularity width (%d).", 12526a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski function, i, member, value, granularity); 12536a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski } 12546a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski return skip; 12556a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski} 12566a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski 12576a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski// Check valid usage Image Tranfer Granularity requirements for elements of a VkBufferImageCopy structure 12586a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinskibool ValidateCopyBufferImageTransferGranularityRequirements(layer_data *device_data, const GLOBAL_CB_NODE *cb_node, 12596a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski const IMAGE_STATE *img, const VkBufferImageCopy *region, 12606a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski const uint32_t i, const char *function) { 12616a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski bool skip = false; 126216769f6b2a7721e391952a97f010cbb530e4f211Dave Houlton if (FormatIsCompressed(img->createInfo.format) == true) { 12636a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski // TODO: Add granularity checking for compressed formats 12646a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski 12656a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski // bufferRowLength must be a multiple of the compressed texel block width 12666a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski // bufferImageHeight must be a multiple of the compressed texel block height 12676a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski // all members of imageOffset must be a multiple of the corresponding dimensions of the compressed texel block 12686a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski // bufferOffset must be a multiple of the compressed texel block size in bytes 12696a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski // imageExtent.width must be a multiple of the compressed texel block width or (imageExtent.width + imageOffset.x) 12706a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski // must equal the image subresource width 12716a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski // imageExtent.height must be a multiple of the compressed texel block height or (imageExtent.height + imageOffset.y) 12726a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski // must equal the image subresource height 12736a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski // imageExtent.depth must be a multiple of the compressed texel block depth or (imageExtent.depth + imageOffset.z) 12746a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski // must equal the image subresource depth 12756a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski } else { 12766a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski VkExtent3D granularity = GetScaledItg(device_data, cb_node, img); 12776a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski skip |= CheckItgSize(device_data, cb_node, region->bufferOffset, granularity.width, i, function, "bufferOffset"); 12786a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski skip |= CheckItgInt(device_data, cb_node, region->bufferRowLength, granularity.width, i, function, "bufferRowLength"); 12796a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski skip |= CheckItgInt(device_data, cb_node, region->bufferImageHeight, granularity.width, i, function, "bufferImageHeight"); 12806a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski skip |= CheckItgOffset(device_data, cb_node, ®ion->imageOffset, &granularity, i, function, "imageOffset"); 12816a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski VkExtent3D subresource_extent = GetImageSubresourceExtent(img, ®ion->imageSubresource); 12826a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski skip |= CheckItgExtent(device_data, cb_node, ®ion->imageExtent, ®ion->imageOffset, &granularity, &subresource_extent, 12836a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski i, function, "imageExtent"); 12846a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski } 12856a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski return skip; 12866a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski} 12876a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski 12886a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski// Check valid usage Image Tranfer Granularity requirements for elements of a VkImageCopy structure 12896a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinskibool ValidateCopyImageTransferGranularityRequirements(layer_data *device_data, const GLOBAL_CB_NODE *cb_node, 12906a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski const IMAGE_STATE *img, const VkImageCopy *region, const uint32_t i, 12916a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski const char *function) { 12926a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski bool skip = false; 12936a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski VkExtent3D granularity = GetScaledItg(device_data, cb_node, img); 12946a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski skip |= CheckItgOffset(device_data, cb_node, ®ion->srcOffset, &granularity, i, function, "srcOffset"); 12956a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski skip |= CheckItgOffset(device_data, cb_node, ®ion->dstOffset, &granularity, i, function, "dstOffset"); 12966a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski VkExtent3D subresource_extent = GetImageSubresourceExtent(img, ®ion->dstSubresource); 12976a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski skip |= CheckItgExtent(device_data, cb_node, ®ion->extent, ®ion->dstOffset, &granularity, &subresource_extent, i, 12986a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski function, "extent"); 12996a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski return skip; 13006a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski} 13016a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski 1302e40189d4deab674240cd9baf4c063bab4567c212Tobin Ehlisbool PreCallValidateCmdCopyImage(layer_data *device_data, GLOBAL_CB_NODE *cb_node, IMAGE_STATE *src_image_state, 13036a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski IMAGE_STATE *dst_image_state, uint32_t region_count, const VkImageCopy *regions, 13046a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski VkImageLayout src_image_layout, VkImageLayout dst_image_layout) { 1305ff309c48cf48eec4599c9bf83f5b5cd802fa2db0Mark Lobodzinski bool skip = false; 1306ff309c48cf48eec4599c9bf83f5b5cd802fa2db0Mark Lobodzinski const debug_report_data *report_data = core_validation::GetReportData(device_data); 1307ff309c48cf48eec4599c9bf83f5b5cd802fa2db0Mark Lobodzinski VkCommandBuffer command_buffer = cb_node->commandBuffer; 1308ff309c48cf48eec4599c9bf83f5b5cd802fa2db0Mark Lobodzinski 13096a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski for (uint32_t i = 0; i < region_count; i++) { 13106a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski if (regions[i].srcSubresource.layerCount == 0) { 13116a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski std::stringstream ss; 13126a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski ss << "vkCmdCopyImage: number of layers in pRegions[" << i << "] srcSubresource is zero"; 13136a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 13146a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski reinterpret_cast<uint64_t &>(command_buffer), __LINE__, DRAWSTATE_INVALID_IMAGE_ASPECT, "IMAGE", "%s", 13156a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski ss.str().c_str()); 13166a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski } 1317ff309c48cf48eec4599c9bf83f5b5cd802fa2db0Mark Lobodzinski 13186a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski if (regions[i].dstSubresource.layerCount == 0) { 13196a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski std::stringstream ss; 13206a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski ss << "vkCmdCopyImage: number of layers in pRegions[" << i << "] dstSubresource is zero"; 13216a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 13226a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski reinterpret_cast<uint64_t &>(command_buffer), __LINE__, DRAWSTATE_INVALID_IMAGE_ASPECT, "IMAGE", "%s", 13236a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski ss.str().c_str()); 13246a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski } 1325ff309c48cf48eec4599c9bf83f5b5cd802fa2db0Mark Lobodzinski 132657eda737eea95dd728f6dce5c78d6b00fb126076Mike Schuchardt if (!GetDeviceExtensions(device_data)->khr_maintenance1_enabled) { 132757eda737eea95dd728f6dce5c78d6b00fb126076Mike Schuchardt // For each region the layerCount member of srcSubresource and dstSubresource must match 132857eda737eea95dd728f6dce5c78d6b00fb126076Mike Schuchardt if (regions[i].srcSubresource.layerCount != regions[i].dstSubresource.layerCount) { 132957eda737eea95dd728f6dce5c78d6b00fb126076Mike Schuchardt std::stringstream ss; 133057eda737eea95dd728f6dce5c78d6b00fb126076Mike Schuchardt ss << "vkCmdCopyImage: number of layers in source and destination subresources for pRegions[" << i 133157eda737eea95dd728f6dce5c78d6b00fb126076Mike Schuchardt << "] do not match"; 133257eda737eea95dd728f6dce5c78d6b00fb126076Mike Schuchardt skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 133357eda737eea95dd728f6dce5c78d6b00fb126076Mike Schuchardt reinterpret_cast<uint64_t &>(command_buffer), __LINE__, VALIDATION_ERROR_01198, "IMAGE", "%s. %s", 133457eda737eea95dd728f6dce5c78d6b00fb126076Mike Schuchardt ss.str().c_str(), validation_error_map[VALIDATION_ERROR_01198]); 133557eda737eea95dd728f6dce5c78d6b00fb126076Mike Schuchardt } 13366a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski } 1337ff309c48cf48eec4599c9bf83f5b5cd802fa2db0Mark Lobodzinski 13386a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski // For each region, the aspectMask member of srcSubresource and dstSubresource must match 13396a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski if (regions[i].srcSubresource.aspectMask != regions[i].dstSubresource.aspectMask) { 13406a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski char const str[] = "vkCmdCopyImage: Src and dest aspectMasks for each region must match"; 13416a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 13426a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski reinterpret_cast<uint64_t &>(command_buffer), __LINE__, VALIDATION_ERROR_01197, "IMAGE", "%s. %s", str, 13436a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski validation_error_map[VALIDATION_ERROR_01197]); 13446a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski } 1345ff309c48cf48eec4599c9bf83f5b5cd802fa2db0Mark Lobodzinski 1346e9d74ac8e13687c1be3ee147efce42e8215a049eDave Houlton // For each region, the aspectMask member of srcSubresource must be present in the source image 1347e9d74ac8e13687c1be3ee147efce42e8215a049eDave Houlton if (!VerifyAspectsPresent(regions[i].srcSubresource.aspectMask, src_image_state->createInfo.format)) { 1348e9d74ac8e13687c1be3ee147efce42e8215a049eDave Houlton std::stringstream ss; 1349e9d74ac8e13687c1be3ee147efce42e8215a049eDave Houlton ss << "vkCmdCopyImage: pRegion[" << i 1350e9d74ac8e13687c1be3ee147efce42e8215a049eDave Houlton << "] srcSubresource.aspectMask cannot specify aspects not present in source image"; 1351e9d74ac8e13687c1be3ee147efce42e8215a049eDave Houlton skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 1352e9d74ac8e13687c1be3ee147efce42e8215a049eDave Houlton reinterpret_cast<uint64_t &>(command_buffer), __LINE__, VALIDATION_ERROR_01200, "IMAGE", "%s. %s", 1353e9d74ac8e13687c1be3ee147efce42e8215a049eDave Houlton ss.str().c_str(), validation_error_map[VALIDATION_ERROR_01200]); 1354e9d74ac8e13687c1be3ee147efce42e8215a049eDave Houlton } 1355e9d74ac8e13687c1be3ee147efce42e8215a049eDave Houlton 1356e9d74ac8e13687c1be3ee147efce42e8215a049eDave Houlton // For each region, the aspectMask member of dstSubresource must be present in the destination image 1357e9d74ac8e13687c1be3ee147efce42e8215a049eDave Houlton if (!VerifyAspectsPresent(regions[i].dstSubresource.aspectMask, dst_image_state->createInfo.format)) { 1358e9d74ac8e13687c1be3ee147efce42e8215a049eDave Houlton std::stringstream ss; 1359e9d74ac8e13687c1be3ee147efce42e8215a049eDave Houlton ss << "vkCmdCopyImage: pRegion[" << i << "] dstSubresource.aspectMask cannot specify aspects not present in dest image"; 1360e9d74ac8e13687c1be3ee147efce42e8215a049eDave Houlton skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 1361e9d74ac8e13687c1be3ee147efce42e8215a049eDave Houlton reinterpret_cast<uint64_t &>(command_buffer), __LINE__, VALIDATION_ERROR_01201, "IMAGE", "%s. %s", 1362e9d74ac8e13687c1be3ee147efce42e8215a049eDave Houlton ss.str().c_str(), validation_error_map[VALIDATION_ERROR_01201]); 1363e9d74ac8e13687c1be3ee147efce42e8215a049eDave Houlton } 1364e9d74ac8e13687c1be3ee147efce42e8215a049eDave Houlton 13656a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski // AspectMask must not contain VK_IMAGE_ASPECT_METADATA_BIT 13666a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski if ((regions[i].srcSubresource.aspectMask & VK_IMAGE_ASPECT_METADATA_BIT) || 13676a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski (regions[i].dstSubresource.aspectMask & VK_IMAGE_ASPECT_METADATA_BIT)) { 13686a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski std::stringstream ss; 13696a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski ss << "vkCmdCopyImage: pRegions[" << i << "] may not specify aspectMask containing VK_IMAGE_ASPECT_METADATA_BIT"; 13706a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 13716a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski reinterpret_cast<uint64_t &>(command_buffer), __LINE__, VALIDATION_ERROR_01222, "IMAGE", "%s. %s", 13726a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski ss.str().c_str(), validation_error_map[VALIDATION_ERROR_01222]); 13736a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski } 1374ff309c48cf48eec4599c9bf83f5b5cd802fa2db0Mark Lobodzinski 13756a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski // For each region, if aspectMask contains VK_IMAGE_ASPECT_COLOR_BIT, it must not contain either of 13766a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski // VK_IMAGE_ASPECT_DEPTH_BIT or VK_IMAGE_ASPECT_STENCIL_BIT 13776a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski if ((regions[i].srcSubresource.aspectMask & VK_IMAGE_ASPECT_COLOR_BIT) && 13786a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski (regions[i].srcSubresource.aspectMask & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT))) { 13796a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski char const str[] = "vkCmdCopyImage aspectMask cannot specify both COLOR and DEPTH/STENCIL aspects"; 13806a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 13816a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski reinterpret_cast<uint64_t &>(command_buffer), __LINE__, VALIDATION_ERROR_01221, "IMAGE", "%s. %s", str, 13826a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski validation_error_map[VALIDATION_ERROR_01221]); 13836a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski } 1384ff309c48cf48eec4599c9bf83f5b5cd802fa2db0Mark Lobodzinski 138557eda737eea95dd728f6dce5c78d6b00fb126076Mike Schuchardt if (!GetDeviceExtensions(device_data)->khr_maintenance1_enabled) { 138657eda737eea95dd728f6dce5c78d6b00fb126076Mike Schuchardt // If either of the calling command's src_image or dst_image parameters are of VkImageType VK_IMAGE_TYPE_3D, 138757eda737eea95dd728f6dce5c78d6b00fb126076Mike Schuchardt // the baseArrayLayer and layerCount members of both srcSubresource and dstSubresource must be 0 and 1, respectively 138857eda737eea95dd728f6dce5c78d6b00fb126076Mike Schuchardt if (((src_image_state->createInfo.imageType == VK_IMAGE_TYPE_3D) || 138957eda737eea95dd728f6dce5c78d6b00fb126076Mike Schuchardt (dst_image_state->createInfo.imageType == VK_IMAGE_TYPE_3D)) && 139057eda737eea95dd728f6dce5c78d6b00fb126076Mike Schuchardt ((regions[i].srcSubresource.baseArrayLayer != 0) || (regions[i].srcSubresource.layerCount != 1) || 139157eda737eea95dd728f6dce5c78d6b00fb126076Mike Schuchardt (regions[i].dstSubresource.baseArrayLayer != 0) || (regions[i].dstSubresource.layerCount != 1))) { 139257eda737eea95dd728f6dce5c78d6b00fb126076Mike Schuchardt std::stringstream ss; 139357eda737eea95dd728f6dce5c78d6b00fb126076Mike Schuchardt ss << "vkCmdCopyImage: src or dstImage type was IMAGE_TYPE_3D, but in subRegion[" << i 139457eda737eea95dd728f6dce5c78d6b00fb126076Mike Schuchardt << "] baseArrayLayer was not zero or layerCount was not 1."; 139557eda737eea95dd728f6dce5c78d6b00fb126076Mike Schuchardt skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 139657eda737eea95dd728f6dce5c78d6b00fb126076Mike Schuchardt reinterpret_cast<uint64_t &>(command_buffer), __LINE__, VALIDATION_ERROR_01199, "IMAGE", "%s. %s", 139757eda737eea95dd728f6dce5c78d6b00fb126076Mike Schuchardt ss.str().c_str(), validation_error_map[VALIDATION_ERROR_01199]); 139857eda737eea95dd728f6dce5c78d6b00fb126076Mike Schuchardt } 13996a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski } 1400ff309c48cf48eec4599c9bf83f5b5cd802fa2db0Mark Lobodzinski 14016a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski // MipLevel must be less than the mipLevels specified in VkImageCreateInfo when the image was created 14026a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski if (regions[i].srcSubresource.mipLevel >= src_image_state->createInfo.mipLevels) { 14036a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski std::stringstream ss; 14046a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski ss << "vkCmdCopyImage: pRegions[" << i 14056a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski << "] specifies a src mipLevel greater than the number specified when the srcImage was created."; 14066a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 14076a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski reinterpret_cast<uint64_t &>(command_buffer), __LINE__, VALIDATION_ERROR_01223, "IMAGE", "%s. %s", 14086a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski ss.str().c_str(), validation_error_map[VALIDATION_ERROR_01223]); 14096a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski } 14106a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski if (regions[i].dstSubresource.mipLevel >= dst_image_state->createInfo.mipLevels) { 14116a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski std::stringstream ss; 14126a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski ss << "vkCmdCopyImage: pRegions[" << i 14136a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski << "] specifies a dst mipLevel greater than the number specified when the dstImage was created."; 14146a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 14156a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski reinterpret_cast<uint64_t &>(command_buffer), __LINE__, VALIDATION_ERROR_01223, "IMAGE", "%s. %s", 14166a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski ss.str().c_str(), validation_error_map[VALIDATION_ERROR_01223]); 14176a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski } 1418ff309c48cf48eec4599c9bf83f5b5cd802fa2db0Mark Lobodzinski 14196a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski // (baseArrayLayer + layerCount) must be less than or equal to the arrayLayers specified in VkImageCreateInfo when the 14206a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski // image was created 14216a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski if ((regions[i].srcSubresource.baseArrayLayer + regions[i].srcSubresource.layerCount) > 14226a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski src_image_state->createInfo.arrayLayers) { 14236a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski std::stringstream ss; 14246a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski ss << "vkCmdCopyImage: srcImage arrayLayers was " << src_image_state->createInfo.arrayLayers << " but subRegion[" << i 14256a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski << "] baseArrayLayer + layerCount is " 14266a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski << (regions[i].srcSubresource.baseArrayLayer + regions[i].srcSubresource.layerCount); 14276a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 14286a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski reinterpret_cast<uint64_t &>(command_buffer), __LINE__, VALIDATION_ERROR_01224, "IMAGE", "%s. %s", 14296a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski ss.str().c_str(), validation_error_map[VALIDATION_ERROR_01224]); 14306a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski } 14316a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski if ((regions[i].dstSubresource.baseArrayLayer + regions[i].dstSubresource.layerCount) > 14326a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski dst_image_state->createInfo.arrayLayers) { 14336a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski std::stringstream ss; 14346a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski ss << "vkCmdCopyImage: dstImage arrayLayers was " << dst_image_state->createInfo.arrayLayers << " but subRegion[" << i 14356a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski << "] baseArrayLayer + layerCount is " 14366a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski << (regions[i].dstSubresource.baseArrayLayer + regions[i].dstSubresource.layerCount); 14376a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 14386a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski reinterpret_cast<uint64_t &>(command_buffer), __LINE__, VALIDATION_ERROR_01224, "IMAGE", "%s. %s", 14396a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski ss.str().c_str(), validation_error_map[VALIDATION_ERROR_01224]); 14406a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski } 1441ff309c48cf48eec4599c9bf83f5b5cd802fa2db0Mark Lobodzinski 144257eda737eea95dd728f6dce5c78d6b00fb126076Mike Schuchardt // Check region extents for 1D-1D, 2D-2D, and 3D-3D copies 144357eda737eea95dd728f6dce5c78d6b00fb126076Mike Schuchardt if (src_image_state->createInfo.imageType == dst_image_state->createInfo.imageType) { 144457eda737eea95dd728f6dce5c78d6b00fb126076Mike Schuchardt // The source region specified by a given element of regions must be a region that is contained within srcImage 14453fb79e4c87829ef090622d69a117f33ec7d4ded5Dave Houlton VkExtent3D img_extent = GetImageSubresourceExtent(src_image_state, &(regions[i].srcSubresource)); 14463fb79e4c87829ef090622d69a117f33ec7d4ded5Dave Houlton if (0 != ExceedsBounds(®ions[i].srcOffset, ®ions[i].extent, &img_extent)) { 144757eda737eea95dd728f6dce5c78d6b00fb126076Mike Schuchardt std::stringstream ss; 14483fb79e4c87829ef090622d69a117f33ec7d4ded5Dave Houlton ss << "vkCmdCopyImage: Source pRegion[" << i << "] with mipLevel [ " << regions[i].srcSubresource.mipLevel 14493fb79e4c87829ef090622d69a117f33ec7d4ded5Dave Houlton << " ], offset [ " << regions[i].srcOffset.x << ", " << regions[i].srcOffset.y << ", " << regions[i].srcOffset.z 14503fb79e4c87829ef090622d69a117f33ec7d4ded5Dave Houlton << " ], extent [ " << regions[i].extent.width << ", " << regions[i].extent.height << ", " 14513fb79e4c87829ef090622d69a117f33ec7d4ded5Dave Houlton << regions[i].extent.depth << " ] exceeds the source image dimensions"; 145257eda737eea95dd728f6dce5c78d6b00fb126076Mike Schuchardt skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 145357eda737eea95dd728f6dce5c78d6b00fb126076Mike Schuchardt reinterpret_cast<uint64_t &>(command_buffer), __LINE__, VALIDATION_ERROR_01175, "IMAGE", "%s. %s", 145457eda737eea95dd728f6dce5c78d6b00fb126076Mike Schuchardt ss.str().c_str(), validation_error_map[VALIDATION_ERROR_01175]); 145557eda737eea95dd728f6dce5c78d6b00fb126076Mike Schuchardt } 1456ff309c48cf48eec4599c9bf83f5b5cd802fa2db0Mark Lobodzinski 145757eda737eea95dd728f6dce5c78d6b00fb126076Mike Schuchardt // The destination region specified by a given element of regions must be a region that is contained within dst_image 14583fb79e4c87829ef090622d69a117f33ec7d4ded5Dave Houlton img_extent = GetImageSubresourceExtent(dst_image_state, &(regions[i].dstSubresource)); 14593fb79e4c87829ef090622d69a117f33ec7d4ded5Dave Houlton if (0 != ExceedsBounds(®ions[i].dstOffset, ®ions[i].extent, &img_extent)) { 146057eda737eea95dd728f6dce5c78d6b00fb126076Mike Schuchardt std::stringstream ss; 14613fb79e4c87829ef090622d69a117f33ec7d4ded5Dave Houlton ss << "vkCmdCopyImage: Dest pRegion[" << i << "] with mipLevel [ " << regions[i].dstSubresource.mipLevel 14623fb79e4c87829ef090622d69a117f33ec7d4ded5Dave Houlton << " ], offset [ " << regions[i].dstOffset.x << ", " << regions[i].dstOffset.y << ", " << regions[i].dstOffset.z 14633fb79e4c87829ef090622d69a117f33ec7d4ded5Dave Houlton << " ], extent [ " << regions[i].extent.width << ", " << regions[i].extent.height << ", " 14643fb79e4c87829ef090622d69a117f33ec7d4ded5Dave Houlton << regions[i].extent.depth << " ] exceeds the destination image dimensions"; 146557eda737eea95dd728f6dce5c78d6b00fb126076Mike Schuchardt skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 146657eda737eea95dd728f6dce5c78d6b00fb126076Mike Schuchardt reinterpret_cast<uint64_t &>(command_buffer), __LINE__, VALIDATION_ERROR_01176, "IMAGE", "%s. %s", 146757eda737eea95dd728f6dce5c78d6b00fb126076Mike Schuchardt ss.str().c_str(), validation_error_map[VALIDATION_ERROR_01176]); 146857eda737eea95dd728f6dce5c78d6b00fb126076Mike Schuchardt } 14696a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski } 1470ff309c48cf48eec4599c9bf83f5b5cd802fa2db0Mark Lobodzinski 14713fb79e4c87829ef090622d69a117f33ec7d4ded5Dave Houlton // Each dimension offset + extent limits must fall with image subresource extent 14723fb79e4c87829ef090622d69a117f33ec7d4ded5Dave Houlton VkExtent3D subresource_extent = GetImageSubresourceExtent(src_image_state, &(regions[i].srcSubresource)); 14733fb79e4c87829ef090622d69a117f33ec7d4ded5Dave Houlton uint32_t extent_check = ExceedsBounds(&(regions[i].srcOffset), ®ions[i].extent, &subresource_extent); 14743fb79e4c87829ef090622d69a117f33ec7d4ded5Dave Houlton if (extent_check & x_bit) { 14753fb79e4c87829ef090622d69a117f33ec7d4ded5Dave Houlton skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 14763fb79e4c87829ef090622d69a117f33ec7d4ded5Dave Houlton reinterpret_cast<uint64_t &>(command_buffer), __LINE__, VALIDATION_ERROR_01202, "IMAGE", 14773fb79e4c87829ef090622d69a117f33ec7d4ded5Dave Houlton "vkCmdCopyImage: Source image pRegion %1d x-dimension offset [%1d] + extent [%1d] exceeds subResource " 14783fb79e4c87829ef090622d69a117f33ec7d4ded5Dave Houlton "width [%1d]. %s", 14793fb79e4c87829ef090622d69a117f33ec7d4ded5Dave Houlton i, regions[i].srcOffset.x, regions[i].extent.width, subresource_extent.width, 14803fb79e4c87829ef090622d69a117f33ec7d4ded5Dave Houlton validation_error_map[VALIDATION_ERROR_01202]); 14813fb79e4c87829ef090622d69a117f33ec7d4ded5Dave Houlton } 14823fb79e4c87829ef090622d69a117f33ec7d4ded5Dave Houlton 14833fb79e4c87829ef090622d69a117f33ec7d4ded5Dave Houlton if (extent_check & y_bit) { 14843fb79e4c87829ef090622d69a117f33ec7d4ded5Dave Houlton skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 14853fb79e4c87829ef090622d69a117f33ec7d4ded5Dave Houlton reinterpret_cast<uint64_t &>(command_buffer), __LINE__, VALIDATION_ERROR_01203, "IMAGE", 14863fb79e4c87829ef090622d69a117f33ec7d4ded5Dave Houlton "vkCmdCopyImage: Source image pRegion %1d y-dimension offset [%1d] + extent [%1d] exceeds subResource " 14873fb79e4c87829ef090622d69a117f33ec7d4ded5Dave Houlton "height [%1d]. %s", 14883fb79e4c87829ef090622d69a117f33ec7d4ded5Dave Houlton i, regions[i].srcOffset.y, regions[i].extent.height, subresource_extent.height, 14893fb79e4c87829ef090622d69a117f33ec7d4ded5Dave Houlton validation_error_map[VALIDATION_ERROR_01203]); 14903fb79e4c87829ef090622d69a117f33ec7d4ded5Dave Houlton } 14913fb79e4c87829ef090622d69a117f33ec7d4ded5Dave Houlton if (extent_check & z_bit) { 14923fb79e4c87829ef090622d69a117f33ec7d4ded5Dave Houlton skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 14933fb79e4c87829ef090622d69a117f33ec7d4ded5Dave Houlton reinterpret_cast<uint64_t &>(command_buffer), __LINE__, VALIDATION_ERROR_01204, "IMAGE", 14943fb79e4c87829ef090622d69a117f33ec7d4ded5Dave Houlton "vkCmdCopyImage: Source image pRegion %1d z-dimension offset [%1d] + extent [%1d] exceeds subResource " 14953fb79e4c87829ef090622d69a117f33ec7d4ded5Dave Houlton "depth [%1d]. %s", 14963fb79e4c87829ef090622d69a117f33ec7d4ded5Dave Houlton i, regions[i].srcOffset.z, regions[i].extent.depth, subresource_extent.depth, 14973fb79e4c87829ef090622d69a117f33ec7d4ded5Dave Houlton validation_error_map[VALIDATION_ERROR_01204]); 14983fb79e4c87829ef090622d69a117f33ec7d4ded5Dave Houlton } 14993fb79e4c87829ef090622d69a117f33ec7d4ded5Dave Houlton 15003fb79e4c87829ef090622d69a117f33ec7d4ded5Dave Houlton subresource_extent = GetImageSubresourceExtent(dst_image_state, &(regions[i].dstSubresource)); 15013fb79e4c87829ef090622d69a117f33ec7d4ded5Dave Houlton extent_check = ExceedsBounds(&(regions[i].dstOffset), ®ions[i].extent, &subresource_extent); 15023fb79e4c87829ef090622d69a117f33ec7d4ded5Dave Houlton if (extent_check & x_bit) { 15033fb79e4c87829ef090622d69a117f33ec7d4ded5Dave Houlton skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 15043fb79e4c87829ef090622d69a117f33ec7d4ded5Dave Houlton reinterpret_cast<uint64_t &>(command_buffer), __LINE__, VALIDATION_ERROR_01205, "IMAGE", 15053fb79e4c87829ef090622d69a117f33ec7d4ded5Dave Houlton "vkCmdCopyImage: Dest image pRegion %1d x-dimension offset [%1d] + extent [%1d] exceeds subResource " 15063fb79e4c87829ef090622d69a117f33ec7d4ded5Dave Houlton "width [%1d]. %s", 15073fb79e4c87829ef090622d69a117f33ec7d4ded5Dave Houlton i, regions[i].dstOffset.x, regions[i].extent.width, subresource_extent.width, 15083fb79e4c87829ef090622d69a117f33ec7d4ded5Dave Houlton validation_error_map[VALIDATION_ERROR_01205]); 15093fb79e4c87829ef090622d69a117f33ec7d4ded5Dave Houlton } 15103fb79e4c87829ef090622d69a117f33ec7d4ded5Dave Houlton if (extent_check & y_bit) { 15113fb79e4c87829ef090622d69a117f33ec7d4ded5Dave Houlton skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 15123fb79e4c87829ef090622d69a117f33ec7d4ded5Dave Houlton reinterpret_cast<uint64_t &>(command_buffer), __LINE__, VALIDATION_ERROR_01206, "IMAGE", 15133fb79e4c87829ef090622d69a117f33ec7d4ded5Dave Houlton "vkCmdCopyImage: Dest image pRegion %1d y-dimension offset [%1d] + extent [%1d] exceeds subResource " 15143fb79e4c87829ef090622d69a117f33ec7d4ded5Dave Houlton "height [%1d]. %s", 15153fb79e4c87829ef090622d69a117f33ec7d4ded5Dave Houlton i, regions[i].dstOffset.y, regions[i].extent.height, subresource_extent.height, 15163fb79e4c87829ef090622d69a117f33ec7d4ded5Dave Houlton validation_error_map[VALIDATION_ERROR_01206]); 15173fb79e4c87829ef090622d69a117f33ec7d4ded5Dave Houlton } 15183fb79e4c87829ef090622d69a117f33ec7d4ded5Dave Houlton if (extent_check & z_bit) { 15193fb79e4c87829ef090622d69a117f33ec7d4ded5Dave Houlton skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 15203fb79e4c87829ef090622d69a117f33ec7d4ded5Dave Houlton reinterpret_cast<uint64_t &>(command_buffer), __LINE__, VALIDATION_ERROR_01207, "IMAGE", 15213fb79e4c87829ef090622d69a117f33ec7d4ded5Dave Houlton "vkCmdCopyImage: Dest image pRegion %1d z-dimension offset [%1d] + extent [%1d] exceeds subResource " 15223fb79e4c87829ef090622d69a117f33ec7d4ded5Dave Houlton "depth [%1d]. %s", 15233fb79e4c87829ef090622d69a117f33ec7d4ded5Dave Houlton i, regions[i].dstOffset.z, regions[i].extent.depth, subresource_extent.depth, 15243fb79e4c87829ef090622d69a117f33ec7d4ded5Dave Houlton validation_error_map[VALIDATION_ERROR_01207]); 15253fb79e4c87829ef090622d69a117f33ec7d4ded5Dave Houlton } 15263fb79e4c87829ef090622d69a117f33ec7d4ded5Dave Houlton 15276a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski // The union of all source regions, and the union of all destination regions, specified by the elements of regions, 15286a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski // must not overlap in memory 15296a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski if (src_image_state->image == dst_image_state->image) { 15306a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski for (uint32_t j = 0; j < region_count; j++) { 15316a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski if (RegionIntersects(®ions[i], ®ions[j], src_image_state->createInfo.imageType)) { 15326a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski std::stringstream ss; 15336a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski ss << "vkCmdCopyImage: pRegions[" << i << "] src overlaps with pRegions[" << j << "]."; 15346a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 15356a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski reinterpret_cast<uint64_t &>(command_buffer), __LINE__, VALIDATION_ERROR_01177, "IMAGE", 15366a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski "%s. %s", ss.str().c_str(), validation_error_map[VALIDATION_ERROR_01177]); 1537ff309c48cf48eec4599c9bf83f5b5cd802fa2db0Mark Lobodzinski } 1538ff309c48cf48eec4599c9bf83f5b5cd802fa2db0Mark Lobodzinski } 1539ff309c48cf48eec4599c9bf83f5b5cd802fa2db0Mark Lobodzinski } 15406a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski } 1541ff309c48cf48eec4599c9bf83f5b5cd802fa2db0Mark Lobodzinski 15426a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski // The formats of src_image and dst_image must be compatible. Formats are considered compatible if their texel size in bytes 15436a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski // is the same between both formats. For example, VK_FORMAT_R8G8B8A8_UNORM is compatible with VK_FORMAT_R32_UINT because 15446a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski // because both texels are 4 bytes in size. Depth/stencil formats must match exactly. 1545cf2ce8673669ca1111e333bdea272c4dd57cb5c2Dave Houlton if (FormatIsDepthOrStencil(src_image_state->createInfo.format) || FormatIsDepthOrStencil(dst_image_state->createInfo.format)) { 15466a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski if (src_image_state->createInfo.format != dst_image_state->createInfo.format) { 15476a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski char const str[] = "vkCmdCopyImage called with unmatched source and dest image depth/stencil formats."; 15486a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski skip |= 15496a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 15506a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski reinterpret_cast<uint64_t &>(command_buffer), __LINE__, DRAWSTATE_MISMATCHED_IMAGE_FORMAT, "IMAGE", str); 15516a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski } 15526a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski } else { 155316769f6b2a7721e391952a97f010cbb530e4f211Dave Houlton size_t srcSize = FormatSize(src_image_state->createInfo.format); 155416769f6b2a7721e391952a97f010cbb530e4f211Dave Houlton size_t destSize = FormatSize(dst_image_state->createInfo.format); 15556a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski if (srcSize != destSize) { 15566a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski char const str[] = "vkCmdCopyImage called with unmatched source and dest image format sizes."; 15576a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 15586a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski reinterpret_cast<uint64_t &>(command_buffer), __LINE__, VALIDATION_ERROR_01184, "IMAGE", "%s. %s", str, 15596a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski validation_error_map[VALIDATION_ERROR_01184]); 1560ff309c48cf48eec4599c9bf83f5b5cd802fa2db0Mark Lobodzinski } 1561ff309c48cf48eec4599c9bf83f5b5cd802fa2db0Mark Lobodzinski } 15626a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski 156392c9c5dfbd0dec1d76ca18faa487fa8c2d302a65Dave Houlton // Source and dest image sample counts must match 156492c9c5dfbd0dec1d76ca18faa487fa8c2d302a65Dave Houlton if (src_image_state->createInfo.samples != dst_image_state->createInfo.samples) { 156592c9c5dfbd0dec1d76ca18faa487fa8c2d302a65Dave Houlton char const str[] = "vkCmdCopyImage() called on image pair with non-identical sample counts."; 156692c9c5dfbd0dec1d76ca18faa487fa8c2d302a65Dave Houlton skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 1567e9d74ac8e13687c1be3ee147efce42e8215a049eDave Houlton reinterpret_cast<uint64_t &>(command_buffer), __LINE__, VALIDATION_ERROR_01185, "IMAGE", "%s %s", str, 1568e9d74ac8e13687c1be3ee147efce42e8215a049eDave Houlton validation_error_map[VALIDATION_ERROR_01185]); 156992c9c5dfbd0dec1d76ca18faa487fa8c2d302a65Dave Houlton } 157092c9c5dfbd0dec1d76ca18faa487fa8c2d302a65Dave Houlton 15716a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski skip |= ValidateMemoryIsBoundToImage(device_data, src_image_state, "vkCmdCopyImage()", VALIDATION_ERROR_02533); 15726a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski skip |= ValidateMemoryIsBoundToImage(device_data, dst_image_state, "vkCmdCopyImage()", VALIDATION_ERROR_02534); 15736a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski // Validate that SRC & DST images have correct usage flags set 15746a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski skip |= ValidateImageUsageFlags(device_data, src_image_state, VK_IMAGE_USAGE_TRANSFER_SRC_BIT, true, VALIDATION_ERROR_01178, 15756a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski "vkCmdCopyImage()", "VK_IMAGE_USAGE_TRANSFER_SRC_BIT"); 15766a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski skip |= ValidateImageUsageFlags(device_data, dst_image_state, VK_IMAGE_USAGE_TRANSFER_DST_BIT, true, VALIDATION_ERROR_01181, 15776a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski "vkCmdCopyImage()", "VK_IMAGE_USAGE_TRANSFER_DST_BIT"); 1578baa50ccc5a8cf7a6f7474148f301802c5480e715Mike Schuchardt skip |= ValidateCmdQueueFlags(device_data, cb_node, "vkCmdCopyImage()", 1579baa50ccc5a8cf7a6f7474148f301802c5480e715Mike Schuchardt VK_QUEUE_TRANSFER_BIT | VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT, VALIDATION_ERROR_01193); 15806a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski skip |= ValidateCmd(device_data, cb_node, CMD_COPYIMAGE, "vkCmdCopyImage()"); 15816a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski skip |= insideRenderPass(device_data, cb_node, "vkCmdCopyImage()", VALIDATION_ERROR_01194); 15820db18ab1345f9e10907913b22ea5d57bd48077ebTobin Ehlis bool hit_error = false; 15836a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski for (uint32_t i = 0; i < region_count; ++i) { 1584fab4fd84d0d187bc73b5bc6709d8ed6370bb7cc3Tobin Ehlis skip |= VerifyImageLayout(device_data, cb_node, src_image_state, regions[i].srcSubresource, src_image_layout, 15850db18ab1345f9e10907913b22ea5d57bd48077ebTobin Ehlis VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, "vkCmdCopyImage()", VALIDATION_ERROR_01180, &hit_error); 1586fab4fd84d0d187bc73b5bc6709d8ed6370bb7cc3Tobin Ehlis skip |= VerifyImageLayout(device_data, cb_node, dst_image_state, regions[i].dstSubresource, dst_image_layout, 15870db18ab1345f9e10907913b22ea5d57bd48077ebTobin Ehlis VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, "vkCmdCopyImage()", VALIDATION_ERROR_01183, &hit_error); 15886a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski skip |= ValidateCopyImageTransferGranularityRequirements(device_data, cb_node, dst_image_state, ®ions[i], i, 15896a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski "vkCmdCopyImage()"); 15906a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski } 15916a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski 1592ff309c48cf48eec4599c9bf83f5b5cd802fa2db0Mark Lobodzinski return skip; 1593ff309c48cf48eec4599c9bf83f5b5cd802fa2db0Mark Lobodzinski} 1594a6b0aebe9298e0dfc98174423f78bb7d06f1da97Mark Lobodzinski 15956a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinskivoid PreCallRecordCmdCopyImage(layer_data *device_data, GLOBAL_CB_NODE *cb_node, IMAGE_STATE *src_image_state, 1596a07ae8bd5f566eb9b073498dd4280efdb0b838b9Tobin Ehlis IMAGE_STATE *dst_image_state, uint32_t region_count, const VkImageCopy *regions, 1597a07ae8bd5f566eb9b073498dd4280efdb0b838b9Tobin Ehlis VkImageLayout src_image_layout, VkImageLayout dst_image_layout) { 1598a07ae8bd5f566eb9b073498dd4280efdb0b838b9Tobin Ehlis // Make sure that all image slices are updated to correct layout 1599a07ae8bd5f566eb9b073498dd4280efdb0b838b9Tobin Ehlis for (uint32_t i = 0; i < region_count; ++i) { 1600a07ae8bd5f566eb9b073498dd4280efdb0b838b9Tobin Ehlis SetImageLayout(device_data, cb_node, src_image_state, regions[i].srcSubresource, src_image_layout); 1601a07ae8bd5f566eb9b073498dd4280efdb0b838b9Tobin Ehlis SetImageLayout(device_data, cb_node, dst_image_state, regions[i].dstSubresource, dst_image_layout); 1602a07ae8bd5f566eb9b073498dd4280efdb0b838b9Tobin Ehlis } 16036a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski // Update bindings between images and cmd buffer 16046a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski AddCommandBufferBindingImage(device_data, cb_node, src_image_state); 16056a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski AddCommandBufferBindingImage(device_data, cb_node, dst_image_state); 16063f97578f1f51ffcb797a9feef4e5c8a600711a94Dave Houlton std::function<bool()> function = [=]() { return ValidateImageMemoryIsValid(device_data, src_image_state, "vkCmdCopyImage()"); }; 16076a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski cb_node->validate_functions.push_back(function); 16086a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski function = [=]() { 16096a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski SetImageMemoryValid(device_data, dst_image_state, true); 16106a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski return false; 16116a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski }; 16126a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski cb_node->validate_functions.push_back(function); 16136a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski core_validation::UpdateCmdBufferLastCmd(cb_node, CMD_COPYIMAGE); 16146a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski} 16156a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski 1616a6b0aebe9298e0dfc98174423f78bb7d06f1da97Mark Lobodzinski// Returns true if sub_rect is entirely contained within rect 1617a6b0aebe9298e0dfc98174423f78bb7d06f1da97Mark Lobodzinskistatic inline bool ContainsRect(VkRect2D rect, VkRect2D sub_rect) { 1618a6b0aebe9298e0dfc98174423f78bb7d06f1da97Mark Lobodzinski if ((sub_rect.offset.x < rect.offset.x) || (sub_rect.offset.x + sub_rect.extent.width > rect.offset.x + rect.extent.width) || 1619a6b0aebe9298e0dfc98174423f78bb7d06f1da97Mark Lobodzinski (sub_rect.offset.y < rect.offset.y) || (sub_rect.offset.y + sub_rect.extent.height > rect.offset.y + rect.extent.height)) 1620a6b0aebe9298e0dfc98174423f78bb7d06f1da97Mark Lobodzinski return false; 1621a6b0aebe9298e0dfc98174423f78bb7d06f1da97Mark Lobodzinski return true; 1622a6b0aebe9298e0dfc98174423f78bb7d06f1da97Mark Lobodzinski} 1623a6b0aebe9298e0dfc98174423f78bb7d06f1da97Mark Lobodzinski 1624e40189d4deab674240cd9baf4c063bab4567c212Tobin Ehlisbool PreCallValidateCmdClearAttachments(layer_data *device_data, VkCommandBuffer commandBuffer, uint32_t attachmentCount, 1625e40189d4deab674240cd9baf4c063bab4567c212Tobin Ehlis const VkClearAttachment *pAttachments, uint32_t rectCount, const VkClearRect *pRects) { 16269a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis GLOBAL_CB_NODE *cb_node = GetCBNode(device_data, commandBuffer); 1627a6b0aebe9298e0dfc98174423f78bb7d06f1da97Mark Lobodzinski const debug_report_data *report_data = core_validation::GetReportData(device_data); 1628a6b0aebe9298e0dfc98174423f78bb7d06f1da97Mark Lobodzinski 1629a6b0aebe9298e0dfc98174423f78bb7d06f1da97Mark Lobodzinski bool skip = false; 1630a6b0aebe9298e0dfc98174423f78bb7d06f1da97Mark Lobodzinski if (cb_node) { 1631baa50ccc5a8cf7a6f7474148f301802c5480e715Mike Schuchardt skip |= 1632baa50ccc5a8cf7a6f7474148f301802c5480e715Mike Schuchardt ValidateCmdQueueFlags(device_data, cb_node, "vkCmdClearAttachments()", VK_QUEUE_GRAPHICS_BIT, VALIDATION_ERROR_01121); 1633a6b0aebe9298e0dfc98174423f78bb7d06f1da97Mark Lobodzinski skip |= ValidateCmd(device_data, cb_node, CMD_CLEARATTACHMENTS, "vkCmdClearAttachments()"); 16349a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis core_validation::UpdateCmdBufferLastCmd(cb_node, CMD_CLEARATTACHMENTS); 1635a6b0aebe9298e0dfc98174423f78bb7d06f1da97Mark Lobodzinski // Warn if this is issued prior to Draw Cmd and clearing the entire attachment 1636b68b13ed4952bce61f6ebb0023542660c26b0562Chris Forbes if (!cb_node->hasDrawCmd && (cb_node->activeRenderPassBeginInfo.renderArea.extent.width == pRects[0].rect.extent.width) && 1637a6b0aebe9298e0dfc98174423f78bb7d06f1da97Mark Lobodzinski (cb_node->activeRenderPassBeginInfo.renderArea.extent.height == pRects[0].rect.extent.height)) { 1638a6b0aebe9298e0dfc98174423f78bb7d06f1da97Mark Lobodzinski // There are times where app needs to use ClearAttachments (generally when reusing a buffer inside of a render pass) 16398e0190bd5904b8a8f044dae2c6ae23a891eb5e11Mark Lobodzinski // This warning should be made more specific. It'd be best to avoid triggering this test if it's a use that must call 16408e0190bd5904b8a8f044dae2c6ae23a891eb5e11Mark Lobodzinski // CmdClearAttachments. 164173f044278acc4f663257c463f9032b603a5f1be7Mark Lobodzinski skip |= 164273f044278acc4f663257c463f9032b603a5f1be7Mark Lobodzinski log_msg(report_data, VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 164373f044278acc4f663257c463f9032b603a5f1be7Mark Lobodzinski reinterpret_cast<uint64_t &>(commandBuffer), 0, DRAWSTATE_CLEAR_CMD_BEFORE_DRAW, "DS", 164473f044278acc4f663257c463f9032b603a5f1be7Mark Lobodzinski "vkCmdClearAttachments() issued on command buffer object 0x%p prior to any Draw Cmds." 164573f044278acc4f663257c463f9032b603a5f1be7Mark Lobodzinski " It is recommended you use RenderPass LOAD_OP_CLEAR on Attachments prior to any Draw.", 164673f044278acc4f663257c463f9032b603a5f1be7Mark Lobodzinski commandBuffer); 1647a6b0aebe9298e0dfc98174423f78bb7d06f1da97Mark Lobodzinski } 1648a6b0aebe9298e0dfc98174423f78bb7d06f1da97Mark Lobodzinski skip |= outsideRenderPass(device_data, cb_node, "vkCmdClearAttachments()", VALIDATION_ERROR_01122); 1649a6b0aebe9298e0dfc98174423f78bb7d06f1da97Mark Lobodzinski } 1650a6b0aebe9298e0dfc98174423f78bb7d06f1da97Mark Lobodzinski 1651a6b0aebe9298e0dfc98174423f78bb7d06f1da97Mark Lobodzinski // Validate that attachment is in reference list of active subpass 1652a6b0aebe9298e0dfc98174423f78bb7d06f1da97Mark Lobodzinski if (cb_node->activeRenderPass) { 1653a6b0aebe9298e0dfc98174423f78bb7d06f1da97Mark Lobodzinski const VkRenderPassCreateInfo *renderpass_create_info = cb_node->activeRenderPass->createInfo.ptr(); 1654a6b0aebe9298e0dfc98174423f78bb7d06f1da97Mark Lobodzinski const VkSubpassDescription *subpass_desc = &renderpass_create_info->pSubpasses[cb_node->activeSubpass]; 16559a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto framebuffer = GetFramebufferState(device_data, cb_node->activeFramebuffer); 1656a6b0aebe9298e0dfc98174423f78bb7d06f1da97Mark Lobodzinski 1657a6b0aebe9298e0dfc98174423f78bb7d06f1da97Mark Lobodzinski for (uint32_t i = 0; i < attachmentCount; i++) { 1658a6b0aebe9298e0dfc98174423f78bb7d06f1da97Mark Lobodzinski auto clear_desc = &pAttachments[i]; 1659a6b0aebe9298e0dfc98174423f78bb7d06f1da97Mark Lobodzinski VkImageView image_view = VK_NULL_HANDLE; 1660a6b0aebe9298e0dfc98174423f78bb7d06f1da97Mark Lobodzinski 166173f044278acc4f663257c463f9032b603a5f1be7Mark Lobodzinski if (0 == clear_desc->aspectMask) { 166273f044278acc4f663257c463f9032b603a5f1be7Mark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 1663fdc75c21ced997fbbc180734bef87bf6d5811d4bMark Lobodzinski reinterpret_cast<uint64_t>(commandBuffer), __LINE__, VALIDATION_ERROR_01128, "IMAGE", "%s", 166473f044278acc4f663257c463f9032b603a5f1be7Mark Lobodzinski validation_error_map[VALIDATION_ERROR_01128]); 166573f044278acc4f663257c463f9032b603a5f1be7Mark Lobodzinski } else if (clear_desc->aspectMask & VK_IMAGE_ASPECT_METADATA_BIT) { 166673f044278acc4f663257c463f9032b603a5f1be7Mark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 1667fdc75c21ced997fbbc180734bef87bf6d5811d4bMark Lobodzinski reinterpret_cast<uint64_t>(commandBuffer), __LINE__, VALIDATION_ERROR_01126, "IMAGE", "%s", 166873f044278acc4f663257c463f9032b603a5f1be7Mark Lobodzinski validation_error_map[VALIDATION_ERROR_01126]); 166973f044278acc4f663257c463f9032b603a5f1be7Mark Lobodzinski } else if (clear_desc->aspectMask & VK_IMAGE_ASPECT_COLOR_BIT) { 1670a6b0aebe9298e0dfc98174423f78bb7d06f1da97Mark Lobodzinski if (clear_desc->colorAttachment >= subpass_desc->colorAttachmentCount) { 167173f044278acc4f663257c463f9032b603a5f1be7Mark Lobodzinski skip |= 167273f044278acc4f663257c463f9032b603a5f1be7Mark Lobodzinski log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 1673fdc75c21ced997fbbc180734bef87bf6d5811d4bMark Lobodzinski reinterpret_cast<uint64_t>(commandBuffer), __LINE__, VALIDATION_ERROR_01114, "DS", 167473f044278acc4f663257c463f9032b603a5f1be7Mark Lobodzinski "vkCmdClearAttachments() color attachment index %d out of range for active subpass %d. %s", 167573f044278acc4f663257c463f9032b603a5f1be7Mark Lobodzinski clear_desc->colorAttachment, cb_node->activeSubpass, validation_error_map[VALIDATION_ERROR_01114]); 1676a6b0aebe9298e0dfc98174423f78bb7d06f1da97Mark Lobodzinski } else if (subpass_desc->pColorAttachments[clear_desc->colorAttachment].attachment == VK_ATTACHMENT_UNUSED) { 1677a6b0aebe9298e0dfc98174423f78bb7d06f1da97Mark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT, 1678fdc75c21ced997fbbc180734bef87bf6d5811d4bMark Lobodzinski VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, reinterpret_cast<uint64_t>(commandBuffer), 1679fdc75c21ced997fbbc180734bef87bf6d5811d4bMark Lobodzinski __LINE__, DRAWSTATE_MISSING_ATTACHMENT_REFERENCE, "DS", 168073f044278acc4f663257c463f9032b603a5f1be7Mark Lobodzinski "vkCmdClearAttachments() color attachment index %d is VK_ATTACHMENT_UNUSED; ignored.", 168173f044278acc4f663257c463f9032b603a5f1be7Mark Lobodzinski clear_desc->colorAttachment); 1682a6b0aebe9298e0dfc98174423f78bb7d06f1da97Mark Lobodzinski } else { 1683a6b0aebe9298e0dfc98174423f78bb7d06f1da97Mark Lobodzinski image_view = framebuffer->createInfo 168473f044278acc4f663257c463f9032b603a5f1be7Mark Lobodzinski .pAttachments[subpass_desc->pColorAttachments[clear_desc->colorAttachment].attachment]; 1685a6b0aebe9298e0dfc98174423f78bb7d06f1da97Mark Lobodzinski } 168673f044278acc4f663257c463f9032b603a5f1be7Mark Lobodzinski if ((clear_desc->aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT) || 168773f044278acc4f663257c463f9032b603a5f1be7Mark Lobodzinski (clear_desc->aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT)) { 168873f044278acc4f663257c463f9032b603a5f1be7Mark Lobodzinski char const str[] = 168973f044278acc4f663257c463f9032b603a5f1be7Mark Lobodzinski "vkCmdClearAttachments aspectMask [%d] must set only VK_IMAGE_ASPECT_COLOR_BIT of a color attachment. %s"; 169073f044278acc4f663257c463f9032b603a5f1be7Mark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 1691fdc75c21ced997fbbc180734bef87bf6d5811d4bMark Lobodzinski reinterpret_cast<uint64_t>(commandBuffer), __LINE__, VALIDATION_ERROR_01125, "IMAGE", str, i, 169273f044278acc4f663257c463f9032b603a5f1be7Mark Lobodzinski validation_error_map[VALIDATION_ERROR_01125]); 169373f044278acc4f663257c463f9032b603a5f1be7Mark Lobodzinski } 169473f044278acc4f663257c463f9032b603a5f1be7Mark Lobodzinski } else { // Must be depth and/or stencil 169573f044278acc4f663257c463f9032b603a5f1be7Mark Lobodzinski if (((clear_desc->aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT) != VK_IMAGE_ASPECT_DEPTH_BIT) && 169673f044278acc4f663257c463f9032b603a5f1be7Mark Lobodzinski ((clear_desc->aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT) != VK_IMAGE_ASPECT_STENCIL_BIT)) { 169773f044278acc4f663257c463f9032b603a5f1be7Mark Lobodzinski char const str[] = "vkCmdClearAttachments aspectMask [%d] is not a valid combination of bits. %s"; 169873f044278acc4f663257c463f9032b603a5f1be7Mark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 1699fdc75c21ced997fbbc180734bef87bf6d5811d4bMark Lobodzinski reinterpret_cast<uint64_t>(commandBuffer), __LINE__, VALIDATION_ERROR_01127, "IMAGE", str, i, 170073f044278acc4f663257c463f9032b603a5f1be7Mark Lobodzinski validation_error_map[VALIDATION_ERROR_01127]); 170173f044278acc4f663257c463f9032b603a5f1be7Mark Lobodzinski } 170273f044278acc4f663257c463f9032b603a5f1be7Mark Lobodzinski if (!subpass_desc->pDepthStencilAttachment || 170373f044278acc4f663257c463f9032b603a5f1be7Mark Lobodzinski (subpass_desc->pDepthStencilAttachment->attachment == VK_ATTACHMENT_UNUSED)) { 170473f044278acc4f663257c463f9032b603a5f1be7Mark Lobodzinski skip |= log_msg( 170573f044278acc4f663257c463f9032b603a5f1be7Mark Lobodzinski report_data, VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 1706fdc75c21ced997fbbc180734bef87bf6d5811d4bMark Lobodzinski reinterpret_cast<uint64_t>(commandBuffer), __LINE__, DRAWSTATE_MISSING_ATTACHMENT_REFERENCE, "DS", 170773f044278acc4f663257c463f9032b603a5f1be7Mark Lobodzinski "vkCmdClearAttachments() depth/stencil clear with no depth/stencil attachment in subpass; ignored"); 1708a6b0aebe9298e0dfc98174423f78bb7d06f1da97Mark Lobodzinski } else { 1709a6b0aebe9298e0dfc98174423f78bb7d06f1da97Mark Lobodzinski image_view = framebuffer->createInfo.pAttachments[subpass_desc->pDepthStencilAttachment->attachment]; 1710a6b0aebe9298e0dfc98174423f78bb7d06f1da97Mark Lobodzinski } 1711a6b0aebe9298e0dfc98174423f78bb7d06f1da97Mark Lobodzinski } 1712a6b0aebe9298e0dfc98174423f78bb7d06f1da97Mark Lobodzinski if (image_view) { 17139a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto image_view_state = GetImageViewState(device_data, image_view); 1714a6b0aebe9298e0dfc98174423f78bb7d06f1da97Mark Lobodzinski for (uint32_t j = 0; j < rectCount; j++) { 171573f044278acc4f663257c463f9032b603a5f1be7Mark Lobodzinski // The rectangular region specified by a given element of pRects must be contained within the render area of 171673f044278acc4f663257c463f9032b603a5f1be7Mark Lobodzinski // the current render pass instance 17178e0190bd5904b8a8f044dae2c6ae23a891eb5e11Mark Lobodzinski // TODO: This check should be moved to CmdExecuteCommands or QueueSubmit to cover secondary CB cases 17188e0190bd5904b8a8f044dae2c6ae23a891eb5e11Mark Lobodzinski if ((cb_node->createInfo.level == VK_COMMAND_BUFFER_LEVEL_PRIMARY) && 17198e0190bd5904b8a8f044dae2c6ae23a891eb5e11Mark Lobodzinski (false == ContainsRect(cb_node->activeRenderPassBeginInfo.renderArea, pRects[j].rect))) { 1720fdc75c21ced997fbbc180734bef87bf6d5811d4bMark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 1721fdc75c21ced997fbbc180734bef87bf6d5811d4bMark Lobodzinski reinterpret_cast<uint64_t>(commandBuffer), __LINE__, VALIDATION_ERROR_01115, "DS", 172273f044278acc4f663257c463f9032b603a5f1be7Mark Lobodzinski "vkCmdClearAttachments(): The area defined by pRects[%d] is not contained in the area of " 172373f044278acc4f663257c463f9032b603a5f1be7Mark Lobodzinski "the current render pass instance. %s", 172473f044278acc4f663257c463f9032b603a5f1be7Mark Lobodzinski j, validation_error_map[VALIDATION_ERROR_01115]); 1725a6b0aebe9298e0dfc98174423f78bb7d06f1da97Mark Lobodzinski } 1726a6b0aebe9298e0dfc98174423f78bb7d06f1da97Mark Lobodzinski // The layers specified by a given element of pRects must be contained within every attachment that 1727a6b0aebe9298e0dfc98174423f78bb7d06f1da97Mark Lobodzinski // pAttachments refers to 1728a6b0aebe9298e0dfc98174423f78bb7d06f1da97Mark Lobodzinski auto attachment_base_array_layer = image_view_state->create_info.subresourceRange.baseArrayLayer; 1729a6b0aebe9298e0dfc98174423f78bb7d06f1da97Mark Lobodzinski auto attachment_layer_count = image_view_state->create_info.subresourceRange.layerCount; 1730a6b0aebe9298e0dfc98174423f78bb7d06f1da97Mark Lobodzinski if ((pRects[j].baseArrayLayer < attachment_base_array_layer) || pRects[j].layerCount > attachment_layer_count) { 1731a6b0aebe9298e0dfc98174423f78bb7d06f1da97Mark Lobodzinski skip |= 1732fdc75c21ced997fbbc180734bef87bf6d5811d4bMark Lobodzinski log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 1733fdc75c21ced997fbbc180734bef87bf6d5811d4bMark Lobodzinski reinterpret_cast<uint64_t>(commandBuffer), __LINE__, VALIDATION_ERROR_01116, "DS", 173473f044278acc4f663257c463f9032b603a5f1be7Mark Lobodzinski "vkCmdClearAttachments(): The layers defined in pRects[%d] are not contained in the layers of " 173573f044278acc4f663257c463f9032b603a5f1be7Mark Lobodzinski "pAttachment[%d]. %s", 173673f044278acc4f663257c463f9032b603a5f1be7Mark Lobodzinski j, i, validation_error_map[VALIDATION_ERROR_01116]); 1737a6b0aebe9298e0dfc98174423f78bb7d06f1da97Mark Lobodzinski } 1738a6b0aebe9298e0dfc98174423f78bb7d06f1da97Mark Lobodzinski } 1739a6b0aebe9298e0dfc98174423f78bb7d06f1da97Mark Lobodzinski } 1740a6b0aebe9298e0dfc98174423f78bb7d06f1da97Mark Lobodzinski } 1741a6b0aebe9298e0dfc98174423f78bb7d06f1da97Mark Lobodzinski } 1742a6b0aebe9298e0dfc98174423f78bb7d06f1da97Mark Lobodzinski return skip; 174360568995aca225f81acda8ce40cfabbea2c19397Mark Lobodzinski} 174460568995aca225f81acda8ce40cfabbea2c19397Mark Lobodzinski 1745e40189d4deab674240cd9baf4c063bab4567c212Tobin Ehlisbool PreCallValidateCmdResolveImage(layer_data *device_data, GLOBAL_CB_NODE *cb_node, IMAGE_STATE *src_image_state, 174654c03b0fa365789b242e680223bd30c940f1abb3Mark Lobodzinski IMAGE_STATE *dst_image_state, uint32_t regionCount, const VkImageResolve *pRegions) { 174725f7873c9ce3ed39d18bba8750d7538905e150dfMark Lobodzinski const debug_report_data *report_data = core_validation::GetReportData(device_data); 174860568995aca225f81acda8ce40cfabbea2c19397Mark Lobodzinski bool skip = false; 174960568995aca225f81acda8ce40cfabbea2c19397Mark Lobodzinski if (cb_node && src_image_state && dst_image_state) { 175060568995aca225f81acda8ce40cfabbea2c19397Mark Lobodzinski skip |= ValidateMemoryIsBoundToImage(device_data, src_image_state, "vkCmdResolveImage()", VALIDATION_ERROR_02541); 175160568995aca225f81acda8ce40cfabbea2c19397Mark Lobodzinski skip |= ValidateMemoryIsBoundToImage(device_data, dst_image_state, "vkCmdResolveImage()", VALIDATION_ERROR_02542); 1752baa50ccc5a8cf7a6f7474148f301802c5480e715Mike Schuchardt skip |= ValidateCmdQueueFlags(device_data, cb_node, "vkCmdResolveImage()", VK_QUEUE_GRAPHICS_BIT, VALIDATION_ERROR_01334); 175360568995aca225f81acda8ce40cfabbea2c19397Mark Lobodzinski skip |= ValidateCmd(device_data, cb_node, CMD_RESOLVEIMAGE, "vkCmdResolveImage()"); 175460568995aca225f81acda8ce40cfabbea2c19397Mark Lobodzinski skip |= insideRenderPass(device_data, cb_node, "vkCmdResolveImage()", VALIDATION_ERROR_01335); 175525f7873c9ce3ed39d18bba8750d7538905e150dfMark Lobodzinski 175625f7873c9ce3ed39d18bba8750d7538905e150dfMark Lobodzinski // For each region, the number of layers in the image subresource should not be zero 175725f7873c9ce3ed39d18bba8750d7538905e150dfMark Lobodzinski // For each region, src and dest image aspect must be color only 175825f7873c9ce3ed39d18bba8750d7538905e150dfMark Lobodzinski for (uint32_t i = 0; i < regionCount; i++) { 175925f7873c9ce3ed39d18bba8750d7538905e150dfMark Lobodzinski if (pRegions[i].srcSubresource.layerCount == 0) { 176025f7873c9ce3ed39d18bba8750d7538905e150dfMark Lobodzinski char const str[] = "vkCmdResolveImage: number of layers in source subresource is zero"; 176154c03b0fa365789b242e680223bd30c940f1abb3Mark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 176225f7873c9ce3ed39d18bba8750d7538905e150dfMark Lobodzinski reinterpret_cast<uint64_t>(cb_node->commandBuffer), __LINE__, DRAWSTATE_MISMATCHED_IMAGE_ASPECT, 176325f7873c9ce3ed39d18bba8750d7538905e150dfMark Lobodzinski "IMAGE", str); 176425f7873c9ce3ed39d18bba8750d7538905e150dfMark Lobodzinski } 176525f7873c9ce3ed39d18bba8750d7538905e150dfMark Lobodzinski if (pRegions[i].dstSubresource.layerCount == 0) { 176625f7873c9ce3ed39d18bba8750d7538905e150dfMark Lobodzinski char const str[] = "vkCmdResolveImage: number of layers in destination subresource is zero"; 176754c03b0fa365789b242e680223bd30c940f1abb3Mark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 176825f7873c9ce3ed39d18bba8750d7538905e150dfMark Lobodzinski reinterpret_cast<uint64_t>(cb_node->commandBuffer), __LINE__, DRAWSTATE_MISMATCHED_IMAGE_ASPECT, 176925f7873c9ce3ed39d18bba8750d7538905e150dfMark Lobodzinski "IMAGE", str); 177025f7873c9ce3ed39d18bba8750d7538905e150dfMark Lobodzinski } 177154c03b0fa365789b242e680223bd30c940f1abb3Mark Lobodzinski if (pRegions[i].srcSubresource.layerCount != pRegions[i].dstSubresource.layerCount) { 177254c03b0fa365789b242e680223bd30c940f1abb3Mark Lobodzinski skip |= log_msg( 177354c03b0fa365789b242e680223bd30c940f1abb3Mark Lobodzinski report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 177454c03b0fa365789b242e680223bd30c940f1abb3Mark Lobodzinski reinterpret_cast<uint64_t>(cb_node->commandBuffer), __LINE__, VALIDATION_ERROR_01339, "IMAGE", 177554c03b0fa365789b242e680223bd30c940f1abb3Mark Lobodzinski "vkCmdResolveImage: layerCount in source and destination subresource of pRegions[%d] does not match. %s", i, 177654c03b0fa365789b242e680223bd30c940f1abb3Mark Lobodzinski validation_error_map[VALIDATION_ERROR_01339]); 177754c03b0fa365789b242e680223bd30c940f1abb3Mark Lobodzinski } 177825f7873c9ce3ed39d18bba8750d7538905e150dfMark Lobodzinski if ((pRegions[i].srcSubresource.aspectMask != VK_IMAGE_ASPECT_COLOR_BIT) || 177925f7873c9ce3ed39d18bba8750d7538905e150dfMark Lobodzinski (pRegions[i].dstSubresource.aspectMask != VK_IMAGE_ASPECT_COLOR_BIT)) { 178025f7873c9ce3ed39d18bba8750d7538905e150dfMark Lobodzinski char const str[] = 178125f7873c9ce3ed39d18bba8750d7538905e150dfMark Lobodzinski "vkCmdResolveImage: src and dest aspectMasks for each region must specify only VK_IMAGE_ASPECT_COLOR_BIT"; 178225f7873c9ce3ed39d18bba8750d7538905e150dfMark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 178325f7873c9ce3ed39d18bba8750d7538905e150dfMark Lobodzinski reinterpret_cast<uint64_t>(cb_node->commandBuffer), __LINE__, VALIDATION_ERROR_01338, "IMAGE", 178425f7873c9ce3ed39d18bba8750d7538905e150dfMark Lobodzinski "%s. %s", str, validation_error_map[VALIDATION_ERROR_01338]); 178525f7873c9ce3ed39d18bba8750d7538905e150dfMark Lobodzinski } 178625f7873c9ce3ed39d18bba8750d7538905e150dfMark Lobodzinski } 178725f7873c9ce3ed39d18bba8750d7538905e150dfMark Lobodzinski 178825f7873c9ce3ed39d18bba8750d7538905e150dfMark Lobodzinski if (src_image_state->createInfo.format != dst_image_state->createInfo.format) { 178925f7873c9ce3ed39d18bba8750d7538905e150dfMark Lobodzinski char const str[] = "vkCmdResolveImage called with unmatched source and dest formats."; 179054c03b0fa365789b242e680223bd30c940f1abb3Mark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 179125f7873c9ce3ed39d18bba8750d7538905e150dfMark Lobodzinski reinterpret_cast<uint64_t>(cb_node->commandBuffer), __LINE__, DRAWSTATE_MISMATCHED_IMAGE_FORMAT, 179225f7873c9ce3ed39d18bba8750d7538905e150dfMark Lobodzinski "IMAGE", str); 179325f7873c9ce3ed39d18bba8750d7538905e150dfMark Lobodzinski } 179425f7873c9ce3ed39d18bba8750d7538905e150dfMark Lobodzinski if (src_image_state->createInfo.imageType != dst_image_state->createInfo.imageType) { 179525f7873c9ce3ed39d18bba8750d7538905e150dfMark Lobodzinski char const str[] = "vkCmdResolveImage called with unmatched source and dest image types."; 179654c03b0fa365789b242e680223bd30c940f1abb3Mark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 179725f7873c9ce3ed39d18bba8750d7538905e150dfMark Lobodzinski reinterpret_cast<uint64_t>(cb_node->commandBuffer), __LINE__, DRAWSTATE_MISMATCHED_IMAGE_TYPE, "IMAGE", 179825f7873c9ce3ed39d18bba8750d7538905e150dfMark Lobodzinski str); 179925f7873c9ce3ed39d18bba8750d7538905e150dfMark Lobodzinski } 180025f7873c9ce3ed39d18bba8750d7538905e150dfMark Lobodzinski if (src_image_state->createInfo.samples == VK_SAMPLE_COUNT_1_BIT) { 180125f7873c9ce3ed39d18bba8750d7538905e150dfMark Lobodzinski char const str[] = "vkCmdResolveImage called with source sample count less than 2."; 180225f7873c9ce3ed39d18bba8750d7538905e150dfMark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 180325f7873c9ce3ed39d18bba8750d7538905e150dfMark Lobodzinski reinterpret_cast<uint64_t>(cb_node->commandBuffer), __LINE__, VALIDATION_ERROR_01320, "IMAGE", "%s. %s", 180425f7873c9ce3ed39d18bba8750d7538905e150dfMark Lobodzinski str, validation_error_map[VALIDATION_ERROR_01320]); 180525f7873c9ce3ed39d18bba8750d7538905e150dfMark Lobodzinski } 180625f7873c9ce3ed39d18bba8750d7538905e150dfMark Lobodzinski if (dst_image_state->createInfo.samples != VK_SAMPLE_COUNT_1_BIT) { 180725f7873c9ce3ed39d18bba8750d7538905e150dfMark Lobodzinski char const str[] = "vkCmdResolveImage called with dest sample count greater than 1."; 180825f7873c9ce3ed39d18bba8750d7538905e150dfMark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 180925f7873c9ce3ed39d18bba8750d7538905e150dfMark Lobodzinski reinterpret_cast<uint64_t>(cb_node->commandBuffer), __LINE__, VALIDATION_ERROR_01321, "IMAGE", "%s. %s", 181025f7873c9ce3ed39d18bba8750d7538905e150dfMark Lobodzinski str, validation_error_map[VALIDATION_ERROR_01321]); 181125f7873c9ce3ed39d18bba8750d7538905e150dfMark Lobodzinski } 181260568995aca225f81acda8ce40cfabbea2c19397Mark Lobodzinski } else { 181360568995aca225f81acda8ce40cfabbea2c19397Mark Lobodzinski assert(0); 181460568995aca225f81acda8ce40cfabbea2c19397Mark Lobodzinski } 181560568995aca225f81acda8ce40cfabbea2c19397Mark Lobodzinski return skip; 181660568995aca225f81acda8ce40cfabbea2c19397Mark Lobodzinski} 181760568995aca225f81acda8ce40cfabbea2c19397Mark Lobodzinski 1818e40189d4deab674240cd9baf4c063bab4567c212Tobin Ehlisvoid PreCallRecordCmdResolveImage(layer_data *device_data, GLOBAL_CB_NODE *cb_node, IMAGE_STATE *src_image_state, 1819e40189d4deab674240cd9baf4c063bab4567c212Tobin Ehlis IMAGE_STATE *dst_image_state) { 182060568995aca225f81acda8ce40cfabbea2c19397Mark Lobodzinski // Update bindings between images and cmd buffer 182160568995aca225f81acda8ce40cfabbea2c19397Mark Lobodzinski AddCommandBufferBindingImage(device_data, cb_node, src_image_state); 182260568995aca225f81acda8ce40cfabbea2c19397Mark Lobodzinski AddCommandBufferBindingImage(device_data, cb_node, dst_image_state); 182360568995aca225f81acda8ce40cfabbea2c19397Mark Lobodzinski 182460568995aca225f81acda8ce40cfabbea2c19397Mark Lobodzinski std::function<bool()> function = [=]() { 182560568995aca225f81acda8ce40cfabbea2c19397Mark Lobodzinski return ValidateImageMemoryIsValid(device_data, src_image_state, "vkCmdResolveImage()"); 182660568995aca225f81acda8ce40cfabbea2c19397Mark Lobodzinski }; 182760568995aca225f81acda8ce40cfabbea2c19397Mark Lobodzinski cb_node->validate_functions.push_back(function); 182860568995aca225f81acda8ce40cfabbea2c19397Mark Lobodzinski function = [=]() { 182960568995aca225f81acda8ce40cfabbea2c19397Mark Lobodzinski SetImageMemoryValid(device_data, dst_image_state, true); 183060568995aca225f81acda8ce40cfabbea2c19397Mark Lobodzinski return false; 183160568995aca225f81acda8ce40cfabbea2c19397Mark Lobodzinski }; 183260568995aca225f81acda8ce40cfabbea2c19397Mark Lobodzinski cb_node->validate_functions.push_back(function); 18339a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis core_validation::UpdateCmdBufferLastCmd(cb_node, CMD_RESOLVEIMAGE); 183460568995aca225f81acda8ce40cfabbea2c19397Mark Lobodzinski} 183560568995aca225f81acda8ce40cfabbea2c19397Mark Lobodzinski 1836e40189d4deab674240cd9baf4c063bab4567c212Tobin Ehlisbool PreCallValidateCmdBlitImage(layer_data *device_data, GLOBAL_CB_NODE *cb_node, IMAGE_STATE *src_image_state, 1837055112ec99304db71d55b69a60e1da14e8af8f60Mark Lobodzinski IMAGE_STATE *dst_image_state, uint32_t regionCount, const VkImageBlit *pRegions, VkFilter filter) { 1838055112ec99304db71d55b69a60e1da14e8af8f60Mark Lobodzinski const debug_report_data *report_data = core_validation::GetReportData(device_data); 1839055112ec99304db71d55b69a60e1da14e8af8f60Mark Lobodzinski 184060568995aca225f81acda8ce40cfabbea2c19397Mark Lobodzinski bool skip = false; 184160568995aca225f81acda8ce40cfabbea2c19397Mark Lobodzinski if (cb_node && src_image_state && dst_image_state) { 184260568995aca225f81acda8ce40cfabbea2c19397Mark Lobodzinski skip |= ValidateImageSampleCount(device_data, src_image_state, VK_SAMPLE_COUNT_1_BIT, "vkCmdBlitImage(): srcImage", 1843055112ec99304db71d55b69a60e1da14e8af8f60Mark Lobodzinski VALIDATION_ERROR_02194); 184460568995aca225f81acda8ce40cfabbea2c19397Mark Lobodzinski skip |= ValidateImageSampleCount(device_data, dst_image_state, VK_SAMPLE_COUNT_1_BIT, "vkCmdBlitImage(): dstImage", 1845055112ec99304db71d55b69a60e1da14e8af8f60Mark Lobodzinski VALIDATION_ERROR_02195); 184660568995aca225f81acda8ce40cfabbea2c19397Mark Lobodzinski skip |= ValidateMemoryIsBoundToImage(device_data, src_image_state, "vkCmdBlitImage()", VALIDATION_ERROR_02539); 184760568995aca225f81acda8ce40cfabbea2c19397Mark Lobodzinski skip |= ValidateMemoryIsBoundToImage(device_data, dst_image_state, "vkCmdBlitImage()", VALIDATION_ERROR_02540); 184860568995aca225f81acda8ce40cfabbea2c19397Mark Lobodzinski skip |= ValidateImageUsageFlags(device_data, src_image_state, VK_IMAGE_USAGE_TRANSFER_SRC_BIT, true, VALIDATION_ERROR_02182, 1849055112ec99304db71d55b69a60e1da14e8af8f60Mark Lobodzinski "vkCmdBlitImage()", "VK_IMAGE_USAGE_TRANSFER_SRC_BIT"); 185060568995aca225f81acda8ce40cfabbea2c19397Mark Lobodzinski skip |= ValidateImageUsageFlags(device_data, dst_image_state, VK_IMAGE_USAGE_TRANSFER_DST_BIT, true, VALIDATION_ERROR_02186, 1851055112ec99304db71d55b69a60e1da14e8af8f60Mark Lobodzinski "vkCmdBlitImage()", "VK_IMAGE_USAGE_TRANSFER_DST_BIT"); 1852baa50ccc5a8cf7a6f7474148f301802c5480e715Mike Schuchardt skip |= ValidateCmdQueueFlags(device_data, cb_node, "vkCmdBlitImage()", VK_QUEUE_GRAPHICS_BIT, VALIDATION_ERROR_01299); 185360568995aca225f81acda8ce40cfabbea2c19397Mark Lobodzinski skip |= ValidateCmd(device_data, cb_node, CMD_BLITIMAGE, "vkCmdBlitImage()"); 185460568995aca225f81acda8ce40cfabbea2c19397Mark Lobodzinski skip |= insideRenderPass(device_data, cb_node, "vkCmdBlitImage()", VALIDATION_ERROR_01300); 1855055112ec99304db71d55b69a60e1da14e8af8f60Mark Lobodzinski 1856055112ec99304db71d55b69a60e1da14e8af8f60Mark Lobodzinski for (uint32_t i = 0; i < regionCount; i++) { 1857d81f107590290d41d3e39fcbf3f077658be0f5a6Mark Lobodzinski // Warn for zero-sized regions 1858055112ec99304db71d55b69a60e1da14e8af8f60Mark Lobodzinski if ((pRegions[i].srcOffsets[0].x == pRegions[i].srcOffsets[1].x) || 1859055112ec99304db71d55b69a60e1da14e8af8f60Mark Lobodzinski (pRegions[i].srcOffsets[0].y == pRegions[i].srcOffsets[1].y) || 1860055112ec99304db71d55b69a60e1da14e8af8f60Mark Lobodzinski (pRegions[i].srcOffsets[0].z == pRegions[i].srcOffsets[1].z)) { 1861055112ec99304db71d55b69a60e1da14e8af8f60Mark Lobodzinski std::stringstream ss; 1862055112ec99304db71d55b69a60e1da14e8af8f60Mark Lobodzinski ss << "vkCmdBlitImage: pRegions[" << i << "].srcOffsets specify a zero-volume area."; 1863055112ec99304db71d55b69a60e1da14e8af8f60Mark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 1864055112ec99304db71d55b69a60e1da14e8af8f60Mark Lobodzinski reinterpret_cast<uint64_t>(cb_node->commandBuffer), __LINE__, DRAWSTATE_INVALID_EXTENTS, "IMAGE", 1865055112ec99304db71d55b69a60e1da14e8af8f60Mark Lobodzinski "%s", ss.str().c_str()); 1866055112ec99304db71d55b69a60e1da14e8af8f60Mark Lobodzinski } 1867055112ec99304db71d55b69a60e1da14e8af8f60Mark Lobodzinski if ((pRegions[i].dstOffsets[0].x == pRegions[i].dstOffsets[1].x) || 1868055112ec99304db71d55b69a60e1da14e8af8f60Mark Lobodzinski (pRegions[i].dstOffsets[0].y == pRegions[i].dstOffsets[1].y) || 1869055112ec99304db71d55b69a60e1da14e8af8f60Mark Lobodzinski (pRegions[i].dstOffsets[0].z == pRegions[i].dstOffsets[1].z)) { 1870055112ec99304db71d55b69a60e1da14e8af8f60Mark Lobodzinski std::stringstream ss; 1871055112ec99304db71d55b69a60e1da14e8af8f60Mark Lobodzinski ss << "vkCmdBlitImage: pRegions[" << i << "].dstOffsets specify a zero-volume area."; 1872055112ec99304db71d55b69a60e1da14e8af8f60Mark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 1873055112ec99304db71d55b69a60e1da14e8af8f60Mark Lobodzinski reinterpret_cast<uint64_t>(cb_node->commandBuffer), __LINE__, DRAWSTATE_INVALID_EXTENTS, "IMAGE", 1874055112ec99304db71d55b69a60e1da14e8af8f60Mark Lobodzinski "%s", ss.str().c_str()); 1875055112ec99304db71d55b69a60e1da14e8af8f60Mark Lobodzinski } 1876d81f107590290d41d3e39fcbf3f077658be0f5a6Mark Lobodzinski if (pRegions[i].srcSubresource.layerCount == 0) { 1877d81f107590290d41d3e39fcbf3f077658be0f5a6Mark Lobodzinski char const str[] = "vkCmdBlitImage: number of layers in source subresource is zero"; 1878d81f107590290d41d3e39fcbf3f077658be0f5a6Mark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 18793f97578f1f51ffcb797a9feef4e5c8a600711a94Dave Houlton reinterpret_cast<uint64_t>(cb_node->commandBuffer), __LINE__, DRAWSTATE_MISMATCHED_IMAGE_ASPECT, 18803f97578f1f51ffcb797a9feef4e5c8a600711a94Dave Houlton "IMAGE", str); 1881d81f107590290d41d3e39fcbf3f077658be0f5a6Mark Lobodzinski } 1882d81f107590290d41d3e39fcbf3f077658be0f5a6Mark Lobodzinski if (pRegions[i].dstSubresource.layerCount == 0) { 1883d81f107590290d41d3e39fcbf3f077658be0f5a6Mark Lobodzinski char const str[] = "vkCmdBlitImage: number of layers in destination subresource is zero"; 1884d81f107590290d41d3e39fcbf3f077658be0f5a6Mark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 18853f97578f1f51ffcb797a9feef4e5c8a600711a94Dave Houlton reinterpret_cast<uint64_t>(cb_node->commandBuffer), __LINE__, DRAWSTATE_MISMATCHED_IMAGE_ASPECT, 18863f97578f1f51ffcb797a9feef4e5c8a600711a94Dave Houlton "IMAGE", str); 1887d81f107590290d41d3e39fcbf3f077658be0f5a6Mark Lobodzinski } 1888d81f107590290d41d3e39fcbf3f077658be0f5a6Mark Lobodzinski 1889d81f107590290d41d3e39fcbf3f077658be0f5a6Mark Lobodzinski // Check that src/dst layercounts match 1890d81f107590290d41d3e39fcbf3f077658be0f5a6Mark Lobodzinski if (pRegions[i].srcSubresource.layerCount != pRegions[i].dstSubresource.layerCount) { 1891d81f107590290d41d3e39fcbf3f077658be0f5a6Mark Lobodzinski skip |= 1892d81f107590290d41d3e39fcbf3f077658be0f5a6Mark Lobodzinski log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 1893d81f107590290d41d3e39fcbf3f077658be0f5a6Mark Lobodzinski reinterpret_cast<uint64_t>(cb_node->commandBuffer), __LINE__, VALIDATION_ERROR_01304, "IMAGE", 1894d81f107590290d41d3e39fcbf3f077658be0f5a6Mark Lobodzinski "vkCmdBlitImage: layerCount in source and destination subresource of pRegions[%d] does not match. %s", 1895d81f107590290d41d3e39fcbf3f077658be0f5a6Mark Lobodzinski i, validation_error_map[VALIDATION_ERROR_01304]); 1896d81f107590290d41d3e39fcbf3f077658be0f5a6Mark Lobodzinski } 18978068cb0f90422b6789d0c120f0831f55eb76b71aMark Lobodzinski 18988068cb0f90422b6789d0c120f0831f55eb76b71aMark Lobodzinski if (pRegions[i].srcSubresource.aspectMask != pRegions[i].dstSubresource.aspectMask) { 18998068cb0f90422b6789d0c120f0831f55eb76b71aMark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 19008068cb0f90422b6789d0c120f0831f55eb76b71aMark Lobodzinski reinterpret_cast<uint64_t>(cb_node->commandBuffer), __LINE__, VALIDATION_ERROR_01303, "IMAGE", 19018068cb0f90422b6789d0c120f0831f55eb76b71aMark Lobodzinski "vkCmdBlitImage: aspectMask members for pRegion[%d] do not match. %s", i, 19028068cb0f90422b6789d0c120f0831f55eb76b71aMark Lobodzinski validation_error_map[VALIDATION_ERROR_01303]); 19038068cb0f90422b6789d0c120f0831f55eb76b71aMark Lobodzinski } 1904055112ec99304db71d55b69a60e1da14e8af8f60Mark Lobodzinski } 1905055112ec99304db71d55b69a60e1da14e8af8f60Mark Lobodzinski 1906055112ec99304db71d55b69a60e1da14e8af8f60Mark Lobodzinski VkFormat src_format = src_image_state->createInfo.format; 1907055112ec99304db71d55b69a60e1da14e8af8f60Mark Lobodzinski VkFormat dst_format = dst_image_state->createInfo.format; 1908055112ec99304db71d55b69a60e1da14e8af8f60Mark Lobodzinski 1909055112ec99304db71d55b69a60e1da14e8af8f60Mark Lobodzinski // Validate consistency for unsigned formats 191016769f6b2a7721e391952a97f010cbb530e4f211Dave Houlton if (FormatIsUInt(src_format) != FormatIsUInt(dst_format)) { 1911055112ec99304db71d55b69a60e1da14e8af8f60Mark Lobodzinski std::stringstream ss; 1912055112ec99304db71d55b69a60e1da14e8af8f60Mark Lobodzinski ss << "vkCmdBlitImage: If one of srcImage and dstImage images has unsigned integer format, " 1913055112ec99304db71d55b69a60e1da14e8af8f60Mark Lobodzinski << "the other one must also have unsigned integer format. " 1914055112ec99304db71d55b69a60e1da14e8af8f60Mark Lobodzinski << "Source format is " << string_VkFormat(src_format) << " Destination format is " << string_VkFormat(dst_format); 1915055112ec99304db71d55b69a60e1da14e8af8f60Mark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 1916055112ec99304db71d55b69a60e1da14e8af8f60Mark Lobodzinski reinterpret_cast<uint64_t>(cb_node->commandBuffer), __LINE__, VALIDATION_ERROR_02191, "IMAGE", "%s. %s", 1917055112ec99304db71d55b69a60e1da14e8af8f60Mark Lobodzinski ss.str().c_str(), validation_error_map[VALIDATION_ERROR_02191]); 1918055112ec99304db71d55b69a60e1da14e8af8f60Mark Lobodzinski } 1919055112ec99304db71d55b69a60e1da14e8af8f60Mark Lobodzinski 1920055112ec99304db71d55b69a60e1da14e8af8f60Mark Lobodzinski // Validate consistency for signed formats 192116769f6b2a7721e391952a97f010cbb530e4f211Dave Houlton if (FormatIsSInt(src_format) != FormatIsSInt(dst_format)) { 1922055112ec99304db71d55b69a60e1da14e8af8f60Mark Lobodzinski std::stringstream ss; 1923055112ec99304db71d55b69a60e1da14e8af8f60Mark Lobodzinski ss << "vkCmdBlitImage: If one of srcImage and dstImage images has signed integer format, " 1924055112ec99304db71d55b69a60e1da14e8af8f60Mark Lobodzinski << "the other one must also have signed integer format. " 1925055112ec99304db71d55b69a60e1da14e8af8f60Mark Lobodzinski << "Source format is " << string_VkFormat(src_format) << " Destination format is " << string_VkFormat(dst_format); 1926055112ec99304db71d55b69a60e1da14e8af8f60Mark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 1927055112ec99304db71d55b69a60e1da14e8af8f60Mark Lobodzinski reinterpret_cast<uint64_t>(cb_node->commandBuffer), __LINE__, VALIDATION_ERROR_02190, "IMAGE", "%s. %s", 1928055112ec99304db71d55b69a60e1da14e8af8f60Mark Lobodzinski ss.str().c_str(), validation_error_map[VALIDATION_ERROR_02190]); 1929055112ec99304db71d55b69a60e1da14e8af8f60Mark Lobodzinski } 1930055112ec99304db71d55b69a60e1da14e8af8f60Mark Lobodzinski 1931055112ec99304db71d55b69a60e1da14e8af8f60Mark Lobodzinski // Validate aspect bits and formats for depth/stencil images 193216769f6b2a7721e391952a97f010cbb530e4f211Dave Houlton if (FormatIsDepthOrStencil(src_format) || FormatIsDepthOrStencil(dst_format)) { 1933055112ec99304db71d55b69a60e1da14e8af8f60Mark Lobodzinski if (src_format != dst_format) { 1934055112ec99304db71d55b69a60e1da14e8af8f60Mark Lobodzinski std::stringstream ss; 1935055112ec99304db71d55b69a60e1da14e8af8f60Mark Lobodzinski ss << "vkCmdBlitImage: If one of srcImage and dstImage images has a format of depth, stencil or depth " 1936055112ec99304db71d55b69a60e1da14e8af8f60Mark Lobodzinski << "stencil, the other one must have exactly the same format. " 1937055112ec99304db71d55b69a60e1da14e8af8f60Mark Lobodzinski << "Source format is " << string_VkFormat(src_format) << " Destination format is " 1938055112ec99304db71d55b69a60e1da14e8af8f60Mark Lobodzinski << string_VkFormat(dst_format); 1939055112ec99304db71d55b69a60e1da14e8af8f60Mark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 1940055112ec99304db71d55b69a60e1da14e8af8f60Mark Lobodzinski reinterpret_cast<uint64_t>(cb_node->commandBuffer), __LINE__, VALIDATION_ERROR_02192, "IMAGE", 1941055112ec99304db71d55b69a60e1da14e8af8f60Mark Lobodzinski "%s. %s", ss.str().c_str(), validation_error_map[VALIDATION_ERROR_02192]); 1942055112ec99304db71d55b69a60e1da14e8af8f60Mark Lobodzinski } 1943055112ec99304db71d55b69a60e1da14e8af8f60Mark Lobodzinski 1944055112ec99304db71d55b69a60e1da14e8af8f60Mark Lobodzinski for (uint32_t i = 0; i < regionCount; i++) { 1945055112ec99304db71d55b69a60e1da14e8af8f60Mark Lobodzinski VkImageAspectFlags srcAspect = pRegions[i].srcSubresource.aspectMask; 1946055112ec99304db71d55b69a60e1da14e8af8f60Mark Lobodzinski 194716769f6b2a7721e391952a97f010cbb530e4f211Dave Houlton if (FormatIsDepthAndStencil(src_format)) { 1948055112ec99304db71d55b69a60e1da14e8af8f60Mark Lobodzinski if ((srcAspect != VK_IMAGE_ASPECT_DEPTH_BIT) && (srcAspect != VK_IMAGE_ASPECT_STENCIL_BIT)) { 1949055112ec99304db71d55b69a60e1da14e8af8f60Mark Lobodzinski std::stringstream ss; 1950055112ec99304db71d55b69a60e1da14e8af8f60Mark Lobodzinski ss << "vkCmdBlitImage: Combination depth/stencil image formats must have only one of " 1951055112ec99304db71d55b69a60e1da14e8af8f60Mark Lobodzinski "VK_IMAGE_ASPECT_DEPTH_BIT " 1952055112ec99304db71d55b69a60e1da14e8af8f60Mark Lobodzinski << "and VK_IMAGE_ASPECT_STENCIL_BIT set in srcImage and dstImage"; 1953055112ec99304db71d55b69a60e1da14e8af8f60Mark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 1954055112ec99304db71d55b69a60e1da14e8af8f60Mark Lobodzinski reinterpret_cast<uint64_t>(cb_node->commandBuffer), __LINE__, 1955055112ec99304db71d55b69a60e1da14e8af8f60Mark Lobodzinski DRAWSTATE_INVALID_IMAGE_ASPECT, "IMAGE", "%s", ss.str().c_str()); 1956055112ec99304db71d55b69a60e1da14e8af8f60Mark Lobodzinski } 195716769f6b2a7721e391952a97f010cbb530e4f211Dave Houlton } else if (FormatIsStencilOnly(src_format)) { 1958055112ec99304db71d55b69a60e1da14e8af8f60Mark Lobodzinski if (srcAspect != VK_IMAGE_ASPECT_STENCIL_BIT) { 1959055112ec99304db71d55b69a60e1da14e8af8f60Mark Lobodzinski std::stringstream ss; 1960055112ec99304db71d55b69a60e1da14e8af8f60Mark Lobodzinski ss << "vkCmdBlitImage: Stencil-only image formats must have only the VK_IMAGE_ASPECT_STENCIL_BIT " 1961055112ec99304db71d55b69a60e1da14e8af8f60Mark Lobodzinski << "set in both the srcImage and dstImage"; 1962055112ec99304db71d55b69a60e1da14e8af8f60Mark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 1963055112ec99304db71d55b69a60e1da14e8af8f60Mark Lobodzinski reinterpret_cast<uint64_t>(cb_node->commandBuffer), __LINE__, 1964055112ec99304db71d55b69a60e1da14e8af8f60Mark Lobodzinski DRAWSTATE_INVALID_IMAGE_ASPECT, "IMAGE", "%s", ss.str().c_str()); 1965055112ec99304db71d55b69a60e1da14e8af8f60Mark Lobodzinski } 196616769f6b2a7721e391952a97f010cbb530e4f211Dave Houlton } else if (FormatIsDepthOnly(src_format)) { 1967055112ec99304db71d55b69a60e1da14e8af8f60Mark Lobodzinski if (srcAspect != VK_IMAGE_ASPECT_DEPTH_BIT) { 1968055112ec99304db71d55b69a60e1da14e8af8f60Mark Lobodzinski std::stringstream ss; 1969055112ec99304db71d55b69a60e1da14e8af8f60Mark Lobodzinski ss << "vkCmdBlitImage: Depth-only image formats must have only the VK_IMAGE_ASPECT_DEPTH " 1970055112ec99304db71d55b69a60e1da14e8af8f60Mark Lobodzinski << "set in both the srcImage and dstImage"; 1971055112ec99304db71d55b69a60e1da14e8af8f60Mark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 1972055112ec99304db71d55b69a60e1da14e8af8f60Mark Lobodzinski reinterpret_cast<uint64_t>(cb_node->commandBuffer), __LINE__, 1973055112ec99304db71d55b69a60e1da14e8af8f60Mark Lobodzinski DRAWSTATE_INVALID_IMAGE_ASPECT, "IMAGE", "%s", ss.str().c_str()); 1974055112ec99304db71d55b69a60e1da14e8af8f60Mark Lobodzinski } 1975055112ec99304db71d55b69a60e1da14e8af8f60Mark Lobodzinski } 1976055112ec99304db71d55b69a60e1da14e8af8f60Mark Lobodzinski } 1977055112ec99304db71d55b69a60e1da14e8af8f60Mark Lobodzinski } 1978055112ec99304db71d55b69a60e1da14e8af8f60Mark Lobodzinski 1979055112ec99304db71d55b69a60e1da14e8af8f60Mark Lobodzinski // Validate filter 198016769f6b2a7721e391952a97f010cbb530e4f211Dave Houlton if (FormatIsDepthOrStencil(src_format) && (filter != VK_FILTER_NEAREST)) { 1981055112ec99304db71d55b69a60e1da14e8af8f60Mark Lobodzinski std::stringstream ss; 1982055112ec99304db71d55b69a60e1da14e8af8f60Mark Lobodzinski ss << "vkCmdBlitImage: If the format of srcImage is a depth, stencil, or depth stencil " 1983055112ec99304db71d55b69a60e1da14e8af8f60Mark Lobodzinski << "then filter must be VK_FILTER_NEAREST."; 1984055112ec99304db71d55b69a60e1da14e8af8f60Mark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 1985055112ec99304db71d55b69a60e1da14e8af8f60Mark Lobodzinski reinterpret_cast<uint64_t>(cb_node->commandBuffer), __LINE__, VALIDATION_ERROR_02193, "IMAGE", "%s. %s", 1986055112ec99304db71d55b69a60e1da14e8af8f60Mark Lobodzinski ss.str().c_str(), validation_error_map[VALIDATION_ERROR_02193]); 1987055112ec99304db71d55b69a60e1da14e8af8f60Mark Lobodzinski } 198860568995aca225f81acda8ce40cfabbea2c19397Mark Lobodzinski } else { 198960568995aca225f81acda8ce40cfabbea2c19397Mark Lobodzinski assert(0); 199060568995aca225f81acda8ce40cfabbea2c19397Mark Lobodzinski } 199160568995aca225f81acda8ce40cfabbea2c19397Mark Lobodzinski return skip; 199260568995aca225f81acda8ce40cfabbea2c19397Mark Lobodzinski} 199360568995aca225f81acda8ce40cfabbea2c19397Mark Lobodzinski 1994e40189d4deab674240cd9baf4c063bab4567c212Tobin Ehlisvoid PreCallRecordCmdBlitImage(layer_data *device_data, GLOBAL_CB_NODE *cb_node, IMAGE_STATE *src_image_state, 1995e40189d4deab674240cd9baf4c063bab4567c212Tobin Ehlis IMAGE_STATE *dst_image_state) { 199660568995aca225f81acda8ce40cfabbea2c19397Mark Lobodzinski // Update bindings between images and cmd buffer 199760568995aca225f81acda8ce40cfabbea2c19397Mark Lobodzinski AddCommandBufferBindingImage(device_data, cb_node, src_image_state); 199860568995aca225f81acda8ce40cfabbea2c19397Mark Lobodzinski AddCommandBufferBindingImage(device_data, cb_node, dst_image_state); 199960568995aca225f81acda8ce40cfabbea2c19397Mark Lobodzinski 200060568995aca225f81acda8ce40cfabbea2c19397Mark Lobodzinski std::function<bool()> function = [=]() { return ValidateImageMemoryIsValid(device_data, src_image_state, "vkCmdBlitImage()"); }; 200160568995aca225f81acda8ce40cfabbea2c19397Mark Lobodzinski cb_node->validate_functions.push_back(function); 200260568995aca225f81acda8ce40cfabbea2c19397Mark Lobodzinski function = [=]() { 200360568995aca225f81acda8ce40cfabbea2c19397Mark Lobodzinski SetImageMemoryValid(device_data, dst_image_state, true); 200460568995aca225f81acda8ce40cfabbea2c19397Mark Lobodzinski return false; 200560568995aca225f81acda8ce40cfabbea2c19397Mark Lobodzinski }; 200660568995aca225f81acda8ce40cfabbea2c19397Mark Lobodzinski cb_node->validate_functions.push_back(function); 20079a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis core_validation::UpdateCmdBufferLastCmd(cb_node, CMD_BLITIMAGE); 200860568995aca225f81acda8ce40cfabbea2c19397Mark Lobodzinski} 200960568995aca225f81acda8ce40cfabbea2c19397Mark Lobodzinski 201051920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour// This validates that the initial layout specified in the command buffer for 201151920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour// the IMAGE is the same 201251920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour// as the global IMAGE layout 2013440bdd357701497c3442e3515f12ac1cfffc180aTony Barbourbool ValidateCmdBufImageLayouts(layer_data *device_data, GLOBAL_CB_NODE *pCB, 2014440bdd357701497c3442e3515f12ac1cfffc180aTony Barbour std::unordered_map<ImageSubresourcePair, IMAGE_LAYOUT_NODE> &imageLayoutMap) { 201590e629846621a0d870212dc0cebfbc83431cc5b8Mark Lobodzinski bool skip = false; 201651920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour const debug_report_data *report_data = core_validation::GetReportData(device_data); 2017788ff59d81fc816f451414dcf2a9d6c29456ff63Mark Lobodzinski for (auto cb_image_data : pCB->imageLayoutMap) { 2018788ff59d81fc816f451414dcf2a9d6c29456ff63Mark Lobodzinski VkImageLayout imageLayout; 201951920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour 2020521b2f3957b3b31aeb2dbcc7529b54e06c9dc9ecJeremy Hayes if (FindLayout(imageLayoutMap, cb_image_data.first, imageLayout)) { 2021788ff59d81fc816f451414dcf2a9d6c29456ff63Mark Lobodzinski if (cb_image_data.second.initialLayout == VK_IMAGE_LAYOUT_UNDEFINED) { 2022788ff59d81fc816f451414dcf2a9d6c29456ff63Mark Lobodzinski // TODO: Set memory invalid which is in mem_tracker currently 2023788ff59d81fc816f451414dcf2a9d6c29456ff63Mark Lobodzinski } else if (imageLayout != cb_image_data.second.initialLayout) { 2024788ff59d81fc816f451414dcf2a9d6c29456ff63Mark Lobodzinski if (cb_image_data.first.hasSubresource) { 20253f97578f1f51ffcb797a9feef4e5c8a600711a94Dave Houlton skip |= log_msg( 20263f97578f1f51ffcb797a9feef4e5c8a600711a94Dave Houlton report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 20273f97578f1f51ffcb797a9feef4e5c8a600711a94Dave Houlton reinterpret_cast<uint64_t &>(pCB->commandBuffer), __LINE__, DRAWSTATE_INVALID_IMAGE_LAYOUT, "DS", 20283f97578f1f51ffcb797a9feef4e5c8a600711a94Dave Houlton "Cannot submit cmd buffer using image (0x%" PRIx64 20293f97578f1f51ffcb797a9feef4e5c8a600711a94Dave Houlton ") [sub-resource: aspectMask 0x%X array layer %u, mip level %u], " 20303f97578f1f51ffcb797a9feef4e5c8a600711a94Dave Houlton "with layout %s when first use is %s.", 20313f97578f1f51ffcb797a9feef4e5c8a600711a94Dave Houlton reinterpret_cast<const uint64_t &>(cb_image_data.first.image), cb_image_data.first.subresource.aspectMask, 20323f97578f1f51ffcb797a9feef4e5c8a600711a94Dave Houlton cb_image_data.first.subresource.arrayLayer, cb_image_data.first.subresource.mipLevel, 20333f97578f1f51ffcb797a9feef4e5c8a600711a94Dave Houlton string_VkImageLayout(imageLayout), string_VkImageLayout(cb_image_data.second.initialLayout)); 2034788ff59d81fc816f451414dcf2a9d6c29456ff63Mark Lobodzinski } else { 20353f97578f1f51ffcb797a9feef4e5c8a600711a94Dave Houlton skip |= 20363f97578f1f51ffcb797a9feef4e5c8a600711a94Dave Houlton log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 20373f97578f1f51ffcb797a9feef4e5c8a600711a94Dave Houlton reinterpret_cast<uint64_t &>(pCB->commandBuffer), __LINE__, DRAWSTATE_INVALID_IMAGE_LAYOUT, "DS", 20383f97578f1f51ffcb797a9feef4e5c8a600711a94Dave Houlton "Cannot submit cmd buffer using image (0x%" PRIx64 20393f97578f1f51ffcb797a9feef4e5c8a600711a94Dave Houlton ") with layout %s when " 20403f97578f1f51ffcb797a9feef4e5c8a600711a94Dave Houlton "first use is %s.", 20413f97578f1f51ffcb797a9feef4e5c8a600711a94Dave Houlton reinterpret_cast<const uint64_t &>(cb_image_data.first.image), string_VkImageLayout(imageLayout), 20423f97578f1f51ffcb797a9feef4e5c8a600711a94Dave Houlton string_VkImageLayout(cb_image_data.second.initialLayout)); 2043788ff59d81fc816f451414dcf2a9d6c29456ff63Mark Lobodzinski } 2044788ff59d81fc816f451414dcf2a9d6c29456ff63Mark Lobodzinski } 204551920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour SetLayout(imageLayoutMap, cb_image_data.first, cb_image_data.second.layout); 2046788ff59d81fc816f451414dcf2a9d6c29456ff63Mark Lobodzinski } 2047788ff59d81fc816f451414dcf2a9d6c29456ff63Mark Lobodzinski } 204890e629846621a0d870212dc0cebfbc83431cc5b8Mark Lobodzinski return skip; 2049788ff59d81fc816f451414dcf2a9d6c29456ff63Mark Lobodzinski} 2050940eb407cf288675f9bc7552dca723cd7028edacMark Lobodzinski 205151920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbourvoid UpdateCmdBufImageLayouts(layer_data *device_data, GLOBAL_CB_NODE *pCB) { 205251920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour for (auto cb_image_data : pCB->imageLayoutMap) { 205351920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour VkImageLayout imageLayout; 205451920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour FindGlobalLayout(device_data, cb_image_data.first, imageLayout); 205551920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour SetGlobalLayout(device_data, cb_image_data.first, cb_image_data.second.layout); 205651920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour } 205751920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour} 205851920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour 2059940eb407cf288675f9bc7552dca723cd7028edacMark Lobodzinski// Print readable FlagBits in FlagMask 2060940eb407cf288675f9bc7552dca723cd7028edacMark Lobodzinskistatic std::string string_VkAccessFlags(VkAccessFlags accessMask) { 2061940eb407cf288675f9bc7552dca723cd7028edacMark Lobodzinski std::string result; 2062940eb407cf288675f9bc7552dca723cd7028edacMark Lobodzinski std::string separator; 2063940eb407cf288675f9bc7552dca723cd7028edacMark Lobodzinski 2064940eb407cf288675f9bc7552dca723cd7028edacMark Lobodzinski if (accessMask == 0) { 2065940eb407cf288675f9bc7552dca723cd7028edacMark Lobodzinski result = "[None]"; 2066940eb407cf288675f9bc7552dca723cd7028edacMark Lobodzinski } else { 2067940eb407cf288675f9bc7552dca723cd7028edacMark Lobodzinski result = "["; 2068940eb407cf288675f9bc7552dca723cd7028edacMark Lobodzinski for (auto i = 0; i < 32; i++) { 2069940eb407cf288675f9bc7552dca723cd7028edacMark Lobodzinski if (accessMask & (1 << i)) { 2070940eb407cf288675f9bc7552dca723cd7028edacMark Lobodzinski result = result + separator + string_VkAccessFlagBits((VkAccessFlagBits)(1 << i)); 2071940eb407cf288675f9bc7552dca723cd7028edacMark Lobodzinski separator = " | "; 2072940eb407cf288675f9bc7552dca723cd7028edacMark Lobodzinski } 2073940eb407cf288675f9bc7552dca723cd7028edacMark Lobodzinski } 2074940eb407cf288675f9bc7552dca723cd7028edacMark Lobodzinski result = result + "]"; 2075940eb407cf288675f9bc7552dca723cd7028edacMark Lobodzinski } 2076940eb407cf288675f9bc7552dca723cd7028edacMark Lobodzinski return result; 2077940eb407cf288675f9bc7552dca723cd7028edacMark Lobodzinski} 2078940eb407cf288675f9bc7552dca723cd7028edacMark Lobodzinski 20798fefffdd7f4b8a91b65b50dedb70ad4be159e998Mark Lobodzinski// AccessFlags MUST have 'required_bit' set, and may have one or more of 'optional_bits' set. If required_bit is zero, accessMask 20808fefffdd7f4b8a91b65b50dedb70ad4be159e998Mark Lobodzinski// must have at least one of 'optional_bits' set 2081940eb407cf288675f9bc7552dca723cd7028edacMark Lobodzinski// TODO: Add tracking to ensure that at least one barrier has been set for these layout transitions 20828fefffdd7f4b8a91b65b50dedb70ad4be159e998Mark Lobodzinskistatic bool ValidateMaskBits(core_validation::layer_data *device_data, VkCommandBuffer cmdBuffer, const VkAccessFlags &accessMask, 20838fefffdd7f4b8a91b65b50dedb70ad4be159e998Mark Lobodzinski const VkImageLayout &layout, VkAccessFlags required_bit, VkAccessFlags optional_bits, 20848fefffdd7f4b8a91b65b50dedb70ad4be159e998Mark Lobodzinski const char *type) { 20858fefffdd7f4b8a91b65b50dedb70ad4be159e998Mark Lobodzinski const debug_report_data *report_data = core_validation::GetReportData(device_data); 20868fefffdd7f4b8a91b65b50dedb70ad4be159e998Mark Lobodzinski bool skip = false; 2087940eb407cf288675f9bc7552dca723cd7028edacMark Lobodzinski 2088940eb407cf288675f9bc7552dca723cd7028edacMark Lobodzinski if ((accessMask & required_bit) || (!required_bit && (accessMask & optional_bits))) { 2089940eb407cf288675f9bc7552dca723cd7028edacMark Lobodzinski if (accessMask & ~(required_bit | optional_bits)) { 2090940eb407cf288675f9bc7552dca723cd7028edacMark Lobodzinski // TODO: Verify against Valid Use 2091fdc75c21ced997fbbc180734bef87bf6d5811d4bMark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 2092fdc75c21ced997fbbc180734bef87bf6d5811d4bMark Lobodzinski reinterpret_cast<uint64_t>(cmdBuffer), __LINE__, DRAWSTATE_INVALID_BARRIER, "DS", 20938fefffdd7f4b8a91b65b50dedb70ad4be159e998Mark Lobodzinski "Additional bits in %s accessMask 0x%X %s are specified when layout is %s.", type, accessMask, 20948fefffdd7f4b8a91b65b50dedb70ad4be159e998Mark Lobodzinski string_VkAccessFlags(accessMask).c_str(), string_VkImageLayout(layout)); 2095940eb407cf288675f9bc7552dca723cd7028edacMark Lobodzinski } 2096940eb407cf288675f9bc7552dca723cd7028edacMark Lobodzinski } else { 2097940eb407cf288675f9bc7552dca723cd7028edacMark Lobodzinski if (!required_bit) { 2098fdc75c21ced997fbbc180734bef87bf6d5811d4bMark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 2099fdc75c21ced997fbbc180734bef87bf6d5811d4bMark Lobodzinski reinterpret_cast<uint64_t>(cmdBuffer), __LINE__, DRAWSTATE_INVALID_BARRIER, "DS", 21008fefffdd7f4b8a91b65b50dedb70ad4be159e998Mark Lobodzinski "%s AccessMask %d %s must contain at least one of access bits %d " 21018fefffdd7f4b8a91b65b50dedb70ad4be159e998Mark Lobodzinski "%s when layout is %s, unless the app has previously added a " 21028fefffdd7f4b8a91b65b50dedb70ad4be159e998Mark Lobodzinski "barrier for this transition.", 21038fefffdd7f4b8a91b65b50dedb70ad4be159e998Mark Lobodzinski type, accessMask, string_VkAccessFlags(accessMask).c_str(), optional_bits, 21048fefffdd7f4b8a91b65b50dedb70ad4be159e998Mark Lobodzinski string_VkAccessFlags(optional_bits).c_str(), string_VkImageLayout(layout)); 2105940eb407cf288675f9bc7552dca723cd7028edacMark Lobodzinski } else { 2106940eb407cf288675f9bc7552dca723cd7028edacMark Lobodzinski std::string opt_bits; 2107940eb407cf288675f9bc7552dca723cd7028edacMark Lobodzinski if (optional_bits != 0) { 2108940eb407cf288675f9bc7552dca723cd7028edacMark Lobodzinski std::stringstream ss; 2109940eb407cf288675f9bc7552dca723cd7028edacMark Lobodzinski ss << optional_bits; 2110940eb407cf288675f9bc7552dca723cd7028edacMark Lobodzinski opt_bits = "and may have optional bits " + ss.str() + ' ' + string_VkAccessFlags(optional_bits); 2111940eb407cf288675f9bc7552dca723cd7028edacMark Lobodzinski } 2112fdc75c21ced997fbbc180734bef87bf6d5811d4bMark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 2113fdc75c21ced997fbbc180734bef87bf6d5811d4bMark Lobodzinski reinterpret_cast<uint64_t>(cmdBuffer), __LINE__, DRAWSTATE_INVALID_BARRIER, "DS", 21148fefffdd7f4b8a91b65b50dedb70ad4be159e998Mark Lobodzinski "%s AccessMask %d %s must have required access bit %d %s %s when " 21158fefffdd7f4b8a91b65b50dedb70ad4be159e998Mark Lobodzinski "layout is %s, unless the app has previously added a barrier for " 21168fefffdd7f4b8a91b65b50dedb70ad4be159e998Mark Lobodzinski "this transition.", 21178fefffdd7f4b8a91b65b50dedb70ad4be159e998Mark Lobodzinski type, accessMask, string_VkAccessFlags(accessMask).c_str(), required_bit, 21188fefffdd7f4b8a91b65b50dedb70ad4be159e998Mark Lobodzinski string_VkAccessFlags(required_bit).c_str(), opt_bits.c_str(), string_VkImageLayout(layout)); 2119940eb407cf288675f9bc7552dca723cd7028edacMark Lobodzinski } 2120940eb407cf288675f9bc7552dca723cd7028edacMark Lobodzinski } 21218fefffdd7f4b8a91b65b50dedb70ad4be159e998Mark Lobodzinski return skip; 2122940eb407cf288675f9bc7552dca723cd7028edacMark Lobodzinski} 2123940eb407cf288675f9bc7552dca723cd7028edacMark Lobodzinski 21248fefffdd7f4b8a91b65b50dedb70ad4be159e998Mark Lobodzinskibool ValidateMaskBitsFromLayouts(core_validation::layer_data *device_data, VkCommandBuffer cmdBuffer, 21258fefffdd7f4b8a91b65b50dedb70ad4be159e998Mark Lobodzinski const VkAccessFlags &accessMask, const VkImageLayout &layout, const char *type) { 21268fefffdd7f4b8a91b65b50dedb70ad4be159e998Mark Lobodzinski const debug_report_data *report_data = core_validation::GetReportData(device_data); 2127940eb407cf288675f9bc7552dca723cd7028edacMark Lobodzinski 21288fefffdd7f4b8a91b65b50dedb70ad4be159e998Mark Lobodzinski bool skip = false; 2129940eb407cf288675f9bc7552dca723cd7028edacMark Lobodzinski switch (layout) { 21308fefffdd7f4b8a91b65b50dedb70ad4be159e998Mark Lobodzinski case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL: { 21318fefffdd7f4b8a91b65b50dedb70ad4be159e998Mark Lobodzinski skip |= ValidateMaskBits(device_data, cmdBuffer, accessMask, layout, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, 21328fefffdd7f4b8a91b65b50dedb70ad4be159e998Mark Lobodzinski VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_INPUT_ATTACHMENT_READ_BIT, type); 21338fefffdd7f4b8a91b65b50dedb70ad4be159e998Mark Lobodzinski break; 2134940eb407cf288675f9bc7552dca723cd7028edacMark Lobodzinski } 21358fefffdd7f4b8a91b65b50dedb70ad4be159e998Mark Lobodzinski case VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL: { 21368fefffdd7f4b8a91b65b50dedb70ad4be159e998Mark Lobodzinski skip |= ValidateMaskBits(device_data, cmdBuffer, accessMask, layout, VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, 21378fefffdd7f4b8a91b65b50dedb70ad4be159e998Mark Lobodzinski VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_INPUT_ATTACHMENT_READ_BIT, type); 21388fefffdd7f4b8a91b65b50dedb70ad4be159e998Mark Lobodzinski break; 21398fefffdd7f4b8a91b65b50dedb70ad4be159e998Mark Lobodzinski } 21408fefffdd7f4b8a91b65b50dedb70ad4be159e998Mark Lobodzinski case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL: { 21418fefffdd7f4b8a91b65b50dedb70ad4be159e998Mark Lobodzinski skip |= ValidateMaskBits(device_data, cmdBuffer, accessMask, layout, VK_ACCESS_TRANSFER_WRITE_BIT, 0, type); 21428fefffdd7f4b8a91b65b50dedb70ad4be159e998Mark Lobodzinski break; 21438fefffdd7f4b8a91b65b50dedb70ad4be159e998Mark Lobodzinski } 21448fefffdd7f4b8a91b65b50dedb70ad4be159e998Mark Lobodzinski case VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL: { 21458fefffdd7f4b8a91b65b50dedb70ad4be159e998Mark Lobodzinski skip |= ValidateMaskBits( 21468fefffdd7f4b8a91b65b50dedb70ad4be159e998Mark Lobodzinski device_data, cmdBuffer, accessMask, layout, 0, 21478fefffdd7f4b8a91b65b50dedb70ad4be159e998Mark Lobodzinski VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_INPUT_ATTACHMENT_READ_BIT, 21488fefffdd7f4b8a91b65b50dedb70ad4be159e998Mark Lobodzinski type); 21498fefffdd7f4b8a91b65b50dedb70ad4be159e998Mark Lobodzinski break; 21508fefffdd7f4b8a91b65b50dedb70ad4be159e998Mark Lobodzinski } 21518fefffdd7f4b8a91b65b50dedb70ad4be159e998Mark Lobodzinski case VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL: { 21528fefffdd7f4b8a91b65b50dedb70ad4be159e998Mark Lobodzinski skip |= ValidateMaskBits(device_data, cmdBuffer, accessMask, layout, 0, 21538fefffdd7f4b8a91b65b50dedb70ad4be159e998Mark Lobodzinski VK_ACCESS_INPUT_ATTACHMENT_READ_BIT | VK_ACCESS_SHADER_READ_BIT, type); 21548fefffdd7f4b8a91b65b50dedb70ad4be159e998Mark Lobodzinski break; 21558fefffdd7f4b8a91b65b50dedb70ad4be159e998Mark Lobodzinski } 21568fefffdd7f4b8a91b65b50dedb70ad4be159e998Mark Lobodzinski case VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL: { 21578fefffdd7f4b8a91b65b50dedb70ad4be159e998Mark Lobodzinski skip |= ValidateMaskBits(device_data, cmdBuffer, accessMask, layout, VK_ACCESS_TRANSFER_READ_BIT, 0, type); 21588fefffdd7f4b8a91b65b50dedb70ad4be159e998Mark Lobodzinski break; 21598fefffdd7f4b8a91b65b50dedb70ad4be159e998Mark Lobodzinski } 21608fefffdd7f4b8a91b65b50dedb70ad4be159e998Mark Lobodzinski case VK_IMAGE_LAYOUT_UNDEFINED: { 21618fefffdd7f4b8a91b65b50dedb70ad4be159e998Mark Lobodzinski if (accessMask != 0) { 21628fefffdd7f4b8a91b65b50dedb70ad4be159e998Mark Lobodzinski // TODO: Verify against Valid Use section spec 2163fdc75c21ced997fbbc180734bef87bf6d5811d4bMark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 2164fdc75c21ced997fbbc180734bef87bf6d5811d4bMark Lobodzinski reinterpret_cast<uint64_t>(cmdBuffer), __LINE__, DRAWSTATE_INVALID_BARRIER, "DS", 21658fefffdd7f4b8a91b65b50dedb70ad4be159e998Mark Lobodzinski "Additional bits in %s accessMask 0x%X %s are specified when layout is %s.", type, accessMask, 21668fefffdd7f4b8a91b65b50dedb70ad4be159e998Mark Lobodzinski string_VkAccessFlags(accessMask).c_str(), string_VkImageLayout(layout)); 21678fefffdd7f4b8a91b65b50dedb70ad4be159e998Mark Lobodzinski } 21688fefffdd7f4b8a91b65b50dedb70ad4be159e998Mark Lobodzinski break; 21698fefffdd7f4b8a91b65b50dedb70ad4be159e998Mark Lobodzinski } 21706e3442c40be4c735b830775a753bb449c331e15dChris Forbes case VK_IMAGE_LAYOUT_PRESENT_SRC_KHR: 2171cf2ce8673669ca1111e333bdea272c4dd57cb5c2Dave Houlton // Notes: QueuePresentKHR performs automatic visibility operations, 2172cf2ce8673669ca1111e333bdea272c4dd57cb5c2Dave Houlton // so the app is /NOT/ required to include VK_ACCESS_MEMORY_READ_BIT 2173cf2ce8673669ca1111e333bdea272c4dd57cb5c2Dave Houlton // when transitioning to this layout. 2174cf2ce8673669ca1111e333bdea272c4dd57cb5c2Dave Houlton // 2175cf2ce8673669ca1111e333bdea272c4dd57cb5c2Dave Houlton // When transitioning /from/ this layout, the application needs to 2176cf2ce8673669ca1111e333bdea272c4dd57cb5c2Dave Houlton // avoid only a WAR hazard -- any writes need to be ordered after 2177cf2ce8673669ca1111e333bdea272c4dd57cb5c2Dave Houlton // the PE's reads. There is no need for a memory dependency for this 2178cf2ce8673669ca1111e333bdea272c4dd57cb5c2Dave Houlton // case. 2179cf2ce8673669ca1111e333bdea272c4dd57cb5c2Dave Houlton /* fallthrough */ 21806e3442c40be4c735b830775a753bb449c331e15dChris Forbes 21818fefffdd7f4b8a91b65b50dedb70ad4be159e998Mark Lobodzinski case VK_IMAGE_LAYOUT_GENERAL: 21828fefffdd7f4b8a91b65b50dedb70ad4be159e998Mark Lobodzinski default: { break; } 2183940eb407cf288675f9bc7552dca723cd7028edacMark Lobodzinski } 21848fefffdd7f4b8a91b65b50dedb70ad4be159e998Mark Lobodzinski return skip; 2185940eb407cf288675f9bc7552dca723cd7028edacMark Lobodzinski} 2186d76960c655c53f47aaf2e16538ea0c40e6d527ecMark Lobodzinski 2187d76960c655c53f47aaf2e16538ea0c40e6d527ecMark Lobodzinski// ValidateLayoutVsAttachmentDescription is a general function where we can validate various state associated with the 2188374d6151f9db5d62891ffdbe833bcbb51848db6bMark Lobodzinski// VkAttachmentDescription structs that are used by the sub-passes of a renderpass. Initial check is to make sure that READ_ONLY 2189374d6151f9db5d62891ffdbe833bcbb51848db6bMark Lobodzinski// layout attachments don't have CLEAR as their loadOp. 2190d76960c655c53f47aaf2e16538ea0c40e6d527ecMark Lobodzinskibool ValidateLayoutVsAttachmentDescription(const debug_report_data *report_data, const VkImageLayout first_layout, 2191374d6151f9db5d62891ffdbe833bcbb51848db6bMark Lobodzinski const uint32_t attachment, const VkAttachmentDescription &attachment_description) { 2192374d6151f9db5d62891ffdbe833bcbb51848db6bMark Lobodzinski bool skip = false; 2193d76960c655c53f47aaf2e16538ea0c40e6d527ecMark Lobodzinski // Verify that initial loadOp on READ_ONLY attachments is not CLEAR 2194d76960c655c53f47aaf2e16538ea0c40e6d527ecMark Lobodzinski if (attachment_description.loadOp == VK_ATTACHMENT_LOAD_OP_CLEAR) { 2195d76960c655c53f47aaf2e16538ea0c40e6d527ecMark Lobodzinski if ((first_layout == VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL) || 2196d76960c655c53f47aaf2e16538ea0c40e6d527ecMark Lobodzinski (first_layout == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL)) { 21975b9ab1fb8720c30edfbe8dd974e2364425471ad5Mark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, 21985b9ab1fb8720c30edfbe8dd974e2364425471ad5Mark Lobodzinski VALIDATION_ERROR_02351, "DS", "Cannot clear attachment %d with invalid first layout %s. %s", attachment, 2199374d6151f9db5d62891ffdbe833bcbb51848db6bMark Lobodzinski string_VkImageLayout(first_layout), validation_error_map[VALIDATION_ERROR_02351]); 2200d76960c655c53f47aaf2e16538ea0c40e6d527ecMark Lobodzinski } 2201d76960c655c53f47aaf2e16538ea0c40e6d527ecMark Lobodzinski } 2202374d6151f9db5d62891ffdbe833bcbb51848db6bMark Lobodzinski return skip; 2203d76960c655c53f47aaf2e16538ea0c40e6d527ecMark Lobodzinski} 2204d76960c655c53f47aaf2e16538ea0c40e6d527ecMark Lobodzinski 2205374d6151f9db5d62891ffdbe833bcbb51848db6bMark Lobodzinskibool ValidateLayouts(core_validation::layer_data *device_data, VkDevice device, const VkRenderPassCreateInfo *pCreateInfo) { 2206374d6151f9db5d62891ffdbe833bcbb51848db6bMark Lobodzinski const debug_report_data *report_data = core_validation::GetReportData(device_data); 2207d76960c655c53f47aaf2e16538ea0c40e6d527ecMark Lobodzinski bool skip = false; 2208d76960c655c53f47aaf2e16538ea0c40e6d527ecMark Lobodzinski 2209d76960c655c53f47aaf2e16538ea0c40e6d527ecMark Lobodzinski // Track when we're observing the first use of an attachment 2210d76960c655c53f47aaf2e16538ea0c40e6d527ecMark Lobodzinski std::vector<bool> attach_first_use(pCreateInfo->attachmentCount, true); 2211d76960c655c53f47aaf2e16538ea0c40e6d527ecMark Lobodzinski for (uint32_t i = 0; i < pCreateInfo->subpassCount; ++i) { 2212d76960c655c53f47aaf2e16538ea0c40e6d527ecMark Lobodzinski const VkSubpassDescription &subpass = pCreateInfo->pSubpasses[i]; 2213d76960c655c53f47aaf2e16538ea0c40e6d527ecMark Lobodzinski for (uint32_t j = 0; j < subpass.colorAttachmentCount; ++j) { 2214d76960c655c53f47aaf2e16538ea0c40e6d527ecMark Lobodzinski auto attach_index = subpass.pColorAttachments[j].attachment; 2215d76960c655c53f47aaf2e16538ea0c40e6d527ecMark Lobodzinski if (attach_index == VK_ATTACHMENT_UNUSED) continue; 2216d76960c655c53f47aaf2e16538ea0c40e6d527ecMark Lobodzinski 2217d76960c655c53f47aaf2e16538ea0c40e6d527ecMark Lobodzinski switch (subpass.pColorAttachments[j].layout) { 2218374d6151f9db5d62891ffdbe833bcbb51848db6bMark Lobodzinski case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL: 2219374d6151f9db5d62891ffdbe833bcbb51848db6bMark Lobodzinski // This is ideal. 2220374d6151f9db5d62891ffdbe833bcbb51848db6bMark Lobodzinski break; 2221d76960c655c53f47aaf2e16538ea0c40e6d527ecMark Lobodzinski 2222374d6151f9db5d62891ffdbe833bcbb51848db6bMark Lobodzinski case VK_IMAGE_LAYOUT_GENERAL: 2223374d6151f9db5d62891ffdbe833bcbb51848db6bMark Lobodzinski // May not be optimal; TODO: reconsider this warning based on other constraints? 2224374d6151f9db5d62891ffdbe833bcbb51848db6bMark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT, 2225374d6151f9db5d62891ffdbe833bcbb51848db6bMark Lobodzinski VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, DRAWSTATE_INVALID_IMAGE_LAYOUT, "DS", 2226374d6151f9db5d62891ffdbe833bcbb51848db6bMark Lobodzinski "Layout for color attachment is GENERAL but should be COLOR_ATTACHMENT_OPTIMAL."); 2227374d6151f9db5d62891ffdbe833bcbb51848db6bMark Lobodzinski break; 2228374d6151f9db5d62891ffdbe833bcbb51848db6bMark Lobodzinski 2229374d6151f9db5d62891ffdbe833bcbb51848db6bMark Lobodzinski default: 2230374d6151f9db5d62891ffdbe833bcbb51848db6bMark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, 2231374d6151f9db5d62891ffdbe833bcbb51848db6bMark Lobodzinski __LINE__, DRAWSTATE_INVALID_IMAGE_LAYOUT, "DS", 2232374d6151f9db5d62891ffdbe833bcbb51848db6bMark Lobodzinski "Layout for color attachment is %s but can only be COLOR_ATTACHMENT_OPTIMAL or GENERAL.", 2233374d6151f9db5d62891ffdbe833bcbb51848db6bMark Lobodzinski string_VkImageLayout(subpass.pColorAttachments[j].layout)); 2234d76960c655c53f47aaf2e16538ea0c40e6d527ecMark Lobodzinski } 2235d76960c655c53f47aaf2e16538ea0c40e6d527ecMark Lobodzinski 2236d76960c655c53f47aaf2e16538ea0c40e6d527ecMark Lobodzinski if (attach_first_use[attach_index]) { 2237374d6151f9db5d62891ffdbe833bcbb51848db6bMark Lobodzinski skip |= ValidateLayoutVsAttachmentDescription(report_data, subpass.pColorAttachments[j].layout, attach_index, 2238374d6151f9db5d62891ffdbe833bcbb51848db6bMark Lobodzinski pCreateInfo->pAttachments[attach_index]); 2239d76960c655c53f47aaf2e16538ea0c40e6d527ecMark Lobodzinski } 2240d76960c655c53f47aaf2e16538ea0c40e6d527ecMark Lobodzinski attach_first_use[attach_index] = false; 2241d76960c655c53f47aaf2e16538ea0c40e6d527ecMark Lobodzinski } 2242d76960c655c53f47aaf2e16538ea0c40e6d527ecMark Lobodzinski if (subpass.pDepthStencilAttachment && subpass.pDepthStencilAttachment->attachment != VK_ATTACHMENT_UNUSED) { 2243d76960c655c53f47aaf2e16538ea0c40e6d527ecMark Lobodzinski switch (subpass.pDepthStencilAttachment->layout) { 2244374d6151f9db5d62891ffdbe833bcbb51848db6bMark Lobodzinski case VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL: 2245374d6151f9db5d62891ffdbe833bcbb51848db6bMark Lobodzinski case VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL: 2246374d6151f9db5d62891ffdbe833bcbb51848db6bMark Lobodzinski // These are ideal. 2247374d6151f9db5d62891ffdbe833bcbb51848db6bMark Lobodzinski break; 2248374d6151f9db5d62891ffdbe833bcbb51848db6bMark Lobodzinski 2249374d6151f9db5d62891ffdbe833bcbb51848db6bMark Lobodzinski case VK_IMAGE_LAYOUT_GENERAL: 2250374d6151f9db5d62891ffdbe833bcbb51848db6bMark Lobodzinski // May not be optimal; TODO: reconsider this warning based on other constraints? GENERAL can be better than 2251374d6151f9db5d62891ffdbe833bcbb51848db6bMark Lobodzinski // doing a bunch of transitions. 2252374d6151f9db5d62891ffdbe833bcbb51848db6bMark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT, 2253374d6151f9db5d62891ffdbe833bcbb51848db6bMark Lobodzinski VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, DRAWSTATE_INVALID_IMAGE_LAYOUT, "DS", 2254374d6151f9db5d62891ffdbe833bcbb51848db6bMark Lobodzinski "GENERAL layout for depth attachment may not give optimal performance."); 2255374d6151f9db5d62891ffdbe833bcbb51848db6bMark Lobodzinski break; 2256374d6151f9db5d62891ffdbe833bcbb51848db6bMark Lobodzinski 2257374d6151f9db5d62891ffdbe833bcbb51848db6bMark Lobodzinski default: 2258374d6151f9db5d62891ffdbe833bcbb51848db6bMark Lobodzinski // No other layouts are acceptable 2259374d6151f9db5d62891ffdbe833bcbb51848db6bMark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, 2260374d6151f9db5d62891ffdbe833bcbb51848db6bMark Lobodzinski __LINE__, DRAWSTATE_INVALID_IMAGE_LAYOUT, "DS", 2261374d6151f9db5d62891ffdbe833bcbb51848db6bMark Lobodzinski "Layout for depth attachment is %s but can only be DEPTH_STENCIL_ATTACHMENT_OPTIMAL, " 2262374d6151f9db5d62891ffdbe833bcbb51848db6bMark Lobodzinski "DEPTH_STENCIL_READ_ONLY_OPTIMAL or GENERAL.", 2263374d6151f9db5d62891ffdbe833bcbb51848db6bMark Lobodzinski string_VkImageLayout(subpass.pDepthStencilAttachment->layout)); 2264d76960c655c53f47aaf2e16538ea0c40e6d527ecMark Lobodzinski } 2265d76960c655c53f47aaf2e16538ea0c40e6d527ecMark Lobodzinski 2266d76960c655c53f47aaf2e16538ea0c40e6d527ecMark Lobodzinski auto attach_index = subpass.pDepthStencilAttachment->attachment; 2267d76960c655c53f47aaf2e16538ea0c40e6d527ecMark Lobodzinski if (attach_first_use[attach_index]) { 2268374d6151f9db5d62891ffdbe833bcbb51848db6bMark Lobodzinski skip |= ValidateLayoutVsAttachmentDescription(report_data, subpass.pDepthStencilAttachment->layout, attach_index, 2269374d6151f9db5d62891ffdbe833bcbb51848db6bMark Lobodzinski pCreateInfo->pAttachments[attach_index]); 2270d76960c655c53f47aaf2e16538ea0c40e6d527ecMark Lobodzinski } 2271d76960c655c53f47aaf2e16538ea0c40e6d527ecMark Lobodzinski attach_first_use[attach_index] = false; 2272d76960c655c53f47aaf2e16538ea0c40e6d527ecMark Lobodzinski } 2273d76960c655c53f47aaf2e16538ea0c40e6d527ecMark Lobodzinski for (uint32_t j = 0; j < subpass.inputAttachmentCount; ++j) { 2274d76960c655c53f47aaf2e16538ea0c40e6d527ecMark Lobodzinski auto attach_index = subpass.pInputAttachments[j].attachment; 2275d76960c655c53f47aaf2e16538ea0c40e6d527ecMark Lobodzinski if (attach_index == VK_ATTACHMENT_UNUSED) continue; 2276d76960c655c53f47aaf2e16538ea0c40e6d527ecMark Lobodzinski 2277d76960c655c53f47aaf2e16538ea0c40e6d527ecMark Lobodzinski switch (subpass.pInputAttachments[j].layout) { 2278374d6151f9db5d62891ffdbe833bcbb51848db6bMark Lobodzinski case VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL: 2279374d6151f9db5d62891ffdbe833bcbb51848db6bMark Lobodzinski case VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL: 2280374d6151f9db5d62891ffdbe833bcbb51848db6bMark Lobodzinski // These are ideal. 2281374d6151f9db5d62891ffdbe833bcbb51848db6bMark Lobodzinski break; 2282d76960c655c53f47aaf2e16538ea0c40e6d527ecMark Lobodzinski 2283374d6151f9db5d62891ffdbe833bcbb51848db6bMark Lobodzinski case VK_IMAGE_LAYOUT_GENERAL: 2284374d6151f9db5d62891ffdbe833bcbb51848db6bMark Lobodzinski // May not be optimal. TODO: reconsider this warning based on other constraints. 2285374d6151f9db5d62891ffdbe833bcbb51848db6bMark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT, 2286374d6151f9db5d62891ffdbe833bcbb51848db6bMark Lobodzinski VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, DRAWSTATE_INVALID_IMAGE_LAYOUT, "DS", 2287374d6151f9db5d62891ffdbe833bcbb51848db6bMark Lobodzinski "Layout for input attachment is GENERAL but should be READ_ONLY_OPTIMAL."); 2288374d6151f9db5d62891ffdbe833bcbb51848db6bMark Lobodzinski break; 2289374d6151f9db5d62891ffdbe833bcbb51848db6bMark Lobodzinski 2290374d6151f9db5d62891ffdbe833bcbb51848db6bMark Lobodzinski default: 2291374d6151f9db5d62891ffdbe833bcbb51848db6bMark Lobodzinski // No other layouts are acceptable 2292fdc75c21ced997fbbc180734bef87bf6d5811d4bMark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, 2293fdc75c21ced997fbbc180734bef87bf6d5811d4bMark Lobodzinski __LINE__, DRAWSTATE_INVALID_IMAGE_LAYOUT, "DS", 2294374d6151f9db5d62891ffdbe833bcbb51848db6bMark Lobodzinski "Layout for input attachment is %s but can only be READ_ONLY_OPTIMAL or GENERAL.", 2295374d6151f9db5d62891ffdbe833bcbb51848db6bMark Lobodzinski string_VkImageLayout(subpass.pInputAttachments[j].layout)); 2296d76960c655c53f47aaf2e16538ea0c40e6d527ecMark Lobodzinski } 2297d76960c655c53f47aaf2e16538ea0c40e6d527ecMark Lobodzinski 2298d76960c655c53f47aaf2e16538ea0c40e6d527ecMark Lobodzinski if (attach_first_use[attach_index]) { 2299374d6151f9db5d62891ffdbe833bcbb51848db6bMark Lobodzinski skip |= ValidateLayoutVsAttachmentDescription(report_data, subpass.pInputAttachments[j].layout, attach_index, 2300374d6151f9db5d62891ffdbe833bcbb51848db6bMark Lobodzinski pCreateInfo->pAttachments[attach_index]); 2301d76960c655c53f47aaf2e16538ea0c40e6d527ecMark Lobodzinski } 2302d76960c655c53f47aaf2e16538ea0c40e6d527ecMark Lobodzinski attach_first_use[attach_index] = false; 2303d76960c655c53f47aaf2e16538ea0c40e6d527ecMark Lobodzinski } 2304d76960c655c53f47aaf2e16538ea0c40e6d527ecMark Lobodzinski } 2305d76960c655c53f47aaf2e16538ea0c40e6d527ecMark Lobodzinski return skip; 2306d76960c655c53f47aaf2e16538ea0c40e6d527ecMark Lobodzinski} 2307c3340a06ecac4d7b9540592cae339f8fc224d0b1Mark Lobodzinski 2308c3340a06ecac4d7b9540592cae339f8fc224d0b1Mark Lobodzinski// For any image objects that overlap mapped memory, verify that their layouts are PREINIT or GENERAL 230909cd2c76808f1485206baeda9864f7ed907d7e05Mark Lobodzinskibool ValidateMapImageLayouts(core_validation::layer_data *device_data, VkDevice device, DEVICE_MEM_INFO const *mem_info, 231009cd2c76808f1485206baeda9864f7ed907d7e05Mark Lobodzinski VkDeviceSize offset, VkDeviceSize end_offset) { 231109cd2c76808f1485206baeda9864f7ed907d7e05Mark Lobodzinski const debug_report_data *report_data = core_validation::GetReportData(device_data); 231209cd2c76808f1485206baeda9864f7ed907d7e05Mark Lobodzinski bool skip = false; 231309cd2c76808f1485206baeda9864f7ed907d7e05Mark Lobodzinski // Iterate over all bound image ranges and verify that for any that overlap the map ranges, the layouts are 231409cd2c76808f1485206baeda9864f7ed907d7e05Mark Lobodzinski // VK_IMAGE_LAYOUT_PREINITIALIZED or VK_IMAGE_LAYOUT_GENERAL 2315c3340a06ecac4d7b9540592cae339f8fc224d0b1Mark Lobodzinski // TODO : This can be optimized if we store ranges based on starting address and early exit when we pass our range 2316c3340a06ecac4d7b9540592cae339f8fc224d0b1Mark Lobodzinski for (auto image_handle : mem_info->bound_images) { 2317c3340a06ecac4d7b9540592cae339f8fc224d0b1Mark Lobodzinski auto img_it = mem_info->bound_ranges.find(image_handle); 2318c3340a06ecac4d7b9540592cae339f8fc224d0b1Mark Lobodzinski if (img_it != mem_info->bound_ranges.end()) { 231909cd2c76808f1485206baeda9864f7ed907d7e05Mark Lobodzinski if (rangesIntersect(device_data, &img_it->second, offset, end_offset)) { 2320c3340a06ecac4d7b9540592cae339f8fc224d0b1Mark Lobodzinski std::vector<VkImageLayout> layouts; 232109cd2c76808f1485206baeda9864f7ed907d7e05Mark Lobodzinski if (FindLayouts(device_data, VkImage(image_handle), layouts)) { 2322c3340a06ecac4d7b9540592cae339f8fc224d0b1Mark Lobodzinski for (auto layout : layouts) { 2323c3340a06ecac4d7b9540592cae339f8fc224d0b1Mark Lobodzinski if (layout != VK_IMAGE_LAYOUT_PREINITIALIZED && layout != VK_IMAGE_LAYOUT_GENERAL) { 2324fdc75c21ced997fbbc180734bef87bf6d5811d4bMark Lobodzinski skip |= log_msg( 2325fdc75c21ced997fbbc180734bef87bf6d5811d4bMark Lobodzinski report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT, 2326fdc75c21ced997fbbc180734bef87bf6d5811d4bMark Lobodzinski reinterpret_cast<const uint64_t &>(mem_info->mem), __LINE__, DRAWSTATE_INVALID_IMAGE_LAYOUT, "DS", 2327fdc75c21ced997fbbc180734bef87bf6d5811d4bMark Lobodzinski "Mapping an image with layout %s can result in undefined behavior if this memory is " 2328fdc75c21ced997fbbc180734bef87bf6d5811d4bMark Lobodzinski "used by the device. Only GENERAL or PREINITIALIZED should be used.", 2329fdc75c21ced997fbbc180734bef87bf6d5811d4bMark Lobodzinski string_VkImageLayout(layout)); 2330c3340a06ecac4d7b9540592cae339f8fc224d0b1Mark Lobodzinski } 2331c3340a06ecac4d7b9540592cae339f8fc224d0b1Mark Lobodzinski } 2332c3340a06ecac4d7b9540592cae339f8fc224d0b1Mark Lobodzinski } 2333c3340a06ecac4d7b9540592cae339f8fc224d0b1Mark Lobodzinski } 2334c3340a06ecac4d7b9540592cae339f8fc224d0b1Mark Lobodzinski } 2335c3340a06ecac4d7b9540592cae339f8fc224d0b1Mark Lobodzinski } 233609cd2c76808f1485206baeda9864f7ed907d7e05Mark Lobodzinski return skip; 2337c3340a06ecac4d7b9540592cae339f8fc224d0b1Mark Lobodzinski} 23383683836d93195a82dfd2c715ce9d56b030801598Mark Lobodzinski 23393683836d93195a82dfd2c715ce9d56b030801598Mark Lobodzinski// Helper function to validate correct usage bits set for buffers or images. Verify that (actual & desired) flags != 0 or, if strict 23403683836d93195a82dfd2c715ce9d56b030801598Mark Lobodzinski// is true, verify that (actual & desired) flags == desired 2341abfd2f0c07bb8ff00d48dbe6127819eaf839c9aeMark Lobodzinskistatic bool validate_usage_flags(layer_data *device_data, VkFlags actual, VkFlags desired, VkBool32 strict, uint64_t obj_handle, 23427a9423788398dbeb6d1fe0354a66123b61afda96Mark Lobodzinski VulkanObjectType obj_type, int32_t const msgCode, char const *func_name, char const *usage_str) { 2343abfd2f0c07bb8ff00d48dbe6127819eaf839c9aeMark Lobodzinski const debug_report_data *report_data = core_validation::GetReportData(device_data); 23443683836d93195a82dfd2c715ce9d56b030801598Mark Lobodzinski 23453683836d93195a82dfd2c715ce9d56b030801598Mark Lobodzinski bool correct_usage = false; 2346abfd2f0c07bb8ff00d48dbe6127819eaf839c9aeMark Lobodzinski bool skip = false; 23477a9423788398dbeb6d1fe0354a66123b61afda96Mark Lobodzinski const char *type_str = object_string[obj_type]; 23483683836d93195a82dfd2c715ce9d56b030801598Mark Lobodzinski if (strict) { 23493683836d93195a82dfd2c715ce9d56b030801598Mark Lobodzinski correct_usage = ((actual & desired) == desired); 23503683836d93195a82dfd2c715ce9d56b030801598Mark Lobodzinski } else { 23513683836d93195a82dfd2c715ce9d56b030801598Mark Lobodzinski correct_usage = ((actual & desired) != 0); 23523683836d93195a82dfd2c715ce9d56b030801598Mark Lobodzinski } 23533683836d93195a82dfd2c715ce9d56b030801598Mark Lobodzinski if (!correct_usage) { 23543683836d93195a82dfd2c715ce9d56b030801598Mark Lobodzinski if (msgCode == -1) { 23553683836d93195a82dfd2c715ce9d56b030801598Mark Lobodzinski // TODO: Fix callers with msgCode == -1 to use correct validation checks. 235602a510945ff39f3d9e486e456aca5bfa6ea0c43aMark Lobodzinski skip = log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, get_debug_report_enum[obj_type], obj_handle, __LINE__, 23577a9423788398dbeb6d1fe0354a66123b61afda96Mark Lobodzinski MEMTRACK_INVALID_USAGE_FLAG, "MEM", 23587a9423788398dbeb6d1fe0354a66123b61afda96Mark Lobodzinski "Invalid usage flag for %s 0x%" PRIxLEAST64 23597a9423788398dbeb6d1fe0354a66123b61afda96Mark Lobodzinski " used by %s. In this case, %s should have %s set during creation.", 23607a9423788398dbeb6d1fe0354a66123b61afda96Mark Lobodzinski type_str, obj_handle, func_name, type_str, usage_str); 23613683836d93195a82dfd2c715ce9d56b030801598Mark Lobodzinski } else { 23623683836d93195a82dfd2c715ce9d56b030801598Mark Lobodzinski const char *valid_usage = (msgCode == -1) ? "" : validation_error_map[msgCode]; 23637a9423788398dbeb6d1fe0354a66123b61afda96Mark Lobodzinski skip = log_msg( 236402a510945ff39f3d9e486e456aca5bfa6ea0c43aMark Lobodzinski report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, get_debug_report_enum[obj_type], obj_handle, __LINE__, msgCode, "MEM", 23657a9423788398dbeb6d1fe0354a66123b61afda96Mark Lobodzinski "Invalid usage flag for %s 0x%" PRIxLEAST64 " used by %s. In this case, %s should have %s set during creation. %s", 23667a9423788398dbeb6d1fe0354a66123b61afda96Mark Lobodzinski type_str, obj_handle, func_name, type_str, usage_str, valid_usage); 23673683836d93195a82dfd2c715ce9d56b030801598Mark Lobodzinski } 23683683836d93195a82dfd2c715ce9d56b030801598Mark Lobodzinski } 2369abfd2f0c07bb8ff00d48dbe6127819eaf839c9aeMark Lobodzinski return skip; 23703683836d93195a82dfd2c715ce9d56b030801598Mark Lobodzinski} 23713683836d93195a82dfd2c715ce9d56b030801598Mark Lobodzinski 23723683836d93195a82dfd2c715ce9d56b030801598Mark Lobodzinski// Helper function to validate usage flags for buffers. For given buffer_state send actual vs. desired usage off to helper above 23733683836d93195a82dfd2c715ce9d56b030801598Mark Lobodzinski// where an error will be flagged if usage is not correct 23740bcfcca3af64ac0214112949aa68496914b8d7a9Chris Forbesbool ValidateImageUsageFlags(layer_data *device_data, IMAGE_STATE const *image_state, VkFlags desired, bool strict, 23753683836d93195a82dfd2c715ce9d56b030801598Mark Lobodzinski int32_t const msgCode, char const *func_name, char const *usage_string) { 2376abfd2f0c07bb8ff00d48dbe6127819eaf839c9aeMark Lobodzinski return validate_usage_flags(device_data, image_state->createInfo.usage, desired, strict, 23777a9423788398dbeb6d1fe0354a66123b61afda96Mark Lobodzinski reinterpret_cast<const uint64_t &>(image_state->image), kVulkanObjectTypeImage, msgCode, func_name, 23787a9423788398dbeb6d1fe0354a66123b61afda96Mark Lobodzinski usage_string); 23793683836d93195a82dfd2c715ce9d56b030801598Mark Lobodzinski} 23803683836d93195a82dfd2c715ce9d56b030801598Mark Lobodzinski 23813683836d93195a82dfd2c715ce9d56b030801598Mark Lobodzinski// Helper function to validate usage flags for buffers. For given buffer_state send actual vs. desired usage off to helper above 23823683836d93195a82dfd2c715ce9d56b030801598Mark Lobodzinski// where an error will be flagged if usage is not correct 23830bcfcca3af64ac0214112949aa68496914b8d7a9Chris Forbesbool ValidateBufferUsageFlags(layer_data *device_data, BUFFER_STATE const *buffer_state, VkFlags desired, bool strict, 23843683836d93195a82dfd2c715ce9d56b030801598Mark Lobodzinski int32_t const msgCode, char const *func_name, char const *usage_string) { 2385abfd2f0c07bb8ff00d48dbe6127819eaf839c9aeMark Lobodzinski return validate_usage_flags(device_data, buffer_state->createInfo.usage, desired, strict, 23867a9423788398dbeb6d1fe0354a66123b61afda96Mark Lobodzinski reinterpret_cast<const uint64_t &>(buffer_state->buffer), kVulkanObjectTypeBuffer, msgCode, 23877a9423788398dbeb6d1fe0354a66123b61afda96Mark Lobodzinski func_name, usage_string); 23883683836d93195a82dfd2c715ce9d56b030801598Mark Lobodzinski} 23893683836d93195a82dfd2c715ce9d56b030801598Mark Lobodzinski 2390abfd2f0c07bb8ff00d48dbe6127819eaf839c9aeMark Lobodzinskibool PreCallValidateCreateBuffer(layer_data *device_data, const VkBufferCreateInfo *pCreateInfo) { 23913683836d93195a82dfd2c715ce9d56b030801598Mark Lobodzinski bool skip = false; 239201363bf3d84ba5841a6870b40c041c2f53d76583Mark Lobodzinski const debug_report_data *report_data = core_validation::GetReportData(device_data); 239301363bf3d84ba5841a6870b40c041c2f53d76583Mark Lobodzinski 23943683836d93195a82dfd2c715ce9d56b030801598Mark Lobodzinski // TODO: Add check for VALIDATION_ERROR_00658 23953683836d93195a82dfd2c715ce9d56b030801598Mark Lobodzinski // TODO: Add check for VALIDATION_ERROR_00667 23963683836d93195a82dfd2c715ce9d56b030801598Mark Lobodzinski // TODO: Add check for VALIDATION_ERROR_00668 23973683836d93195a82dfd2c715ce9d56b030801598Mark Lobodzinski // TODO: Add check for VALIDATION_ERROR_00669 239801363bf3d84ba5841a6870b40c041c2f53d76583Mark Lobodzinski 239901363bf3d84ba5841a6870b40c041c2f53d76583Mark Lobodzinski if ((pCreateInfo->flags & VK_BUFFER_CREATE_SPARSE_BINDING_BIT) && (!GetEnabledFeatures(device_data)->sparseBinding)) { 240001363bf3d84ba5841a6870b40c041c2f53d76583Mark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, 240101363bf3d84ba5841a6870b40c041c2f53d76583Mark Lobodzinski VALIDATION_ERROR_00666, "DS", 240201363bf3d84ba5841a6870b40c041c2f53d76583Mark Lobodzinski "vkCreateBuffer(): the sparseBinding device feature is disabled: Buffers cannot be created with the " 240301363bf3d84ba5841a6870b40c041c2f53d76583Mark Lobodzinski "VK_BUFFER_CREATE_SPARSE_BINDING_BIT set. %s", 240401363bf3d84ba5841a6870b40c041c2f53d76583Mark Lobodzinski validation_error_map[VALIDATION_ERROR_00666]); 240501363bf3d84ba5841a6870b40c041c2f53d76583Mark Lobodzinski } 2406f575247dabffb70e4de1a6f9522db3f09a55492eMark Lobodzinski 2407f575247dabffb70e4de1a6f9522db3f09a55492eMark Lobodzinski if ((pCreateInfo->flags & VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT) && (!GetEnabledFeatures(device_data)->sparseResidencyBuffer)) { 2408f575247dabffb70e4de1a6f9522db3f09a55492eMark Lobodzinski skip |= 2409f575247dabffb70e4de1a6f9522db3f09a55492eMark Lobodzinski log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, 2410f575247dabffb70e4de1a6f9522db3f09a55492eMark Lobodzinski DRAWSTATE_INVALID_FEATURE, "DS", 2411f575247dabffb70e4de1a6f9522db3f09a55492eMark Lobodzinski "vkCreateBuffer(): the sparseResidencyBuffer device feature is disabled: Buffers cannot be created with the " 2412f575247dabffb70e4de1a6f9522db3f09a55492eMark Lobodzinski "VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT set."); 2413f575247dabffb70e4de1a6f9522db3f09a55492eMark Lobodzinski } 24147e105b26dcb40aff4f9776b8f5b5f1326aa1e36cMark Lobodzinski 24157e105b26dcb40aff4f9776b8f5b5f1326aa1e36cMark Lobodzinski if ((pCreateInfo->flags & VK_BUFFER_CREATE_SPARSE_ALIASED_BIT) && (!GetEnabledFeatures(device_data)->sparseResidencyAliased)) { 24167e105b26dcb40aff4f9776b8f5b5f1326aa1e36cMark Lobodzinski skip |= 24177e105b26dcb40aff4f9776b8f5b5f1326aa1e36cMark Lobodzinski log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, 24187e105b26dcb40aff4f9776b8f5b5f1326aa1e36cMark Lobodzinski DRAWSTATE_INVALID_FEATURE, "DS", 24197e105b26dcb40aff4f9776b8f5b5f1326aa1e36cMark Lobodzinski "vkCreateBuffer(): the sparseResidencyAliased device feature is disabled: Buffers cannot be created with the " 24207e105b26dcb40aff4f9776b8f5b5f1326aa1e36cMark Lobodzinski "VK_BUFFER_CREATE_SPARSE_ALIASED_BIT set."); 24217e105b26dcb40aff4f9776b8f5b5f1326aa1e36cMark Lobodzinski } 24223683836d93195a82dfd2c715ce9d56b030801598Mark Lobodzinski return skip; 24233683836d93195a82dfd2c715ce9d56b030801598Mark Lobodzinski} 24243683836d93195a82dfd2c715ce9d56b030801598Mark Lobodzinski 24253683836d93195a82dfd2c715ce9d56b030801598Mark Lobodzinskivoid PostCallRecordCreateBuffer(layer_data *device_data, const VkBufferCreateInfo *pCreateInfo, VkBuffer *pBuffer) { 24263683836d93195a82dfd2c715ce9d56b030801598Mark Lobodzinski // TODO : This doesn't create deep copy of pQueueFamilyIndices so need to fix that if/when we want that data to be valid 24273683836d93195a82dfd2c715ce9d56b030801598Mark Lobodzinski GetBufferMap(device_data) 24283683836d93195a82dfd2c715ce9d56b030801598Mark Lobodzinski ->insert(std::make_pair(*pBuffer, std::unique_ptr<BUFFER_STATE>(new BUFFER_STATE(*pBuffer, pCreateInfo)))); 24293683836d93195a82dfd2c715ce9d56b030801598Mark Lobodzinski} 24303683836d93195a82dfd2c715ce9d56b030801598Mark Lobodzinski 2431abfd2f0c07bb8ff00d48dbe6127819eaf839c9aeMark Lobodzinskibool PreCallValidateCreateBufferView(layer_data *device_data, const VkBufferViewCreateInfo *pCreateInfo) { 2432abfd2f0c07bb8ff00d48dbe6127819eaf839c9aeMark Lobodzinski bool skip = false; 2433abfd2f0c07bb8ff00d48dbe6127819eaf839c9aeMark Lobodzinski BUFFER_STATE *buffer_state = GetBufferState(device_data, pCreateInfo->buffer); 24343683836d93195a82dfd2c715ce9d56b030801598Mark Lobodzinski // If this isn't a sparse buffer, it needs to have memory backing it at CreateBufferView time 24353683836d93195a82dfd2c715ce9d56b030801598Mark Lobodzinski if (buffer_state) { 2436abfd2f0c07bb8ff00d48dbe6127819eaf839c9aeMark Lobodzinski skip |= ValidateMemoryIsBoundToBuffer(device_data, buffer_state, "vkCreateBufferView()", VALIDATION_ERROR_02522); 24373683836d93195a82dfd2c715ce9d56b030801598Mark Lobodzinski // In order to create a valid buffer view, the buffer must have been created with at least one of the following flags: 24383683836d93195a82dfd2c715ce9d56b030801598Mark Lobodzinski // UNIFORM_TEXEL_BUFFER_BIT or STORAGE_TEXEL_BUFFER_BIT 2439abfd2f0c07bb8ff00d48dbe6127819eaf839c9aeMark Lobodzinski skip |= ValidateBufferUsageFlags( 2440abfd2f0c07bb8ff00d48dbe6127819eaf839c9aeMark Lobodzinski device_data, buffer_state, VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT | VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT, false, 24413683836d93195a82dfd2c715ce9d56b030801598Mark Lobodzinski VALIDATION_ERROR_00694, "vkCreateBufferView()", "VK_BUFFER_USAGE_[STORAGE|UNIFORM]_TEXEL_BUFFER_BIT"); 24423683836d93195a82dfd2c715ce9d56b030801598Mark Lobodzinski } 2443abfd2f0c07bb8ff00d48dbe6127819eaf839c9aeMark Lobodzinski return skip; 24443683836d93195a82dfd2c715ce9d56b030801598Mark Lobodzinski} 24453683836d93195a82dfd2c715ce9d56b030801598Mark Lobodzinski 24463683836d93195a82dfd2c715ce9d56b030801598Mark Lobodzinskivoid PostCallRecordCreateBufferView(layer_data *device_data, const VkBufferViewCreateInfo *pCreateInfo, VkBufferView *pView) { 24473683836d93195a82dfd2c715ce9d56b030801598Mark Lobodzinski (*GetBufferViewMap(device_data))[*pView] = std::unique_ptr<BUFFER_VIEW_STATE>(new BUFFER_VIEW_STATE(*pView, pCreateInfo)); 24483683836d93195a82dfd2c715ce9d56b030801598Mark Lobodzinski} 24491c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski 24501c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski// For the given format verify that the aspect masks make sense 24511c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinskibool ValidateImageAspectMask(layer_data *device_data, VkImage image, VkFormat format, VkImageAspectFlags aspect_mask, 24521c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski const char *func_name) { 24531c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski const debug_report_data *report_data = core_validation::GetReportData(device_data); 24541c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski bool skip = false; 245516769f6b2a7721e391952a97f010cbb530e4f211Dave Houlton if (FormatIsColor(format)) { 24561c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski if ((aspect_mask & VK_IMAGE_ASPECT_COLOR_BIT) != VK_IMAGE_ASPECT_COLOR_BIT) { 24571c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, (uint64_t)image, 24581c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski __LINE__, VALIDATION_ERROR_00741, "IMAGE", 24591c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski "%s: Color image formats must have the VK_IMAGE_ASPECT_COLOR_BIT set. %s", func_name, 24601c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski validation_error_map[VALIDATION_ERROR_00741]); 24611c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski } else if ((aspect_mask & VK_IMAGE_ASPECT_COLOR_BIT) != aspect_mask) { 24621c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, (uint64_t)image, 24631c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski __LINE__, VALIDATION_ERROR_00741, "IMAGE", 24641c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski "%s: Color image formats must have ONLY the VK_IMAGE_ASPECT_COLOR_BIT set. %s", func_name, 24651c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski validation_error_map[VALIDATION_ERROR_00741]); 24661c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski } 246716769f6b2a7721e391952a97f010cbb530e4f211Dave Houlton } else if (FormatIsDepthAndStencil(format)) { 24681c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski if ((aspect_mask & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) == 0) { 24691c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, (uint64_t)image, 24701c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski __LINE__, VALIDATION_ERROR_00741, "IMAGE", 24711c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski "%s: Depth/stencil image formats must have " 24721c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski "at least one of VK_IMAGE_ASPECT_DEPTH_BIT " 24731c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski "and VK_IMAGE_ASPECT_STENCIL_BIT set. %s", 24741c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski func_name, validation_error_map[VALIDATION_ERROR_00741]); 24751c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski } else if ((aspect_mask & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) != aspect_mask) { 24761c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, (uint64_t)image, 24771c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski __LINE__, VALIDATION_ERROR_00741, "IMAGE", 24781c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski "%s: Combination depth/stencil image formats can have only the VK_IMAGE_ASPECT_DEPTH_BIT and " 24791c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski "VK_IMAGE_ASPECT_STENCIL_BIT set. %s", 24801c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski func_name, validation_error_map[VALIDATION_ERROR_00741]); 24811c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski } 248216769f6b2a7721e391952a97f010cbb530e4f211Dave Houlton } else if (FormatIsDepthOnly(format)) { 24831c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski if ((aspect_mask & VK_IMAGE_ASPECT_DEPTH_BIT) != VK_IMAGE_ASPECT_DEPTH_BIT) { 24841c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, (uint64_t)image, 24851c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski __LINE__, VALIDATION_ERROR_00741, "IMAGE", 24861c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski "%s: Depth-only image formats must have the VK_IMAGE_ASPECT_DEPTH_BIT set. %s", func_name, 24871c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski validation_error_map[VALIDATION_ERROR_00741]); 24881c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski } else if ((aspect_mask & VK_IMAGE_ASPECT_DEPTH_BIT) != aspect_mask) { 24891c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, (uint64_t)image, 24901c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski __LINE__, VALIDATION_ERROR_00741, "IMAGE", 24911c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski "%s: Depth-only image formats can have only the VK_IMAGE_ASPECT_DEPTH_BIT set. %s", func_name, 24921c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski validation_error_map[VALIDATION_ERROR_00741]); 24931c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski } 249416769f6b2a7721e391952a97f010cbb530e4f211Dave Houlton } else if (FormatIsStencilOnly(format)) { 24951c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski if ((aspect_mask & VK_IMAGE_ASPECT_STENCIL_BIT) != VK_IMAGE_ASPECT_STENCIL_BIT) { 24961c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, (uint64_t)image, 24971c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski __LINE__, VALIDATION_ERROR_00741, "IMAGE", 24981c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski "%s: Stencil-only image formats must have the VK_IMAGE_ASPECT_STENCIL_BIT set. %s", func_name, 24991c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski validation_error_map[VALIDATION_ERROR_00741]); 25001c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski } else if ((aspect_mask & VK_IMAGE_ASPECT_STENCIL_BIT) != aspect_mask) { 25011c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, (uint64_t)image, 25021c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski __LINE__, VALIDATION_ERROR_00741, "IMAGE", 25031c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski "%s: Stencil-only image formats can have only the VK_IMAGE_ASPECT_STENCIL_BIT set. %s", func_name, 25041c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski validation_error_map[VALIDATION_ERROR_00741]); 25051c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski } 25061c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski } 25071c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski return skip; 25081c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski} 25091c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski 25101c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinskibool ValidateImageSubrangeLevelLayerCounts(layer_data *device_data, const VkImageSubresourceRange &subresourceRange, 25111c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski const char *func_name) { 25121c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski const debug_report_data *report_data = core_validation::GetReportData(device_data); 25131c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski bool skip = false; 25141c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski if (subresourceRange.levelCount == 0) { 2515fdc75c21ced997fbbc180734bef87bf6d5811d4bMark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, 25161c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski VALIDATION_ERROR_00768, "IMAGE", "%s called with 0 in subresourceRange.levelCount. %s", func_name, 25171c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski validation_error_map[VALIDATION_ERROR_00768]); 25181c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski } 25191c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski if (subresourceRange.layerCount == 0) { 2520fdc75c21ced997fbbc180734bef87bf6d5811d4bMark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, 25211c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski VALIDATION_ERROR_00769, "IMAGE", "%s called with 0 in subresourceRange.layerCount. %s", func_name, 25221c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski validation_error_map[VALIDATION_ERROR_00769]); 25231c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski } 25241c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski return skip; 25251c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski} 25261c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski 25271c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinskibool PreCallValidateCreateImageView(layer_data *device_data, const VkImageViewCreateInfo *create_info) { 25281c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski const debug_report_data *report_data = core_validation::GetReportData(device_data); 25291c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski bool skip = false; 25301c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski IMAGE_STATE *image_state = GetImageState(device_data, create_info->image); 25311c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski if (image_state) { 25321c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski skip |= ValidateImageUsageFlags( 25331c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski device_data, image_state, 25341c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | 25351c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, 25361c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski false, -1, "vkCreateImageView()", 25371c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski "VK_IMAGE_USAGE_[SAMPLED|STORAGE|COLOR_ATTACHMENT|DEPTH_STENCIL_ATTACHMENT|INPUT_ATTACHMENT]_BIT"); 25381c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski // If this isn't a sparse image, it needs to have memory backing it at CreateImageView time 25391c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski skip |= ValidateMemoryIsBoundToImage(device_data, image_state, "vkCreateImageView()", VALIDATION_ERROR_02524); 25401c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski // Checks imported from image layer 2541b831ab1eb11c80b51fb33c1c390298421d65b540Jeremy Hayes if ((create_info->subresourceRange.baseMipLevel + create_info->subresourceRange.levelCount) > 2542b831ab1eb11c80b51fb33c1c390298421d65b540Jeremy Hayes image_state->createInfo.mipLevels) { 25431c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski std::stringstream ss; 25441c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski ss << "vkCreateImageView called with baseMipLevel " << create_info->subresourceRange.baseMipLevel << " for image " 25451c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski << create_info->image << " that only has " << image_state->createInfo.mipLevels << " mip levels."; 25461c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski skip |= 2547fdc75c21ced997fbbc180734bef87bf6d5811d4bMark Lobodzinski log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, 25481c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski VALIDATION_ERROR_00768, "IMAGE", "%s %s", ss.str().c_str(), validation_error_map[VALIDATION_ERROR_00768]); 25491c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski } 255057eda737eea95dd728f6dce5c78d6b00fb126076Mike Schuchardt if (!GetDeviceExtensions(device_data)->khr_maintenance1_enabled) { 255157eda737eea95dd728f6dce5c78d6b00fb126076Mike Schuchardt if (create_info->subresourceRange.baseArrayLayer >= image_state->createInfo.arrayLayers) { 255257eda737eea95dd728f6dce5c78d6b00fb126076Mike Schuchardt std::stringstream ss; 255357eda737eea95dd728f6dce5c78d6b00fb126076Mike Schuchardt ss << "vkCreateImageView called with baseArrayLayer " << create_info->subresourceRange.baseArrayLayer 255457eda737eea95dd728f6dce5c78d6b00fb126076Mike Schuchardt << " for image " << create_info->image << " that only has " << image_state->createInfo.arrayLayers 255557eda737eea95dd728f6dce5c78d6b00fb126076Mike Schuchardt << " array layers."; 255657eda737eea95dd728f6dce5c78d6b00fb126076Mike Schuchardt skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, 255757eda737eea95dd728f6dce5c78d6b00fb126076Mike Schuchardt VALIDATION_ERROR_00769, "IMAGE", "%s %s", ss.str().c_str(), 255857eda737eea95dd728f6dce5c78d6b00fb126076Mike Schuchardt validation_error_map[VALIDATION_ERROR_00769]); 255957eda737eea95dd728f6dce5c78d6b00fb126076Mike Schuchardt } 25601c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski } 25611c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski // TODO: Need new valid usage language for levelCount == 0 & layerCount == 0 25621c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski skip |= ValidateImageSubrangeLevelLayerCounts(device_data, create_info->subresourceRange, "vkCreateImageView()"); 25631c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski 25641c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski VkImageCreateFlags image_flags = image_state->createInfo.flags; 25651c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski VkFormat image_format = image_state->createInfo.format; 25661c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski VkFormat view_format = create_info->format; 25671c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski VkImageAspectFlags aspect_mask = create_info->subresourceRange.aspectMask; 25681c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski 25691c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski // Validate VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT state 25701c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski if (image_flags & VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT) { 25711c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski // Format MUST be compatible (in the same format compatibility class) as the format the image was created with 257216769f6b2a7721e391952a97f010cbb530e4f211Dave Houlton if (FormatCompatibilityClass(image_format) != FormatCompatibilityClass(view_format)) { 25731c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski std::stringstream ss; 25741c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski ss << "vkCreateImageView(): ImageView format " << string_VkFormat(view_format) 25751c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski << " is not in the same format compatibility class as image (" << (uint64_t)create_info->image << ") format " 25761c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski << string_VkFormat(image_format) << ". Images created with the VK_IMAGE_CREATE_MUTABLE_FORMAT BIT " 25771c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski << "can support ImageViews with differing formats but they must be in the same compatibility class."; 2578fdc75c21ced997fbbc180734bef87bf6d5811d4bMark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, 25791c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski VALIDATION_ERROR_02171, "IMAGE", "%s %s", ss.str().c_str(), 25801c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski validation_error_map[VALIDATION_ERROR_02171]); 25811c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski } 25821c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski } else { 25831c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski // Format MUST be IDENTICAL to the format the image was created with 25841c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski if (image_format != view_format) { 25851c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski std::stringstream ss; 25861c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski ss << "vkCreateImageView() format " << string_VkFormat(view_format) << " differs from image " 25871c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski << (uint64_t)create_info->image << " format " << string_VkFormat(image_format) 25881c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski << ". Formats MUST be IDENTICAL unless VK_IMAGE_CREATE_MUTABLE_FORMAT BIT was set on image creation."; 2589fdc75c21ced997fbbc180734bef87bf6d5811d4bMark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, 25901c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski VALIDATION_ERROR_02172, "IMAGE", "%s %s", ss.str().c_str(), 25911c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski validation_error_map[VALIDATION_ERROR_02172]); 25921c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski } 25931c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski } 25941c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski 25951c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski // Validate correct image aspect bits for desired formats and format consistency 25961c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski skip |= ValidateImageAspectMask(device_data, image_state->image, image_format, aspect_mask, "vkCreateImageView()"); 25971c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski } 25981c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski return skip; 25991c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski} 26001c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski 2601d0b59d0aabea9048c518840e762c7a510927c132Mark Lobodzinskivoid PostCallRecordCreateImageView(layer_data *device_data, const VkImageViewCreateInfo *create_info, VkImageView view) { 2602d0b59d0aabea9048c518840e762c7a510927c132Mark Lobodzinski auto image_view_map = GetImageViewMap(device_data); 2603d0b59d0aabea9048c518840e762c7a510927c132Mark Lobodzinski (*image_view_map)[view] = std::unique_ptr<IMAGE_VIEW_STATE>(new IMAGE_VIEW_STATE(view, create_info)); 2604d0b59d0aabea9048c518840e762c7a510927c132Mark Lobodzinski 2605d0b59d0aabea9048c518840e762c7a510927c132Mark Lobodzinski auto image_state = GetImageState(device_data, create_info->image); 2606e9d74ac8e13687c1be3ee147efce42e8215a049eDave Houlton auto &sub_res_range = (*image_view_map)[view].get()->create_info.subresourceRange; 260795b7894efd5e101e410da92fc697429aec3ffa7bMark Lobodzinski sub_res_range.levelCount = ResolveRemainingLevels(&sub_res_range, image_state->createInfo.mipLevels); 260895b7894efd5e101e410da92fc697429aec3ffa7bMark Lobodzinski sub_res_range.layerCount = ResolveRemainingLayers(&sub_res_range, image_state->createInfo.arrayLayers); 26091c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski} 26106a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski 2611c40a396f8341e1e1e5fdf1d023a987b874763446Mark Lobodzinskibool PreCallValidateCmdCopyBuffer(layer_data *device_data, GLOBAL_CB_NODE *cb_node, BUFFER_STATE *src_buffer_state, 2612c40a396f8341e1e1e5fdf1d023a987b874763446Mark Lobodzinski BUFFER_STATE *dst_buffer_state) { 2613c40a396f8341e1e1e5fdf1d023a987b874763446Mark Lobodzinski bool skip = false; 2614c40a396f8341e1e1e5fdf1d023a987b874763446Mark Lobodzinski skip |= ValidateMemoryIsBoundToBuffer(device_data, src_buffer_state, "vkCmdCopyBuffer()", VALIDATION_ERROR_02531); 2615c40a396f8341e1e1e5fdf1d023a987b874763446Mark Lobodzinski skip |= ValidateMemoryIsBoundToBuffer(device_data, dst_buffer_state, "vkCmdCopyBuffer()", VALIDATION_ERROR_02532); 2616c40a396f8341e1e1e5fdf1d023a987b874763446Mark Lobodzinski // Validate that SRC & DST buffers have correct usage flags set 2617c40a396f8341e1e1e5fdf1d023a987b874763446Mark Lobodzinski skip |= ValidateBufferUsageFlags(device_data, src_buffer_state, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, true, VALIDATION_ERROR_01164, 2618c40a396f8341e1e1e5fdf1d023a987b874763446Mark Lobodzinski "vkCmdCopyBuffer()", "VK_BUFFER_USAGE_TRANSFER_SRC_BIT"); 2619c40a396f8341e1e1e5fdf1d023a987b874763446Mark Lobodzinski skip |= ValidateBufferUsageFlags(device_data, dst_buffer_state, VK_BUFFER_USAGE_TRANSFER_DST_BIT, true, VALIDATION_ERROR_01165, 2620c40a396f8341e1e1e5fdf1d023a987b874763446Mark Lobodzinski "vkCmdCopyBuffer()", "VK_BUFFER_USAGE_TRANSFER_DST_BIT"); 2621baa50ccc5a8cf7a6f7474148f301802c5480e715Mike Schuchardt skip |= ValidateCmdQueueFlags(device_data, cb_node, "vkCmdCopyBuffer()", 2622baa50ccc5a8cf7a6f7474148f301802c5480e715Mike Schuchardt VK_QUEUE_TRANSFER_BIT | VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT, VALIDATION_ERROR_01171); 2623c40a396f8341e1e1e5fdf1d023a987b874763446Mark Lobodzinski skip |= ValidateCmd(device_data, cb_node, CMD_COPYBUFFER, "vkCmdCopyBuffer()"); 2624c40a396f8341e1e1e5fdf1d023a987b874763446Mark Lobodzinski skip |= insideRenderPass(device_data, cb_node, "vkCmdCopyBuffer()", VALIDATION_ERROR_01172); 2625c40a396f8341e1e1e5fdf1d023a987b874763446Mark Lobodzinski return skip; 2626c40a396f8341e1e1e5fdf1d023a987b874763446Mark Lobodzinski} 26276a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski 2628c40a396f8341e1e1e5fdf1d023a987b874763446Mark Lobodzinskivoid PreCallRecordCmdCopyBuffer(layer_data *device_data, GLOBAL_CB_NODE *cb_node, BUFFER_STATE *src_buffer_state, 2629c40a396f8341e1e1e5fdf1d023a987b874763446Mark Lobodzinski BUFFER_STATE *dst_buffer_state) { 2630c40a396f8341e1e1e5fdf1d023a987b874763446Mark Lobodzinski // Update bindings between buffers and cmd buffer 2631c40a396f8341e1e1e5fdf1d023a987b874763446Mark Lobodzinski AddCommandBufferBindingBuffer(device_data, cb_node, src_buffer_state); 2632c40a396f8341e1e1e5fdf1d023a987b874763446Mark Lobodzinski AddCommandBufferBindingBuffer(device_data, cb_node, dst_buffer_state); 2633c40a396f8341e1e1e5fdf1d023a987b874763446Mark Lobodzinski 2634c40a396f8341e1e1e5fdf1d023a987b874763446Mark Lobodzinski std::function<bool()> function = [=]() { 2635c40a396f8341e1e1e5fdf1d023a987b874763446Mark Lobodzinski return ValidateBufferMemoryIsValid(device_data, src_buffer_state, "vkCmdCopyBuffer()"); 2636c40a396f8341e1e1e5fdf1d023a987b874763446Mark Lobodzinski }; 2637c40a396f8341e1e1e5fdf1d023a987b874763446Mark Lobodzinski cb_node->validate_functions.push_back(function); 2638c40a396f8341e1e1e5fdf1d023a987b874763446Mark Lobodzinski function = [=]() { 2639c40a396f8341e1e1e5fdf1d023a987b874763446Mark Lobodzinski SetBufferMemoryValid(device_data, dst_buffer_state, true); 2640c40a396f8341e1e1e5fdf1d023a987b874763446Mark Lobodzinski return false; 2641c40a396f8341e1e1e5fdf1d023a987b874763446Mark Lobodzinski }; 2642c40a396f8341e1e1e5fdf1d023a987b874763446Mark Lobodzinski cb_node->validate_functions.push_back(function); 2643c40a396f8341e1e1e5fdf1d023a987b874763446Mark Lobodzinski core_validation::UpdateCmdBufferLastCmd(cb_node, CMD_COPYBUFFER); 2644c40a396f8341e1e1e5fdf1d023a987b874763446Mark Lobodzinski} 2645842b2d28ded1c6e2c38491a81213d0e1d1b7295aMark Lobodzinski 2646842b2d28ded1c6e2c38491a81213d0e1d1b7295aMark Lobodzinskistatic bool validateIdleBuffer(layer_data *device_data, VkBuffer buffer) { 2647842b2d28ded1c6e2c38491a81213d0e1d1b7295aMark Lobodzinski const debug_report_data *report_data = core_validation::GetReportData(device_data); 2648842b2d28ded1c6e2c38491a81213d0e1d1b7295aMark Lobodzinski bool skip = false; 2649842b2d28ded1c6e2c38491a81213d0e1d1b7295aMark Lobodzinski auto buffer_state = GetBufferState(device_data, buffer); 2650842b2d28ded1c6e2c38491a81213d0e1d1b7295aMark Lobodzinski if (!buffer_state) { 2651842b2d28ded1c6e2c38491a81213d0e1d1b7295aMark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT, (uint64_t)(buffer), 2652842b2d28ded1c6e2c38491a81213d0e1d1b7295aMark Lobodzinski __LINE__, DRAWSTATE_DOUBLE_DESTROY, "DS", 2653842b2d28ded1c6e2c38491a81213d0e1d1b7295aMark Lobodzinski "Cannot free buffer 0x%" PRIxLEAST64 " that has not been allocated.", (uint64_t)(buffer)); 2654842b2d28ded1c6e2c38491a81213d0e1d1b7295aMark Lobodzinski } else { 2655842b2d28ded1c6e2c38491a81213d0e1d1b7295aMark Lobodzinski if (buffer_state->in_use.load()) { 2656842b2d28ded1c6e2c38491a81213d0e1d1b7295aMark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT, (uint64_t)(buffer), 2657842b2d28ded1c6e2c38491a81213d0e1d1b7295aMark Lobodzinski __LINE__, VALIDATION_ERROR_00676, "DS", 2658842b2d28ded1c6e2c38491a81213d0e1d1b7295aMark Lobodzinski "Cannot free buffer 0x%" PRIxLEAST64 " that is in use by a command buffer. %s", (uint64_t)(buffer), 2659842b2d28ded1c6e2c38491a81213d0e1d1b7295aMark Lobodzinski validation_error_map[VALIDATION_ERROR_00676]); 2660842b2d28ded1c6e2c38491a81213d0e1d1b7295aMark Lobodzinski } 2661842b2d28ded1c6e2c38491a81213d0e1d1b7295aMark Lobodzinski } 2662842b2d28ded1c6e2c38491a81213d0e1d1b7295aMark Lobodzinski return skip; 2663842b2d28ded1c6e2c38491a81213d0e1d1b7295aMark Lobodzinski} 2664842b2d28ded1c6e2c38491a81213d0e1d1b7295aMark Lobodzinski 2665842b2d28ded1c6e2c38491a81213d0e1d1b7295aMark Lobodzinskibool PreCallValidateDestroyImageView(layer_data *device_data, VkImageView image_view, IMAGE_VIEW_STATE **image_view_state, 2666842b2d28ded1c6e2c38491a81213d0e1d1b7295aMark Lobodzinski VK_OBJECT *obj_struct) { 2667842b2d28ded1c6e2c38491a81213d0e1d1b7295aMark Lobodzinski *image_view_state = GetImageViewState(device_data, image_view); 26687a9423788398dbeb6d1fe0354a66123b61afda96Mark Lobodzinski *obj_struct = {reinterpret_cast<uint64_t &>(image_view), kVulkanObjectTypeImageView}; 2669842b2d28ded1c6e2c38491a81213d0e1d1b7295aMark Lobodzinski if (GetDisables(device_data)->destroy_image_view) return false; 2670842b2d28ded1c6e2c38491a81213d0e1d1b7295aMark Lobodzinski bool skip = false; 2671842b2d28ded1c6e2c38491a81213d0e1d1b7295aMark Lobodzinski if (*image_view_state) { 2672842b2d28ded1c6e2c38491a81213d0e1d1b7295aMark Lobodzinski skip |= ValidateObjectNotInUse(device_data, *image_view_state, *obj_struct, VALIDATION_ERROR_00776); 2673842b2d28ded1c6e2c38491a81213d0e1d1b7295aMark Lobodzinski } 2674842b2d28ded1c6e2c38491a81213d0e1d1b7295aMark Lobodzinski return skip; 2675842b2d28ded1c6e2c38491a81213d0e1d1b7295aMark Lobodzinski} 2676842b2d28ded1c6e2c38491a81213d0e1d1b7295aMark Lobodzinski 2677842b2d28ded1c6e2c38491a81213d0e1d1b7295aMark Lobodzinskivoid PostCallRecordDestroyImageView(layer_data *device_data, VkImageView image_view, IMAGE_VIEW_STATE *image_view_state, 2678842b2d28ded1c6e2c38491a81213d0e1d1b7295aMark Lobodzinski VK_OBJECT obj_struct) { 2679842b2d28ded1c6e2c38491a81213d0e1d1b7295aMark Lobodzinski // Any bound cmd buffers are now invalid 2680842b2d28ded1c6e2c38491a81213d0e1d1b7295aMark Lobodzinski invalidateCommandBuffers(device_data, image_view_state->cb_bindings, obj_struct); 2681842b2d28ded1c6e2c38491a81213d0e1d1b7295aMark Lobodzinski (*GetImageViewMap(device_data)).erase(image_view); 2682842b2d28ded1c6e2c38491a81213d0e1d1b7295aMark Lobodzinski} 2683842b2d28ded1c6e2c38491a81213d0e1d1b7295aMark Lobodzinski 2684842b2d28ded1c6e2c38491a81213d0e1d1b7295aMark Lobodzinskibool PreCallValidateDestroyBuffer(layer_data *device_data, VkBuffer buffer, BUFFER_STATE **buffer_state, VK_OBJECT *obj_struct) { 2685842b2d28ded1c6e2c38491a81213d0e1d1b7295aMark Lobodzinski *buffer_state = GetBufferState(device_data, buffer); 2686cf2ce8673669ca1111e333bdea272c4dd57cb5c2Dave Houlton *obj_struct = {reinterpret_cast<uint64_t &>(buffer), kVulkanObjectTypeBuffer}; 2687842b2d28ded1c6e2c38491a81213d0e1d1b7295aMark Lobodzinski if (GetDisables(device_data)->destroy_buffer) return false; 2688842b2d28ded1c6e2c38491a81213d0e1d1b7295aMark Lobodzinski bool skip = false; 2689842b2d28ded1c6e2c38491a81213d0e1d1b7295aMark Lobodzinski if (*buffer_state) { 2690842b2d28ded1c6e2c38491a81213d0e1d1b7295aMark Lobodzinski skip |= validateIdleBuffer(device_data, buffer); 2691842b2d28ded1c6e2c38491a81213d0e1d1b7295aMark Lobodzinski } 2692842b2d28ded1c6e2c38491a81213d0e1d1b7295aMark Lobodzinski return skip; 2693842b2d28ded1c6e2c38491a81213d0e1d1b7295aMark Lobodzinski} 2694842b2d28ded1c6e2c38491a81213d0e1d1b7295aMark Lobodzinski 2695842b2d28ded1c6e2c38491a81213d0e1d1b7295aMark Lobodzinskivoid PostCallRecordDestroyBuffer(layer_data *device_data, VkBuffer buffer, BUFFER_STATE *buffer_state, VK_OBJECT obj_struct) { 2696842b2d28ded1c6e2c38491a81213d0e1d1b7295aMark Lobodzinski invalidateCommandBuffers(device_data, buffer_state->cb_bindings, obj_struct); 2697842b2d28ded1c6e2c38491a81213d0e1d1b7295aMark Lobodzinski for (auto mem_binding : buffer_state->GetBoundMemory()) { 2698842b2d28ded1c6e2c38491a81213d0e1d1b7295aMark Lobodzinski auto mem_info = GetMemObjInfo(device_data, mem_binding); 2699842b2d28ded1c6e2c38491a81213d0e1d1b7295aMark Lobodzinski if (mem_info) { 2700842b2d28ded1c6e2c38491a81213d0e1d1b7295aMark Lobodzinski core_validation::RemoveBufferMemoryRange(reinterpret_cast<uint64_t &>(buffer), mem_info); 2701842b2d28ded1c6e2c38491a81213d0e1d1b7295aMark Lobodzinski } 2702842b2d28ded1c6e2c38491a81213d0e1d1b7295aMark Lobodzinski } 27037a9423788398dbeb6d1fe0354a66123b61afda96Mark Lobodzinski ClearMemoryObjectBindings(device_data, reinterpret_cast<uint64_t &>(buffer), kVulkanObjectTypeBuffer); 2704842b2d28ded1c6e2c38491a81213d0e1d1b7295aMark Lobodzinski GetBufferMap(device_data)->erase(buffer_state->buffer); 2705842b2d28ded1c6e2c38491a81213d0e1d1b7295aMark Lobodzinski} 2706842b2d28ded1c6e2c38491a81213d0e1d1b7295aMark Lobodzinski 2707842b2d28ded1c6e2c38491a81213d0e1d1b7295aMark Lobodzinskibool PreCallValidateDestroyBufferView(layer_data *device_data, VkBufferView buffer_view, BUFFER_VIEW_STATE **buffer_view_state, 2708842b2d28ded1c6e2c38491a81213d0e1d1b7295aMark Lobodzinski VK_OBJECT *obj_struct) { 2709842b2d28ded1c6e2c38491a81213d0e1d1b7295aMark Lobodzinski *buffer_view_state = GetBufferViewState(device_data, buffer_view); 2710cf2ce8673669ca1111e333bdea272c4dd57cb5c2Dave Houlton *obj_struct = {reinterpret_cast<uint64_t &>(buffer_view), kVulkanObjectTypeBufferView}; 2711842b2d28ded1c6e2c38491a81213d0e1d1b7295aMark Lobodzinski if (GetDisables(device_data)->destroy_buffer_view) return false; 2712842b2d28ded1c6e2c38491a81213d0e1d1b7295aMark Lobodzinski bool skip = false; 2713842b2d28ded1c6e2c38491a81213d0e1d1b7295aMark Lobodzinski if (*buffer_view_state) { 2714842b2d28ded1c6e2c38491a81213d0e1d1b7295aMark Lobodzinski skip |= ValidateObjectNotInUse(device_data, *buffer_view_state, *obj_struct, VALIDATION_ERROR_00701); 2715842b2d28ded1c6e2c38491a81213d0e1d1b7295aMark Lobodzinski } 2716842b2d28ded1c6e2c38491a81213d0e1d1b7295aMark Lobodzinski return skip; 2717842b2d28ded1c6e2c38491a81213d0e1d1b7295aMark Lobodzinski} 2718842b2d28ded1c6e2c38491a81213d0e1d1b7295aMark Lobodzinski 2719842b2d28ded1c6e2c38491a81213d0e1d1b7295aMark Lobodzinskivoid PostCallRecordDestroyBufferView(layer_data *device_data, VkBufferView buffer_view, BUFFER_VIEW_STATE *buffer_view_state, 2720842b2d28ded1c6e2c38491a81213d0e1d1b7295aMark Lobodzinski VK_OBJECT obj_struct) { 2721842b2d28ded1c6e2c38491a81213d0e1d1b7295aMark Lobodzinski // Any bound cmd buffers are now invalid 2722842b2d28ded1c6e2c38491a81213d0e1d1b7295aMark Lobodzinski invalidateCommandBuffers(device_data, buffer_view_state->cb_bindings, obj_struct); 2723842b2d28ded1c6e2c38491a81213d0e1d1b7295aMark Lobodzinski GetBufferViewMap(device_data)->erase(buffer_view); 2724842b2d28ded1c6e2c38491a81213d0e1d1b7295aMark Lobodzinski} 272523bb5a2fd221f6788daf2dd976bf19a5e9b20fb9Mark Lobodzinski 272623bb5a2fd221f6788daf2dd976bf19a5e9b20fb9Mark Lobodzinskibool PreCallValidateCmdFillBuffer(layer_data *device_data, GLOBAL_CB_NODE *cb_node, BUFFER_STATE *buffer_state) { 272723bb5a2fd221f6788daf2dd976bf19a5e9b20fb9Mark Lobodzinski bool skip = false; 272823bb5a2fd221f6788daf2dd976bf19a5e9b20fb9Mark Lobodzinski skip |= ValidateMemoryIsBoundToBuffer(device_data, buffer_state, "vkCmdFillBuffer()", VALIDATION_ERROR_02529); 2729baa50ccc5a8cf7a6f7474148f301802c5480e715Mike Schuchardt skip |= ValidateCmdQueueFlags(device_data, cb_node, "vkCmdFillBuffer()", 2730baa50ccc5a8cf7a6f7474148f301802c5480e715Mike Schuchardt VK_QUEUE_TRANSFER_BIT | VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT, VALIDATION_ERROR_01141); 273123bb5a2fd221f6788daf2dd976bf19a5e9b20fb9Mark Lobodzinski skip |= ValidateCmd(device_data, cb_node, CMD_FILLBUFFER, "vkCmdFillBuffer()"); 273223bb5a2fd221f6788daf2dd976bf19a5e9b20fb9Mark Lobodzinski // Validate that DST buffer has correct usage flags set 273323bb5a2fd221f6788daf2dd976bf19a5e9b20fb9Mark Lobodzinski skip |= ValidateBufferUsageFlags(device_data, buffer_state, VK_BUFFER_USAGE_TRANSFER_DST_BIT, true, VALIDATION_ERROR_01137, 273423bb5a2fd221f6788daf2dd976bf19a5e9b20fb9Mark Lobodzinski "vkCmdFillBuffer()", "VK_BUFFER_USAGE_TRANSFER_DST_BIT"); 273523bb5a2fd221f6788daf2dd976bf19a5e9b20fb9Mark Lobodzinski skip |= insideRenderPass(device_data, cb_node, "vkCmdFillBuffer()", VALIDATION_ERROR_01142); 273623bb5a2fd221f6788daf2dd976bf19a5e9b20fb9Mark Lobodzinski return skip; 273723bb5a2fd221f6788daf2dd976bf19a5e9b20fb9Mark Lobodzinski} 273823bb5a2fd221f6788daf2dd976bf19a5e9b20fb9Mark Lobodzinski 273923bb5a2fd221f6788daf2dd976bf19a5e9b20fb9Mark Lobodzinskivoid PreCallRecordCmdFillBuffer(layer_data *device_data, GLOBAL_CB_NODE *cb_node, BUFFER_STATE *buffer_state) { 274023bb5a2fd221f6788daf2dd976bf19a5e9b20fb9Mark Lobodzinski std::function<bool()> function = [=]() { 274123bb5a2fd221f6788daf2dd976bf19a5e9b20fb9Mark Lobodzinski SetBufferMemoryValid(device_data, buffer_state, true); 274223bb5a2fd221f6788daf2dd976bf19a5e9b20fb9Mark Lobodzinski return false; 274323bb5a2fd221f6788daf2dd976bf19a5e9b20fb9Mark Lobodzinski }; 274423bb5a2fd221f6788daf2dd976bf19a5e9b20fb9Mark Lobodzinski cb_node->validate_functions.push_back(function); 274523bb5a2fd221f6788daf2dd976bf19a5e9b20fb9Mark Lobodzinski // Update bindings between buffer and cmd buffer 274623bb5a2fd221f6788daf2dd976bf19a5e9b20fb9Mark Lobodzinski AddCommandBufferBindingBuffer(device_data, cb_node, buffer_state); 274723bb5a2fd221f6788daf2dd976bf19a5e9b20fb9Mark Lobodzinski core_validation::UpdateCmdBufferLastCmd(cb_node, CMD_FILLBUFFER); 274823bb5a2fd221f6788daf2dd976bf19a5e9b20fb9Mark Lobodzinski} 2749877577537c1f97bf8d50e32aecd7d3ca09a230a2Mark Lobodzinski 275071c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinskibool ValidateBufferImageCopyData(const debug_report_data *report_data, uint32_t regionCount, const VkBufferImageCopy *pRegions, 275171c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski IMAGE_STATE *image_state, const char *function) { 2752877577537c1f97bf8d50e32aecd7d3ca09a230a2Mark Lobodzinski bool skip = false; 2753877577537c1f97bf8d50e32aecd7d3ca09a230a2Mark Lobodzinski 2754877577537c1f97bf8d50e32aecd7d3ca09a230a2Mark Lobodzinski for (uint32_t i = 0; i < regionCount; i++) { 27555971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton if (image_state->createInfo.imageType == VK_IMAGE_TYPE_1D) { 27565971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton if ((pRegions[i].imageOffset.y != 0) || (pRegions[i].imageExtent.height != 1)) { 27575971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, 27585971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton reinterpret_cast<uint64_t &>(image_state->image), __LINE__, VALIDATION_ERROR_01746, "IMAGE", 27595971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton "%s(): pRegion[%d] imageOffset.y is %d and imageExtent.height is %d. For 1D images these " 27605971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton "must be 0 and 1, respectively. %s", 27615971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton function, i, pRegions[i].imageOffset.y, pRegions[i].imageExtent.height, 27625971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton validation_error_map[VALIDATION_ERROR_01746]); 2763877577537c1f97bf8d50e32aecd7d3ca09a230a2Mark Lobodzinski } 27645971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton } 2765877577537c1f97bf8d50e32aecd7d3ca09a230a2Mark Lobodzinski 27665971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton if ((image_state->createInfo.imageType == VK_IMAGE_TYPE_1D) || (image_state->createInfo.imageType == VK_IMAGE_TYPE_2D)) { 27675971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton if ((pRegions[i].imageOffset.z != 0) || (pRegions[i].imageExtent.depth != 1)) { 2768877577537c1f97bf8d50e32aecd7d3ca09a230a2Mark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, 27695971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton reinterpret_cast<uint64_t &>(image_state->image), __LINE__, VALIDATION_ERROR_01747, "IMAGE", 27705971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton "%s(): pRegion[%d] imageOffset.z is %d and imageExtent.depth is %d. For 1D and 2D images these " 27715971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton "must be 0 and 1, respectively. %s", 27725971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton function, i, pRegions[i].imageOffset.z, pRegions[i].imageExtent.depth, 27735971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton validation_error_map[VALIDATION_ERROR_01747]); 2774877577537c1f97bf8d50e32aecd7d3ca09a230a2Mark Lobodzinski } 27755971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton } 2776877577537c1f97bf8d50e32aecd7d3ca09a230a2Mark Lobodzinski 27775971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton if (image_state->createInfo.imageType == VK_IMAGE_TYPE_3D) { 27785971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton if ((0 != pRegions[i].imageSubresource.baseArrayLayer) || (1 != pRegions[i].imageSubresource.layerCount)) { 2779877577537c1f97bf8d50e32aecd7d3ca09a230a2Mark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, 27805971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton reinterpret_cast<uint64_t &>(image_state->image), __LINE__, VALIDATION_ERROR_01281, "IMAGE", 27815971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton "%s(): pRegion[%d] imageSubresource.baseArrayLayer is %d and imageSubresource.layerCount is " 27825971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton "%d. For 3D images these must be 0 and 1, respectively. %s", 27835971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton function, i, pRegions[i].imageSubresource.baseArrayLayer, pRegions[i].imageSubresource.layerCount, 27845971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton validation_error_map[VALIDATION_ERROR_01281]); 2785877577537c1f97bf8d50e32aecd7d3ca09a230a2Mark Lobodzinski } 27865971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton } 2787877577537c1f97bf8d50e32aecd7d3ca09a230a2Mark Lobodzinski 27885971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton // If the the calling command's VkImage parameter's format is not a depth/stencil format, 27895971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton // then bufferOffset must be a multiple of the calling command's VkImage parameter's texel size 279016769f6b2a7721e391952a97f010cbb530e4f211Dave Houlton auto texel_size = FormatSize(image_state->createInfo.format); 2791cf2ce8673669ca1111e333bdea272c4dd57cb5c2Dave Houlton if (!FormatIsDepthAndStencil(image_state->createInfo.format) && SafeModulo(pRegions[i].bufferOffset, texel_size) != 0) { 27925971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, 27935971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton reinterpret_cast<uint64_t &>(image_state->image), __LINE__, VALIDATION_ERROR_01263, "IMAGE", 27945971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton "%s(): pRegion[%d] bufferOffset 0x%" PRIxLEAST64 27955971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton " must be a multiple of this format's texel size (" PRINTF_SIZE_T_SPECIFIER "). %s", 27965971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton function, i, pRegions[i].bufferOffset, texel_size, validation_error_map[VALIDATION_ERROR_01263]); 27975971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton } 27985971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton 27995971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton // BufferOffset must be a multiple of 4 280016769f6b2a7721e391952a97f010cbb530e4f211Dave Houlton if (SafeModulo(pRegions[i].bufferOffset, 4) != 0) { 28015971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, 28025971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton reinterpret_cast<uint64_t &>(image_state->image), __LINE__, VALIDATION_ERROR_01264, "IMAGE", 28035971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton "%s(): pRegion[%d] bufferOffset 0x%" PRIxLEAST64 " must be a multiple of 4. %s", function, i, 28045971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton pRegions[i].bufferOffset, validation_error_map[VALIDATION_ERROR_01264]); 28055971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton } 28065971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton 28075971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton // BufferRowLength must be 0, or greater than or equal to the width member of imageExtent 28085971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton if ((pRegions[i].bufferRowLength != 0) && (pRegions[i].bufferRowLength < pRegions[i].imageExtent.width)) { 28095971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton skip |= log_msg( 28105971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, 28115971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton reinterpret_cast<uint64_t &>(image_state->image), __LINE__, VALIDATION_ERROR_01265, "IMAGE", 28125971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton "%s(): pRegion[%d] bufferRowLength (%d) must be zero or greater-than-or-equal-to imageExtent.width (%d). %s", 28135971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton function, i, pRegions[i].bufferRowLength, pRegions[i].imageExtent.width, 28145971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton validation_error_map[VALIDATION_ERROR_01265]); 28155971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton } 28165971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton 28175971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton // BufferImageHeight must be 0, or greater than or equal to the height member of imageExtent 28185971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton if ((pRegions[i].bufferImageHeight != 0) && (pRegions[i].bufferImageHeight < pRegions[i].imageExtent.height)) { 28195971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton skip |= log_msg( 28205971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, 28215971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton reinterpret_cast<uint64_t &>(image_state->image), __LINE__, VALIDATION_ERROR_01266, "IMAGE", 28225971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton "%s(): pRegion[%d] bufferImageHeight (%d) must be zero or greater-than-or-equal-to imageExtent.height (%d). %s", 28235971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton function, i, pRegions[i].bufferImageHeight, pRegions[i].imageExtent.height, 28245971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton validation_error_map[VALIDATION_ERROR_01266]); 28255971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton } 28265971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton 28275971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton // subresource aspectMask must have exactly 1 bit set 28285971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton const int num_bits = sizeof(VkFlags) * CHAR_BIT; 28295971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton std::bitset<num_bits> aspect_mask_bits(pRegions[i].imageSubresource.aspectMask); 28305971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton if (aspect_mask_bits.count() != 1) { 28315971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, 28325971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton reinterpret_cast<uint64_t &>(image_state->image), __LINE__, VALIDATION_ERROR_01280, "IMAGE", 28335971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton "%s: aspectMasks for imageSubresource in each region must have only a single bit set. %s", function, 28345971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton validation_error_map[VALIDATION_ERROR_01280]); 28355971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton } 28365971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton 28375971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton // image subresource aspect bit must match format 2838e9d74ac8e13687c1be3ee147efce42e8215a049eDave Houlton if (!VerifyAspectsPresent(pRegions[i].imageSubresource.aspectMask, image_state->createInfo.format)) { 28395971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton skip |= log_msg( 28405971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, 28415971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton reinterpret_cast<uint64_t &>(image_state->image), __LINE__, VALIDATION_ERROR_01279, "IMAGE", 28425971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton "%s(): pRegion[%d] subresource aspectMask 0x%x specifies aspects that are not present in image format 0x%x. %s", 28435971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton function, i, pRegions[i].imageSubresource.aspectMask, image_state->createInfo.format, 28445971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton validation_error_map[VALIDATION_ERROR_01279]); 28455971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton } 28465971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton 28475971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton // Checks that apply only to compressed images 28485971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton // TODO: there is a comment in ValidateCopyBufferImageTransferGranularityRequirements() in core_validation.cpp that 28495971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton // reserves a place for these compressed image checks. This block of code could move there once the image 28505971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton // stuff is moved into core validation. 285116769f6b2a7721e391952a97f010cbb530e4f211Dave Houlton if (FormatIsCompressed(image_state->createInfo.format)) { 285216769f6b2a7721e391952a97f010cbb530e4f211Dave Houlton auto block_size = FormatCompressedTexelBlockExtent(image_state->createInfo.format); 2853877577537c1f97bf8d50e32aecd7d3ca09a230a2Mark Lobodzinski 28545971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton // BufferRowLength must be a multiple of block width 285516769f6b2a7721e391952a97f010cbb530e4f211Dave Houlton if (SafeModulo(pRegions[i].bufferRowLength, block_size.width) != 0) { 2856877577537c1f97bf8d50e32aecd7d3ca09a230a2Mark Lobodzinski skip |= log_msg( 2857877577537c1f97bf8d50e32aecd7d3ca09a230a2Mark Lobodzinski report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, 28585971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton reinterpret_cast<uint64_t &>(image_state->image), __LINE__, VALIDATION_ERROR_01271, "IMAGE", 28595971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton "%s(): pRegion[%d] bufferRowLength (%d) must be a multiple of the compressed image's texel width (%d). %s.", 28605971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton function, i, pRegions[i].bufferRowLength, block_size.width, validation_error_map[VALIDATION_ERROR_01271]); 2861877577537c1f97bf8d50e32aecd7d3ca09a230a2Mark Lobodzinski } 2862877577537c1f97bf8d50e32aecd7d3ca09a230a2Mark Lobodzinski 28635971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton // BufferRowHeight must be a multiple of block height 286416769f6b2a7721e391952a97f010cbb530e4f211Dave Houlton if (SafeModulo(pRegions[i].bufferImageHeight, block_size.height) != 0) { 2865877577537c1f97bf8d50e32aecd7d3ca09a230a2Mark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, 28665971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton reinterpret_cast<uint64_t &>(image_state->image), __LINE__, VALIDATION_ERROR_01272, "IMAGE", 28675971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton "%s(): pRegion[%d] bufferImageHeight (%d) must be a multiple of the compressed image's texel " 28685971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton "height (%d). %s.", 28695971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton function, i, pRegions[i].bufferImageHeight, block_size.height, 28705971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton validation_error_map[VALIDATION_ERROR_01272]); 2871877577537c1f97bf8d50e32aecd7d3ca09a230a2Mark Lobodzinski } 2872877577537c1f97bf8d50e32aecd7d3ca09a230a2Mark Lobodzinski 28735971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton // image offsets must be multiples of block dimensions 287416769f6b2a7721e391952a97f010cbb530e4f211Dave Houlton if ((SafeModulo(pRegions[i].imageOffset.x, block_size.width) != 0) || 287516769f6b2a7721e391952a97f010cbb530e4f211Dave Houlton (SafeModulo(pRegions[i].imageOffset.y, block_size.height) != 0) || 287616769f6b2a7721e391952a97f010cbb530e4f211Dave Houlton (SafeModulo(pRegions[i].imageOffset.z, block_size.depth) != 0)) { 28775971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, 28785971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton reinterpret_cast<uint64_t &>(image_state->image), __LINE__, VALIDATION_ERROR_01273, "IMAGE", 28795971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton "%s(): pRegion[%d] imageOffset(x,y) (%d, %d) must be multiples of the compressed image's texel " 28805971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton "width & height (%d, %d). %s.", 28815971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton function, i, pRegions[i].imageOffset.x, pRegions[i].imageOffset.y, block_size.width, 28825971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton block_size.height, validation_error_map[VALIDATION_ERROR_01273]); 2883877577537c1f97bf8d50e32aecd7d3ca09a230a2Mark Lobodzinski } 2884877577537c1f97bf8d50e32aecd7d3ca09a230a2Mark Lobodzinski 28855971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton // bufferOffset must be a multiple of block size (linear bytes) 288616769f6b2a7721e391952a97f010cbb530e4f211Dave Houlton size_t block_size_in_bytes = FormatSize(image_state->createInfo.format); 288716769f6b2a7721e391952a97f010cbb530e4f211Dave Houlton if (SafeModulo(pRegions[i].bufferOffset, block_size_in_bytes) != 0) { 28885971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, 28895971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton reinterpret_cast<uint64_t &>(image_state->image), __LINE__, VALIDATION_ERROR_01274, "IMAGE", 28905971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton "%s(): pRegion[%d] bufferOffset (0x%" PRIxLEAST64 28915971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton ") must be a multiple of the compressed image's texel block " 28925971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton "size (" PRINTF_SIZE_T_SPECIFIER "). %s.", 28935971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton function, i, pRegions[i].bufferOffset, block_size_in_bytes, 28945971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton validation_error_map[VALIDATION_ERROR_01274]); 2895877577537c1f97bf8d50e32aecd7d3ca09a230a2Mark Lobodzinski } 28962cd49094dcd399721f50c123413b8f55693348d7Dave Houlton 28972cd49094dcd399721f50c123413b8f55693348d7Dave Houlton // imageExtent width must be a multiple of block width, or extent+offset width must equal subresource width 2898045a77f666b6efc8a229481b2a7a351f725e3725Dave Houlton VkExtent3D mip_extent = GetImageSubresourceExtent(image_state, &(pRegions[i].imageSubresource)); 289916769f6b2a7721e391952a97f010cbb530e4f211Dave Houlton if ((SafeModulo(pRegions[i].imageExtent.width, block_size.width) != 0) && 2900045a77f666b6efc8a229481b2a7a351f725e3725Dave Houlton (pRegions[i].imageExtent.width + pRegions[i].imageOffset.x != mip_extent.width)) { 2901045a77f666b6efc8a229481b2a7a351f725e3725Dave Houlton skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, 2902045a77f666b6efc8a229481b2a7a351f725e3725Dave Houlton reinterpret_cast<uint64_t &>(image_state->image), __LINE__, VALIDATION_ERROR_01275, "IMAGE", 2903045a77f666b6efc8a229481b2a7a351f725e3725Dave Houlton "%s(): pRegion[%d] extent width (%d) must be a multiple of the compressed texture block width " 2904045a77f666b6efc8a229481b2a7a351f725e3725Dave Houlton "(%d), or when added to offset.x (%d) must equal the image subresource width (%d). %s.", 2905045a77f666b6efc8a229481b2a7a351f725e3725Dave Houlton function, i, pRegions[i].imageExtent.width, block_size.width, pRegions[i].imageOffset.x, 2906045a77f666b6efc8a229481b2a7a351f725e3725Dave Houlton mip_extent.width, validation_error_map[VALIDATION_ERROR_01275]); 29072cd49094dcd399721f50c123413b8f55693348d7Dave Houlton } 29082cd49094dcd399721f50c123413b8f55693348d7Dave Houlton 29092cd49094dcd399721f50c123413b8f55693348d7Dave Houlton // imageExtent height must be a multiple of block height, or extent+offset height must equal subresource height 291016769f6b2a7721e391952a97f010cbb530e4f211Dave Houlton if ((SafeModulo(pRegions[i].imageExtent.height, block_size.height) != 0) && 2911045a77f666b6efc8a229481b2a7a351f725e3725Dave Houlton (pRegions[i].imageExtent.height + pRegions[i].imageOffset.y != mip_extent.height)) { 2912045a77f666b6efc8a229481b2a7a351f725e3725Dave Houlton skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, 2913045a77f666b6efc8a229481b2a7a351f725e3725Dave Houlton reinterpret_cast<uint64_t &>(image_state->image), __LINE__, VALIDATION_ERROR_01276, "IMAGE", 2914045a77f666b6efc8a229481b2a7a351f725e3725Dave Houlton "%s(): pRegion[%d] extent height (%d) must be a multiple of the compressed texture block height " 2915045a77f666b6efc8a229481b2a7a351f725e3725Dave Houlton "(%d), or when added to offset.y (%d) must equal the image subresource height (%d). %s.", 2916045a77f666b6efc8a229481b2a7a351f725e3725Dave Houlton function, i, pRegions[i].imageExtent.height, block_size.height, pRegions[i].imageOffset.y, 2917045a77f666b6efc8a229481b2a7a351f725e3725Dave Houlton mip_extent.height, validation_error_map[VALIDATION_ERROR_01276]); 29182cd49094dcd399721f50c123413b8f55693348d7Dave Houlton } 29192cd49094dcd399721f50c123413b8f55693348d7Dave Houlton 29202cd49094dcd399721f50c123413b8f55693348d7Dave Houlton // imageExtent depth must be a multiple of block depth, or extent+offset depth must equal subresource depth 292116769f6b2a7721e391952a97f010cbb530e4f211Dave Houlton if ((SafeModulo(pRegions[i].imageExtent.depth, block_size.depth) != 0) && 2922045a77f666b6efc8a229481b2a7a351f725e3725Dave Houlton (pRegions[i].imageExtent.depth + pRegions[i].imageOffset.z != mip_extent.depth)) { 2923045a77f666b6efc8a229481b2a7a351f725e3725Dave Houlton skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, 2924045a77f666b6efc8a229481b2a7a351f725e3725Dave Houlton reinterpret_cast<uint64_t &>(image_state->image), __LINE__, VALIDATION_ERROR_01277, "IMAGE", 2925045a77f666b6efc8a229481b2a7a351f725e3725Dave Houlton "%s(): pRegion[%d] extent width (%d) must be a multiple of the compressed texture block depth " 2926045a77f666b6efc8a229481b2a7a351f725e3725Dave Houlton "(%d), or when added to offset.z (%d) must equal the image subresource depth (%d). %s.", 2927045a77f666b6efc8a229481b2a7a351f725e3725Dave Houlton function, i, pRegions[i].imageExtent.depth, block_size.depth, pRegions[i].imageOffset.z, 2928045a77f666b6efc8a229481b2a7a351f725e3725Dave Houlton mip_extent.depth, validation_error_map[VALIDATION_ERROR_01277]); 29292cd49094dcd399721f50c123413b8f55693348d7Dave Houlton } 29305971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton } 293171c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski } 293271c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski 293371c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski return skip; 293471c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski} 293571c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski 29365971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houltonstatic bool ValidateImageBounds(const debug_report_data *report_data, const IMAGE_STATE *image_state, const uint32_t regionCount, 29375971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton const VkBufferImageCopy *pRegions, const char *func_name, UNIQUE_VALIDATION_ERROR_CODE msg_code) { 293871c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski bool skip = false; 29395971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton const VkImageCreateInfo *image_info = &(image_state->createInfo); 294071c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski 294171c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski for (uint32_t i = 0; i < regionCount; i++) { 294271c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski VkExtent3D extent = pRegions[i].imageExtent; 294371c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski VkOffset3D offset = pRegions[i].imageOffset; 294471c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski 29455971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton if (IsExtentSizeZero(&extent)) // Warn on zero area subresource 29465971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton { 29475971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton skip |= log_msg(report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 29485971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton (uint64_t)0, __LINE__, IMAGE_ZERO_AREA_SUBREGION, "IMAGE", 29495971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton "%s: pRegion[%d] imageExtent of {%1d, %1d, %1d} has zero area", func_name, i, extent.width, 29505971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton extent.height, extent.depth); 295171c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski } 295271c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski 29535971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton VkExtent3D image_extent = GetImageSubresourceExtent(image_state, &(pRegions[i].imageSubresource)); 29545971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton 29555971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton // If we're using a compressed format, valid extent is rounded up to multiple of block size (per 18.1) 295616769f6b2a7721e391952a97f010cbb530e4f211Dave Houlton if (FormatIsCompressed(image_info->format)) { 295716769f6b2a7721e391952a97f010cbb530e4f211Dave Houlton auto block_extent = FormatCompressedTexelBlockExtent(image_info->format); 29585971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton if (image_extent.width % block_extent.width) { 29595971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton image_extent.width += (block_extent.width - (image_extent.width % block_extent.width)); 29605971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton } 29615971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton if (image_extent.height % block_extent.height) { 29625971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton image_extent.height += (block_extent.height - (image_extent.height % block_extent.height)); 29635971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton } 29645971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton if (image_extent.depth % block_extent.depth) { 29655971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton image_extent.depth += (block_extent.depth - (image_extent.depth % block_extent.depth)); 29665971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton } 296771c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski } 296871c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski 29693fb79e4c87829ef090622d69a117f33ec7d4ded5Dave Houlton if (0 != ExceedsBounds(&offset, &extent, &image_extent)) { 297071c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, (uint64_t)0, 29715971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton __LINE__, msg_code, "IMAGE", "%s: pRegion[%d] exceeds image bounds. %s.", func_name, i, 297271c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski validation_error_map[msg_code]); 2973877577537c1f97bf8d50e32aecd7d3ca09a230a2Mark Lobodzinski } 2974877577537c1f97bf8d50e32aecd7d3ca09a230a2Mark Lobodzinski } 2975877577537c1f97bf8d50e32aecd7d3ca09a230a2Mark Lobodzinski 2976877577537c1f97bf8d50e32aecd7d3ca09a230a2Mark Lobodzinski return skip; 2977877577537c1f97bf8d50e32aecd7d3ca09a230a2Mark Lobodzinski} 2978877577537c1f97bf8d50e32aecd7d3ca09a230a2Mark Lobodzinski 297971c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinskistatic inline bool ValidtateBufferBounds(const debug_report_data *report_data, IMAGE_STATE *image_state, BUFFER_STATE *buff_state, 298071c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski uint32_t regionCount, const VkBufferImageCopy *pRegions, const char *func_name, 298171c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski UNIQUE_VALIDATION_ERROR_CODE msg_code) { 298271c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski bool skip = false; 298371c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski 298471c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski VkDeviceSize buffer_size = buff_state->createInfo.size; 298571c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski 298671c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski for (uint32_t i = 0; i < regionCount; i++) { 298771c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski VkExtent3D copy_extent = pRegions[i].imageExtent; 298871c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski 298971c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski VkDeviceSize buffer_width = (0 == pRegions[i].bufferRowLength ? copy_extent.width : pRegions[i].bufferRowLength); 299071c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski VkDeviceSize buffer_height = (0 == pRegions[i].bufferImageHeight ? copy_extent.height : pRegions[i].bufferImageHeight); 299116769f6b2a7721e391952a97f010cbb530e4f211Dave Houlton VkDeviceSize unit_size = FormatSize(image_state->createInfo.format); // size (bytes) of texel or block 299271c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski 29931dc764a1d9155b6fb137006f21e7f6a354aad310Dave Houlton // Handle special buffer packing rules for specific depth/stencil formats 29941dc764a1d9155b6fb137006f21e7f6a354aad310Dave Houlton if (pRegions[i].imageSubresource.aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT) { 299516769f6b2a7721e391952a97f010cbb530e4f211Dave Houlton unit_size = FormatSize(VK_FORMAT_S8_UINT); 29961dc764a1d9155b6fb137006f21e7f6a354aad310Dave Houlton } else if (pRegions[i].imageSubresource.aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT) { 29971dc764a1d9155b6fb137006f21e7f6a354aad310Dave Houlton switch (image_state->createInfo.format) { 29981dc764a1d9155b6fb137006f21e7f6a354aad310Dave Houlton case VK_FORMAT_D16_UNORM_S8_UINT: 299916769f6b2a7721e391952a97f010cbb530e4f211Dave Houlton unit_size = FormatSize(VK_FORMAT_D16_UNORM); 30001dc764a1d9155b6fb137006f21e7f6a354aad310Dave Houlton break; 30011dc764a1d9155b6fb137006f21e7f6a354aad310Dave Houlton case VK_FORMAT_D32_SFLOAT_S8_UINT: 300216769f6b2a7721e391952a97f010cbb530e4f211Dave Houlton unit_size = FormatSize(VK_FORMAT_D32_SFLOAT); 30031dc764a1d9155b6fb137006f21e7f6a354aad310Dave Houlton break; 30045971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton case VK_FORMAT_X8_D24_UNORM_PACK32: // Fall through 30051dc764a1d9155b6fb137006f21e7f6a354aad310Dave Houlton case VK_FORMAT_D24_UNORM_S8_UINT: 30061dc764a1d9155b6fb137006f21e7f6a354aad310Dave Houlton unit_size = 4; 30071dc764a1d9155b6fb137006f21e7f6a354aad310Dave Houlton break; 30081dc764a1d9155b6fb137006f21e7f6a354aad310Dave Houlton default: 30091dc764a1d9155b6fb137006f21e7f6a354aad310Dave Houlton break; 30101dc764a1d9155b6fb137006f21e7f6a354aad310Dave Houlton } 30111dc764a1d9155b6fb137006f21e7f6a354aad310Dave Houlton } 30121dc764a1d9155b6fb137006f21e7f6a354aad310Dave Houlton 301316769f6b2a7721e391952a97f010cbb530e4f211Dave Houlton if (FormatIsCompressed(image_state->createInfo.format)) { 30145971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton // Switch to texel block units, rounding up for any partially-used blocks 301516769f6b2a7721e391952a97f010cbb530e4f211Dave Houlton auto block_dim = FormatCompressedTexelBlockExtent(image_state->createInfo.format); 30165971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton buffer_width = (buffer_width + block_dim.width - 1) / block_dim.width; 30175971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton buffer_height = (buffer_height + block_dim.height - 1) / block_dim.height; 301871c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski 30195971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton copy_extent.width = (copy_extent.width + block_dim.width - 1) / block_dim.width; 30205971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton copy_extent.height = (copy_extent.height + block_dim.height - 1) / block_dim.height; 30215971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton copy_extent.depth = (copy_extent.depth + block_dim.depth - 1) / block_dim.depth; 30225971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton } 302371c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski 30245971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton // Either depth or layerCount may be greater than 1 (not both). This is the number of 'slices' to copy 30255971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton uint32_t z_copies = std::max(copy_extent.depth, pRegions[i].imageSubresource.layerCount); 30265971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton if (IsExtentSizeZero(©_extent) || (0 == z_copies)) { 30275971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton // TODO: Issure warning here? Already warned in ValidateImageBounds()... 30285971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton } else { 30295971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton // Calculate buffer offset of final copied byte, + 1. 30305971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton VkDeviceSize max_buffer_offset = (z_copies - 1) * buffer_height * buffer_width; // offset to slice 30315971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton max_buffer_offset += ((copy_extent.height - 1) * buffer_width) + copy_extent.width; // add row,col 30325971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton max_buffer_offset *= unit_size; // convert to bytes 30335971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton max_buffer_offset += pRegions[i].bufferOffset; // add initial offset (bytes) 303471c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski 30355971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton if (buffer_size < max_buffer_offset) { 30365971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton skip |= 30375971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, (uint64_t)0, 30385971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton __LINE__, msg_code, "IMAGE", "%s: pRegion[%d] exceeds buffer size of %" PRIu64 " bytes. %s.", func_name, 30395971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton i, buffer_size, validation_error_map[msg_code]); 30405971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton } 304171c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski } 304271c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski } 304371c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski 304471c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski return skip; 304571c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski} 304671c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski 304771c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinskibool PreCallValidateCmdCopyImageToBuffer(layer_data *device_data, VkImageLayout srcImageLayout, GLOBAL_CB_NODE *cb_node, 3048940f70f1340803d185c67633b05ef048d277952eMark Lobodzinski IMAGE_STATE *src_image_state, BUFFER_STATE *dst_buffer_state, uint32_t regionCount, 3049877577537c1f97bf8d50e32aecd7d3ca09a230a2Mark Lobodzinski const VkBufferImageCopy *pRegions, const char *func_name) { 305071c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski const debug_report_data *report_data = core_validation::GetReportData(device_data); 305171c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski bool skip = ValidateBufferImageCopyData(report_data, regionCount, pRegions, src_image_state, "vkCmdCopyImageToBuffer"); 305271c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski 305371c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski // Validate command buffer state 305471c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski if (CB_RECORDING != cb_node->state) { 305571c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 305671c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski (uint64_t)cb_node->commandBuffer, __LINE__, VALIDATION_ERROR_01258, "DS", 305771c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski "Cannot call vkCmdCopyImageToBuffer() on command buffer which is not in recording state. %s.", 305871c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski validation_error_map[VALIDATION_ERROR_01258]); 305971c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski } else { 306071c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski skip |= ValidateCmdSubpassState(device_data, cb_node, CMD_COPYIMAGETOBUFFER); 306171c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski } 306271c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski 306371c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski // Command pool must support graphics, compute, or transfer operations 306471c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski auto pPool = GetCommandPoolNode(device_data, cb_node->createInfo.commandPool); 306571c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski 306671c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski VkQueueFlags queue_flags = GetPhysDevProperties(device_data)->queue_family_properties[pPool->queueFamilyIndex].queueFlags; 306771c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski if (0 == (queue_flags & (VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT | VK_QUEUE_TRANSFER_BIT))) { 306871c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 306971c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski (uint64_t)cb_node->createInfo.commandPool, __LINE__, VALIDATION_ERROR_01259, "DS", 307071c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski "Cannot call vkCmdCopyImageToBuffer() on a command buffer allocated from a pool without graphics, compute, " 307171c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski "or transfer capabilities. %s.", 307271c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski validation_error_map[VALIDATION_ERROR_01259]); 307371c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski } 30745971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton skip |= ValidateImageBounds(report_data, src_image_state, regionCount, pRegions, "vkCmdCopyBufferToImage()", 307571c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski VALIDATION_ERROR_01245); 3076940f70f1340803d185c67633b05ef048d277952eMark Lobodzinski skip |= ValidtateBufferBounds(report_data, src_image_state, dst_buffer_state, regionCount, pRegions, "vkCmdCopyImageToBuffer()", 307771c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski VALIDATION_ERROR_01246); 307871c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski 307971c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski skip |= ValidateImageSampleCount(device_data, src_image_state, VK_SAMPLE_COUNT_1_BIT, "vkCmdCopyImageToBuffer(): srcImage", 308071c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski VALIDATION_ERROR_01249); 308171c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski skip |= ValidateMemoryIsBoundToImage(device_data, src_image_state, "vkCmdCopyImageToBuffer()", VALIDATION_ERROR_02537); 3082940f70f1340803d185c67633b05ef048d277952eMark Lobodzinski skip |= ValidateMemoryIsBoundToBuffer(device_data, dst_buffer_state, "vkCmdCopyImageToBuffer()", VALIDATION_ERROR_02538); 3083d5cde34b61eb694c6fe1d5e53de61bb87bf6936aMark Lobodzinski 308471c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski // Validate that SRC image & DST buffer have correct usage flags set 308571c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski skip |= ValidateImageUsageFlags(device_data, src_image_state, VK_IMAGE_USAGE_TRANSFER_SRC_BIT, true, VALIDATION_ERROR_01248, 308671c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski "vkCmdCopyImageToBuffer()", "VK_IMAGE_USAGE_TRANSFER_SRC_BIT"); 3087940f70f1340803d185c67633b05ef048d277952eMark Lobodzinski skip |= ValidateBufferUsageFlags(device_data, dst_buffer_state, VK_BUFFER_USAGE_TRANSFER_DST_BIT, true, VALIDATION_ERROR_01252, 308871c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski "vkCmdCopyImageToBuffer()", "VK_BUFFER_USAGE_TRANSFER_DST_BIT"); 3089d5cde34b61eb694c6fe1d5e53de61bb87bf6936aMark Lobodzinski skip |= insideRenderPass(device_data, cb_node, "vkCmdCopyImageToBuffer()", VALIDATION_ERROR_01260); 30900db18ab1345f9e10907913b22ea5d57bd48077ebTobin Ehlis bool hit_error = false; 3091d5cde34b61eb694c6fe1d5e53de61bb87bf6936aMark Lobodzinski for (uint32_t i = 0; i < regionCount; ++i) { 30920db18ab1345f9e10907913b22ea5d57bd48077ebTobin Ehlis skip |= 30930db18ab1345f9e10907913b22ea5d57bd48077ebTobin Ehlis VerifyImageLayout(device_data, cb_node, src_image_state, pRegions[i].imageSubresource, srcImageLayout, 30940db18ab1345f9e10907913b22ea5d57bd48077ebTobin Ehlis VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, "vkCmdCopyImageToBuffer()", VALIDATION_ERROR_01251, &hit_error); 3095d5cde34b61eb694c6fe1d5e53de61bb87bf6936aMark Lobodzinski skip |= ValidateCopyBufferImageTransferGranularityRequirements(device_data, cb_node, src_image_state, &pRegions[i], i, 3096fab4fd84d0d187bc73b5bc6709d8ed6370bb7cc3Tobin Ehlis "vkCmdCopyImageToBuffer()"); 3097d5cde34b61eb694c6fe1d5e53de61bb87bf6936aMark Lobodzinski } 3098d5cde34b61eb694c6fe1d5e53de61bb87bf6936aMark Lobodzinski return skip; 3099d5cde34b61eb694c6fe1d5e53de61bb87bf6936aMark Lobodzinski} 3100d5cde34b61eb694c6fe1d5e53de61bb87bf6936aMark Lobodzinski 3101d5cde34b61eb694c6fe1d5e53de61bb87bf6936aMark Lobodzinskivoid PreCallRecordCmdCopyImageToBuffer(layer_data *device_data, GLOBAL_CB_NODE *cb_node, IMAGE_STATE *src_image_state, 3102a07ae8bd5f566eb9b073498dd4280efdb0b838b9Tobin Ehlis BUFFER_STATE *dst_buffer_state, uint32_t region_count, const VkBufferImageCopy *regions, 3103a07ae8bd5f566eb9b073498dd4280efdb0b838b9Tobin Ehlis VkImageLayout src_image_layout) { 3104a07ae8bd5f566eb9b073498dd4280efdb0b838b9Tobin Ehlis // Make sure that all image slices are updated to correct layout 3105a07ae8bd5f566eb9b073498dd4280efdb0b838b9Tobin Ehlis for (uint32_t i = 0; i < region_count; ++i) { 3106a07ae8bd5f566eb9b073498dd4280efdb0b838b9Tobin Ehlis SetImageLayout(device_data, cb_node, src_image_state, regions[i].imageSubresource, src_image_layout); 3107a07ae8bd5f566eb9b073498dd4280efdb0b838b9Tobin Ehlis } 3108d5cde34b61eb694c6fe1d5e53de61bb87bf6936aMark Lobodzinski // Update bindings between buffer/image and cmd buffer 3109d5cde34b61eb694c6fe1d5e53de61bb87bf6936aMark Lobodzinski AddCommandBufferBindingImage(device_data, cb_node, src_image_state); 3110940f70f1340803d185c67633b05ef048d277952eMark Lobodzinski AddCommandBufferBindingBuffer(device_data, cb_node, dst_buffer_state); 3111d5cde34b61eb694c6fe1d5e53de61bb87bf6936aMark Lobodzinski 311271c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski std::function<bool()> function = [=]() { 311371c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski return ValidateImageMemoryIsValid(device_data, src_image_state, "vkCmdCopyImageToBuffer()"); 311471c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski }; 311571c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski cb_node->validate_functions.push_back(function); 311671c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski function = [=]() { 3117940f70f1340803d185c67633b05ef048d277952eMark Lobodzinski SetBufferMemoryValid(device_data, dst_buffer_state, true); 311871c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski return false; 311971c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski }; 312071c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski cb_node->validate_functions.push_back(function); 312171c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski 312271c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski core_validation::UpdateCmdBufferLastCmd(cb_node, CMD_COPYIMAGETOBUFFER); 3123877577537c1f97bf8d50e32aecd7d3ca09a230a2Mark Lobodzinski} 3124877577537c1f97bf8d50e32aecd7d3ca09a230a2Mark Lobodzinski 312571c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinskibool PreCallValidateCmdCopyBufferToImage(layer_data *device_data, VkImageLayout dstImageLayout, GLOBAL_CB_NODE *cb_node, 3126940f70f1340803d185c67633b05ef048d277952eMark Lobodzinski BUFFER_STATE *src_buffer_state, IMAGE_STATE *dst_image_state, uint32_t regionCount, 3127877577537c1f97bf8d50e32aecd7d3ca09a230a2Mark Lobodzinski const VkBufferImageCopy *pRegions, const char *func_name) { 312871c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski const debug_report_data *report_data = core_validation::GetReportData(device_data); 312971c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski bool skip = ValidateBufferImageCopyData(report_data, regionCount, pRegions, dst_image_state, "vkCmdCopyBufferToImage"); 313071c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski 313171c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski // Validate command buffer state 313271c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski if (CB_RECORDING != cb_node->state) { 313371c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 313471c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski (uint64_t)cb_node->commandBuffer, __LINE__, VALIDATION_ERROR_01240, "DS", 313571c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski "Cannot call vkCmdCopyBufferToImage() on command buffer which is not in recording state. %s.", 313671c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski validation_error_map[VALIDATION_ERROR_01240]); 313771c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski } else { 313871c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski skip |= ValidateCmdSubpassState(device_data, cb_node, CMD_COPYBUFFERTOIMAGE); 313971c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski } 314071c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski 314171c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski // Command pool must support graphics, compute, or transfer operations 314271c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski auto pPool = GetCommandPoolNode(device_data, cb_node->createInfo.commandPool); 314371c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski VkQueueFlags queue_flags = GetPhysDevProperties(device_data)->queue_family_properties[pPool->queueFamilyIndex].queueFlags; 314471c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski if (0 == (queue_flags & (VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT | VK_QUEUE_TRANSFER_BIT))) { 314571c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 314671c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski (uint64_t)cb_node->createInfo.commandPool, __LINE__, VALIDATION_ERROR_01241, "DS", 314771c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski "Cannot call vkCmdCopyBufferToImage() on a command buffer allocated from a pool without graphics, compute, " 314871c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski "or transfer capabilities. %s.", 314971c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski validation_error_map[VALIDATION_ERROR_01241]); 315071c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski } 31515971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton skip |= ValidateImageBounds(report_data, dst_image_state, regionCount, pRegions, "vkCmdCopyBufferToImage()", 315271c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski VALIDATION_ERROR_01228); 3153940f70f1340803d185c67633b05ef048d277952eMark Lobodzinski skip |= ValidtateBufferBounds(report_data, dst_image_state, src_buffer_state, regionCount, pRegions, "vkCmdCopyBufferToImage()", 315471c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski VALIDATION_ERROR_01227); 315571c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski skip |= ValidateImageSampleCount(device_data, dst_image_state, VK_SAMPLE_COUNT_1_BIT, "vkCmdCopyBufferToImage(): dstImage", 315671c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski VALIDATION_ERROR_01232); 3157940f70f1340803d185c67633b05ef048d277952eMark Lobodzinski skip |= ValidateMemoryIsBoundToBuffer(device_data, src_buffer_state, "vkCmdCopyBufferToImage()", VALIDATION_ERROR_02535); 315871c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski skip |= ValidateMemoryIsBoundToImage(device_data, dst_image_state, "vkCmdCopyBufferToImage()", VALIDATION_ERROR_02536); 3159940f70f1340803d185c67633b05ef048d277952eMark Lobodzinski skip |= ValidateBufferUsageFlags(device_data, src_buffer_state, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, true, VALIDATION_ERROR_01230, 316071c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski "vkCmdCopyBufferToImage()", "VK_BUFFER_USAGE_TRANSFER_SRC_BIT"); 316171c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski skip |= ValidateImageUsageFlags(device_data, dst_image_state, VK_IMAGE_USAGE_TRANSFER_DST_BIT, true, VALIDATION_ERROR_01231, 316271c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski "vkCmdCopyBufferToImage()", "VK_IMAGE_USAGE_TRANSFER_DST_BIT"); 3163d5cde34b61eb694c6fe1d5e53de61bb87bf6936aMark Lobodzinski skip |= insideRenderPass(device_data, cb_node, "vkCmdCopyBufferToImage()", VALIDATION_ERROR_01242); 31640db18ab1345f9e10907913b22ea5d57bd48077ebTobin Ehlis bool hit_error = false; 3165d5cde34b61eb694c6fe1d5e53de61bb87bf6936aMark Lobodzinski for (uint32_t i = 0; i < regionCount; ++i) { 31660db18ab1345f9e10907913b22ea5d57bd48077ebTobin Ehlis skip |= 31670db18ab1345f9e10907913b22ea5d57bd48077ebTobin Ehlis VerifyImageLayout(device_data, cb_node, dst_image_state, pRegions[i].imageSubresource, dstImageLayout, 31680db18ab1345f9e10907913b22ea5d57bd48077ebTobin Ehlis VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, "vkCmdCopyBufferToImage()", VALIDATION_ERROR_01234, &hit_error); 3169d5cde34b61eb694c6fe1d5e53de61bb87bf6936aMark Lobodzinski skip |= ValidateCopyBufferImageTransferGranularityRequirements(device_data, cb_node, dst_image_state, &pRegions[i], i, 3170d5cde34b61eb694c6fe1d5e53de61bb87bf6936aMark Lobodzinski "vkCmdCopyBufferToImage()"); 3171d5cde34b61eb694c6fe1d5e53de61bb87bf6936aMark Lobodzinski } 3172d5cde34b61eb694c6fe1d5e53de61bb87bf6936aMark Lobodzinski return skip; 3173d5cde34b61eb694c6fe1d5e53de61bb87bf6936aMark Lobodzinski} 3174d5cde34b61eb694c6fe1d5e53de61bb87bf6936aMark Lobodzinski 3175940f70f1340803d185c67633b05ef048d277952eMark Lobodzinskivoid PreCallRecordCmdCopyBufferToImage(layer_data *device_data, GLOBAL_CB_NODE *cb_node, BUFFER_STATE *src_buffer_state, 3176a07ae8bd5f566eb9b073498dd4280efdb0b838b9Tobin Ehlis IMAGE_STATE *dst_image_state, uint32_t region_count, const VkBufferImageCopy *regions, 3177a07ae8bd5f566eb9b073498dd4280efdb0b838b9Tobin Ehlis VkImageLayout dst_image_layout) { 3178a07ae8bd5f566eb9b073498dd4280efdb0b838b9Tobin Ehlis // Make sure that all image slices are updated to correct layout 3179a07ae8bd5f566eb9b073498dd4280efdb0b838b9Tobin Ehlis for (uint32_t i = 0; i < region_count; ++i) { 3180a07ae8bd5f566eb9b073498dd4280efdb0b838b9Tobin Ehlis SetImageLayout(device_data, cb_node, dst_image_state, regions[i].imageSubresource, dst_image_layout); 3181a07ae8bd5f566eb9b073498dd4280efdb0b838b9Tobin Ehlis } 3182940f70f1340803d185c67633b05ef048d277952eMark Lobodzinski AddCommandBufferBindingBuffer(device_data, cb_node, src_buffer_state); 3183d5cde34b61eb694c6fe1d5e53de61bb87bf6936aMark Lobodzinski AddCommandBufferBindingImage(device_data, cb_node, dst_image_state); 318471c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski std::function<bool()> function = [=]() { 318571c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski SetImageMemoryValid(device_data, dst_image_state, true); 318671c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski return false; 318771c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski }; 318871c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski cb_node->validate_functions.push_back(function); 3189940f70f1340803d185c67633b05ef048d277952eMark Lobodzinski function = [=]() { return ValidateBufferMemoryIsValid(device_data, src_buffer_state, "vkCmdCopyBufferToImage()"); }; 319071c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski cb_node->validate_functions.push_back(function); 319171c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski 319271c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski core_validation::UpdateCmdBufferLastCmd(cb_node, CMD_COPYBUFFERTOIMAGE); 3193877577537c1f97bf8d50e32aecd7d3ca09a230a2Mark Lobodzinski} 3194e6e50fcd129baea00fd5eb908cad29b252abaaa7Mike Weiblen 3195e6e50fcd129baea00fd5eb908cad29b252abaaa7Mike Weiblenbool PreCallValidateGetImageSubresourceLayout(layer_data *device_data, VkImage image, const VkImageSubresource *pSubresource) { 3196e6e50fcd129baea00fd5eb908cad29b252abaaa7Mike Weiblen const auto report_data = core_validation::GetReportData(device_data); 3197e6e50fcd129baea00fd5eb908cad29b252abaaa7Mike Weiblen bool skip = false; 3198e6e50fcd129baea00fd5eb908cad29b252abaaa7Mike Weiblen const VkImageAspectFlags sub_aspect = pSubresource->aspectMask; 3199e6e50fcd129baea00fd5eb908cad29b252abaaa7Mike Weiblen 3200e6e50fcd129baea00fd5eb908cad29b252abaaa7Mike Weiblen // VU 00733: The aspectMask member of pSubresource must only have a single bit set 3201e6e50fcd129baea00fd5eb908cad29b252abaaa7Mike Weiblen const int num_bits = sizeof(sub_aspect) * CHAR_BIT; 3202e6e50fcd129baea00fd5eb908cad29b252abaaa7Mike Weiblen std::bitset<num_bits> aspect_mask_bits(sub_aspect); 3203e6e50fcd129baea00fd5eb908cad29b252abaaa7Mike Weiblen if (aspect_mask_bits.count() != 1) { 3204fdc75c21ced997fbbc180734bef87bf6d5811d4bMark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, 3205fdc75c21ced997fbbc180734bef87bf6d5811d4bMark Lobodzinski reinterpret_cast<uint64_t &>(image), __LINE__, VALIDATION_ERROR_00733, "IMAGE", 3206e6e50fcd129baea00fd5eb908cad29b252abaaa7Mike Weiblen "vkGetImageSubresourceLayout(): VkImageSubresource.aspectMask must have exactly 1 bit set. %s", 3207e6e50fcd129baea00fd5eb908cad29b252abaaa7Mike Weiblen validation_error_map[VALIDATION_ERROR_00733]); 3208e6e50fcd129baea00fd5eb908cad29b252abaaa7Mike Weiblen } 3209e6e50fcd129baea00fd5eb908cad29b252abaaa7Mike Weiblen 3210e6e50fcd129baea00fd5eb908cad29b252abaaa7Mike Weiblen IMAGE_STATE *image_entry = GetImageState(device_data, image); 3211e6e50fcd129baea00fd5eb908cad29b252abaaa7Mike Weiblen if (!image_entry) { 3212e6e50fcd129baea00fd5eb908cad29b252abaaa7Mike Weiblen return skip; 3213e6e50fcd129baea00fd5eb908cad29b252abaaa7Mike Weiblen } 3214e6e50fcd129baea00fd5eb908cad29b252abaaa7Mike Weiblen 3215e6e50fcd129baea00fd5eb908cad29b252abaaa7Mike Weiblen // VU 00732: image must have been created with tiling equal to VK_IMAGE_TILING_LINEAR 3216e6e50fcd129baea00fd5eb908cad29b252abaaa7Mike Weiblen if (image_entry->createInfo.tiling != VK_IMAGE_TILING_LINEAR) { 3217fdc75c21ced997fbbc180734bef87bf6d5811d4bMark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, 3218fdc75c21ced997fbbc180734bef87bf6d5811d4bMark Lobodzinski reinterpret_cast<uint64_t &>(image), __LINE__, VALIDATION_ERROR_00732, "IMAGE", 3219e6e50fcd129baea00fd5eb908cad29b252abaaa7Mike Weiblen "vkGetImageSubresourceLayout(): Image must have tiling of VK_IMAGE_TILING_LINEAR. %s", 3220e6e50fcd129baea00fd5eb908cad29b252abaaa7Mike Weiblen validation_error_map[VALIDATION_ERROR_00732]); 3221e6e50fcd129baea00fd5eb908cad29b252abaaa7Mike Weiblen } 3222e6e50fcd129baea00fd5eb908cad29b252abaaa7Mike Weiblen 3223e6e50fcd129baea00fd5eb908cad29b252abaaa7Mike Weiblen // VU 00739: mipLevel must be less than the mipLevels specified in VkImageCreateInfo when the image was created 3224e6e50fcd129baea00fd5eb908cad29b252abaaa7Mike Weiblen if (pSubresource->mipLevel >= image_entry->createInfo.mipLevels) { 3225fdc75c21ced997fbbc180734bef87bf6d5811d4bMark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, 3226fdc75c21ced997fbbc180734bef87bf6d5811d4bMark Lobodzinski reinterpret_cast<uint64_t &>(image), __LINE__, VALIDATION_ERROR_00739, "IMAGE", 3227e6e50fcd129baea00fd5eb908cad29b252abaaa7Mike Weiblen "vkGetImageSubresourceLayout(): pSubresource.mipLevel (%d) must be less than %d. %s", 3228e6e50fcd129baea00fd5eb908cad29b252abaaa7Mike Weiblen pSubresource->mipLevel, image_entry->createInfo.mipLevels, validation_error_map[VALIDATION_ERROR_00739]); 3229e6e50fcd129baea00fd5eb908cad29b252abaaa7Mike Weiblen } 3230e6e50fcd129baea00fd5eb908cad29b252abaaa7Mike Weiblen 3231e6e50fcd129baea00fd5eb908cad29b252abaaa7Mike Weiblen // VU 00740: arrayLayer must be less than the arrayLayers specified in VkImageCreateInfo when the image was created 3232e6e50fcd129baea00fd5eb908cad29b252abaaa7Mike Weiblen if (pSubresource->arrayLayer >= image_entry->createInfo.arrayLayers) { 3233fdc75c21ced997fbbc180734bef87bf6d5811d4bMark Lobodzinski skip |= 3234fdc75c21ced997fbbc180734bef87bf6d5811d4bMark Lobodzinski log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, 3235fdc75c21ced997fbbc180734bef87bf6d5811d4bMark Lobodzinski reinterpret_cast<uint64_t &>(image), __LINE__, VALIDATION_ERROR_00740, "IMAGE", 3236fdc75c21ced997fbbc180734bef87bf6d5811d4bMark Lobodzinski "vkGetImageSubresourceLayout(): pSubresource.arrayLayer (%d) must be less than %d. %s", 3237fdc75c21ced997fbbc180734bef87bf6d5811d4bMark Lobodzinski pSubresource->arrayLayer, image_entry->createInfo.arrayLayers, validation_error_map[VALIDATION_ERROR_00740]); 3238e6e50fcd129baea00fd5eb908cad29b252abaaa7Mike Weiblen } 3239e6e50fcd129baea00fd5eb908cad29b252abaaa7Mike Weiblen 3240e6e50fcd129baea00fd5eb908cad29b252abaaa7Mike Weiblen // VU 00741: subresource's aspect must be compatible with image's format. 3241e6e50fcd129baea00fd5eb908cad29b252abaaa7Mike Weiblen const VkFormat img_format = image_entry->createInfo.format; 324216769f6b2a7721e391952a97f010cbb530e4f211Dave Houlton if (FormatIsColor(img_format)) { 3243e6e50fcd129baea00fd5eb908cad29b252abaaa7Mike Weiblen if (sub_aspect != VK_IMAGE_ASPECT_COLOR_BIT) { 3244e6e50fcd129baea00fd5eb908cad29b252abaaa7Mike Weiblen skip |= log_msg( 3245fdc75c21ced997fbbc180734bef87bf6d5811d4bMark Lobodzinski report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, 3246fdc75c21ced997fbbc180734bef87bf6d5811d4bMark Lobodzinski reinterpret_cast<uint64_t &>(image), __LINE__, VALIDATION_ERROR_00741, "IMAGE", 3247e6e50fcd129baea00fd5eb908cad29b252abaaa7Mike Weiblen "vkGetImageSubresourceLayout(): For color formats, VkImageSubresource.aspectMask must be VK_IMAGE_ASPECT_COLOR. %s", 3248e6e50fcd129baea00fd5eb908cad29b252abaaa7Mike Weiblen validation_error_map[VALIDATION_ERROR_00741]); 3249e6e50fcd129baea00fd5eb908cad29b252abaaa7Mike Weiblen } 325016769f6b2a7721e391952a97f010cbb530e4f211Dave Houlton } else if (FormatIsDepthOrStencil(img_format)) { 3251e6e50fcd129baea00fd5eb908cad29b252abaaa7Mike Weiblen if ((sub_aspect != VK_IMAGE_ASPECT_DEPTH_BIT) && (sub_aspect != VK_IMAGE_ASPECT_STENCIL_BIT)) { 3252fdc75c21ced997fbbc180734bef87bf6d5811d4bMark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, 3253fdc75c21ced997fbbc180734bef87bf6d5811d4bMark Lobodzinski reinterpret_cast<uint64_t &>(image), __LINE__, VALIDATION_ERROR_00741, "IMAGE", 3254e6e50fcd129baea00fd5eb908cad29b252abaaa7Mike Weiblen "vkGetImageSubresourceLayout(): For depth/stencil formats, VkImageSubresource.aspectMask must be " 3255e6e50fcd129baea00fd5eb908cad29b252abaaa7Mike Weiblen "either VK_IMAGE_ASPECT_DEPTH_BIT or VK_IMAGE_ASPECT_STENCIL_BIT. %s", 3256e6e50fcd129baea00fd5eb908cad29b252abaaa7Mike Weiblen validation_error_map[VALIDATION_ERROR_00741]); 3257e6e50fcd129baea00fd5eb908cad29b252abaaa7Mike Weiblen } 3258e6e50fcd129baea00fd5eb908cad29b252abaaa7Mike Weiblen } 3259e6e50fcd129baea00fd5eb908cad29b252abaaa7Mike Weiblen return skip; 3260e6e50fcd129baea00fd5eb908cad29b252abaaa7Mike Weiblen} 3261