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 2523c5a2092f724fef497a5c87a489f32c8fa51e58Petr Kraus#include <inttypes.h> 268dea300c362f709ad26886548ea46eb4c315e401Mark Lobodzinski#include <sstream> 2723c5a2092f724fef497a5c87a489f32c8fa51e58Petr Kraus#include <string> 288dea300c362f709ad26886548ea46eb4c315e401Mark Lobodzinski 298dea300c362f709ad26886548ea46eb4c315e401Mark Lobodzinski#include "vk_enum_string_helper.h" 308dea300c362f709ad26886548ea46eb4c315e401Mark Lobodzinski#include "vk_layer_data.h" 318dea300c362f709ad26886548ea46eb4c315e401Mark Lobodzinski#include "vk_layer_utils.h" 328dea300c362f709ad26886548ea46eb4c315e401Mark Lobodzinski#include "vk_layer_logging.h" 338dea300c362f709ad26886548ea46eb4c315e401Mark Lobodzinski 34584b2b6a66e3069a66727639e5a0b7ef9ebf13b6Mark Lobodzinski#include "buffer_validation.h" 35c06c9b88f5f5bcc7033ba41d5547b048fa6015a4Mark Lobodzinski 36e40189d4deab674240cd9baf4c063bab4567c212Tobin Ehlisvoid SetLayout(layer_data *device_data, GLOBAL_CB_NODE *pCB, ImageSubresourcePair imgpair, const VkImageLayout &layout) { 370d2fd381af11d2202d3856cb2da2c7122a0294efChris Forbes if (pCB->imageLayoutMap.find(imgpair) != pCB->imageLayoutMap.end()) { 3855867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski pCB->imageLayoutMap[imgpair].layout = layout; 3955867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski } else { 4055867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski assert(imgpair.hasSubresource); 4155867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski IMAGE_CMD_BUF_LAYOUT_NODE node; 4255867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski if (!FindCmdBufLayout(device_data, pCB, imgpair.image, imgpair.subresource, node)) { 4355867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski node.initialLayout = layout; 4455867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski } 4555867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski SetLayout(device_data, pCB, imgpair, {node.initialLayout, layout}); 4655867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski } 4755867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski} 4855867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinskitemplate <class OBJECT, class LAYOUT> 49e40189d4deab674240cd9baf4c063bab4567c212Tobin Ehlisvoid SetLayout(layer_data *device_data, OBJECT *pObject, VkImage image, VkImageSubresource range, const LAYOUT &layout) { 5055867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski ImageSubresourcePair imgpair = {image, true, range}; 5155867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski SetLayout(device_data, pObject, imgpair, layout, VK_IMAGE_ASPECT_COLOR_BIT); 5255867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski SetLayout(device_data, pObject, imgpair, layout, VK_IMAGE_ASPECT_DEPTH_BIT); 5355867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski SetLayout(device_data, pObject, imgpair, layout, VK_IMAGE_ASPECT_STENCIL_BIT); 5455867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski SetLayout(device_data, pObject, imgpair, layout, VK_IMAGE_ASPECT_METADATA_BIT); 5555867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski} 5655867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski 5755867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinskitemplate <class OBJECT, class LAYOUT> 58e40189d4deab674240cd9baf4c063bab4567c212Tobin Ehlisvoid SetLayout(layer_data *device_data, OBJECT *pObject, ImageSubresourcePair imgpair, const LAYOUT &layout, 5955867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski VkImageAspectFlags aspectMask) { 6055867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski if (imgpair.subresource.aspectMask & aspectMask) { 6155867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski imgpair.subresource.aspectMask = aspectMask; 6255867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski SetLayout(device_data, pObject, imgpair, layout); 6355867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski } 6455867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski} 6555867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski 6651920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour// Set the layout in supplied map 67440bdd357701497c3442e3515f12ac1cfffc180aTony Barbourvoid SetLayout(std::unordered_map<ImageSubresourcePair, IMAGE_LAYOUT_NODE> &imageLayoutMap, ImageSubresourcePair imgpair, 68440bdd357701497c3442e3515f12ac1cfffc180aTony Barbour VkImageLayout layout) { 6951920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour imageLayoutMap[imgpair].layout = layout; 7051920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour} 7151920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour 720db18ab1345f9e10907913b22ea5d57bd48077ebTobin Ehlisbool FindLayoutVerifyNode(layer_data const *device_data, GLOBAL_CB_NODE const *pCB, ImageSubresourcePair imgpair, 7355867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski IMAGE_CMD_BUF_LAYOUT_NODE &node, const VkImageAspectFlags aspectMask) { 7455867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski const debug_report_data *report_data = core_validation::GetReportData(device_data); 7555867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski 7655867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski if (!(imgpair.subresource.aspectMask & aspectMask)) { 7755867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski return false; 7855867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski } 7955867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski VkImageAspectFlags oldAspectMask = imgpair.subresource.aspectMask; 8055867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski imgpair.subresource.aspectMask = aspectMask; 8155867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski auto imgsubIt = pCB->imageLayoutMap.find(imgpair); 8255867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski if (imgsubIt == pCB->imageLayoutMap.end()) { 8355867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski return false; 8455867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski } 8555867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski if (node.layout != VK_IMAGE_LAYOUT_MAX_ENUM && node.layout != imgsubIt->second.layout) { 869b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, HandleToUint64(imgpair.image), 879b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus __LINE__, DRAWSTATE_INVALID_LAYOUT, "DS", 8855867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski "Cannot query for VkImage 0x%" PRIx64 " layout when combined aspect mask %d has multiple layout types: %s and %s", 899b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(imgpair.image), oldAspectMask, string_VkImageLayout(node.layout), 9055867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski string_VkImageLayout(imgsubIt->second.layout)); 9155867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski } 9255867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski if (node.initialLayout != VK_IMAGE_LAYOUT_MAX_ENUM && node.initialLayout != imgsubIt->second.initialLayout) { 939b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, HandleToUint64(imgpair.image), 949b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus __LINE__, DRAWSTATE_INVALID_LAYOUT, "DS", 9555867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski "Cannot query for VkImage 0x%" PRIx64 9655867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski " layout when combined aspect mask %d has multiple initial layout types: %s and %s", 979b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(imgpair.image), oldAspectMask, string_VkImageLayout(node.initialLayout), 9855867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski string_VkImageLayout(imgsubIt->second.initialLayout)); 9955867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski } 10055867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski node = imgsubIt->second; 10155867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski return true; 10255867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski} 10355867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski 1040db18ab1345f9e10907913b22ea5d57bd48077ebTobin Ehlisbool FindLayoutVerifyLayout(layer_data const *device_data, ImageSubresourcePair imgpair, VkImageLayout &layout, 10555867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski const VkImageAspectFlags aspectMask) { 10655867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski if (!(imgpair.subresource.aspectMask & aspectMask)) { 10755867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski return false; 10855867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski } 10955867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski const debug_report_data *report_data = core_validation::GetReportData(device_data); 11055867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski VkImageAspectFlags oldAspectMask = imgpair.subresource.aspectMask; 11155867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski imgpair.subresource.aspectMask = aspectMask; 11255867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski auto imgsubIt = (*core_validation::GetImageLayoutMap(device_data)).find(imgpair); 11355867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski if (imgsubIt == (*core_validation::GetImageLayoutMap(device_data)).end()) { 11455867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski return false; 11555867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski } 11655867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski if (layout != VK_IMAGE_LAYOUT_MAX_ENUM && layout != imgsubIt->second.layout) { 1179b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, HandleToUint64(imgpair.image), 1189b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus __LINE__, DRAWSTATE_INVALID_LAYOUT, "DS", 11955867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski "Cannot query for VkImage 0x%" PRIx64 " layout when combined aspect mask %d has multiple layout types: %s and %s", 1209b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(imgpair.image), oldAspectMask, string_VkImageLayout(layout), 12155867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski string_VkImageLayout(imgsubIt->second.layout)); 12255867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski } 12355867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski layout = imgsubIt->second.layout; 12455867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski return true; 12555867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski} 12655867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski 12755867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski// Find layout(s) on the command buffer level 1280db18ab1345f9e10907913b22ea5d57bd48077ebTobin Ehlisbool FindCmdBufLayout(layer_data const *device_data, GLOBAL_CB_NODE const *pCB, VkImage image, VkImageSubresource range, 12955867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski IMAGE_CMD_BUF_LAYOUT_NODE &node) { 13055867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski ImageSubresourcePair imgpair = {image, true, range}; 13155867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski node = IMAGE_CMD_BUF_LAYOUT_NODE(VK_IMAGE_LAYOUT_MAX_ENUM, VK_IMAGE_LAYOUT_MAX_ENUM); 13255867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski FindLayoutVerifyNode(device_data, pCB, imgpair, node, VK_IMAGE_ASPECT_COLOR_BIT); 13355867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski FindLayoutVerifyNode(device_data, pCB, imgpair, node, VK_IMAGE_ASPECT_DEPTH_BIT); 13455867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski FindLayoutVerifyNode(device_data, pCB, imgpair, node, VK_IMAGE_ASPECT_STENCIL_BIT); 13555867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski FindLayoutVerifyNode(device_data, pCB, imgpair, node, VK_IMAGE_ASPECT_METADATA_BIT); 13655867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski if (node.layout == VK_IMAGE_LAYOUT_MAX_ENUM) { 13755867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski imgpair = {image, false, VkImageSubresource()}; 13855867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski auto imgsubIt = pCB->imageLayoutMap.find(imgpair); 13955867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski if (imgsubIt == pCB->imageLayoutMap.end()) return false; 14055867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski // TODO: This is ostensibly a find function but it changes state here 14155867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski node = imgsubIt->second; 14255867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski } 14355867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski return true; 14455867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski} 14555867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski 14655867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski// Find layout(s) on the global level 147e40189d4deab674240cd9baf4c063bab4567c212Tobin Ehlisbool FindGlobalLayout(layer_data *device_data, ImageSubresourcePair imgpair, VkImageLayout &layout) { 14855867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski layout = VK_IMAGE_LAYOUT_MAX_ENUM; 14955867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski FindLayoutVerifyLayout(device_data, imgpair, layout, VK_IMAGE_ASPECT_COLOR_BIT); 15055867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski FindLayoutVerifyLayout(device_data, imgpair, layout, VK_IMAGE_ASPECT_DEPTH_BIT); 15155867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski FindLayoutVerifyLayout(device_data, imgpair, layout, VK_IMAGE_ASPECT_STENCIL_BIT); 15255867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski FindLayoutVerifyLayout(device_data, imgpair, layout, VK_IMAGE_ASPECT_METADATA_BIT); 15355867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski if (layout == VK_IMAGE_LAYOUT_MAX_ENUM) { 15455867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski imgpair = {imgpair.image, false, VkImageSubresource()}; 15555867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski auto imgsubIt = (*core_validation::GetImageLayoutMap(device_data)).find(imgpair); 15655867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski if (imgsubIt == (*core_validation::GetImageLayoutMap(device_data)).end()) return false; 15755867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski layout = imgsubIt->second.layout; 15855867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski } 15955867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski return true; 16055867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski} 16155867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski 162e40189d4deab674240cd9baf4c063bab4567c212Tobin Ehlisbool FindLayouts(layer_data *device_data, VkImage image, std::vector<VkImageLayout> &layouts) { 16355867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski auto sub_data = (*core_validation::GetImageSubresourceMap(device_data)).find(image); 16455867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski if (sub_data == (*core_validation::GetImageSubresourceMap(device_data)).end()) return false; 1659a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto image_state = GetImageState(device_data, image); 16655867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski if (!image_state) return false; 16755867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski bool ignoreGlobal = false; 16855867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski // TODO: Make this robust for >1 aspect mask. Now it will just say ignore potential errors in this case. 16955867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski if (sub_data->second.size() >= (image_state->createInfo.arrayLayers * image_state->createInfo.mipLevels + 1)) { 17055867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski ignoreGlobal = true; 17155867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski } 17255867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski for (auto imgsubpair : sub_data->second) { 17355867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski if (ignoreGlobal && !imgsubpair.hasSubresource) continue; 17455867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski auto img_data = (*core_validation::GetImageLayoutMap(device_data)).find(imgsubpair); 17555867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski if (img_data != (*core_validation::GetImageLayoutMap(device_data)).end()) { 17655867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski layouts.push_back(img_data->second.layout); 17755867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski } 17855867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski } 17955867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski return true; 18055867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski} 181440bdd357701497c3442e3515f12ac1cfffc180aTony Barbourbool FindLayout(const std::unordered_map<ImageSubresourcePair, IMAGE_LAYOUT_NODE> &imageLayoutMap, ImageSubresourcePair imgpair, 182440bdd357701497c3442e3515f12ac1cfffc180aTony Barbour VkImageLayout &layout, const VkImageAspectFlags aspectMask) { 18351920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour if (!(imgpair.subresource.aspectMask & aspectMask)) { 18451920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour return false; 18551920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour } 18651920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour imgpair.subresource.aspectMask = aspectMask; 18751920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour auto imgsubIt = imageLayoutMap.find(imgpair); 18851920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour if (imgsubIt == imageLayoutMap.end()) { 18951920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour return false; 19051920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour } 19151920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour layout = imgsubIt->second.layout; 19251920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour return true; 193440bdd357701497c3442e3515f12ac1cfffc180aTony Barbour} 19451920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour 19551920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour// find layout in supplied map 196440bdd357701497c3442e3515f12ac1cfffc180aTony Barbourbool FindLayout(const std::unordered_map<ImageSubresourcePair, IMAGE_LAYOUT_NODE> &imageLayoutMap, ImageSubresourcePair imgpair, 197440bdd357701497c3442e3515f12ac1cfffc180aTony Barbour VkImageLayout &layout) { 19851920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour layout = VK_IMAGE_LAYOUT_MAX_ENUM; 19951920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour FindLayout(imageLayoutMap, imgpair, layout, VK_IMAGE_ASPECT_COLOR_BIT); 20051920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour FindLayout(imageLayoutMap, imgpair, layout, VK_IMAGE_ASPECT_DEPTH_BIT); 20151920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour FindLayout(imageLayoutMap, imgpair, layout, VK_IMAGE_ASPECT_STENCIL_BIT); 20251920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour FindLayout(imageLayoutMap, imgpair, layout, VK_IMAGE_ASPECT_METADATA_BIT); 20351920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour if (layout == VK_IMAGE_LAYOUT_MAX_ENUM) { 20451920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour imgpair = {imgpair.image, false, VkImageSubresource()}; 20551920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour auto imgsubIt = imageLayoutMap.find(imgpair); 20651920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour if (imgsubIt == imageLayoutMap.end()) return false; 20751920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour layout = imgsubIt->second.layout; 20851920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour } 20951920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour return true; 21051920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour} 21155867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski 21255867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski// Set the layout on the global level 213e40189d4deab674240cd9baf4c063bab4567c212Tobin Ehlisvoid SetGlobalLayout(layer_data *device_data, ImageSubresourcePair imgpair, const VkImageLayout &layout) { 21455867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski VkImage &image = imgpair.image; 21555867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski (*core_validation::GetImageLayoutMap(device_data))[imgpair].layout = layout; 21655867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski auto &image_subresources = (*core_validation::GetImageSubresourceMap(device_data))[image]; 21755867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski auto subresource = std::find(image_subresources.begin(), image_subresources.end(), imgpair); 21855867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski if (subresource == image_subresources.end()) { 21955867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski image_subresources.push_back(imgpair); 22055867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski } 22155867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski} 22255867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski 22355867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski// Set the layout on the cmdbuf level 224e40189d4deab674240cd9baf4c063bab4567c212Tobin Ehlisvoid SetLayout(layer_data *device_data, GLOBAL_CB_NODE *pCB, ImageSubresourcePair imgpair, const IMAGE_CMD_BUF_LAYOUT_NODE &node) { 22555867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski pCB->imageLayoutMap[imgpair] = node; 22655867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski} 227a07ae8bd5f566eb9b073498dd4280efdb0b838b9Tobin Ehlis// Set image layout for given VkImageSubresourceRange struct 228a07ae8bd5f566eb9b073498dd4280efdb0b838b9Tobin Ehlisvoid SetImageLayout(layer_data *device_data, GLOBAL_CB_NODE *cb_node, const IMAGE_STATE *image_state, 229a07ae8bd5f566eb9b073498dd4280efdb0b838b9Tobin Ehlis VkImageSubresourceRange image_subresource_range, const VkImageLayout &layout) { 230a07ae8bd5f566eb9b073498dd4280efdb0b838b9Tobin Ehlis assert(image_state); 23161e4ca90b669387237558926a72d120b2083bc9cJohn Zulauf cb_node->image_layout_change_count++; // Change the version of this data to force revalidation 232a07ae8bd5f566eb9b073498dd4280efdb0b838b9Tobin Ehlis for (uint32_t level_index = 0; level_index < image_subresource_range.levelCount; ++level_index) { 233a07ae8bd5f566eb9b073498dd4280efdb0b838b9Tobin Ehlis uint32_t level = image_subresource_range.baseMipLevel + level_index; 234a07ae8bd5f566eb9b073498dd4280efdb0b838b9Tobin Ehlis for (uint32_t layer_index = 0; layer_index < image_subresource_range.layerCount; layer_index++) { 235a07ae8bd5f566eb9b073498dd4280efdb0b838b9Tobin Ehlis uint32_t layer = image_subresource_range.baseArrayLayer + layer_index; 236a07ae8bd5f566eb9b073498dd4280efdb0b838b9Tobin Ehlis VkImageSubresource sub = {image_subresource_range.aspectMask, level, layer}; 23755867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski // TODO: If ImageView was created with depth or stencil, transition both layouts as the aspectMask is ignored and both 23855867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski // are used. Verify that the extra implicit layout is OK for descriptor set layout validation 239a07ae8bd5f566eb9b073498dd4280efdb0b838b9Tobin Ehlis if (image_subresource_range.aspectMask & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) { 24016769f6b2a7721e391952a97f010cbb530e4f211Dave Houlton if (FormatIsDepthAndStencil(image_state->createInfo.format)) { 24155867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski sub.aspectMask |= (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT); 24255867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski } 24355867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski } 244a07ae8bd5f566eb9b073498dd4280efdb0b838b9Tobin Ehlis SetLayout(device_data, cb_node, image_state->image, sub, layout); 24555867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski } 24655867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski } 24755867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski} 248a07ae8bd5f566eb9b073498dd4280efdb0b838b9Tobin Ehlis// Set image layout for given VkImageSubresourceLayers struct 249a07ae8bd5f566eb9b073498dd4280efdb0b838b9Tobin Ehlisvoid SetImageLayout(layer_data *device_data, GLOBAL_CB_NODE *cb_node, const IMAGE_STATE *image_state, 250a07ae8bd5f566eb9b073498dd4280efdb0b838b9Tobin Ehlis VkImageSubresourceLayers image_subresource_layers, const VkImageLayout &layout) { 251a07ae8bd5f566eb9b073498dd4280efdb0b838b9Tobin Ehlis // Transfer VkImageSubresourceLayers into VkImageSubresourceRange struct 252a07ae8bd5f566eb9b073498dd4280efdb0b838b9Tobin Ehlis VkImageSubresourceRange image_subresource_range; 253a07ae8bd5f566eb9b073498dd4280efdb0b838b9Tobin Ehlis image_subresource_range.aspectMask = image_subresource_layers.aspectMask; 254a07ae8bd5f566eb9b073498dd4280efdb0b838b9Tobin Ehlis image_subresource_range.baseArrayLayer = image_subresource_layers.baseArrayLayer; 255a07ae8bd5f566eb9b073498dd4280efdb0b838b9Tobin Ehlis image_subresource_range.layerCount = image_subresource_layers.layerCount; 256a07ae8bd5f566eb9b073498dd4280efdb0b838b9Tobin Ehlis image_subresource_range.baseMipLevel = image_subresource_layers.mipLevel; 257a07ae8bd5f566eb9b073498dd4280efdb0b838b9Tobin Ehlis image_subresource_range.levelCount = 1; 258a07ae8bd5f566eb9b073498dd4280efdb0b838b9Tobin Ehlis SetImageLayout(device_data, cb_node, image_state, image_subresource_range, layout); 259a07ae8bd5f566eb9b073498dd4280efdb0b838b9Tobin Ehlis} 260a07ae8bd5f566eb9b073498dd4280efdb0b838b9Tobin Ehlis// Set image layout for all slices of an image view 261a07ae8bd5f566eb9b073498dd4280efdb0b838b9Tobin Ehlisvoid SetImageViewLayout(layer_data *device_data, GLOBAL_CB_NODE *cb_node, VkImageView imageView, const VkImageLayout &layout) { 262a07ae8bd5f566eb9b073498dd4280efdb0b838b9Tobin Ehlis auto view_state = GetImageViewState(device_data, imageView); 263a07ae8bd5f566eb9b073498dd4280efdb0b838b9Tobin Ehlis assert(view_state); 264a07ae8bd5f566eb9b073498dd4280efdb0b838b9Tobin Ehlis 265a07ae8bd5f566eb9b073498dd4280efdb0b838b9Tobin Ehlis SetImageLayout(device_data, cb_node, GetImageState(device_data, view_state->create_info.image), 266a07ae8bd5f566eb9b073498dd4280efdb0b838b9Tobin Ehlis view_state->create_info.subresourceRange, layout); 267a07ae8bd5f566eb9b073498dd4280efdb0b838b9Tobin Ehlis} 26855867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski 269e40189d4deab674240cd9baf4c063bab4567c212Tobin Ehlisbool VerifyFramebufferAndRenderPassLayouts(layer_data *device_data, GLOBAL_CB_NODE *pCB, 27055867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski const VkRenderPassBeginInfo *pRenderPassBegin, 27155867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski const FRAMEBUFFER_STATE *framebuffer_state) { 2723251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = false; 2739a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto const pRenderPassInfo = GetRenderPassState(device_data, pRenderPassBegin->renderPass)->createInfo.ptr(); 27455867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski auto const &framebufferInfo = framebuffer_state->createInfo; 27555867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski const auto report_data = core_validation::GetReportData(device_data); 27655867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski if (pRenderPassInfo->attachmentCount != framebufferInfo.attachmentCount) { 2773251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 2789b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(pCB->commandBuffer), __LINE__, DRAWSTATE_INVALID_RENDERPASS, "DS", 2795f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton "You cannot start a render pass using a framebuffer with a different number of attachments."); 28055867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski } 28155867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski for (uint32_t i = 0; i < pRenderPassInfo->attachmentCount; ++i) { 28255867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski const VkImageView &image_view = framebufferInfo.pAttachments[i]; 2839a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto view_state = GetImageViewState(device_data, image_view); 28455867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski assert(view_state); 28555867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski const VkImage &image = view_state->create_info.image; 28655867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski const VkImageSubresourceRange &subRange = view_state->create_info.subresourceRange; 2875f025a7d647e3257e12a816fa1db078b5fc8ed49Tobin Ehlis auto initial_layout = pRenderPassInfo->pAttachments[i].initialLayout; 28855867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski // TODO: Do not iterate over every possibility - consolidate where possible 28955867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski for (uint32_t j = 0; j < subRange.levelCount; j++) { 29055867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski uint32_t level = subRange.baseMipLevel + j; 29155867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski for (uint32_t k = 0; k < subRange.layerCount; k++) { 29255867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski uint32_t layer = subRange.baseArrayLayer + k; 29355867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski VkImageSubresource sub = {subRange.aspectMask, level, layer}; 29455867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski IMAGE_CMD_BUF_LAYOUT_NODE node; 29555867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski if (!FindCmdBufLayout(device_data, pCB, image, sub, node)) { 2965f025a7d647e3257e12a816fa1db078b5fc8ed49Tobin Ehlis // Missing layouts will be added during state update 29755867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski continue; 29855867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski } 2995f025a7d647e3257e12a816fa1db078b5fc8ed49Tobin Ehlis if (initial_layout != VK_IMAGE_LAYOUT_UNDEFINED && initial_layout != node.layout) { 3003251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, 3013251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski __LINE__, DRAWSTATE_INVALID_RENDERPASS, "DS", 3025f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton "You cannot start a render pass using attachment %u where the render pass initial layout is %s " 3035f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton "and the previous known layout of the attachment is %s. The layouts must match, or the render " 3045f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton "pass initial layout for the attachment must be 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 339e2d4ce3059fa77badeea63fa2003b83a04ca9c98Tobin Ehlisbool ValidateImageAspectLayout(layer_data *device_data, GLOBAL_CB_NODE const *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) { 353055fc8fd459f0da279d4814f927ea7090dd0f7e9Petr Kraus skip |= log_msg(core_validation::GetReportData(device_data), VK_DEBUG_REPORT_ERROR_BIT_EXT, 354055fc8fd459f0da279d4814f927ea7090dd0f7e9Petr Kraus VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, HandleToUint64(pCB->commandBuffer), __LINE__, 355055fc8fd459f0da279d4814f927ea7090dd0f7e9Petr Kraus DRAWSTATE_INVALID_IMAGE_LAYOUT, "DS", 356055fc8fd459f0da279d4814f927ea7090dd0f7e9Petr Kraus "For image 0x%" PRIx64 " you cannot transition the layout of aspect %d from %s when current layout is %s.", 357055fc8fd459f0da279d4814f927ea7090dd0f7e9Petr Kraus HandleToUint64(mem_barrier->image), aspect, string_VkImageLayout(mem_barrier->oldLayout), 358055fc8fd459f0da279d4814f927ea7090dd0f7e9Petr Kraus string_VkImageLayout(node.layout)); 35955867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski } 36055867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski return skip; 36155867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski} 36255867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski 3635f025a7d647e3257e12a816fa1db078b5fc8ed49Tobin Ehlis// Transition the layout state for renderpass attachments based on the BeginRenderPass() call. This includes: 3645f025a7d647e3257e12a816fa1db078b5fc8ed49Tobin Ehlis// 1. Transition into initialLayout state 3655f025a7d647e3257e12a816fa1db078b5fc8ed49Tobin Ehlis// 2. Transition from initialLayout to layout used in subpass 0 3665f025a7d647e3257e12a816fa1db078b5fc8ed49Tobin Ehlisvoid TransitionBeginRenderPassLayouts(layer_data *device_data, GLOBAL_CB_NODE *cb_state, const RENDER_PASS_STATE *render_pass_state, 3675f025a7d647e3257e12a816fa1db078b5fc8ed49Tobin Ehlis FRAMEBUFFER_STATE *framebuffer_state) { 3685f025a7d647e3257e12a816fa1db078b5fc8ed49Tobin Ehlis // First transition into initialLayout 3695f025a7d647e3257e12a816fa1db078b5fc8ed49Tobin Ehlis auto const rpci = render_pass_state->createInfo.ptr(); 3705f025a7d647e3257e12a816fa1db078b5fc8ed49Tobin Ehlis for (uint32_t i = 0; i < rpci->attachmentCount; ++i) { 3715f025a7d647e3257e12a816fa1db078b5fc8ed49Tobin Ehlis VkImageView image_view = framebuffer_state->createInfo.pAttachments[i]; 3725f025a7d647e3257e12a816fa1db078b5fc8ed49Tobin Ehlis SetImageViewLayout(device_data, cb_state, image_view, rpci->pAttachments[i].initialLayout); 3735f025a7d647e3257e12a816fa1db078b5fc8ed49Tobin Ehlis } 3745f025a7d647e3257e12a816fa1db078b5fc8ed49Tobin Ehlis // Now transition for first subpass (index 0) 3755f025a7d647e3257e12a816fa1db078b5fc8ed49Tobin Ehlis TransitionSubpassLayouts(device_data, cb_state, render_pass_state, 0, framebuffer_state); 3765f025a7d647e3257e12a816fa1db078b5fc8ed49Tobin Ehlis} 3775f025a7d647e3257e12a816fa1db078b5fc8ed49Tobin Ehlis 378e659c986db0f3146726d6c744c75772316c3e0c6Mark Lobodzinskivoid TransitionImageAspectLayout(layer_data *device_data, GLOBAL_CB_NODE *pCB, const VkImageMemoryBarrier *mem_barrier, 379e659c986db0f3146726d6c744c75772316c3e0c6Mark Lobodzinski uint32_t level, uint32_t layer, VkImageAspectFlags aspect) { 380e659c986db0f3146726d6c744c75772316c3e0c6Mark Lobodzinski if (!(mem_barrier->subresourceRange.aspectMask & aspect)) { 381e659c986db0f3146726d6c744c75772316c3e0c6Mark Lobodzinski return; 382e659c986db0f3146726d6c744c75772316c3e0c6Mark Lobodzinski } 383e659c986db0f3146726d6c744c75772316c3e0c6Mark Lobodzinski VkImageSubresource sub = {aspect, level, layer}; 384e659c986db0f3146726d6c744c75772316c3e0c6Mark Lobodzinski IMAGE_CMD_BUF_LAYOUT_NODE node; 385e659c986db0f3146726d6c744c75772316c3e0c6Mark Lobodzinski if (!FindCmdBufLayout(device_data, pCB, mem_barrier->image, sub, node)) { 38661e4ca90b669387237558926a72d120b2083bc9cJohn Zulauf pCB->image_layout_change_count++; // Change the version of this data to force revalidation 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) { 421315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis msg_code = VALIDATION_ERROR_0a000970; 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) { 426315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis msg_code = VALIDATION_ERROR_0a000972; 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) { 431315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis msg_code = VALIDATION_ERROR_0a000974; 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) { 436315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis msg_code = VALIDATION_ERROR_0a000976; 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) { 441315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis msg_code = VALIDATION_ERROR_0a000978; 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) { 446315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis msg_code = VALIDATION_ERROR_0a00097a; 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, 4579b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(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", 459055fc8fd459f0da279d4814f927ea7090dd0f7e9Petr Kraus func_name, static_cast<const void *>(img_barrier), ((new_not_old) ? "new" : "old"), 460055fc8fd459f0da279d4814f927ea7090dd0f7e9Petr Kraus string_VkImageLayout(layout), HandleToUint64(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. 466e2d4ce3059fa77badeea63fa2003b83a04ca9c98Tobin Ehlisbool ValidateBarriersToImages(layer_data *device_data, GLOBAL_CB_NODE const *cb_state, uint32_t imageMemoryBarrierCount, 467a90f5fa414aa0994e67cdb911938e6ae48f2ad6aMike Weiblen const VkImageMemoryBarrier *pImageMemoryBarriers, const char *func_name) { 46855867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski bool skip = false; 469a90f5fa414aa0994e67cdb911938e6ae48f2ad6aMike Weiblen 470a90f5fa414aa0994e67cdb911938e6ae48f2ad6aMike Weiblen for (uint32_t i = 0; i < imageMemoryBarrierCount; ++i) { 471a90f5fa414aa0994e67cdb911938e6ae48f2ad6aMike Weiblen auto img_barrier = &pImageMemoryBarriers[i]; 472a90f5fa414aa0994e67cdb911938e6ae48f2ad6aMike Weiblen if (!img_barrier) continue; 47355867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski 47487a57d8e822316de46ee97f514187331b1f4f09dTobin Ehlis auto image_state = GetImageState(device_data, img_barrier->image); 47587a57d8e822316de46ee97f514187331b1f4f09dTobin Ehlis if (image_state) { 47687a57d8e822316de46ee97f514187331b1f4f09dTobin Ehlis VkImageUsageFlags usage_flags = image_state->createInfo.usage; 47787a57d8e822316de46ee97f514187331b1f4f09dTobin Ehlis skip |= ValidateBarrierLayoutToImageUsage(device_data, img_barrier, false, usage_flags, func_name); 47887a57d8e822316de46ee97f514187331b1f4f09dTobin Ehlis skip |= ValidateBarrierLayoutToImageUsage(device_data, img_barrier, true, usage_flags, func_name); 47987a57d8e822316de46ee97f514187331b1f4f09dTobin Ehlis 48087a57d8e822316de46ee97f514187331b1f4f09dTobin Ehlis // Make sure layout is able to be transitioned, currently only presented shared presentable images are locked 48187a57d8e822316de46ee97f514187331b1f4f09dTobin Ehlis if (image_state->layout_locked) { 48287a57d8e822316de46ee97f514187331b1f4f09dTobin Ehlis // TODO: Add unique id for error when available 4831007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton skip |= log_msg( 4841007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton core_validation::GetReportData(device_data), VK_DEBUG_REPORT_ERROR_BIT_EXT, 48587a57d8e822316de46ee97f514187331b1f4f09dTobin Ehlis VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, 0, "DS", 486055fc8fd459f0da279d4814f927ea7090dd0f7e9Petr Kraus "Attempting to transition shared presentable image 0x%" PRIx64 48787a57d8e822316de46ee97f514187331b1f4f09dTobin Ehlis " from layout %s to layout %s, but image has already been presented and cannot have its layout transitioned.", 488055fc8fd459f0da279d4814f927ea7090dd0f7e9Petr Kraus HandleToUint64(img_barrier->image), string_VkImageLayout(img_barrier->oldLayout), 48987a57d8e822316de46ee97f514187331b1f4f09dTobin Ehlis string_VkImageLayout(img_barrier->newLayout)); 49087a57d8e822316de46ee97f514187331b1f4f09dTobin Ehlis } 49187a57d8e822316de46ee97f514187331b1f4f09dTobin Ehlis } 49287a57d8e822316de46ee97f514187331b1f4f09dTobin Ehlis 49395b7894efd5e101e410da92fc697429aec3ffa7bMark Lobodzinski VkImageCreateInfo *image_create_info = &(GetImageState(device_data, img_barrier->image)->createInfo); 494c7455116cef9c14f8405aae43bc0247f2c256f96Tobin Ehlis // For a Depth/Stencil image both aspects MUST be set 495c7455116cef9c14f8405aae43bc0247f2c256f96Tobin Ehlis if (FormatIsDepthAndStencil(image_create_info->format)) { 496c7455116cef9c14f8405aae43bc0247f2c256f96Tobin Ehlis auto const aspect_mask = img_barrier->subresourceRange.aspectMask; 497c7455116cef9c14f8405aae43bc0247f2c256f96Tobin Ehlis auto const ds_mask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT; 498c7455116cef9c14f8405aae43bc0247f2c256f96Tobin Ehlis if ((aspect_mask & ds_mask) != (ds_mask)) { 499055fc8fd459f0da279d4814f927ea7090dd0f7e9Petr Kraus skip |= log_msg( 500055fc8fd459f0da279d4814f927ea7090dd0f7e9Petr Kraus core_validation::GetReportData(device_data), VK_DEBUG_REPORT_ERROR_BIT_EXT, 501055fc8fd459f0da279d4814f927ea7090dd0f7e9Petr Kraus VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, HandleToUint64(img_barrier->image), __LINE__, VALIDATION_ERROR_0a00096e, 5025f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton "DS", 5035f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton "%s: Image barrier 0x%p references image 0x%" PRIx64 5045f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton " of format %s that must have the depth and stencil aspects set, but its aspectMask is 0x%" PRIx32 ". %s", 505055fc8fd459f0da279d4814f927ea7090dd0f7e9Petr Kraus func_name, static_cast<const void *>(img_barrier), HandleToUint64(img_barrier->image), 506055fc8fd459f0da279d4814f927ea7090dd0f7e9Petr Kraus string_VkFormat(image_create_info->format), aspect_mask, validation_error_map[VALIDATION_ERROR_0a00096e]); 507c7455116cef9c14f8405aae43bc0247f2c256f96Tobin Ehlis } 508c7455116cef9c14f8405aae43bc0247f2c256f96Tobin Ehlis } 50995b7894efd5e101e410da92fc697429aec3ffa7bMark Lobodzinski uint32_t level_count = ResolveRemainingLevels(&img_barrier->subresourceRange, image_create_info->mipLevels); 51095b7894efd5e101e410da92fc697429aec3ffa7bMark Lobodzinski uint32_t layer_count = ResolveRemainingLayers(&img_barrier->subresourceRange, image_create_info->arrayLayers); 511a90f5fa414aa0994e67cdb911938e6ae48f2ad6aMike Weiblen 512a90f5fa414aa0994e67cdb911938e6ae48f2ad6aMike Weiblen for (uint32_t j = 0; j < level_count; j++) { 513a90f5fa414aa0994e67cdb911938e6ae48f2ad6aMike Weiblen uint32_t level = img_barrier->subresourceRange.baseMipLevel + j; 514a90f5fa414aa0994e67cdb911938e6ae48f2ad6aMike Weiblen for (uint32_t k = 0; k < layer_count; k++) { 515a90f5fa414aa0994e67cdb911938e6ae48f2ad6aMike Weiblen uint32_t layer = img_barrier->subresourceRange.baseArrayLayer + k; 516e2d4ce3059fa77badeea63fa2003b83a04ca9c98Tobin Ehlis skip |= ValidateImageAspectLayout(device_data, cb_state, img_barrier, level, layer, VK_IMAGE_ASPECT_COLOR_BIT); 517e2d4ce3059fa77badeea63fa2003b83a04ca9c98Tobin Ehlis skip |= ValidateImageAspectLayout(device_data, cb_state, img_barrier, level, layer, VK_IMAGE_ASPECT_DEPTH_BIT); 518e2d4ce3059fa77badeea63fa2003b83a04ca9c98Tobin Ehlis skip |= ValidateImageAspectLayout(device_data, cb_state, img_barrier, level, layer, VK_IMAGE_ASPECT_STENCIL_BIT); 519e2d4ce3059fa77badeea63fa2003b83a04ca9c98Tobin Ehlis skip |= ValidateImageAspectLayout(device_data, cb_state, img_barrier, level, layer, VK_IMAGE_ASPECT_METADATA_BIT); 52055867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski } 52155867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski } 52255867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski } 52355867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski return skip; 52455867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski} 52555867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski 526e659c986db0f3146726d6c744c75772316c3e0c6Mark Lobodzinskivoid TransitionImageLayouts(layer_data *device_data, VkCommandBuffer cmdBuffer, uint32_t memBarrierCount, 527e659c986db0f3146726d6c744c75772316c3e0c6Mark Lobodzinski const VkImageMemoryBarrier *pImgMemBarriers) { 528e659c986db0f3146726d6c744c75772316c3e0c6Mark Lobodzinski GLOBAL_CB_NODE *pCB = GetCBNode(device_data, cmdBuffer); 529e659c986db0f3146726d6c744c75772316c3e0c6Mark Lobodzinski 530e659c986db0f3146726d6c744c75772316c3e0c6Mark Lobodzinski for (uint32_t i = 0; i < memBarrierCount; ++i) { 531e659c986db0f3146726d6c744c75772316c3e0c6Mark Lobodzinski auto mem_barrier = &pImgMemBarriers[i]; 532e659c986db0f3146726d6c744c75772316c3e0c6Mark Lobodzinski if (!mem_barrier) continue; 533e659c986db0f3146726d6c744c75772316c3e0c6Mark Lobodzinski 53495b7894efd5e101e410da92fc697429aec3ffa7bMark Lobodzinski VkImageCreateInfo *image_create_info = &(GetImageState(device_data, mem_barrier->image)->createInfo); 53595b7894efd5e101e410da92fc697429aec3ffa7bMark Lobodzinski uint32_t level_count = ResolveRemainingLevels(&mem_barrier->subresourceRange, image_create_info->mipLevels); 53695b7894efd5e101e410da92fc697429aec3ffa7bMark Lobodzinski uint32_t layer_count = ResolveRemainingLayers(&mem_barrier->subresourceRange, image_create_info->arrayLayers); 53795b7894efd5e101e410da92fc697429aec3ffa7bMark Lobodzinski 53895b7894efd5e101e410da92fc697429aec3ffa7bMark Lobodzinski for (uint32_t j = 0; j < level_count; j++) { 539e659c986db0f3146726d6c744c75772316c3e0c6Mark Lobodzinski uint32_t level = mem_barrier->subresourceRange.baseMipLevel + j; 54095b7894efd5e101e410da92fc697429aec3ffa7bMark Lobodzinski for (uint32_t k = 0; k < layer_count; k++) { 541e659c986db0f3146726d6c744c75772316c3e0c6Mark Lobodzinski uint32_t layer = mem_barrier->subresourceRange.baseArrayLayer + k; 542e659c986db0f3146726d6c744c75772316c3e0c6Mark Lobodzinski TransitionImageAspectLayout(device_data, pCB, mem_barrier, level, layer, VK_IMAGE_ASPECT_COLOR_BIT); 543e659c986db0f3146726d6c744c75772316c3e0c6Mark Lobodzinski TransitionImageAspectLayout(device_data, pCB, mem_barrier, level, layer, VK_IMAGE_ASPECT_DEPTH_BIT); 544e659c986db0f3146726d6c744c75772316c3e0c6Mark Lobodzinski TransitionImageAspectLayout(device_data, pCB, mem_barrier, level, layer, VK_IMAGE_ASPECT_STENCIL_BIT); 545e659c986db0f3146726d6c744c75772316c3e0c6Mark Lobodzinski TransitionImageAspectLayout(device_data, pCB, mem_barrier, level, layer, VK_IMAGE_ASPECT_METADATA_BIT); 546e659c986db0f3146726d6c744c75772316c3e0c6Mark Lobodzinski } 547e659c986db0f3146726d6c744c75772316c3e0c6Mark Lobodzinski } 548e659c986db0f3146726d6c744c75772316c3e0c6Mark Lobodzinski } 549e659c986db0f3146726d6c744c75772316c3e0c6Mark Lobodzinski} 550e659c986db0f3146726d6c744c75772316c3e0c6Mark Lobodzinski 5510db18ab1345f9e10907913b22ea5d57bd48077ebTobin Ehlisbool VerifyImageLayout(layer_data const *device_data, GLOBAL_CB_NODE const *cb_node, IMAGE_STATE *image_state, 552fab4fd84d0d187bc73b5bc6709d8ed6370bb7cc3Tobin Ehlis VkImageSubresourceLayers subLayers, VkImageLayout explicit_layout, VkImageLayout optimal_layout, 5530db18ab1345f9e10907913b22ea5d57bd48077ebTobin Ehlis const char *caller, UNIQUE_VALIDATION_ERROR_CODE msg_code, bool *error) { 55455867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski const auto report_data = core_validation::GetReportData(device_data); 555fab4fd84d0d187bc73b5bc6709d8ed6370bb7cc3Tobin Ehlis const auto image = image_state->image; 5563251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = false; 55755867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski 55855867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski for (uint32_t i = 0; i < subLayers.layerCount; ++i) { 55955867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski uint32_t layer = i + subLayers.baseArrayLayer; 56055867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski VkImageSubresource sub = {subLayers.aspectMask, subLayers.mipLevel, layer}; 56155867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski IMAGE_CMD_BUF_LAYOUT_NODE node; 562a07ae8bd5f566eb9b073498dd4280efdb0b838b9Tobin Ehlis if (FindCmdBufLayout(device_data, cb_node, image, sub, node)) { 563a07ae8bd5f566eb9b073498dd4280efdb0b838b9Tobin Ehlis if (node.layout != explicit_layout) { 5640db18ab1345f9e10907913b22ea5d57bd48077ebTobin Ehlis *error = true; 565a07ae8bd5f566eb9b073498dd4280efdb0b838b9Tobin Ehlis // TODO: Improve log message in the next pass 566055fc8fd459f0da279d4814f927ea7090dd0f7e9Petr Kraus skip |= log_msg( 567055fc8fd459f0da279d4814f927ea7090dd0f7e9Petr Kraus report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 568055fc8fd459f0da279d4814f927ea7090dd0f7e9Petr Kraus HandleToUint64(cb_node->commandBuffer), __LINE__, DRAWSTATE_INVALID_IMAGE_LAYOUT, "DS", 569055fc8fd459f0da279d4814f927ea7090dd0f7e9Petr Kraus "%s: Cannot use image 0x%" PRIx64 " with specific layout %s that doesn't match the actual current layout %s.", 570055fc8fd459f0da279d4814f927ea7090dd0f7e9Petr Kraus caller, HandleToUint64(image), string_VkImageLayout(explicit_layout), string_VkImageLayout(node.layout)); 571a07ae8bd5f566eb9b073498dd4280efdb0b838b9Tobin Ehlis } 57255867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski } 57355867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski } 574fab4fd84d0d187bc73b5bc6709d8ed6370bb7cc3Tobin Ehlis // If optimal_layout is not UNDEFINED, check that layout matches optimal for this case 575fab4fd84d0d187bc73b5bc6709d8ed6370bb7cc3Tobin Ehlis if ((VK_IMAGE_LAYOUT_UNDEFINED != optimal_layout) && (explicit_layout != optimal_layout)) { 576fab4fd84d0d187bc73b5bc6709d8ed6370bb7cc3Tobin Ehlis if (VK_IMAGE_LAYOUT_GENERAL == explicit_layout) { 57755867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski if (image_state->createInfo.tiling != VK_IMAGE_TILING_LINEAR) { 57855867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski // LAYOUT_GENERAL is allowed, but may not be performance optimal, flag as perf warning. 5793251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT, 5809b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, HandleToUint64(cb_node->commandBuffer), __LINE__, 5819b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus DRAWSTATE_INVALID_IMAGE_LAYOUT, "DS", 582055fc8fd459f0da279d4814f927ea7090dd0f7e9Petr Kraus "%s: For optimal performance image 0x%" PRIx64 " layout should be %s instead of GENERAL.", caller, 583055fc8fd459f0da279d4814f927ea7090dd0f7e9Petr Kraus HandleToUint64(image), string_VkImageLayout(optimal_layout)); 58455867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski } 585d4eaca34eca7f4b4e34190c441a579347bb2016aMark Lobodzinski } else if (GetDeviceExtensions(device_data)->vk_khr_shared_presentable_image) { 5866084b78a58b438d27591b81efe30997ac9d88d3cMark Lobodzinski if (image_state->shared_presentable) { 5876084b78a58b438d27591b81efe30997ac9d88d3cMark Lobodzinski if (VK_IMAGE_LAYOUT_SHARED_PRESENT_KHR != explicit_layout) { 5886084b78a58b438d27591b81efe30997ac9d88d3cMark Lobodzinski // TODO: Add unique error id when available. 5896084b78a58b438d27591b81efe30997ac9d88d3cMark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, 5906084b78a58b438d27591b81efe30997ac9d88d3cMark Lobodzinski __LINE__, msg_code, "DS", 5916084b78a58b438d27591b81efe30997ac9d88d3cMark Lobodzinski "Layout for shared presentable image is %s but must be VK_IMAGE_LAYOUT_SHARED_PRESENT_KHR.", 5926084b78a58b438d27591b81efe30997ac9d88d3cMark Lobodzinski string_VkImageLayout(optimal_layout)); 5936084b78a58b438d27591b81efe30997ac9d88d3cMark Lobodzinski } 59487a57d8e822316de46ee97f514187331b1f4f09dTobin Ehlis } 59555867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski } else { 5960db18ab1345f9e10907913b22ea5d57bd48077ebTobin Ehlis *error = true; 5973251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 5989b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(cb_node->commandBuffer), __LINE__, msg_code, "DS", 599055fc8fd459f0da279d4814f927ea7090dd0f7e9Petr Kraus "%s: Layout for image 0x%" PRIx64 " is %s but can only be %s or VK_IMAGE_LAYOUT_GENERAL. %s", caller, 600055fc8fd459f0da279d4814f927ea7090dd0f7e9Petr Kraus HandleToUint64(image), string_VkImageLayout(explicit_layout), string_VkImageLayout(optimal_layout), 601055fc8fd459f0da279d4814f927ea7090dd0f7e9Petr Kraus validation_error_map[msg_code]); 60255867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski } 60355867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski } 6043251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski return skip; 60555867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski} 60655867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski 607e40189d4deab674240cd9baf4c063bab4567c212Tobin Ehlisvoid TransitionFinalSubpassLayouts(layer_data *device_data, GLOBAL_CB_NODE *pCB, const VkRenderPassBeginInfo *pRenderPassBegin, 608e40189d4deab674240cd9baf4c063bab4567c212Tobin Ehlis FRAMEBUFFER_STATE *framebuffer_state) { 6099a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto renderPass = GetRenderPassState(device_data, pRenderPassBegin->renderPass); 61055867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski if (!renderPass) return; 61155867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski 61255867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski const VkRenderPassCreateInfo *pRenderPassInfo = renderPass->createInfo.ptr(); 61355867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski if (framebuffer_state) { 61455867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski for (uint32_t i = 0; i < pRenderPassInfo->attachmentCount; ++i) { 61555867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski auto image_view = framebuffer_state->createInfo.pAttachments[i]; 61655867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski SetImageViewLayout(device_data, pCB, image_view, pRenderPassInfo->pAttachments[i].finalLayout); 61755867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski } 61855867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski } 61955867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski} 6200ac318c71851d1361d004d0895207b8bf40fb573Dave Houlton 621e40189d4deab674240cd9baf4c063bab4567c212Tobin Ehlisbool PreCallValidateCreateImage(layer_data *device_data, const VkImageCreateInfo *pCreateInfo, 6228dea300c362f709ad26886548ea46eb4c315e401Mark Lobodzinski const VkAllocationCallbacks *pAllocator, VkImage *pImage) { 6233251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = false; 6248dea300c362f709ad26886548ea46eb4c315e401Mark Lobodzinski const debug_report_data *report_data = core_validation::GetReportData(device_data); 6258dea300c362f709ad26886548ea46eb4c315e401Mark Lobodzinski 6263c4d73267a033429a5b49318cdfd743432518761Jeremy Hayes if (pCreateInfo->format == VK_FORMAT_UNDEFINED) { 6273251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, 628315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis VALIDATION_ERROR_09e0075e, "IMAGE", "vkCreateImage: VkFormat for image must not be VK_FORMAT_UNDEFINED. %s", 629315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_09e0075e]); 6303c4d73267a033429a5b49318cdfd743432518761Jeremy Hayes 6313251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski return skip; 6323c4d73267a033429a5b49318cdfd743432518761Jeremy Hayes } 6333c4d73267a033429a5b49318cdfd743432518761Jeremy Hayes 63463f3a40c10f2c26b6a85b4fb984cf4f1426797aeDave Houlton bool optimal_tiling = (VK_IMAGE_TILING_OPTIMAL == pCreateInfo->tiling); 63563f3a40c10f2c26b6a85b4fb984cf4f1426797aeDave Houlton const char *tiling_string = string_VkImageTiling(pCreateInfo->tiling); 63663f3a40c10f2c26b6a85b4fb984cf4f1426797aeDave Houlton const char *format_string = string_VkFormat(pCreateInfo->format); 63757f0da98098689f3624c5503cfe1a4b5fede885aJeremy Kniager VkFormatProperties properties = GetFormatProperties(device_data, pCreateInfo->format); 63863f3a40c10f2c26b6a85b4fb984cf4f1426797aeDave Houlton VkFormatFeatureFlags features = (optimal_tiling ? properties.optimalTilingFeatures : properties.linearTilingFeatures); 6393c4d73267a033429a5b49318cdfd743432518761Jeremy Hayes 64063f3a40c10f2c26b6a85b4fb984cf4f1426797aeDave Houlton if (0 == features) { 6413c4d73267a033429a5b49318cdfd743432518761Jeremy Hayes std::stringstream ss; 64263f3a40c10f2c26b6a85b4fb984cf4f1426797aeDave Houlton UNIQUE_VALIDATION_ERROR_CODE vuid = (optimal_tiling ? VALIDATION_ERROR_09e007ac : VALIDATION_ERROR_09e007a2); 64363f3a40c10f2c26b6a85b4fb984cf4f1426797aeDave Houlton ss << "vkCreateImage format parameter " << format_string << " is an unsupported format"; 64463f3a40c10f2c26b6a85b4fb984cf4f1426797aeDave Houlton skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, vuid, 64563f3a40c10f2c26b6a85b4fb984cf4f1426797aeDave Houlton "IMAGE", "%s. %s", ss.str().c_str(), validation_error_map[vuid]); 6463251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski return skip; 6473c4d73267a033429a5b49318cdfd743432518761Jeremy Hayes } 6483c4d73267a033429a5b49318cdfd743432518761Jeremy Hayes 64963f3a40c10f2c26b6a85b4fb984cf4f1426797aeDave Houlton if ((pCreateInfo->usage & VK_IMAGE_USAGE_SAMPLED_BIT) && !(features & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT)) { 6503c4d73267a033429a5b49318cdfd743432518761Jeremy Hayes std::stringstream ss; 65163f3a40c10f2c26b6a85b4fb984cf4f1426797aeDave Houlton UNIQUE_VALIDATION_ERROR_CODE vuid = (optimal_tiling ? VALIDATION_ERROR_09e007ae : VALIDATION_ERROR_09e007a4); 65263f3a40c10f2c26b6a85b4fb984cf4f1426797aeDave Houlton ss << "vkCreateImage: usage bit VK_IMAGE_USAGE_SAMPLED_BIT is not supported for format " << format_string << " with tiling " 65363f3a40c10f2c26b6a85b4fb984cf4f1426797aeDave Houlton << tiling_string; 65463f3a40c10f2c26b6a85b4fb984cf4f1426797aeDave Houlton skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, vuid, 65563f3a40c10f2c26b6a85b4fb984cf4f1426797aeDave Houlton "IMAGE", "%s. %s", ss.str().c_str(), validation_error_map[vuid]); 65663f3a40c10f2c26b6a85b4fb984cf4f1426797aeDave Houlton } 6573c4d73267a033429a5b49318cdfd743432518761Jeremy Hayes 65863f3a40c10f2c26b6a85b4fb984cf4f1426797aeDave Houlton if ((pCreateInfo->usage & VK_IMAGE_USAGE_STORAGE_BIT) && !(features & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT)) { 65963f3a40c10f2c26b6a85b4fb984cf4f1426797aeDave Houlton std::stringstream ss; 66063f3a40c10f2c26b6a85b4fb984cf4f1426797aeDave Houlton UNIQUE_VALIDATION_ERROR_CODE vuid = (optimal_tiling ? VALIDATION_ERROR_09e007b0 : VALIDATION_ERROR_09e007a6); 66163f3a40c10f2c26b6a85b4fb984cf4f1426797aeDave Houlton ss << "vkCreateImage: usage bit VK_IMAGE_USAGE_STORAGE_BIT is not supported for format " << format_string << " with tiling " 66263f3a40c10f2c26b6a85b4fb984cf4f1426797aeDave Houlton << tiling_string; 66363f3a40c10f2c26b6a85b4fb984cf4f1426797aeDave Houlton skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, vuid, 66463f3a40c10f2c26b6a85b4fb984cf4f1426797aeDave Houlton "IMAGE", "%s. %s", ss.str().c_str(), validation_error_map[vuid]); 6653c4d73267a033429a5b49318cdfd743432518761Jeremy Hayes } 6668dea300c362f709ad26886548ea46eb4c315e401Mark Lobodzinski 667093e327fb28d5083306dcc66cd71b7809771f496Lenny Komow // TODO: Add checks for EXTENDED_USAGE images to validate images are compatible 668093e327fb28d5083306dcc66cd71b7809771f496Lenny Komow // For EXTENDED_USAGE images, format can match any image COMPATIBLE with original image 669093e327fb28d5083306dcc66cd71b7809771f496Lenny Komow if (!GetDeviceExtensions(device_data)->vk_khr_maintenance2 || !(pCreateInfo->flags & VK_IMAGE_CREATE_EXTENDED_USAGE_BIT_KHR)) { 670093e327fb28d5083306dcc66cd71b7809771f496Lenny Komow // Validate that format supports usage as color attachment 67163f3a40c10f2c26b6a85b4fb984cf4f1426797aeDave Houlton if ((pCreateInfo->usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) && 67263f3a40c10f2c26b6a85b4fb984cf4f1426797aeDave Houlton (0 == (features & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT))) { 67363f3a40c10f2c26b6a85b4fb984cf4f1426797aeDave Houlton UNIQUE_VALIDATION_ERROR_CODE vuid = (optimal_tiling ? VALIDATION_ERROR_09e007b2 : VALIDATION_ERROR_09e007a8); 67463f3a40c10f2c26b6a85b4fb984cf4f1426797aeDave Houlton std::stringstream ss; 67563f3a40c10f2c26b6a85b4fb984cf4f1426797aeDave Houlton ss << "vkCreateImage: usage bit VK_IMAGE_USAGE_COLOR_ATTACHMENT is not supported for format " << format_string 67663f3a40c10f2c26b6a85b4fb984cf4f1426797aeDave Houlton << " with tiling " << tiling_string; 67763f3a40c10f2c26b6a85b4fb984cf4f1426797aeDave Houlton skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, vuid, 67863f3a40c10f2c26b6a85b4fb984cf4f1426797aeDave Houlton "IMAGE", "%s. %s", ss.str().c_str(), validation_error_map[vuid]); 6798dea300c362f709ad26886548ea46eb4c315e401Mark Lobodzinski } 6808dea300c362f709ad26886548ea46eb4c315e401Mark Lobodzinski 681093e327fb28d5083306dcc66cd71b7809771f496Lenny Komow // Validate that format supports usage as depth/stencil attachment 68263f3a40c10f2c26b6a85b4fb984cf4f1426797aeDave Houlton if ((pCreateInfo->usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) && 68363f3a40c10f2c26b6a85b4fb984cf4f1426797aeDave Houlton (0 == (features & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT))) { 68463f3a40c10f2c26b6a85b4fb984cf4f1426797aeDave Houlton UNIQUE_VALIDATION_ERROR_CODE vuid = (optimal_tiling ? VALIDATION_ERROR_09e007b4 : VALIDATION_ERROR_09e007aa); 68563f3a40c10f2c26b6a85b4fb984cf4f1426797aeDave Houlton std::stringstream ss; 68663f3a40c10f2c26b6a85b4fb984cf4f1426797aeDave Houlton ss << "vkCreateImage: usage bit VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT is not supported for format " << format_string 68763f3a40c10f2c26b6a85b4fb984cf4f1426797aeDave Houlton << " with tiling " << tiling_string; 68863f3a40c10f2c26b6a85b4fb984cf4f1426797aeDave Houlton skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, vuid, 68963f3a40c10f2c26b6a85b4fb984cf4f1426797aeDave Houlton "IMAGE", "%s. %s", ss.str().c_str(), validation_error_map[vuid]); 69063f3a40c10f2c26b6a85b4fb984cf4f1426797aeDave Houlton } 69163f3a40c10f2c26b6a85b4fb984cf4f1426797aeDave Houlton } 69263f3a40c10f2c26b6a85b4fb984cf4f1426797aeDave Houlton 69363f3a40c10f2c26b6a85b4fb984cf4f1426797aeDave Houlton if ((pCreateInfo->flags & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT) && (VK_IMAGE_TYPE_2D != pCreateInfo->imageType)) { 69463f3a40c10f2c26b6a85b4fb984cf4f1426797aeDave Houlton std::stringstream ss; 69563f3a40c10f2c26b6a85b4fb984cf4f1426797aeDave Houlton ss << "vkCreateImage: Image type must be VK_IMAGE_TYPE_2D when VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT flag bit is set"; 69663f3a40c10f2c26b6a85b4fb984cf4f1426797aeDave Houlton skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, 69763f3a40c10f2c26b6a85b4fb984cf4f1426797aeDave Houlton VALIDATION_ERROR_09e0076a, "IMAGE", "%s. %s", ss.str().c_str(), 69863f3a40c10f2c26b6a85b4fb984cf4f1426797aeDave Houlton validation_error_map[VALIDATION_ERROR_09e0076a]); 69963f3a40c10f2c26b6a85b4fb984cf4f1426797aeDave Houlton } 70063f3a40c10f2c26b6a85b4fb984cf4f1426797aeDave Houlton 70163f3a40c10f2c26b6a85b4fb984cf4f1426797aeDave Houlton const VkPhysicalDeviceLimits *device_limits = &(GetPhysicalDeviceProperties(device_data)->limits); 70263f3a40c10f2c26b6a85b4fb984cf4f1426797aeDave Houlton VkImageFormatProperties format_limits; // Format limits may exceed general device limits 70363f3a40c10f2c26b6a85b4fb984cf4f1426797aeDave Houlton VkResult err = GetImageFormatProperties(device_data, pCreateInfo, &format_limits); 70463f3a40c10f2c26b6a85b4fb984cf4f1426797aeDave Houlton if (VK_SUCCESS != err) { 70563f3a40c10f2c26b6a85b4fb984cf4f1426797aeDave Houlton std::stringstream ss; 70663f3a40c10f2c26b6a85b4fb984cf4f1426797aeDave Houlton ss << "vkCreateImage: The combination of format, type, tiling, usage and flags supplied in the VkImageCreateInfo struct is " 70763f3a40c10f2c26b6a85b4fb984cf4f1426797aeDave Houlton "reported by vkGetPhysicalDeviceImageFormatProperties() as unsupported"; 70863f3a40c10f2c26b6a85b4fb984cf4f1426797aeDave Houlton skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, 70963f3a40c10f2c26b6a85b4fb984cf4f1426797aeDave Houlton VALIDATION_ERROR_09e00758, "IMAGE", "%s. %s", ss.str().c_str(), 71063f3a40c10f2c26b6a85b4fb984cf4f1426797aeDave Houlton validation_error_map[VALIDATION_ERROR_09e00758]); 71163f3a40c10f2c26b6a85b4fb984cf4f1426797aeDave Houlton return skip; 71263f3a40c10f2c26b6a85b4fb984cf4f1426797aeDave Houlton } 71363f3a40c10f2c26b6a85b4fb984cf4f1426797aeDave Houlton 71463f3a40c10f2c26b6a85b4fb984cf4f1426797aeDave Houlton if ((VK_IMAGE_TYPE_1D == pCreateInfo->imageType) && 71563f3a40c10f2c26b6a85b4fb984cf4f1426797aeDave Houlton (pCreateInfo->extent.width > std::max(device_limits->maxImageDimension1D, format_limits.maxExtent.width))) { 71663f3a40c10f2c26b6a85b4fb984cf4f1426797aeDave Houlton std::stringstream ss; 71763f3a40c10f2c26b6a85b4fb984cf4f1426797aeDave Houlton ss << "vkCreateImage: 1D image width exceeds maximum supported width for format " << format_string; 71863f3a40c10f2c26b6a85b4fb984cf4f1426797aeDave Houlton skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, 71963f3a40c10f2c26b6a85b4fb984cf4f1426797aeDave Houlton VALIDATION_ERROR_09e0076e, "IMAGE", "%s. %s", ss.str().c_str(), 72063f3a40c10f2c26b6a85b4fb984cf4f1426797aeDave Houlton validation_error_map[VALIDATION_ERROR_09e0076e]); 72163f3a40c10f2c26b6a85b4fb984cf4f1426797aeDave Houlton } 72263f3a40c10f2c26b6a85b4fb984cf4f1426797aeDave Houlton 72363f3a40c10f2c26b6a85b4fb984cf4f1426797aeDave Houlton if (VK_IMAGE_TYPE_2D == pCreateInfo->imageType) { 72463f3a40c10f2c26b6a85b4fb984cf4f1426797aeDave Houlton if (0 == (pCreateInfo->flags & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT)) { 72563f3a40c10f2c26b6a85b4fb984cf4f1426797aeDave Houlton if (pCreateInfo->extent.width > std::max(device_limits->maxImageDimension2D, format_limits.maxExtent.width) || 72663f3a40c10f2c26b6a85b4fb984cf4f1426797aeDave Houlton pCreateInfo->extent.height > std::max(device_limits->maxImageDimension2D, format_limits.maxExtent.height)) { 727093e327fb28d5083306dcc66cd71b7809771f496Lenny Komow std::stringstream ss; 72863f3a40c10f2c26b6a85b4fb984cf4f1426797aeDave Houlton ss << "vkCreateImage: 2D image extent exceeds maximum supported width or height for format " << format_string; 729093e327fb28d5083306dcc66cd71b7809771f496Lenny Komow skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, 73063f3a40c10f2c26b6a85b4fb984cf4f1426797aeDave Houlton VALIDATION_ERROR_09e00770, "IMAGE", "%s. %s", ss.str().c_str(), 73163f3a40c10f2c26b6a85b4fb984cf4f1426797aeDave Houlton validation_error_map[VALIDATION_ERROR_09e00770]); 732093e327fb28d5083306dcc66cd71b7809771f496Lenny Komow } 73363f3a40c10f2c26b6a85b4fb984cf4f1426797aeDave Houlton } else { 73463f3a40c10f2c26b6a85b4fb984cf4f1426797aeDave Houlton if (pCreateInfo->extent.width > std::max(device_limits->maxImageDimensionCube, format_limits.maxExtent.width) || 73563f3a40c10f2c26b6a85b4fb984cf4f1426797aeDave Houlton pCreateInfo->extent.height > std::max(device_limits->maxImageDimensionCube, format_limits.maxExtent.height)) { 736093e327fb28d5083306dcc66cd71b7809771f496Lenny Komow std::stringstream ss; 73763f3a40c10f2c26b6a85b4fb984cf4f1426797aeDave Houlton ss << "vkCreateImage: 2D image extent exceeds maximum supported width or height for cube-compatible images with " 73863f3a40c10f2c26b6a85b4fb984cf4f1426797aeDave Houlton "format " 73963f3a40c10f2c26b6a85b4fb984cf4f1426797aeDave Houlton << format_string; 740093e327fb28d5083306dcc66cd71b7809771f496Lenny Komow skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, 74163f3a40c10f2c26b6a85b4fb984cf4f1426797aeDave Houlton VALIDATION_ERROR_09e00772, "IMAGE", "%s. %s", ss.str().c_str(), 74263f3a40c10f2c26b6a85b4fb984cf4f1426797aeDave Houlton validation_error_map[VALIDATION_ERROR_09e00772]); 743093e327fb28d5083306dcc66cd71b7809771f496Lenny Komow } 7448dea300c362f709ad26886548ea46eb4c315e401Mark Lobodzinski } 7458dea300c362f709ad26886548ea46eb4c315e401Mark Lobodzinski } 7468dea300c362f709ad26886548ea46eb4c315e401Mark Lobodzinski 74763f3a40c10f2c26b6a85b4fb984cf4f1426797aeDave Houlton if (VK_IMAGE_TYPE_3D == pCreateInfo->imageType) { 74863f3a40c10f2c26b6a85b4fb984cf4f1426797aeDave Houlton if ((pCreateInfo->extent.width > std::max(device_limits->maxImageDimension3D, format_limits.maxExtent.width)) || 74963f3a40c10f2c26b6a85b4fb984cf4f1426797aeDave Houlton (pCreateInfo->extent.height > std::max(device_limits->maxImageDimension3D, format_limits.maxExtent.height)) || 75063f3a40c10f2c26b6a85b4fb984cf4f1426797aeDave Houlton (pCreateInfo->extent.depth > std::max(device_limits->maxImageDimension3D, format_limits.maxExtent.depth))) { 75163f3a40c10f2c26b6a85b4fb984cf4f1426797aeDave Houlton std::stringstream ss; 75263f3a40c10f2c26b6a85b4fb984cf4f1426797aeDave Houlton ss << "vkCreateImage: 3D image extent exceeds maximum supported width, height, or depth for format " << format_string; 75363f3a40c10f2c26b6a85b4fb984cf4f1426797aeDave Houlton skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, 75463f3a40c10f2c26b6a85b4fb984cf4f1426797aeDave Houlton VALIDATION_ERROR_09e00776, "IMAGE", "%s. %s", ss.str().c_str(), 75563f3a40c10f2c26b6a85b4fb984cf4f1426797aeDave Houlton validation_error_map[VALIDATION_ERROR_09e00776]); 75663f3a40c10f2c26b6a85b4fb984cf4f1426797aeDave Houlton } 75763f3a40c10f2c26b6a85b4fb984cf4f1426797aeDave Houlton } 7588dea300c362f709ad26886548ea46eb4c315e401Mark Lobodzinski 75963f3a40c10f2c26b6a85b4fb984cf4f1426797aeDave Houlton // NOTE: As of 1/30/2018 the spec VU language is as in the commented code below. I believe this is an 7600ac318c71851d1361d004d0895207b8bf40fb573Dave Houlton // error in the spec, and have submitted Gitlab Vulkan issue #1151 to have it changed to match the 76163f3a40c10f2c26b6a85b4fb984cf4f1426797aeDave Houlton // implementation shown. DJH 76263f3a40c10f2c26b6a85b4fb984cf4f1426797aeDave Houlton // 76363f3a40c10f2c26b6a85b4fb984cf4f1426797aeDave Houlton // if ((pCreateInfo->mipLevels > format_limits.maxMipLevels) && 76463f3a40c10f2c26b6a85b4fb984cf4f1426797aeDave Houlton // (std::max({ pCreateInfo->extent.width, pCreateInfo->extent.height, pCreateInfo->extent.depth }) > 76563f3a40c10f2c26b6a85b4fb984cf4f1426797aeDave Houlton // device_limits->maxImageDimension3D)) { 76663f3a40c10f2c26b6a85b4fb984cf4f1426797aeDave Houlton if (pCreateInfo->mipLevels > format_limits.maxMipLevels) { 76763f3a40c10f2c26b6a85b4fb984cf4f1426797aeDave Houlton std::stringstream ss; 76863f3a40c10f2c26b6a85b4fb984cf4f1426797aeDave Houlton ss << "vkCreateImage: Image mip levels exceed image format maxMipLevels for format " << format_string; 76963f3a40c10f2c26b6a85b4fb984cf4f1426797aeDave Houlton skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, 77063f3a40c10f2c26b6a85b4fb984cf4f1426797aeDave Houlton VALIDATION_ERROR_09e0077e, "IMAGE", "%s. %s", ss.str().c_str(), 77163f3a40c10f2c26b6a85b4fb984cf4f1426797aeDave Houlton validation_error_map[VALIDATION_ERROR_09e0077e]); 77263f3a40c10f2c26b6a85b4fb984cf4f1426797aeDave Houlton } 7738dea300c362f709ad26886548ea46eb4c315e401Mark Lobodzinski 77463f3a40c10f2c26b6a85b4fb984cf4f1426797aeDave Houlton VkImageUsageFlags attach_flags = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | 77563f3a40c10f2c26b6a85b4fb984cf4f1426797aeDave Houlton VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT; 77663f3a40c10f2c26b6a85b4fb984cf4f1426797aeDave Houlton if ((pCreateInfo->usage & attach_flags) && (pCreateInfo->extent.width > device_limits->maxFramebufferWidth)) { 77763f3a40c10f2c26b6a85b4fb984cf4f1426797aeDave Houlton std::stringstream ss; 77863f3a40c10f2c26b6a85b4fb984cf4f1426797aeDave Houlton ss << "vkCreateImage: Image usage flags include a frame buffer attachment bit and image width exceeds device " 77963f3a40c10f2c26b6a85b4fb984cf4f1426797aeDave Houlton "maxFramebufferWidth"; 78063f3a40c10f2c26b6a85b4fb984cf4f1426797aeDave Houlton skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, 78163f3a40c10f2c26b6a85b4fb984cf4f1426797aeDave Houlton VALIDATION_ERROR_09e00788, "IMAGE", "%s. %s", ss.str().c_str(), 78263f3a40c10f2c26b6a85b4fb984cf4f1426797aeDave Houlton validation_error_map[VALIDATION_ERROR_09e00788]); 7838dea300c362f709ad26886548ea46eb4c315e401Mark Lobodzinski } 7848dea300c362f709ad26886548ea46eb4c315e401Mark Lobodzinski 78563f3a40c10f2c26b6a85b4fb984cf4f1426797aeDave Houlton if ((pCreateInfo->usage & attach_flags) && (pCreateInfo->extent.height > device_limits->maxFramebufferHeight)) { 78663f3a40c10f2c26b6a85b4fb984cf4f1426797aeDave Houlton std::stringstream ss; 78763f3a40c10f2c26b6a85b4fb984cf4f1426797aeDave Houlton ss << "vkCreateImage: Image usage flags include a frame buffer attachment bit and image height exceeds device " 78863f3a40c10f2c26b6a85b4fb984cf4f1426797aeDave Houlton "maxFramebufferHeight"; 78963f3a40c10f2c26b6a85b4fb984cf4f1426797aeDave Houlton skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, 79063f3a40c10f2c26b6a85b4fb984cf4f1426797aeDave Houlton VALIDATION_ERROR_09e0078a, "IMAGE", "%s. %s", ss.str().c_str(), 79163f3a40c10f2c26b6a85b4fb984cf4f1426797aeDave Houlton validation_error_map[VALIDATION_ERROR_09e0078a]); 79263f3a40c10f2c26b6a85b4fb984cf4f1426797aeDave Houlton } 79363f3a40c10f2c26b6a85b4fb984cf4f1426797aeDave Houlton 79463f3a40c10f2c26b6a85b4fb984cf4f1426797aeDave Houlton uint64_t total_size = (uint64_t)pCreateInfo->extent.width * (uint64_t)pCreateInfo->extent.height * 79563f3a40c10f2c26b6a85b4fb984cf4f1426797aeDave Houlton (uint64_t)pCreateInfo->extent.depth * (uint64_t)pCreateInfo->arrayLayers * 79663f3a40c10f2c26b6a85b4fb984cf4f1426797aeDave Houlton (uint64_t)pCreateInfo->samples * (uint64_t)FormatSize(pCreateInfo->format); 7978dea300c362f709ad26886548ea46eb4c315e401Mark Lobodzinski 79863f3a40c10f2c26b6a85b4fb984cf4f1426797aeDave Houlton // Round up to imageGranularity boundary 79963f3a40c10f2c26b6a85b4fb984cf4f1426797aeDave Houlton VkDeviceSize imageGranularity = GetPhysicalDeviceProperties(device_data)->limits.bufferImageGranularity; 80063f3a40c10f2c26b6a85b4fb984cf4f1426797aeDave Houlton uint64_t ig_mask = imageGranularity - 1; 80163f3a40c10f2c26b6a85b4fb984cf4f1426797aeDave Houlton total_size = (total_size + ig_mask) & ~ig_mask; 80263f3a40c10f2c26b6a85b4fb984cf4f1426797aeDave Houlton 80363f3a40c10f2c26b6a85b4fb984cf4f1426797aeDave Houlton if (total_size > format_limits.maxResourceSize) { 8043251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, 0, __LINE__, 8053251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski IMAGE_INVALID_FORMAT_LIMITS_VIOLATION, "Image", 8065f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton "CreateImage resource size exceeds allowable maximum Image resource size = 0x%" PRIxLEAST64 8075f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton ", maximum resource size = 0x%" PRIxLEAST64 " ", 80863f3a40c10f2c26b6a85b4fb984cf4f1426797aeDave Houlton total_size, format_limits.maxResourceSize); 8098dea300c362f709ad26886548ea46eb4c315e401Mark Lobodzinski } 8108dea300c362f709ad26886548ea46eb4c315e401Mark Lobodzinski 81163f3a40c10f2c26b6a85b4fb984cf4f1426797aeDave Houlton if (pCreateInfo->arrayLayers > format_limits.maxArrayLayers) { 8123251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, 0, __LINE__, 81363f3a40c10f2c26b6a85b4fb984cf4f1426797aeDave Houlton VALIDATION_ERROR_09e00780, "Image", 81463f3a40c10f2c26b6a85b4fb984cf4f1426797aeDave Houlton "CreateImage arrayLayers=%d exceeds allowable maximum supported by format of %d. %s", 81563f3a40c10f2c26b6a85b4fb984cf4f1426797aeDave Houlton pCreateInfo->arrayLayers, format_limits.maxArrayLayers, validation_error_map[VALIDATION_ERROR_09e00780]); 8168dea300c362f709ad26886548ea46eb4c315e401Mark Lobodzinski } 8178dea300c362f709ad26886548ea46eb4c315e401Mark Lobodzinski 81863f3a40c10f2c26b6a85b4fb984cf4f1426797aeDave Houlton if ((pCreateInfo->samples & format_limits.sampleCounts) == 0) { 8193251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, 0, __LINE__, 820315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis VALIDATION_ERROR_09e0078e, "Image", "CreateImage samples %s is not supported by format 0x%.8X. %s", 82163f3a40c10f2c26b6a85b4fb984cf4f1426797aeDave Houlton string_VkSampleCountFlagBits(pCreateInfo->samples), format_limits.sampleCounts, 822315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_09e0078e]); 8238dea300c362f709ad26886548ea46eb4c315e401Mark Lobodzinski } 8248dea300c362f709ad26886548ea46eb4c315e401Mark Lobodzinski 82501363bf3d84ba5841a6870b40c041c2f53d76583Mark Lobodzinski if ((pCreateInfo->flags & VK_IMAGE_CREATE_SPARSE_BINDING_BIT) && (!GetEnabledFeatures(device_data)->sparseBinding)) { 8263251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, 827315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis VALIDATION_ERROR_09e00792, "DS", 8283251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "vkCreateImage(): the sparseBinding device feature is disabled: Images cannot be created with the " 8293251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "VK_IMAGE_CREATE_SPARSE_BINDING_BIT set. %s", 830315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_09e00792]); 83101363bf3d84ba5841a6870b40c041c2f53d76583Mark Lobodzinski } 83201363bf3d84ba5841a6870b40c041c2f53d76583Mark Lobodzinski 8337e105b26dcb40aff4f9776b8f5b5f1326aa1e36cMark Lobodzinski if ((pCreateInfo->flags & VK_IMAGE_CREATE_SPARSE_ALIASED_BIT) && (!GetEnabledFeatures(device_data)->sparseResidencyAliased)) { 8343251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, 8353251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski DRAWSTATE_INVALID_FEATURE, "DS", 8363251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "vkCreateImage(): the sparseResidencyAliased device feature is disabled: Images cannot be created with the " 8373251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "VK_IMAGE_CREATE_SPARSE_ALIASED_BIT set."); 8387e105b26dcb40aff4f9776b8f5b5f1326aa1e36cMark Lobodzinski } 8397e105b26dcb40aff4f9776b8f5b5f1326aa1e36cMark Lobodzinski 840093e327fb28d5083306dcc66cd71b7809771f496Lenny Komow if (GetDeviceExtensions(device_data)->vk_khr_maintenance2) { 841093e327fb28d5083306dcc66cd71b7809771f496Lenny Komow if (pCreateInfo->flags & VK_IMAGE_CREATE_BLOCK_TEXEL_VIEW_COMPATIBLE_BIT_KHR) { 842093e327fb28d5083306dcc66cd71b7809771f496Lenny Komow if (!(FormatIsCompressed_BC(pCreateInfo->format) || FormatIsCompressed_ASTC_LDR(pCreateInfo->format) || 843093e327fb28d5083306dcc66cd71b7809771f496Lenny Komow FormatIsCompressed_ETC2_EAC(pCreateInfo->format))) { 844093e327fb28d5083306dcc66cd71b7809771f496Lenny Komow // TODO: Add Maintenance2 VUID 845093e327fb28d5083306dcc66cd71b7809771f496Lenny Komow skip |= 846093e327fb28d5083306dcc66cd71b7809771f496Lenny Komow log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, 847093e327fb28d5083306dcc66cd71b7809771f496Lenny Komow VALIDATION_ERROR_UNDEFINED, "DS", 848093e327fb28d5083306dcc66cd71b7809771f496Lenny Komow "vkCreateImage(): If pCreateInfo->flags contains VK_IMAGE_CREATE_BLOCK_TEXEL_VIEW_COMPATIBLE_BIT_KHR, " 849093e327fb28d5083306dcc66cd71b7809771f496Lenny Komow "format must be block, ETC or ASTC compressed, but is %s", 850093e327fb28d5083306dcc66cd71b7809771f496Lenny Komow string_VkFormat(pCreateInfo->format)); 851093e327fb28d5083306dcc66cd71b7809771f496Lenny Komow } 852093e327fb28d5083306dcc66cd71b7809771f496Lenny Komow if (!(pCreateInfo->flags & VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT)) { 853093e327fb28d5083306dcc66cd71b7809771f496Lenny Komow // TODO: Add Maintenance2 VUID 854093e327fb28d5083306dcc66cd71b7809771f496Lenny Komow skip |= 855093e327fb28d5083306dcc66cd71b7809771f496Lenny Komow log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, 856093e327fb28d5083306dcc66cd71b7809771f496Lenny Komow VALIDATION_ERROR_UNDEFINED, "DS", 857093e327fb28d5083306dcc66cd71b7809771f496Lenny Komow "vkCreateImage(): If pCreateInfo->flags contains VK_IMAGE_CREATE_BLOCK_TEXEL_VIEW_COMPATIBLE_BIT_KHR, " 858093e327fb28d5083306dcc66cd71b7809771f496Lenny Komow "flags must also contain VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT."); 859093e327fb28d5083306dcc66cd71b7809771f496Lenny Komow } 860093e327fb28d5083306dcc66cd71b7809771f496Lenny Komow } 861093e327fb28d5083306dcc66cd71b7809771f496Lenny Komow } 862093e327fb28d5083306dcc66cd71b7809771f496Lenny Komow 8633251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski return skip; 8648dea300c362f709ad26886548ea46eb4c315e401Mark Lobodzinski} 8658dea300c362f709ad26886548ea46eb4c315e401Mark Lobodzinski 866e40189d4deab674240cd9baf4c063bab4567c212Tobin Ehlisvoid PostCallRecordCreateImage(layer_data *device_data, const VkImageCreateInfo *pCreateInfo, VkImage *pImage) { 867c06c9b88f5f5bcc7033ba41d5547b048fa6015a4Mark Lobodzinski IMAGE_LAYOUT_NODE image_state; 868c06c9b88f5f5bcc7033ba41d5547b048fa6015a4Mark Lobodzinski image_state.layout = pCreateInfo->initialLayout; 869c06c9b88f5f5bcc7033ba41d5547b048fa6015a4Mark Lobodzinski image_state.format = pCreateInfo->format; 870920311b6aa5614a545cad59521770d0898a75d65Mark Lobodzinski GetImageMap(device_data)->insert(std::make_pair(*pImage, std::unique_ptr<IMAGE_STATE>(new IMAGE_STATE(*pImage, pCreateInfo)))); 871c06c9b88f5f5bcc7033ba41d5547b048fa6015a4Mark Lobodzinski ImageSubresourcePair subpair{*pImage, false, VkImageSubresource()}; 872920311b6aa5614a545cad59521770d0898a75d65Mark Lobodzinski (*core_validation::GetImageSubresourceMap(device_data))[*pImage].push_back(subpair); 873920311b6aa5614a545cad59521770d0898a75d65Mark Lobodzinski (*core_validation::GetImageLayoutMap(device_data))[subpair] = image_state; 874c06c9b88f5f5bcc7033ba41d5547b048fa6015a4Mark Lobodzinski} 8758c59133586421be878d393799b30044497f77727Mark Lobodzinski 876e40189d4deab674240cd9baf4c063bab4567c212Tobin Ehlisbool PreCallValidateDestroyImage(layer_data *device_data, VkImage image, IMAGE_STATE **image_state, VK_OBJECT *obj_struct) { 8778c59133586421be878d393799b30044497f77727Mark Lobodzinski const CHECK_DISABLED *disabled = core_validation::GetDisables(device_data); 8789a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis *image_state = core_validation::GetImageState(device_data, image); 8799b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus *obj_struct = {HandleToUint64(image), kVulkanObjectTypeImage}; 8808c59133586421be878d393799b30044497f77727Mark Lobodzinski if (disabled->destroy_image) return false; 8818c59133586421be878d393799b30044497f77727Mark Lobodzinski bool skip = false; 8828c59133586421be878d393799b30044497f77727Mark Lobodzinski if (*image_state) { 88369ea2c79d7b3f9c987671a10686afac066b275b9Mike Schuchardt skip |= core_validation::ValidateObjectNotInUse(device_data, *image_state, *obj_struct, "vkDestroyImage", 88469ea2c79d7b3f9c987671a10686afac066b275b9Mike Schuchardt VALIDATION_ERROR_252007d0); 8858c59133586421be878d393799b30044497f77727Mark Lobodzinski } 8868c59133586421be878d393799b30044497f77727Mark Lobodzinski return skip; 8878c59133586421be878d393799b30044497f77727Mark Lobodzinski} 8888c59133586421be878d393799b30044497f77727Mark Lobodzinski 889e40189d4deab674240cd9baf4c063bab4567c212Tobin Ehlisvoid PostCallRecordDestroyImage(layer_data *device_data, VkImage image, IMAGE_STATE *image_state, VK_OBJECT obj_struct) { 8908c59133586421be878d393799b30044497f77727Mark Lobodzinski core_validation::invalidateCommandBuffers(device_data, image_state->cb_bindings, obj_struct); 8918c59133586421be878d393799b30044497f77727Mark Lobodzinski // Clean up memory mapping, bindings and range references for image 8928c59133586421be878d393799b30044497f77727Mark Lobodzinski for (auto mem_binding : image_state->GetBoundMemory()) { 8939a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto mem_info = core_validation::GetMemObjInfo(device_data, mem_binding); 8948c59133586421be878d393799b30044497f77727Mark Lobodzinski if (mem_info) { 8958c59133586421be878d393799b30044497f77727Mark Lobodzinski core_validation::RemoveImageMemoryRange(obj_struct.handle, mem_info); 8968c59133586421be878d393799b30044497f77727Mark Lobodzinski } 8978c59133586421be878d393799b30044497f77727Mark Lobodzinski } 8987a9423788398dbeb6d1fe0354a66123b61afda96Mark Lobodzinski core_validation::ClearMemoryObjectBindings(device_data, obj_struct.handle, kVulkanObjectTypeImage); 8998c59133586421be878d393799b30044497f77727Mark Lobodzinski // Remove image from imageMap 9008c59133586421be878d393799b30044497f77727Mark Lobodzinski core_validation::GetImageMap(device_data)->erase(image); 9018c59133586421be878d393799b30044497f77727Mark Lobodzinski std::unordered_map<VkImage, std::vector<ImageSubresourcePair>> *imageSubresourceMap = 9028c59133586421be878d393799b30044497f77727Mark Lobodzinski core_validation::GetImageSubresourceMap(device_data); 9038c59133586421be878d393799b30044497f77727Mark Lobodzinski 9048c59133586421be878d393799b30044497f77727Mark Lobodzinski const auto &sub_entry = imageSubresourceMap->find(image); 9058c59133586421be878d393799b30044497f77727Mark Lobodzinski if (sub_entry != imageSubresourceMap->end()) { 9068c59133586421be878d393799b30044497f77727Mark Lobodzinski for (const auto &pair : sub_entry->second) { 9078c59133586421be878d393799b30044497f77727Mark Lobodzinski core_validation::GetImageLayoutMap(device_data)->erase(pair); 9088c59133586421be878d393799b30044497f77727Mark Lobodzinski } 9098c59133586421be878d393799b30044497f77727Mark Lobodzinski imageSubresourceMap->erase(sub_entry); 9108c59133586421be878d393799b30044497f77727Mark Lobodzinski } 9118c59133586421be878d393799b30044497f77727Mark Lobodzinski} 912509e427aa732fc714b9aa01a175ca5f57b2d7a07Mark Lobodzinski 913e40189d4deab674240cd9baf4c063bab4567c212Tobin Ehlisbool ValidateImageAttributes(layer_data *device_data, IMAGE_STATE *image_state, VkImageSubresourceRange range) { 914509e427aa732fc714b9aa01a175ca5f57b2d7a07Mark Lobodzinski bool skip = false; 915509e427aa732fc714b9aa01a175ca5f57b2d7a07Mark Lobodzinski const debug_report_data *report_data = core_validation::GetReportData(device_data); 916509e427aa732fc714b9aa01a175ca5f57b2d7a07Mark Lobodzinski 917509e427aa732fc714b9aa01a175ca5f57b2d7a07Mark Lobodzinski if (range.aspectMask != VK_IMAGE_ASPECT_COLOR_BIT) { 918509e427aa732fc714b9aa01a175ca5f57b2d7a07Mark Lobodzinski char const str[] = "vkCmdClearColorImage aspectMasks for all subresource ranges must be set to VK_IMAGE_ASPECT_COLOR_BIT"; 919509e427aa732fc714b9aa01a175ca5f57b2d7a07Mark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, 9209b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(image_state->image), __LINE__, DRAWSTATE_INVALID_IMAGE_ASPECT, "IMAGE", str); 921509e427aa732fc714b9aa01a175ca5f57b2d7a07Mark Lobodzinski } 922509e427aa732fc714b9aa01a175ca5f57b2d7a07Mark Lobodzinski 92316769f6b2a7721e391952a97f010cbb530e4f211Dave Houlton if (FormatIsDepthOrStencil(image_state->createInfo.format)) { 924509e427aa732fc714b9aa01a175ca5f57b2d7a07Mark Lobodzinski char const str[] = "vkCmdClearColorImage called with depth/stencil image."; 925509e427aa732fc714b9aa01a175ca5f57b2d7a07Mark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, 926315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(image_state->image), __LINE__, VALIDATION_ERROR_1880000e, "IMAGE", "%s. %s", str, 927315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_1880000e]); 92816769f6b2a7721e391952a97f010cbb530e4f211Dave Houlton } else if (FormatIsCompressed(image_state->createInfo.format)) { 929509e427aa732fc714b9aa01a175ca5f57b2d7a07Mark Lobodzinski char const str[] = "vkCmdClearColorImage called with compressed image."; 930509e427aa732fc714b9aa01a175ca5f57b2d7a07Mark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, 931315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(image_state->image), __LINE__, VALIDATION_ERROR_1880000e, "IMAGE", "%s. %s", str, 932315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_1880000e]); 933509e427aa732fc714b9aa01a175ca5f57b2d7a07Mark Lobodzinski } 934509e427aa732fc714b9aa01a175ca5f57b2d7a07Mark Lobodzinski 935509e427aa732fc714b9aa01a175ca5f57b2d7a07Mark Lobodzinski if (!(image_state->createInfo.usage & VK_IMAGE_USAGE_TRANSFER_DST_BIT)) { 936509e427aa732fc714b9aa01a175ca5f57b2d7a07Mark Lobodzinski char const str[] = "vkCmdClearColorImage called with image created without VK_IMAGE_USAGE_TRANSFER_DST_BIT."; 937509e427aa732fc714b9aa01a175ca5f57b2d7a07Mark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, 938315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(image_state->image), __LINE__, VALIDATION_ERROR_18800004, "IMAGE", "%s. %s", str, 939315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_18800004]); 940509e427aa732fc714b9aa01a175ca5f57b2d7a07Mark Lobodzinski } 941509e427aa732fc714b9aa01a175ca5f57b2d7a07Mark Lobodzinski return skip; 942509e427aa732fc714b9aa01a175ca5f57b2d7a07Mark Lobodzinski} 943623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski 94495b7894efd5e101e410da92fc697429aec3ffa7bMark Lobodzinskiuint32_t ResolveRemainingLevels(const VkImageSubresourceRange *range, uint32_t mip_levels) { 94595b7894efd5e101e410da92fc697429aec3ffa7bMark Lobodzinski // Return correct number of mip levels taking into account VK_REMAINING_MIP_LEVELS 94695b7894efd5e101e410da92fc697429aec3ffa7bMark Lobodzinski uint32_t mip_level_count = range->levelCount; 94708c7aae3177092f8567e2b5a946457be61616e9aMark Lobodzinski if (range->levelCount == VK_REMAINING_MIP_LEVELS) { 94895b7894efd5e101e410da92fc697429aec3ffa7bMark Lobodzinski mip_level_count = mip_levels - range->baseMipLevel; 949623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski } 95095b7894efd5e101e410da92fc697429aec3ffa7bMark Lobodzinski return mip_level_count; 951623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski} 952623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski 95395b7894efd5e101e410da92fc697429aec3ffa7bMark Lobodzinskiuint32_t ResolveRemainingLayers(const VkImageSubresourceRange *range, uint32_t layers) { 95495b7894efd5e101e410da92fc697429aec3ffa7bMark Lobodzinski // Return correct number of layers taking into account VK_REMAINING_ARRAY_LAYERS 95595b7894efd5e101e410da92fc697429aec3ffa7bMark Lobodzinski uint32_t array_layer_count = range->layerCount; 95695b7894efd5e101e410da92fc697429aec3ffa7bMark Lobodzinski if (range->layerCount == VK_REMAINING_ARRAY_LAYERS) { 95795b7894efd5e101e410da92fc697429aec3ffa7bMark Lobodzinski array_layer_count = layers - range->baseArrayLayer; 958623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski } 95995b7894efd5e101e410da92fc697429aec3ffa7bMark Lobodzinski return array_layer_count; 960623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski} 961623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski 962e40189d4deab674240cd9baf4c063bab4567c212Tobin Ehlisbool VerifyClearImageLayout(layer_data *device_data, GLOBAL_CB_NODE *cb_node, IMAGE_STATE *image_state, 963623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski VkImageSubresourceRange range, VkImageLayout dest_image_layout, const char *func_name) { 964623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski bool skip = false; 965623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski const debug_report_data *report_data = core_validation::GetReportData(device_data); 966623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski 96795b7894efd5e101e410da92fc697429aec3ffa7bMark Lobodzinski uint32_t level_count = ResolveRemainingLevels(&range, image_state->createInfo.mipLevels); 96895b7894efd5e101e410da92fc697429aec3ffa7bMark Lobodzinski uint32_t layer_count = ResolveRemainingLayers(&range, image_state->createInfo.arrayLayers); 969623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski 970623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski if (dest_image_layout != VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL) { 971623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski if (dest_image_layout == VK_IMAGE_LAYOUT_GENERAL) { 972623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski if (image_state->createInfo.tiling != VK_IMAGE_TILING_LINEAR) { 973623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski // LAYOUT_GENERAL is allowed, but may not be performance optimal, flag as perf warning. 974fdc75c21ced997fbbc180734bef87bf6d5811d4bMark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, 9759b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(image_state->image), __LINE__, DRAWSTATE_INVALID_IMAGE_LAYOUT, "DS", 976623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski "%s: Layout for cleared image should be TRANSFER_DST_OPTIMAL instead of GENERAL.", func_name); 977623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski } 9786084b78a58b438d27591b81efe30997ac9d88d3cMark Lobodzinski } else if (VK_IMAGE_LAYOUT_SHARED_PRESENT_KHR == dest_image_layout) { 979d4eaca34eca7f4b4e34190c441a579347bb2016aMark Lobodzinski if (!GetDeviceExtensions(device_data)->vk_khr_shared_presentable_image) { 980480a11822ef9a45f577f13644759c0895a49db19Tobin Ehlis // TODO: Add unique error id when available. 9816084b78a58b438d27591b81efe30997ac9d88d3cMark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, 9821007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton HandleToUint64(image_state->image), __LINE__, 0, "DS", 9831007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton "Must enable VK_KHR_shared_presentable_image extension before creating images with a layout type " 9841007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton "of VK_IMAGE_LAYOUT_SHARED_PRESENT_KHR."); 9856084b78a58b438d27591b81efe30997ac9d88d3cMark Lobodzinski 9866084b78a58b438d27591b81efe30997ac9d88d3cMark Lobodzinski } else { 9876084b78a58b438d27591b81efe30997ac9d88d3cMark Lobodzinski if (image_state->shared_presentable) { 9886084b78a58b438d27591b81efe30997ac9d88d3cMark Lobodzinski skip |= log_msg( 9896084b78a58b438d27591b81efe30997ac9d88d3cMark Lobodzinski report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, 990480a11822ef9a45f577f13644759c0895a49db19Tobin Ehlis HandleToUint64(image_state->image), __LINE__, 0, "DS", 9916084b78a58b438d27591b81efe30997ac9d88d3cMark Lobodzinski "Layout for shared presentable cleared image is %s but can only be VK_IMAGE_LAYOUT_SHARED_PRESENT_KHR.", 9926084b78a58b438d27591b81efe30997ac9d88d3cMark Lobodzinski string_VkImageLayout(dest_image_layout)); 9936084b78a58b438d27591b81efe30997ac9d88d3cMark Lobodzinski } 99487a57d8e822316de46ee97f514187331b1f4f09dTobin Ehlis } 995623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski } else { 996315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis UNIQUE_VALIDATION_ERROR_CODE error_code = VALIDATION_ERROR_1880000a; 997623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski if (strcmp(func_name, "vkCmdClearDepthStencilImage()") == 0) { 998315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis error_code = VALIDATION_ERROR_18a00018; 999623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski } else { 1000623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski assert(strcmp(func_name, "vkCmdClearColorImage()") == 0); 1001623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski } 1002fdc75c21ced997fbbc180734bef87bf6d5811d4bMark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, 10039b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(image_state->image), __LINE__, error_code, "DS", 10045f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton "%s: Layout for cleared image is %s but can only be TRANSFER_DST_OPTIMAL or GENERAL. %s", func_name, 10055f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton string_VkImageLayout(dest_image_layout), validation_error_map[error_code]); 1006623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski } 1007623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski } 1008623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski 100995b7894efd5e101e410da92fc697429aec3ffa7bMark Lobodzinski for (uint32_t level_index = 0; level_index < level_count; ++level_index) { 101095b7894efd5e101e410da92fc697429aec3ffa7bMark Lobodzinski uint32_t level = level_index + range.baseMipLevel; 101195b7894efd5e101e410da92fc697429aec3ffa7bMark Lobodzinski for (uint32_t layer_index = 0; layer_index < layer_count; ++layer_index) { 101295b7894efd5e101e410da92fc697429aec3ffa7bMark Lobodzinski uint32_t layer = layer_index + range.baseArrayLayer; 101395b7894efd5e101e410da92fc697429aec3ffa7bMark Lobodzinski VkImageSubresource sub = {range.aspectMask, level, layer}; 1014623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski IMAGE_CMD_BUF_LAYOUT_NODE node; 101555867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski if (FindCmdBufLayout(device_data, cb_node, image_state->image, sub, node)) { 1016623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski if (node.layout != dest_image_layout) { 1017315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis UNIQUE_VALIDATION_ERROR_CODE error_code = VALIDATION_ERROR_18800008; 1018623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski if (strcmp(func_name, "vkCmdClearDepthStencilImage()") == 0) { 1019315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis error_code = VALIDATION_ERROR_18a00016; 1020623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski } else { 1021623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski assert(strcmp(func_name, "vkCmdClearColorImage()") == 0); 1022623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski } 1023623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 0, 1024623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski __LINE__, error_code, "DS", 10255f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton "%s: Cannot clear an image whose layout is %s and doesn't match the current layout %s. %s", 1026623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski func_name, string_VkImageLayout(dest_image_layout), string_VkImageLayout(node.layout), 1027623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski validation_error_map[error_code]); 1028623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski } 1029623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski } 1030623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski } 1031623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski } 1032623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski 1033623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski return skip; 1034623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski} 1035623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski 1036e40189d4deab674240cd9baf4c063bab4567c212Tobin Ehlisvoid RecordClearImageLayout(layer_data *device_data, GLOBAL_CB_NODE *cb_node, VkImage image, VkImageSubresourceRange range, 1037e40189d4deab674240cd9baf4c063bab4567c212Tobin Ehlis VkImageLayout dest_image_layout) { 103895b7894efd5e101e410da92fc697429aec3ffa7bMark Lobodzinski VkImageCreateInfo *image_create_info = &(GetImageState(device_data, image)->createInfo); 103995b7894efd5e101e410da92fc697429aec3ffa7bMark Lobodzinski uint32_t level_count = ResolveRemainingLevels(&range, image_create_info->mipLevels); 104095b7894efd5e101e410da92fc697429aec3ffa7bMark Lobodzinski uint32_t layer_count = ResolveRemainingLayers(&range, image_create_info->arrayLayers); 104195b7894efd5e101e410da92fc697429aec3ffa7bMark Lobodzinski 104295b7894efd5e101e410da92fc697429aec3ffa7bMark Lobodzinski for (uint32_t level_index = 0; level_index < level_count; ++level_index) { 104395b7894efd5e101e410da92fc697429aec3ffa7bMark Lobodzinski uint32_t level = level_index + range.baseMipLevel; 104495b7894efd5e101e410da92fc697429aec3ffa7bMark Lobodzinski for (uint32_t layer_index = 0; layer_index < layer_count; ++layer_index) { 104595b7894efd5e101e410da92fc697429aec3ffa7bMark Lobodzinski uint32_t layer = layer_index + range.baseArrayLayer; 104695b7894efd5e101e410da92fc697429aec3ffa7bMark Lobodzinski VkImageSubresource sub = {range.aspectMask, level, layer}; 1047623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski IMAGE_CMD_BUF_LAYOUT_NODE node; 104855867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski if (!FindCmdBufLayout(device_data, cb_node, image, sub, node)) { 104955867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski SetLayout(device_data, cb_node, image, sub, IMAGE_CMD_BUF_LAYOUT_NODE(dest_image_layout, dest_image_layout)); 1050623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski } 1051623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski } 1052623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski } 1053623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski} 1054623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski 1055e40189d4deab674240cd9baf4c063bab4567c212Tobin Ehlisbool PreCallValidateCmdClearColorImage(layer_data *dev_data, VkCommandBuffer commandBuffer, VkImage image, 1056623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski VkImageLayout imageLayout, uint32_t rangeCount, const VkImageSubresourceRange *pRanges) { 1057623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski bool skip = false; 1058623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski // TODO : Verify memory is in VK_IMAGE_STATE_CLEAR state 10599a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto cb_node = GetCBNode(dev_data, commandBuffer); 10609a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto image_state = GetImageState(dev_data, image); 1061623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski if (cb_node && image_state) { 1062315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= ValidateMemoryIsBoundToImage(dev_data, image_state, "vkCmdClearColorImage()", VALIDATION_ERROR_18800006); 1063baa50ccc5a8cf7a6f7474148f301802c5480e715Mike Schuchardt skip |= ValidateCmdQueueFlags(dev_data, cb_node, "vkCmdClearColorImage()", VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT, 1064315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis VALIDATION_ERROR_18802415); 1065623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski skip |= ValidateCmd(dev_data, cb_node, CMD_CLEARCOLORIMAGE, "vkCmdClearColorImage()"); 1066315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= insideRenderPass(dev_data, cb_node, "vkCmdClearColorImage()", VALIDATION_ERROR_18800017); 1067623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski for (uint32_t i = 0; i < rangeCount; ++i) { 106823c5a2092f724fef497a5c87a489f32c8fa51e58Petr Kraus std::string param_name = "pRanges[" + std::to_string(i) + "]"; 1069e25e057866af155bd456003120aa6155530a0e5fPetr Kraus skip |= ValidateCmdClearColorSubresourceRange(dev_data, image_state, pRanges[i], param_name.c_str()); 1070623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski skip |= ValidateImageAttributes(dev_data, image_state, pRanges[i]); 107108c7aae3177092f8567e2b5a946457be61616e9aMark Lobodzinski skip |= VerifyClearImageLayout(dev_data, cb_node, image_state, pRanges[i], imageLayout, "vkCmdClearColorImage()"); 1072623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski } 1073623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski } 1074623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski return skip; 1075623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski} 1076623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski 1077623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski// This state recording routine is shared between ClearColorImage and ClearDepthStencilImage 1078e40189d4deab674240cd9baf4c063bab4567c212Tobin Ehlisvoid PreCallRecordCmdClearImage(layer_data *dev_data, VkCommandBuffer commandBuffer, VkImage image, VkImageLayout imageLayout, 10790619dc1df076bfedcf0c999ceca3bdecd5ea5171Chris Forbes uint32_t rangeCount, const VkImageSubresourceRange *pRanges) { 10809a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto cb_node = GetCBNode(dev_data, commandBuffer); 10819a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto image_state = GetImageState(dev_data, image); 1082623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski if (cb_node && image_state) { 1083623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski AddCommandBufferBindingImage(dev_data, cb_node, image_state); 1084623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski std::function<bool()> function = [=]() { 1085623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski SetImageMemoryValid(dev_data, image_state, true); 1086623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski return false; 1087623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski }; 1088d807198f24437c1b2478ff1d06a33ce4873a1451Tobin Ehlis cb_node->queue_submit_functions.push_back(function); 1089623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski for (uint32_t i = 0; i < rangeCount; ++i) { 1090623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski RecordClearImageLayout(dev_data, cb_node, image, pRanges[i], imageLayout); 1091623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski } 1092623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski } 1093623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski} 1094623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski 1095e40189d4deab674240cd9baf4c063bab4567c212Tobin Ehlisbool PreCallValidateCmdClearDepthStencilImage(layer_data *device_data, VkCommandBuffer commandBuffer, VkImage image, 1096e40189d4deab674240cd9baf4c063bab4567c212Tobin Ehlis VkImageLayout imageLayout, uint32_t rangeCount, 1097623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski const VkImageSubresourceRange *pRanges) { 1098623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski bool skip = false; 10997244435437260842ba43b67bb7d008e161736c31Mark Lobodzinski const debug_report_data *report_data = core_validation::GetReportData(device_data); 11007244435437260842ba43b67bb7d008e161736c31Mark Lobodzinski 1101623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski // TODO : Verify memory is in VK_IMAGE_STATE_CLEAR state 11029a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto cb_node = GetCBNode(device_data, commandBuffer); 11039a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto image_state = GetImageState(device_data, image); 1104623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski if (cb_node && image_state) { 1105315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= ValidateMemoryIsBoundToImage(device_data, image_state, "vkCmdClearDepthStencilImage()", VALIDATION_ERROR_18a00014); 1106baa50ccc5a8cf7a6f7474148f301802c5480e715Mike Schuchardt skip |= ValidateCmdQueueFlags(device_data, cb_node, "vkCmdClearDepthStencilImage()", VK_QUEUE_GRAPHICS_BIT, 1107315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis VALIDATION_ERROR_18a02415); 11087244435437260842ba43b67bb7d008e161736c31Mark Lobodzinski skip |= ValidateCmd(device_data, cb_node, CMD_CLEARDEPTHSTENCILIMAGE, "vkCmdClearDepthStencilImage()"); 1109315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= insideRenderPass(device_data, cb_node, "vkCmdClearDepthStencilImage()", VALIDATION_ERROR_18a00017); 1110623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski for (uint32_t i = 0; i < rangeCount; ++i) { 111123c5a2092f724fef497a5c87a489f32c8fa51e58Petr Kraus std::string param_name = "pRanges[" + std::to_string(i) + "]"; 1112e25e057866af155bd456003120aa6155530a0e5fPetr Kraus skip |= ValidateCmdClearDepthSubresourceRange(device_data, image_state, pRanges[i], param_name.c_str()); 111308c7aae3177092f8567e2b5a946457be61616e9aMark Lobodzinski skip |= 111408c7aae3177092f8567e2b5a946457be61616e9aMark Lobodzinski VerifyClearImageLayout(device_data, cb_node, image_state, pRanges[i], imageLayout, "vkCmdClearDepthStencilImage()"); 11157244435437260842ba43b67bb7d008e161736c31Mark Lobodzinski // Image aspect must be depth or stencil or both 11167244435437260842ba43b67bb7d008e161736c31Mark Lobodzinski if (((pRanges[i].aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT) != VK_IMAGE_ASPECT_DEPTH_BIT) && 11177244435437260842ba43b67bb7d008e161736c31Mark Lobodzinski ((pRanges[i].aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT) != VK_IMAGE_ASPECT_STENCIL_BIT)) { 11187244435437260842ba43b67bb7d008e161736c31Mark Lobodzinski char const str[] = 11195f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton "vkCmdClearDepthStencilImage aspectMasks for all subresource ranges must be set to VK_IMAGE_ASPECT_DEPTH_BIT " 11205f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton "and/or VK_IMAGE_ASPECT_STENCIL_BIT"; 11217244435437260842ba43b67bb7d008e161736c31Mark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 11229b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(commandBuffer), __LINE__, DRAWSTATE_INVALID_IMAGE_ASPECT, "IMAGE", str); 11237244435437260842ba43b67bb7d008e161736c31Mark Lobodzinski } 11247244435437260842ba43b67bb7d008e161736c31Mark Lobodzinski } 112516769f6b2a7721e391952a97f010cbb530e4f211Dave Houlton if (image_state && !FormatIsDepthOrStencil(image_state->createInfo.format)) { 11267244435437260842ba43b67bb7d008e161736c31Mark Lobodzinski char const str[] = "vkCmdClearDepthStencilImage called without a depth/stencil image."; 1127315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, 1128315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(image), __LINE__, VALIDATION_ERROR_18a0001c, "IMAGE", "%s. %s", str, 1129315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_18a0001c]); 1130623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski } 11316dae233e4721ed58ff91a251ba6179eaf50bc545Tobin Ehlis if (VK_IMAGE_USAGE_TRANSFER_DST_BIT != (VK_IMAGE_USAGE_TRANSFER_DST_BIT & image_state->createInfo.usage)) { 11326dae233e4721ed58ff91a251ba6179eaf50bc545Tobin Ehlis char const str[] = 11336dae233e4721ed58ff91a251ba6179eaf50bc545Tobin Ehlis "vkCmdClearDepthStencilImage() called with an image that was not created with the VK_IMAGE_USAGE_TRANSFER_DST_BIT " 11346dae233e4721ed58ff91a251ba6179eaf50bc545Tobin Ehlis "set."; 11356dae233e4721ed58ff91a251ba6179eaf50bc545Tobin Ehlis skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, 11366dae233e4721ed58ff91a251ba6179eaf50bc545Tobin Ehlis HandleToUint64(image), __LINE__, VALIDATION_ERROR_18a00012, "IMAGE", "%s. %s", str, 11376dae233e4721ed58ff91a251ba6179eaf50bc545Tobin Ehlis validation_error_map[VALIDATION_ERROR_18a00012]); 11386dae233e4721ed58ff91a251ba6179eaf50bc545Tobin Ehlis } 11396dae233e4721ed58ff91a251ba6179eaf50bc545Tobin Ehlis VkFormatProperties props = GetFormatProperties(device_data, image_state->createInfo.format); 11406dae233e4721ed58ff91a251ba6179eaf50bc545Tobin Ehlis VkImageTiling tiling = image_state->createInfo.tiling; 11416dae233e4721ed58ff91a251ba6179eaf50bc545Tobin Ehlis VkFormatFeatureFlags flags = (tiling == VK_IMAGE_TILING_LINEAR ? props.linearTilingFeatures : props.optimalTilingFeatures); 11426dae233e4721ed58ff91a251ba6179eaf50bc545Tobin Ehlis if ((GetDeviceExtensions(device_data)->vk_khr_maintenance1) && 11436dae233e4721ed58ff91a251ba6179eaf50bc545Tobin Ehlis (VK_FORMAT_FEATURE_TRANSFER_DST_BIT_KHR != (flags & VK_FORMAT_FEATURE_TRANSFER_DST_BIT_KHR))) { 11446dae233e4721ed58ff91a251ba6179eaf50bc545Tobin Ehlis skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, 11456dae233e4721ed58ff91a251ba6179eaf50bc545Tobin Ehlis HandleToUint64(image), __LINE__, VALIDATION_ERROR_18a00010, "IMAGE", 11466dae233e4721ed58ff91a251ba6179eaf50bc545Tobin Ehlis "vkCmdClearDepthStencilImage() called with an image of format %s and tiling %s that does not support " 11476dae233e4721ed58ff91a251ba6179eaf50bc545Tobin Ehlis "VK_FORMAT_FEATURE_TRANSFER_DST_BIT_KHR. %s", 11486dae233e4721ed58ff91a251ba6179eaf50bc545Tobin Ehlis string_VkFormat(image_state->createInfo.format), string_VkImageTiling(image_state->createInfo.tiling), 11496dae233e4721ed58ff91a251ba6179eaf50bc545Tobin Ehlis validation_error_map[VALIDATION_ERROR_18a00010]); 11506dae233e4721ed58ff91a251ba6179eaf50bc545Tobin Ehlis } 1151623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski } 1152623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski return skip; 1153623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski} 1154ff309c48cf48eec4599c9bf83f5b5cd802fa2db0Mark Lobodzinski 1155ff309c48cf48eec4599c9bf83f5b5cd802fa2db0Mark Lobodzinski// Returns true if [x, xoffset] and [y, yoffset] overlap 1156ff309c48cf48eec4599c9bf83f5b5cd802fa2db0Mark Lobodzinskistatic bool RangesIntersect(int32_t start, uint32_t start_offset, int32_t end, uint32_t end_offset) { 1157ff309c48cf48eec4599c9bf83f5b5cd802fa2db0Mark Lobodzinski bool result = false; 1158ff309c48cf48eec4599c9bf83f5b5cd802fa2db0Mark Lobodzinski uint32_t intersection_min = std::max(static_cast<uint32_t>(start), static_cast<uint32_t>(end)); 1159ff309c48cf48eec4599c9bf83f5b5cd802fa2db0Mark Lobodzinski uint32_t intersection_max = std::min(static_cast<uint32_t>(start) + start_offset, static_cast<uint32_t>(end) + end_offset); 1160ff309c48cf48eec4599c9bf83f5b5cd802fa2db0Mark Lobodzinski 1161ff309c48cf48eec4599c9bf83f5b5cd802fa2db0Mark Lobodzinski if (intersection_max > intersection_min) { 1162ff309c48cf48eec4599c9bf83f5b5cd802fa2db0Mark Lobodzinski result = true; 1163ff309c48cf48eec4599c9bf83f5b5cd802fa2db0Mark Lobodzinski } 1164ff309c48cf48eec4599c9bf83f5b5cd802fa2db0Mark Lobodzinski return result; 1165ff309c48cf48eec4599c9bf83f5b5cd802fa2db0Mark Lobodzinski} 1166ff309c48cf48eec4599c9bf83f5b5cd802fa2db0Mark Lobodzinski 1167ff309c48cf48eec4599c9bf83f5b5cd802fa2db0Mark Lobodzinski// Returns true if two VkImageCopy structures overlap 1168ff309c48cf48eec4599c9bf83f5b5cd802fa2db0Mark Lobodzinskistatic bool RegionIntersects(const VkImageCopy *src, const VkImageCopy *dst, VkImageType type) { 1169ff309c48cf48eec4599c9bf83f5b5cd802fa2db0Mark Lobodzinski bool result = false; 1170ff309c48cf48eec4599c9bf83f5b5cd802fa2db0Mark Lobodzinski if ((src->srcSubresource.mipLevel == dst->dstSubresource.mipLevel) && 1171ff309c48cf48eec4599c9bf83f5b5cd802fa2db0Mark Lobodzinski (RangesIntersect(src->srcSubresource.baseArrayLayer, src->srcSubresource.layerCount, dst->dstSubresource.baseArrayLayer, 1172ff309c48cf48eec4599c9bf83f5b5cd802fa2db0Mark Lobodzinski dst->dstSubresource.layerCount))) { 1173ff309c48cf48eec4599c9bf83f5b5cd802fa2db0Mark Lobodzinski result = true; 1174ff309c48cf48eec4599c9bf83f5b5cd802fa2db0Mark Lobodzinski switch (type) { 1175ff309c48cf48eec4599c9bf83f5b5cd802fa2db0Mark Lobodzinski case VK_IMAGE_TYPE_3D: 1176ff309c48cf48eec4599c9bf83f5b5cd802fa2db0Mark Lobodzinski result &= RangesIntersect(src->srcOffset.z, src->extent.depth, dst->dstOffset.z, dst->extent.depth); 1177ff309c48cf48eec4599c9bf83f5b5cd802fa2db0Mark Lobodzinski // Intentionally fall through to 2D case 1178ff309c48cf48eec4599c9bf83f5b5cd802fa2db0Mark Lobodzinski case VK_IMAGE_TYPE_2D: 1179ff309c48cf48eec4599c9bf83f5b5cd802fa2db0Mark Lobodzinski result &= RangesIntersect(src->srcOffset.y, src->extent.height, dst->dstOffset.y, dst->extent.height); 1180ff309c48cf48eec4599c9bf83f5b5cd802fa2db0Mark Lobodzinski // Intentionally fall through to 1D case 1181ff309c48cf48eec4599c9bf83f5b5cd802fa2db0Mark Lobodzinski case VK_IMAGE_TYPE_1D: 1182ff309c48cf48eec4599c9bf83f5b5cd802fa2db0Mark Lobodzinski result &= RangesIntersect(src->srcOffset.x, src->extent.width, dst->dstOffset.x, dst->extent.width); 1183ff309c48cf48eec4599c9bf83f5b5cd802fa2db0Mark Lobodzinski break; 1184ff309c48cf48eec4599c9bf83f5b5cd802fa2db0Mark Lobodzinski default: 1185ff309c48cf48eec4599c9bf83f5b5cd802fa2db0Mark Lobodzinski // Unrecognized or new IMAGE_TYPE enums will be caught in parameter_validation 1186ff309c48cf48eec4599c9bf83f5b5cd802fa2db0Mark Lobodzinski assert(false); 1187ff309c48cf48eec4599c9bf83f5b5cd802fa2db0Mark Lobodzinski } 1188ff309c48cf48eec4599c9bf83f5b5cd802fa2db0Mark Lobodzinski } 1189ff309c48cf48eec4599c9bf83f5b5cd802fa2db0Mark Lobodzinski return result; 1190ff309c48cf48eec4599c9bf83f5b5cd802fa2db0Mark Lobodzinski} 1191ff309c48cf48eec4599c9bf83f5b5cd802fa2db0Mark Lobodzinski 11923fb79e4c87829ef090622d69a117f33ec7d4ded5Dave Houlton// Returns non-zero if offset and extent exceed image extents 11933fb79e4c87829ef090622d69a117f33ec7d4ded5Dave Houltonstatic const uint32_t x_bit = 1; 11943fb79e4c87829ef090622d69a117f33ec7d4ded5Dave Houltonstatic const uint32_t y_bit = 2; 11953fb79e4c87829ef090622d69a117f33ec7d4ded5Dave Houltonstatic const uint32_t z_bit = 4; 1196cf2ce8673669ca1111e333bdea272c4dd57cb5c2Dave Houltonstatic uint32_t ExceedsBounds(const VkOffset3D *offset, const VkExtent3D *extent, const VkExtent3D *image_extent) { 11973fb79e4c87829ef090622d69a117f33ec7d4ded5Dave Houlton uint32_t result = 0; 1198ff309c48cf48eec4599c9bf83f5b5cd802fa2db0Mark Lobodzinski // Extents/depths cannot be negative but checks left in for clarity 11995971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton if ((offset->z + extent->depth > image_extent->depth) || (offset->z < 0) || 12005971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton ((offset->z + static_cast<int32_t>(extent->depth)) < 0)) { 12013fb79e4c87829ef090622d69a117f33ec7d4ded5Dave Houlton result |= z_bit; 12025971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton } 12035971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton if ((offset->y + extent->height > image_extent->height) || (offset->y < 0) || 12045971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton ((offset->y + static_cast<int32_t>(extent->height)) < 0)) { 12053fb79e4c87829ef090622d69a117f33ec7d4ded5Dave Houlton result |= y_bit; 12065971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton } 12075971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton if ((offset->x + extent->width > image_extent->width) || (offset->x < 0) || 12085971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton ((offset->x + static_cast<int32_t>(extent->width)) < 0)) { 12093fb79e4c87829ef090622d69a117f33ec7d4ded5Dave Houlton result |= x_bit; 1210ff309c48cf48eec4599c9bf83f5b5cd802fa2db0Mark Lobodzinski } 1211ff309c48cf48eec4599c9bf83f5b5cd802fa2db0Mark Lobodzinski return result; 1212ff309c48cf48eec4599c9bf83f5b5cd802fa2db0Mark Lobodzinski} 1213ff309c48cf48eec4599c9bf83f5b5cd802fa2db0Mark Lobodzinski 12146a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski// Test if two VkExtent3D structs are equivalent 12156a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinskistatic inline bool IsExtentEqual(const VkExtent3D *extent, const VkExtent3D *other_extent) { 12166a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski bool result = true; 12176a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski if ((extent->width != other_extent->width) || (extent->height != other_extent->height) || 12186a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski (extent->depth != other_extent->depth)) { 12196a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski result = false; 12206a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski } 12216a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski return result; 12226a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski} 12236a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski 12243d7012402fcdac8d98db8f65a0eb3958b7d63297Dave Houlton// For image copies between compressed/uncompressed formats, the extent is provided in source image texels 12253d7012402fcdac8d98db8f65a0eb3958b7d63297Dave Houlton// Destination image texel extents must be adjusted by block size for the dest validation checks 12263d7012402fcdac8d98db8f65a0eb3958b7d63297Dave HoultonVkExtent3D GetAdjustedDestImageExtent(VkFormat src_format, VkFormat dst_format, VkExtent3D extent) { 12273d7012402fcdac8d98db8f65a0eb3958b7d63297Dave Houlton VkExtent3D adjusted_extent = extent; 12283d7012402fcdac8d98db8f65a0eb3958b7d63297Dave Houlton if ((FormatIsCompressed(src_format) && (!FormatIsCompressed(dst_format)))) { 12293d7012402fcdac8d98db8f65a0eb3958b7d63297Dave Houlton VkExtent3D block_size = FormatCompressedTexelBlockExtent(src_format); 12303d7012402fcdac8d98db8f65a0eb3958b7d63297Dave Houlton adjusted_extent.width /= block_size.width; 12313d7012402fcdac8d98db8f65a0eb3958b7d63297Dave Houlton adjusted_extent.height /= block_size.height; 12323d7012402fcdac8d98db8f65a0eb3958b7d63297Dave Houlton adjusted_extent.depth /= block_size.depth; 12333d7012402fcdac8d98db8f65a0eb3958b7d63297Dave Houlton } else if ((!FormatIsCompressed(src_format) && (FormatIsCompressed(dst_format)))) { 12343d7012402fcdac8d98db8f65a0eb3958b7d63297Dave Houlton VkExtent3D block_size = FormatCompressedTexelBlockExtent(dst_format); 12353d7012402fcdac8d98db8f65a0eb3958b7d63297Dave Houlton adjusted_extent.width *= block_size.width; 12363d7012402fcdac8d98db8f65a0eb3958b7d63297Dave Houlton adjusted_extent.height *= block_size.height; 12373d7012402fcdac8d98db8f65a0eb3958b7d63297Dave Houlton adjusted_extent.depth *= block_size.depth; 12383d7012402fcdac8d98db8f65a0eb3958b7d63297Dave Houlton } 12393d7012402fcdac8d98db8f65a0eb3958b7d63297Dave Houlton return adjusted_extent; 12403d7012402fcdac8d98db8f65a0eb3958b7d63297Dave Houlton} 12413d7012402fcdac8d98db8f65a0eb3958b7d63297Dave Houlton 124278ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton// Returns the effective extent of an image subresource, adjusted for mip level and array depth. 12436a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinskistatic inline VkExtent3D GetImageSubresourceExtent(const IMAGE_STATE *img, const VkImageSubresourceLayers *subresource) { 12446a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski const uint32_t mip = subresource->mipLevel; 12453fb79e4c87829ef090622d69a117f33ec7d4ded5Dave Houlton 12463fb79e4c87829ef090622d69a117f33ec7d4ded5Dave Houlton // Return zero extent if mip level doesn't exist 1247cf2ce8673669ca1111e333bdea272c4dd57cb5c2Dave Houlton if (mip >= img->createInfo.mipLevels) { 1248cf2ce8673669ca1111e333bdea272c4dd57cb5c2Dave Houlton return VkExtent3D{0, 0, 0}; 12493fb79e4c87829ef090622d69a117f33ec7d4ded5Dave Houlton } 1250cf2ce8673669ca1111e333bdea272c4dd57cb5c2Dave Houlton 12515971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton // Don't allow mip adjustment to create 0 dim, but pass along a 0 if that's what subresource specified 12523fb79e4c87829ef090622d69a117f33ec7d4ded5Dave Houlton VkExtent3D extent = img->createInfo.extent; 12535971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton extent.width = (0 == extent.width ? 0 : std::max(1U, extent.width >> mip)); 12545971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton extent.height = (0 == extent.height ? 0 : std::max(1U, extent.height >> mip)); 12555971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton extent.depth = (0 == extent.depth ? 0 : std::max(1U, extent.depth >> mip)); 12563fb79e4c87829ef090622d69a117f33ec7d4ded5Dave Houlton 125778ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton // Image arrays have an effective z extent that isn't diminished by mip level 125878ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton if (VK_IMAGE_TYPE_3D != img->createInfo.imageType) { 12593fb79e4c87829ef090622d69a117f33ec7d4ded5Dave Houlton extent.depth = img->createInfo.arrayLayers; 12603fb79e4c87829ef090622d69a117f33ec7d4ded5Dave Houlton } 12613fb79e4c87829ef090622d69a117f33ec7d4ded5Dave Houlton 12626a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski return extent; 12636a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski} 12646a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski 12656a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski// Test if the extent argument has all dimensions set to 0. 12665971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houltonstatic inline bool IsExtentAllZeroes(const VkExtent3D *extent) { 12676a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski return ((extent->width == 0) && (extent->height == 0) && (extent->depth == 0)); 12686a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski} 12696a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski 12705971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton// Test if the extent argument has any dimensions set to 0. 12715971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houltonstatic inline bool IsExtentSizeZero(const VkExtent3D *extent) { 12725971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton return ((extent->width == 0) || (extent->height == 0) || (extent->depth == 0)); 12735971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton} 12745971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton 12756a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski// Returns the image transfer granularity for a specific image scaled by compressed block size if necessary. 12766a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinskistatic inline VkExtent3D GetScaledItg(layer_data *device_data, const GLOBAL_CB_NODE *cb_node, const IMAGE_STATE *img) { 12776a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski // Default to (0, 0, 0) granularity in case we can't find the real granularity for the physical device. 12786a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski VkExtent3D granularity = {0, 0, 0}; 12796a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski auto pPool = GetCommandPoolNode(device_data, cb_node->createInfo.commandPool); 12806a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski if (pPool) { 12816a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski granularity = 12826a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski GetPhysDevProperties(device_data)->queue_family_properties[pPool->queueFamilyIndex].minImageTransferGranularity; 128316769f6b2a7721e391952a97f010cbb530e4f211Dave Houlton if (FormatIsCompressed(img->createInfo.format)) { 128416769f6b2a7721e391952a97f010cbb530e4f211Dave Houlton auto block_size = FormatCompressedTexelBlockExtent(img->createInfo.format); 12856a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski granularity.width *= block_size.width; 12866a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski granularity.height *= block_size.height; 12876a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski } 12886a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski } 12896a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski return granularity; 12906a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski} 12916a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski 12926a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski// Test elements of a VkExtent3D structure against alignment constraints contained in another VkExtent3D structure 12936a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinskistatic inline bool IsExtentAligned(const VkExtent3D *extent, const VkExtent3D *granularity) { 12946a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski bool valid = true; 129516769f6b2a7721e391952a97f010cbb530e4f211Dave Houlton if ((SafeModulo(extent->depth, granularity->depth) != 0) || (SafeModulo(extent->width, granularity->width) != 0) || 129616769f6b2a7721e391952a97f010cbb530e4f211Dave Houlton (SafeModulo(extent->height, granularity->height) != 0)) { 12976a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski valid = false; 12986a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski } 12996a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski return valid; 13006a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski} 13016a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski 13026a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski// Check elements of a VkOffset3D structure against a queue family's Image Transfer Granularity values 13036a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinskistatic inline bool CheckItgOffset(layer_data *device_data, const GLOBAL_CB_NODE *cb_node, const VkOffset3D *offset, 13046a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski const VkExtent3D *granularity, const uint32_t i, const char *function, const char *member) { 13056a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski const debug_report_data *report_data = core_validation::GetReportData(device_data); 13066a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski bool skip = false; 13076a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski VkExtent3D offset_extent = {}; 13086a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski offset_extent.width = static_cast<uint32_t>(abs(offset->x)); 13096a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski offset_extent.height = static_cast<uint32_t>(abs(offset->y)); 13106a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski offset_extent.depth = static_cast<uint32_t>(abs(offset->z)); 13115971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton if (IsExtentAllZeroes(granularity)) { 13126a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski // If the queue family image transfer granularity is (0, 0, 0), then the offset must always be (0, 0, 0) 13135971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton if (IsExtentAllZeroes(&offset_extent) == false) { 13149b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 13159b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(cb_node->commandBuffer), __LINE__, DRAWSTATE_IMAGE_TRANSFER_GRANULARITY, "DS", 13165f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton "%s: pRegion[%d].%s (x=%d, y=%d, z=%d) must be (x=0, y=0, z=0) when the command buffer's queue family " 13175f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton "image transfer granularity is (w=0, h=0, d=0).", 13189b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus function, i, member, offset->x, offset->y, offset->z); 13196a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski } 13206a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski } else { 13216a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski // If the queue family image transfer granularity is not (0, 0, 0), then the offset dimensions must always be even 13226a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski // integer multiples of the image transfer granularity. 13236a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski if (IsExtentAligned(&offset_extent, granularity) == false) { 13249b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 13259b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(cb_node->commandBuffer), __LINE__, DRAWSTATE_IMAGE_TRANSFER_GRANULARITY, "DS", 13265f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton "%s: pRegion[%d].%s (x=%d, y=%d, z=%d) dimensions must be even integer multiples of this command " 13275f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton "buffer's queue family image transfer granularity (w=%d, h=%d, d=%d).", 13289b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus function, i, member, offset->x, offset->y, offset->z, granularity->width, granularity->height, 13299b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus granularity->depth); 13306a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski } 13316a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski } 13326a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski return skip; 13336a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski} 13346a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski 13356a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski// Check elements of a VkExtent3D structure against a queue family's Image Transfer Granularity values 13366a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinskistatic inline bool CheckItgExtent(layer_data *device_data, const GLOBAL_CB_NODE *cb_node, const VkExtent3D *extent, 13376a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski const VkOffset3D *offset, const VkExtent3D *granularity, const VkExtent3D *subresource_extent, 13384441dc47d70aa8532ffc69ab548df1ece5065947Mark Lobodzinski const VkImageType image_type, const uint32_t i, const char *function, const char *member) { 13396a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski const debug_report_data *report_data = core_validation::GetReportData(device_data); 13406a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski bool skip = false; 13415971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton if (IsExtentAllZeroes(granularity)) { 13426a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski // If the queue family image transfer granularity is (0, 0, 0), then the extent must always match the image 13436a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski // subresource extent. 13446a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski if (IsExtentEqual(extent, subresource_extent) == false) { 13459b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 13469b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(cb_node->commandBuffer), __LINE__, DRAWSTATE_IMAGE_TRANSFER_GRANULARITY, "DS", 13479b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus "%s: pRegion[%d].%s (w=%d, h=%d, d=%d) must match the image subresource extents (w=%d, h=%d, d=%d) " 13489b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus "when the command buffer's queue family image transfer granularity is (w=0, h=0, d=0).", 13499b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus function, i, member, extent->width, extent->height, extent->depth, subresource_extent->width, 13509b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus subresource_extent->height, subresource_extent->depth); 13516a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski } 13526a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski } else { 13536a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski // If the queue family image transfer granularity is not (0, 0, 0), then the extent dimensions must always be even 13546a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski // integer multiples of the image transfer granularity or the offset + extent dimensions must always match the image 13556a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski // subresource extent dimensions. 13566a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski VkExtent3D offset_extent_sum = {}; 13576a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski offset_extent_sum.width = static_cast<uint32_t>(abs(offset->x)) + extent->width; 13586a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski offset_extent_sum.height = static_cast<uint32_t>(abs(offset->y)) + extent->height; 13596a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski offset_extent_sum.depth = static_cast<uint32_t>(abs(offset->z)) + extent->depth; 13604441dc47d70aa8532ffc69ab548df1ece5065947Mark Lobodzinski bool x_ok = true; 13614441dc47d70aa8532ffc69ab548df1ece5065947Mark Lobodzinski bool y_ok = true; 13624441dc47d70aa8532ffc69ab548df1ece5065947Mark Lobodzinski bool z_ok = true; 13634441dc47d70aa8532ffc69ab548df1ece5065947Mark Lobodzinski switch (image_type) { 13644441dc47d70aa8532ffc69ab548df1ece5065947Mark Lobodzinski case VK_IMAGE_TYPE_3D: 13654441dc47d70aa8532ffc69ab548df1ece5065947Mark Lobodzinski z_ok = ((0 == SafeModulo(extent->depth, granularity->depth)) || 13664441dc47d70aa8532ffc69ab548df1ece5065947Mark Lobodzinski (subresource_extent->depth == offset_extent_sum.depth)); 13674441dc47d70aa8532ffc69ab548df1ece5065947Mark Lobodzinski // Intentionally fall through to 2D case 13684441dc47d70aa8532ffc69ab548df1ece5065947Mark Lobodzinski case VK_IMAGE_TYPE_2D: 13694441dc47d70aa8532ffc69ab548df1ece5065947Mark Lobodzinski y_ok = ((0 == SafeModulo(extent->height, granularity->height)) || 13704441dc47d70aa8532ffc69ab548df1ece5065947Mark Lobodzinski (subresource_extent->height == offset_extent_sum.height)); 13714441dc47d70aa8532ffc69ab548df1ece5065947Mark Lobodzinski // Intentionally fall through to 1D case 13724441dc47d70aa8532ffc69ab548df1ece5065947Mark Lobodzinski case VK_IMAGE_TYPE_1D: 13734441dc47d70aa8532ffc69ab548df1ece5065947Mark Lobodzinski x_ok = ((0 == SafeModulo(extent->width, granularity->width)) || 13744441dc47d70aa8532ffc69ab548df1ece5065947Mark Lobodzinski (subresource_extent->width == offset_extent_sum.width)); 13754441dc47d70aa8532ffc69ab548df1ece5065947Mark Lobodzinski break; 13764441dc47d70aa8532ffc69ab548df1ece5065947Mark Lobodzinski default: 13774441dc47d70aa8532ffc69ab548df1ece5065947Mark Lobodzinski // Unrecognized or new IMAGE_TYPE enums will be caught in parameter_validation 13784441dc47d70aa8532ffc69ab548df1ece5065947Mark Lobodzinski assert(false); 13794441dc47d70aa8532ffc69ab548df1ece5065947Mark Lobodzinski } 138078ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton if (!(x_ok && y_ok && z_ok)) { 13815f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 13825f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton HandleToUint64(cb_node->commandBuffer), __LINE__, DRAWSTATE_IMAGE_TRANSFER_GRANULARITY, "DS", 13835f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton "%s: pRegion[%d].%s (w=%d, h=%d, d=%d) dimensions must be even integer multiples of this command " 13845f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton "buffer's queue family image transfer granularity (w=%d, h=%d, d=%d) or offset (x=%d, y=%d, z=%d) + " 13855f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton "extent (w=%d, h=%d, d=%d) must match the image subresource extents (w=%d, h=%d, d=%d).", 13865f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton function, i, member, extent->width, extent->height, extent->depth, granularity->width, 13875f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton granularity->height, granularity->depth, offset->x, offset->y, offset->z, extent->width, extent->height, 13885f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton extent->depth, subresource_extent->width, subresource_extent->height, subresource_extent->depth); 13896a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski } 13906a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski } 13916a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski return skip; 13926a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski} 13936a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski 13946a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski// Check a uint32_t width or stride value against a queue family's Image Transfer Granularity width value 13956a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinskistatic inline bool CheckItgInt(layer_data *device_data, const GLOBAL_CB_NODE *cb_node, const uint32_t value, 13966a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski const uint32_t granularity, const uint32_t i, const char *function, const char *member) { 13976a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski const debug_report_data *report_data = core_validation::GetReportData(device_data); 13986a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski 13996a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski bool skip = false; 140016769f6b2a7721e391952a97f010cbb530e4f211Dave Houlton if (SafeModulo(value, granularity) != 0) { 1401fdc75c21ced997fbbc180734bef87bf6d5811d4bMark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 14029b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(cb_node->commandBuffer), __LINE__, DRAWSTATE_IMAGE_TRANSFER_GRANULARITY, "DS", 14036a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski "%s: pRegion[%d].%s (%d) must be an even integer multiple of this command buffer's queue family image " 14046a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski "transfer granularity width (%d).", 14056a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski function, i, member, value, granularity); 14066a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski } 14076a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski return skip; 14086a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski} 14096a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski 14106a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski// Check a VkDeviceSize value against a queue family's Image Transfer Granularity width value 14116a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinskistatic inline bool CheckItgSize(layer_data *device_data, const GLOBAL_CB_NODE *cb_node, const VkDeviceSize value, 14126a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski const uint32_t granularity, const uint32_t i, const char *function, const char *member) { 14136a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski const debug_report_data *report_data = core_validation::GetReportData(device_data); 14146a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski bool skip = false; 141516769f6b2a7721e391952a97f010cbb530e4f211Dave Houlton if (SafeModulo(value, granularity) != 0) { 14165f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton skip |= log_msg( 14175f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 14185f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton HandleToUint64(cb_node->commandBuffer), __LINE__, DRAWSTATE_IMAGE_TRANSFER_GRANULARITY, "DS", 14195f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton "%s: pRegion[%d].%s (%" PRIdLEAST64 14205f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton ") must be an even integer multiple of this command buffer's queue family image transfer granularity width (%d).", 14215f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton function, i, member, value, granularity); 14226a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski } 14236a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski return skip; 14246a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski} 14256a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski 14266a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski// Check valid usage Image Tranfer Granularity requirements for elements of a VkBufferImageCopy structure 14276a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinskibool ValidateCopyBufferImageTransferGranularityRequirements(layer_data *device_data, const GLOBAL_CB_NODE *cb_node, 14286a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski const IMAGE_STATE *img, const VkBufferImageCopy *region, 14296a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski const uint32_t i, const char *function) { 14306a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski bool skip = false; 143116769f6b2a7721e391952a97f010cbb530e4f211Dave Houlton if (FormatIsCompressed(img->createInfo.format) == true) { 14326a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski // TODO: Add granularity checking for compressed formats 14336a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski 14346a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski // bufferRowLength must be a multiple of the compressed texel block width 14356a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski // bufferImageHeight must be a multiple of the compressed texel block height 14366a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski // all members of imageOffset must be a multiple of the corresponding dimensions of the compressed texel block 14376a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski // bufferOffset must be a multiple of the compressed texel block size in bytes 14386a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski // imageExtent.width must be a multiple of the compressed texel block width or (imageExtent.width + imageOffset.x) 14396a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski // must equal the image subresource width 14406a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski // imageExtent.height must be a multiple of the compressed texel block height or (imageExtent.height + imageOffset.y) 14416a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski // must equal the image subresource height 14426a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski // imageExtent.depth must be a multiple of the compressed texel block depth or (imageExtent.depth + imageOffset.z) 14436a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski // must equal the image subresource depth 14446a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski } else { 14456a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski VkExtent3D granularity = GetScaledItg(device_data, cb_node, img); 14466a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski skip |= CheckItgSize(device_data, cb_node, region->bufferOffset, granularity.width, i, function, "bufferOffset"); 14476a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski skip |= CheckItgInt(device_data, cb_node, region->bufferRowLength, granularity.width, i, function, "bufferRowLength"); 14486a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski skip |= CheckItgInt(device_data, cb_node, region->bufferImageHeight, granularity.width, i, function, "bufferImageHeight"); 14496a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski skip |= CheckItgOffset(device_data, cb_node, ®ion->imageOffset, &granularity, i, function, "imageOffset"); 14506a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski VkExtent3D subresource_extent = GetImageSubresourceExtent(img, ®ion->imageSubresource); 14516a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski skip |= CheckItgExtent(device_data, cb_node, ®ion->imageExtent, ®ion->imageOffset, &granularity, &subresource_extent, 14524441dc47d70aa8532ffc69ab548df1ece5065947Mark Lobodzinski img->createInfo.imageType, i, function, "imageExtent"); 14536a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski } 14546a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski return skip; 14556a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski} 14566a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski 14576a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski// Check valid usage Image Tranfer Granularity requirements for elements of a VkImageCopy structure 14586a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinskibool ValidateCopyImageTransferGranularityRequirements(layer_data *device_data, const GLOBAL_CB_NODE *cb_node, 145978ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton const IMAGE_STATE *src_img, const IMAGE_STATE *dst_img, 146078ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton const VkImageCopy *region, const uint32_t i, const char *function) { 14616a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski bool skip = false; 146228d05b2329f25145607bac9a16220dd30a44c6fdMark Lobodzinski // Source image checks 146378ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton VkExtent3D granularity = GetScaledItg(device_data, cb_node, src_img); 14646a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski skip |= CheckItgOffset(device_data, cb_node, ®ion->srcOffset, &granularity, i, function, "srcOffset"); 146578ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton VkExtent3D subresource_extent = GetImageSubresourceExtent(src_img, ®ion->srcSubresource); 146676e66f8fbe13e0d7bc526e5fe8f8c4de99915ca0Dave Houlton const VkExtent3D extent = region->extent; 146728d05b2329f25145607bac9a16220dd30a44c6fdMark Lobodzinski skip |= CheckItgExtent(device_data, cb_node, &extent, ®ion->srcOffset, &granularity, &subresource_extent, 14684441dc47d70aa8532ffc69ab548df1ece5065947Mark Lobodzinski src_img->createInfo.imageType, i, function, "extent"); 146978ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton 147028d05b2329f25145607bac9a16220dd30a44c6fdMark Lobodzinski // Destination image checks 147178ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton granularity = GetScaledItg(device_data, cb_node, dst_img); 14726a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski skip |= CheckItgOffset(device_data, cb_node, ®ion->dstOffset, &granularity, i, function, "dstOffset"); 14733d7012402fcdac8d98db8f65a0eb3958b7d63297Dave Houlton // Adjust dest extent, if necessary 147476e66f8fbe13e0d7bc526e5fe8f8c4de99915ca0Dave Houlton const VkExtent3D dest_effective_extent = 147576e66f8fbe13e0d7bc526e5fe8f8c4de99915ca0Dave Houlton GetAdjustedDestImageExtent(src_img->createInfo.format, dst_img->createInfo.format, extent); 147678ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton subresource_extent = GetImageSubresourceExtent(dst_img, ®ion->dstSubresource); 14773d7012402fcdac8d98db8f65a0eb3958b7d63297Dave Houlton skip |= CheckItgExtent(device_data, cb_node, &dest_effective_extent, ®ion->dstOffset, &granularity, &subresource_extent, 14784441dc47d70aa8532ffc69ab548df1ece5065947Mark Lobodzinski dst_img->createInfo.imageType, i, function, "extent"); 14796a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski return skip; 14806a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski} 14816a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski 148278ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton// Validate contents of a VkImageCopy struct 148378ab91073f6d67b85f667f7f409390a93c2239e7Dave Houltonbool ValidateImageCopyData(const layer_data *device_data, const debug_report_data *report_data, const uint32_t regionCount, 148478ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton const VkImageCopy *ic_regions, const IMAGE_STATE *src_state, const IMAGE_STATE *dst_state) { 148578ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton bool skip = false; 148678ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton 148778ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton for (uint32_t i = 0; i < regionCount; i++) { 148876e66f8fbe13e0d7bc526e5fe8f8c4de99915ca0Dave Houlton const VkImageCopy region = ic_regions[i]; 14893d7012402fcdac8d98db8f65a0eb3958b7d63297Dave Houlton 14903d7012402fcdac8d98db8f65a0eb3958b7d63297Dave Houlton // For comp<->uncomp copies, the copy extent for the dest image must be adjusted 149176e66f8fbe13e0d7bc526e5fe8f8c4de99915ca0Dave Houlton const VkExtent3D src_copy_extent = region.extent; 149276e66f8fbe13e0d7bc526e5fe8f8c4de99915ca0Dave Houlton const VkExtent3D dst_copy_extent = 14933d7012402fcdac8d98db8f65a0eb3958b7d63297Dave Houlton GetAdjustedDestImageExtent(src_state->createInfo.format, dst_state->createInfo.format, region.extent); 14943d7012402fcdac8d98db8f65a0eb3958b7d63297Dave Houlton 149578ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton bool slice_override = false; 149678ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton uint32_t depth_slices = 0; 149778ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton 149878ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton // Special case for copying between a 1D/2D array and a 3D image 149978ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton // TBD: This seems like the only way to reconcile 3 mutually-exclusive VU checks for 2D/3D copies. Heads up. 150078ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton if ((VK_IMAGE_TYPE_3D == src_state->createInfo.imageType) && (VK_IMAGE_TYPE_3D != dst_state->createInfo.imageType)) { 15013d7012402fcdac8d98db8f65a0eb3958b7d63297Dave Houlton depth_slices = region.dstSubresource.layerCount; // Slice count from 2D subresource 150278ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton slice_override = (depth_slices != 1); 150378ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton } else if ((VK_IMAGE_TYPE_3D == dst_state->createInfo.imageType) && (VK_IMAGE_TYPE_3D != src_state->createInfo.imageType)) { 15043d7012402fcdac8d98db8f65a0eb3958b7d63297Dave Houlton depth_slices = region.srcSubresource.layerCount; // Slice count from 2D subresource 150578ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton slice_override = (depth_slices != 1); 150678ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton } 150778ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton 150878ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton // Do all checks on source image 150978ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton // 151078ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton if (src_state->createInfo.imageType == VK_IMAGE_TYPE_1D) { 15113d7012402fcdac8d98db8f65a0eb3958b7d63297Dave Houlton if ((0 != region.srcOffset.y) || (1 != src_copy_extent.height)) { 15123d7012402fcdac8d98db8f65a0eb3958b7d63297Dave Houlton skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, 15133d7012402fcdac8d98db8f65a0eb3958b7d63297Dave Houlton HandleToUint64(src_state->image), __LINE__, VALIDATION_ERROR_09c00124, "IMAGE", 15143d7012402fcdac8d98db8f65a0eb3958b7d63297Dave Houlton "vkCmdCopyImage(): pRegion[%d] srcOffset.y is %d and extent.height is %d. For 1D images these must " 15153d7012402fcdac8d98db8f65a0eb3958b7d63297Dave Houlton "be 0 and 1, respectively. %s", 15163d7012402fcdac8d98db8f65a0eb3958b7d63297Dave Houlton i, region.srcOffset.y, src_copy_extent.height, validation_error_map[VALIDATION_ERROR_09c00124]); 151778ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton } 151878ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton } 151978ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton 152078ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton if ((src_state->createInfo.imageType == VK_IMAGE_TYPE_1D) || (src_state->createInfo.imageType == VK_IMAGE_TYPE_2D)) { 15213d7012402fcdac8d98db8f65a0eb3958b7d63297Dave Houlton if ((0 != region.srcOffset.z) || (1 != src_copy_extent.depth)) { 15223d7012402fcdac8d98db8f65a0eb3958b7d63297Dave Houlton skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, 15233d7012402fcdac8d98db8f65a0eb3958b7d63297Dave Houlton HandleToUint64(src_state->image), __LINE__, VALIDATION_ERROR_09c00128, "IMAGE", 15243d7012402fcdac8d98db8f65a0eb3958b7d63297Dave Houlton "vkCmdCopyImage(): pRegion[%d] srcOffset.z is %d and extent.depth is %d. For 1D and 2D images " 15253d7012402fcdac8d98db8f65a0eb3958b7d63297Dave Houlton "these must be 0 and 1, respectively. %s", 15263d7012402fcdac8d98db8f65a0eb3958b7d63297Dave Houlton i, region.srcOffset.z, src_copy_extent.depth, validation_error_map[VALIDATION_ERROR_09c00128]); 152778ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton } 152878ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton } 152978ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton 153078ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton // VU01199 changed with mnt1 1531d4eaca34eca7f4b4e34190c441a579347bb2016aMark Lobodzinski if (GetDeviceExtensions(device_data)->vk_khr_maintenance1) { 153278ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton if (src_state->createInfo.imageType == VK_IMAGE_TYPE_3D) { 15333d7012402fcdac8d98db8f65a0eb3958b7d63297Dave Houlton if ((0 != region.srcSubresource.baseArrayLayer) || (1 != region.srcSubresource.layerCount)) { 153478ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton skip |= 153578ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, 1536055fc8fd459f0da279d4814f927ea7090dd0f7e9Petr Kraus HandleToUint64(src_state->image), __LINE__, VALIDATION_ERROR_09c0011a, "IMAGE", 153778ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton "vkCmdCopyImage(): pRegion[%d] srcSubresource.baseArrayLayer is %d and srcSubresource.layerCount " 153878ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton "is %d. For VK_IMAGE_TYPE_3D images these must be 0 and 1, respectively. %s", 15393d7012402fcdac8d98db8f65a0eb3958b7d63297Dave Houlton i, region.srcSubresource.baseArrayLayer, region.srcSubresource.layerCount, 1540315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_09c0011a]); 154178ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton } 154278ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton } 154378ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton } else { // Pre maint 1 154478ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton if (src_state->createInfo.imageType == VK_IMAGE_TYPE_3D || dst_state->createInfo.imageType == VK_IMAGE_TYPE_3D) { 15453d7012402fcdac8d98db8f65a0eb3958b7d63297Dave Houlton if ((0 != region.srcSubresource.baseArrayLayer) || (1 != region.srcSubresource.layerCount)) { 1546055fc8fd459f0da279d4814f927ea7090dd0f7e9Petr Kraus skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, 1547055fc8fd459f0da279d4814f927ea7090dd0f7e9Petr Kraus HandleToUint64(src_state->image), __LINE__, VALIDATION_ERROR_09c0011a, "IMAGE", 1548055fc8fd459f0da279d4814f927ea7090dd0f7e9Petr Kraus "vkCmdCopyImage(): pRegion[%d] srcSubresource.baseArrayLayer is %d and " 1549055fc8fd459f0da279d4814f927ea7090dd0f7e9Petr Kraus "srcSubresource.layerCount is %d. For copies with either source or dest of type " 1550055fc8fd459f0da279d4814f927ea7090dd0f7e9Petr Kraus "VK_IMAGE_TYPE_3D, these must be 0 and 1, respectively. %s", 15513d7012402fcdac8d98db8f65a0eb3958b7d63297Dave Houlton i, region.srcSubresource.baseArrayLayer, region.srcSubresource.layerCount, 1552055fc8fd459f0da279d4814f927ea7090dd0f7e9Petr Kraus validation_error_map[VALIDATION_ERROR_09c0011a]); 155378ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton } 155478ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton } 155578ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton } 155678ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton 155778ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton // TODO: this VU is redundant with VU01224. Gitlab issue 812 submitted to get it removed from the spec. 15583d7012402fcdac8d98db8f65a0eb3958b7d63297Dave Houlton if ((region.srcSubresource.baseArrayLayer >= src_state->createInfo.arrayLayers) || 15593d7012402fcdac8d98db8f65a0eb3958b7d63297Dave Houlton (region.srcSubresource.baseArrayLayer + region.srcSubresource.layerCount > src_state->createInfo.arrayLayers)) { 156078ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, 1561055fc8fd459f0da279d4814f927ea7090dd0f7e9Petr Kraus HandleToUint64(src_state->image), __LINE__, VALIDATION_ERROR_09c0012a, "IMAGE", 156278ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton "vkCmdCopyImage(): pRegion[%d] srcSubresource.baseArrayLayer (%d) must be less than the source image's " 156378ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton "arrayLayers (%d), and the sum of baseArrayLayer and srcSubresource.layerCount (%d) must be less than " 156478ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton "or equal to the source image's arrayLayers. %s", 15653d7012402fcdac8d98db8f65a0eb3958b7d63297Dave Houlton i, region.srcSubresource.baseArrayLayer, src_state->createInfo.arrayLayers, 15663d7012402fcdac8d98db8f65a0eb3958b7d63297Dave Houlton region.srcSubresource.layerCount, validation_error_map[VALIDATION_ERROR_09c0012a]); 156778ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton } 156878ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton 156978ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton // Checks that apply only to compressed images 157078ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton if (FormatIsCompressed(src_state->createInfo.format)) { 157176e66f8fbe13e0d7bc526e5fe8f8c4de99915ca0Dave Houlton const VkExtent3D block_size = FormatCompressedTexelBlockExtent(src_state->createInfo.format); 157278ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton 157378ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton // image offsets must be multiples of block dimensions 15743d7012402fcdac8d98db8f65a0eb3958b7d63297Dave Houlton if ((SafeModulo(region.srcOffset.x, block_size.width) != 0) || 15753d7012402fcdac8d98db8f65a0eb3958b7d63297Dave Houlton (SafeModulo(region.srcOffset.y, block_size.height) != 0) || 15763d7012402fcdac8d98db8f65a0eb3958b7d63297Dave Houlton (SafeModulo(region.srcOffset.z, block_size.depth) != 0)) { 157778ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, 1578055fc8fd459f0da279d4814f927ea7090dd0f7e9Petr Kraus HandleToUint64(src_state->image), __LINE__, VALIDATION_ERROR_09c0013a, "IMAGE", 157978ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton "vkCmdCopyImage(): pRegion[%d] srcOffset (%d, %d) must be multiples of the compressed image's " 158078ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton "texel width & height (%d, %d). %s.", 15813d7012402fcdac8d98db8f65a0eb3958b7d63297Dave Houlton i, region.srcOffset.x, region.srcOffset.y, block_size.width, block_size.height, 1582315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_09c0013a]); 158378ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton } 158478ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton 158576e66f8fbe13e0d7bc526e5fe8f8c4de99915ca0Dave Houlton const VkExtent3D mip_extent = GetImageSubresourceExtent(src_state, &(region.srcSubresource)); 15863d7012402fcdac8d98db8f65a0eb3958b7d63297Dave Houlton if ((SafeModulo(src_copy_extent.width, block_size.width) != 0) && 15873d7012402fcdac8d98db8f65a0eb3958b7d63297Dave Houlton (src_copy_extent.width + region.srcOffset.x != mip_extent.width)) { 158878ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton skip |= 158978ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, 1590055fc8fd459f0da279d4814f927ea7090dd0f7e9Petr Kraus HandleToUint64(src_state->image), __LINE__, VALIDATION_ERROR_09c0013c, "IMAGE", 159178ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton "vkCmdCopyImage(): pRegion[%d] extent width (%d) must be a multiple of the compressed texture block " 159278ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton "width (%d), or when added to srcOffset.x (%d) must equal the image subresource width (%d). %s.", 15933d7012402fcdac8d98db8f65a0eb3958b7d63297Dave Houlton i, src_copy_extent.width, block_size.width, region.srcOffset.x, mip_extent.width, 1594315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_09c0013c]); 159578ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton } 159678ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton 159728d05b2329f25145607bac9a16220dd30a44c6fdMark Lobodzinski // Extent height must be a multiple of block height, or extent+offset height must equal subresource height 15983d7012402fcdac8d98db8f65a0eb3958b7d63297Dave Houlton if ((SafeModulo(src_copy_extent.height, block_size.height) != 0) && 15993d7012402fcdac8d98db8f65a0eb3958b7d63297Dave Houlton (src_copy_extent.height + region.srcOffset.y != mip_extent.height)) { 160078ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton skip |= 160178ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, 1602055fc8fd459f0da279d4814f927ea7090dd0f7e9Petr Kraus HandleToUint64(src_state->image), __LINE__, VALIDATION_ERROR_09c0013e, "IMAGE", 160378ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton "vkCmdCopyImage(): pRegion[%d] extent height (%d) must be a multiple of the compressed texture block " 160478ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton "height (%d), or when added to srcOffset.y (%d) must equal the image subresource height (%d). %s.", 16053d7012402fcdac8d98db8f65a0eb3958b7d63297Dave Houlton i, src_copy_extent.height, block_size.height, region.srcOffset.y, mip_extent.height, 1606315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_09c0013e]); 160778ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton } 160878ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton 160928d05b2329f25145607bac9a16220dd30a44c6fdMark Lobodzinski // Extent depth must be a multiple of block depth, or extent+offset depth must equal subresource depth 16103d7012402fcdac8d98db8f65a0eb3958b7d63297Dave Houlton uint32_t copy_depth = (slice_override ? depth_slices : src_copy_extent.depth); 16113d7012402fcdac8d98db8f65a0eb3958b7d63297Dave Houlton if ((SafeModulo(copy_depth, block_size.depth) != 0) && (copy_depth + region.srcOffset.z != mip_extent.depth)) { 161278ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton skip |= 161378ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, 1614055fc8fd459f0da279d4814f927ea7090dd0f7e9Petr Kraus HandleToUint64(src_state->image), __LINE__, VALIDATION_ERROR_09c00140, "IMAGE", 161578ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton "vkCmdCopyImage(): pRegion[%d] extent width (%d) must be a multiple of the compressed texture block " 161678ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton "depth (%d), or when added to srcOffset.z (%d) must equal the image subresource depth (%d). %s.", 16173d7012402fcdac8d98db8f65a0eb3958b7d63297Dave Houlton i, src_copy_extent.depth, block_size.depth, region.srcOffset.z, mip_extent.depth, 1618315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_09c00140]); 161978ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton } 162078ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton } // Compressed 162178ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton 162278ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton // Do all checks on dest image 162378ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton // 162478ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton if (dst_state->createInfo.imageType == VK_IMAGE_TYPE_1D) { 16253d7012402fcdac8d98db8f65a0eb3958b7d63297Dave Houlton if ((0 != region.dstOffset.y) || (1 != dst_copy_extent.height)) { 16265f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, 16275f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton HandleToUint64(dst_state->image), __LINE__, VALIDATION_ERROR_09c00130, "IMAGE", 16285f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton "vkCmdCopyImage(): pRegion[%d] dstOffset.y is %d and dst_copy_extent.height is %d. For 1D images " 16295f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton "these must be 0 and 1, respectively. %s", 16305f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton i, region.dstOffset.y, dst_copy_extent.height, validation_error_map[VALIDATION_ERROR_09c00130]); 163178ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton } 163278ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton } 163378ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton 163478ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton if ((dst_state->createInfo.imageType == VK_IMAGE_TYPE_1D) || (dst_state->createInfo.imageType == VK_IMAGE_TYPE_2D)) { 16353d7012402fcdac8d98db8f65a0eb3958b7d63297Dave Houlton if ((0 != region.dstOffset.z) || (1 != dst_copy_extent.depth)) { 16365f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, 16375f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton HandleToUint64(dst_state->image), __LINE__, VALIDATION_ERROR_09c00134, "IMAGE", 16385f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton "vkCmdCopyImage(): pRegion[%d] dstOffset.z is %d and dst_copy_extent.depth is %d. For 1D and 2D " 16395f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton "images these must be 0 and 1, respectively. %s", 16405f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton i, region.dstOffset.z, dst_copy_extent.depth, validation_error_map[VALIDATION_ERROR_09c00134]); 164178ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton } 164278ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton } 164378ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton 164478ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton if (dst_state->createInfo.imageType == VK_IMAGE_TYPE_3D) { 16453d7012402fcdac8d98db8f65a0eb3958b7d63297Dave Houlton if ((0 != region.dstSubresource.baseArrayLayer) || (1 != region.dstSubresource.layerCount)) { 164678ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, 1647055fc8fd459f0da279d4814f927ea7090dd0f7e9Petr Kraus HandleToUint64(dst_state->image), __LINE__, VALIDATION_ERROR_09c0011a, "IMAGE", 164878ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton "vkCmdCopyImage(): pRegion[%d] dstSubresource.baseArrayLayer is %d and dstSubresource.layerCount " 164978ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton "is %d. For VK_IMAGE_TYPE_3D images these must be 0 and 1, respectively. %s", 16503d7012402fcdac8d98db8f65a0eb3958b7d63297Dave Houlton i, region.dstSubresource.baseArrayLayer, region.dstSubresource.layerCount, 1651315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_09c0011a]); 165278ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton } 165378ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton } 165478ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton // VU01199 changed with mnt1 1655d4eaca34eca7f4b4e34190c441a579347bb2016aMark Lobodzinski if (GetDeviceExtensions(device_data)->vk_khr_maintenance1) { 165678ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton if (dst_state->createInfo.imageType == VK_IMAGE_TYPE_3D) { 16573d7012402fcdac8d98db8f65a0eb3958b7d63297Dave Houlton if ((0 != region.dstSubresource.baseArrayLayer) || (1 != region.dstSubresource.layerCount)) { 165878ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton skip |= 165978ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, 1660055fc8fd459f0da279d4814f927ea7090dd0f7e9Petr Kraus HandleToUint64(dst_state->image), __LINE__, VALIDATION_ERROR_09c0011a, "IMAGE", 166178ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton "vkCmdCopyImage(): pRegion[%d] dstSubresource.baseArrayLayer is %d and dstSubresource.layerCount " 166278ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton "is %d. For VK_IMAGE_TYPE_3D images these must be 0 and 1, respectively. %s", 16633d7012402fcdac8d98db8f65a0eb3958b7d63297Dave Houlton i, region.dstSubresource.baseArrayLayer, region.dstSubresource.layerCount, 1664315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_09c0011a]); 166578ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton } 166678ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton } 166778ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton } else { // Pre maint 1 166878ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton if (src_state->createInfo.imageType == VK_IMAGE_TYPE_3D || dst_state->createInfo.imageType == VK_IMAGE_TYPE_3D) { 16693d7012402fcdac8d98db8f65a0eb3958b7d63297Dave Houlton if ((0 != region.dstSubresource.baseArrayLayer) || (1 != region.dstSubresource.layerCount)) { 1670055fc8fd459f0da279d4814f927ea7090dd0f7e9Petr Kraus skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, 1671055fc8fd459f0da279d4814f927ea7090dd0f7e9Petr Kraus HandleToUint64(dst_state->image), __LINE__, VALIDATION_ERROR_09c0011a, "IMAGE", 1672055fc8fd459f0da279d4814f927ea7090dd0f7e9Petr Kraus "vkCmdCopyImage(): pRegion[%d] dstSubresource.baseArrayLayer is %d and " 1673055fc8fd459f0da279d4814f927ea7090dd0f7e9Petr Kraus "dstSubresource.layerCount is %d. For copies with either source or dest of type " 1674055fc8fd459f0da279d4814f927ea7090dd0f7e9Petr Kraus "VK_IMAGE_TYPE_3D, these must be 0 and 1, respectively. %s", 16753d7012402fcdac8d98db8f65a0eb3958b7d63297Dave Houlton i, region.dstSubresource.baseArrayLayer, region.dstSubresource.layerCount, 1676055fc8fd459f0da279d4814f927ea7090dd0f7e9Petr Kraus validation_error_map[VALIDATION_ERROR_09c0011a]); 167778ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton } 167878ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton } 167978ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton } 168078ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton 168178ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton // TODO: this VU is redundant with VU01224. Gitlab issue 812 submitted to get it removed from the spec. 16823d7012402fcdac8d98db8f65a0eb3958b7d63297Dave Houlton if ((region.dstSubresource.baseArrayLayer >= dst_state->createInfo.arrayLayers) || 16833d7012402fcdac8d98db8f65a0eb3958b7d63297Dave Houlton (region.dstSubresource.baseArrayLayer + region.dstSubresource.layerCount > dst_state->createInfo.arrayLayers)) { 168478ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, 1685055fc8fd459f0da279d4814f927ea7090dd0f7e9Petr Kraus HandleToUint64(dst_state->image), __LINE__, VALIDATION_ERROR_09c00136, "IMAGE", 168678ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton "vkCmdCopyImage(): pRegion[%d] dstSubresource.baseArrayLayer (%d) must be less than the dest image's " 168778ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton "arrayLayers (%d), and the sum of baseArrayLayer and dstSubresource.layerCount (%d) must be less than " 168878ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton "or equal to the dest image's arrayLayers. %s", 16893d7012402fcdac8d98db8f65a0eb3958b7d63297Dave Houlton i, region.dstSubresource.baseArrayLayer, dst_state->createInfo.arrayLayers, 16903d7012402fcdac8d98db8f65a0eb3958b7d63297Dave Houlton region.dstSubresource.layerCount, validation_error_map[VALIDATION_ERROR_09c00136]); 169178ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton } 169278ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton 169378ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton // Checks that apply only to compressed images 169478ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton if (FormatIsCompressed(dst_state->createInfo.format)) { 169576e66f8fbe13e0d7bc526e5fe8f8c4de99915ca0Dave Houlton const VkExtent3D block_size = FormatCompressedTexelBlockExtent(dst_state->createInfo.format); 169678ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton 169778ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton // image offsets must be multiples of block dimensions 16983d7012402fcdac8d98db8f65a0eb3958b7d63297Dave Houlton if ((SafeModulo(region.dstOffset.x, block_size.width) != 0) || 16993d7012402fcdac8d98db8f65a0eb3958b7d63297Dave Houlton (SafeModulo(region.dstOffset.y, block_size.height) != 0) || 17003d7012402fcdac8d98db8f65a0eb3958b7d63297Dave Houlton (SafeModulo(region.dstOffset.z, block_size.depth) != 0)) { 170178ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, 1702055fc8fd459f0da279d4814f927ea7090dd0f7e9Petr Kraus HandleToUint64(dst_state->image), __LINE__, VALIDATION_ERROR_09c00144, "IMAGE", 170378ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton "vkCmdCopyImage(): pRegion[%d] dstOffset (%d, %d) must be multiples of the compressed image's " 170478ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton "texel width & height (%d, %d). %s.", 17053d7012402fcdac8d98db8f65a0eb3958b7d63297Dave Houlton i, region.dstOffset.x, region.dstOffset.y, block_size.width, block_size.height, 1706315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_09c00144]); 170778ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton } 170878ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton 170976e66f8fbe13e0d7bc526e5fe8f8c4de99915ca0Dave Houlton const VkExtent3D mip_extent = GetImageSubresourceExtent(dst_state, &(region.dstSubresource)); 17103d7012402fcdac8d98db8f65a0eb3958b7d63297Dave Houlton if ((SafeModulo(dst_copy_extent.width, block_size.width) != 0) && 17113d7012402fcdac8d98db8f65a0eb3958b7d63297Dave Houlton (dst_copy_extent.width + region.dstOffset.x != mip_extent.width)) { 17125f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton skip |= 17135f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, 17145f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton HandleToUint64(dst_state->image), __LINE__, VALIDATION_ERROR_09c00146, "IMAGE", 17155f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton "vkCmdCopyImage(): pRegion[%d] dst_copy_extent width (%d) must be a multiple of the compressed texture " 17165f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton "block width (%d), or when added to dstOffset.x (%d) must equal the image subresource width (%d). %s.", 17175f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton i, dst_copy_extent.width, block_size.width, region.dstOffset.x, mip_extent.width, 17185f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton validation_error_map[VALIDATION_ERROR_09c00146]); 171978ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton } 172078ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton 17213d7012402fcdac8d98db8f65a0eb3958b7d63297Dave Houlton // Extent height must be a multiple of block height, or dst_copy_extent+offset height must equal subresource height 17223d7012402fcdac8d98db8f65a0eb3958b7d63297Dave Houlton if ((SafeModulo(dst_copy_extent.height, block_size.height) != 0) && 17233d7012402fcdac8d98db8f65a0eb3958b7d63297Dave Houlton (dst_copy_extent.height + region.dstOffset.y != mip_extent.height)) { 17245f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, 17255f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton HandleToUint64(dst_state->image), __LINE__, VALIDATION_ERROR_09c00148, "IMAGE", 17265f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton "vkCmdCopyImage(): pRegion[%d] dst_copy_extent height (%d) must be a multiple of the compressed " 17275f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton "texture block height (%d), or when added to dstOffset.y (%d) must equal the image subresource " 17285f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton "height (%d). %s.", 17295f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton i, dst_copy_extent.height, block_size.height, region.dstOffset.y, mip_extent.height, 17305f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton validation_error_map[VALIDATION_ERROR_09c00148]); 173178ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton } 173278ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton 17333d7012402fcdac8d98db8f65a0eb3958b7d63297Dave Houlton // Extent depth must be a multiple of block depth, or dst_copy_extent+offset depth must equal subresource depth 17343d7012402fcdac8d98db8f65a0eb3958b7d63297Dave Houlton uint32_t copy_depth = (slice_override ? depth_slices : dst_copy_extent.depth); 17353d7012402fcdac8d98db8f65a0eb3958b7d63297Dave Houlton if ((SafeModulo(copy_depth, block_size.depth) != 0) && (copy_depth + region.dstOffset.z != mip_extent.depth)) { 17365f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton skip |= 17375f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, 17385f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton HandleToUint64(dst_state->image), __LINE__, VALIDATION_ERROR_09c0014a, "IMAGE", 17395f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton "vkCmdCopyImage(): pRegion[%d] dst_copy_extent width (%d) must be a multiple of the compressed texture " 17405f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton "block depth (%d), or when added to dstOffset.z (%d) must equal the image subresource depth (%d). %s.", 17415f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton i, dst_copy_extent.depth, block_size.depth, region.dstOffset.z, mip_extent.depth, 17425f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton validation_error_map[VALIDATION_ERROR_09c0014a]); 174378ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton } 174478ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton } // Compressed 174578ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton } 174678ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton return skip; 174778ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton} 174878ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton 1749e40189d4deab674240cd9baf4c063bab4567c212Tobin Ehlisbool PreCallValidateCmdCopyImage(layer_data *device_data, GLOBAL_CB_NODE *cb_node, IMAGE_STATE *src_image_state, 17506a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski IMAGE_STATE *dst_image_state, uint32_t region_count, const VkImageCopy *regions, 17516a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski VkImageLayout src_image_layout, VkImageLayout dst_image_layout) { 1752ff309c48cf48eec4599c9bf83f5b5cd802fa2db0Mark Lobodzinski bool skip = false; 1753ff309c48cf48eec4599c9bf83f5b5cd802fa2db0Mark Lobodzinski const debug_report_data *report_data = core_validation::GetReportData(device_data); 175478ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton skip = ValidateImageCopyData(device_data, report_data, region_count, regions, src_image_state, dst_image_state); 175578ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton 1756ff309c48cf48eec4599c9bf83f5b5cd802fa2db0Mark Lobodzinski VkCommandBuffer command_buffer = cb_node->commandBuffer; 1757ff309c48cf48eec4599c9bf83f5b5cd802fa2db0Mark Lobodzinski 17586a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski for (uint32_t i = 0; i < region_count; i++) { 175976e66f8fbe13e0d7bc526e5fe8f8c4de99915ca0Dave Houlton const VkImageCopy region = regions[i]; 17603d7012402fcdac8d98db8f65a0eb3958b7d63297Dave Houlton 17613d7012402fcdac8d98db8f65a0eb3958b7d63297Dave Houlton // For comp/uncomp copies, the copy extent for the dest image must be adjusted 17623d7012402fcdac8d98db8f65a0eb3958b7d63297Dave Houlton VkExtent3D src_copy_extent = region.extent; 17633d7012402fcdac8d98db8f65a0eb3958b7d63297Dave Houlton VkExtent3D dst_copy_extent = 17643d7012402fcdac8d98db8f65a0eb3958b7d63297Dave Houlton GetAdjustedDestImageExtent(src_image_state->createInfo.format, dst_image_state->createInfo.format, region.extent); 17653d7012402fcdac8d98db8f65a0eb3958b7d63297Dave Houlton 176678ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton bool slice_override = false; 176778ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton uint32_t depth_slices = 0; 176878ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton 176978ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton // Special case for copying between a 1D/2D array and a 3D image 177078ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton // TBD: This seems like the only way to reconcile 3 mutually-exclusive VU checks for 2D/3D copies. Heads up. 177178ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton if ((VK_IMAGE_TYPE_3D == src_image_state->createInfo.imageType) && 177278ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton (VK_IMAGE_TYPE_3D != dst_image_state->createInfo.imageType)) { 17733d7012402fcdac8d98db8f65a0eb3958b7d63297Dave Houlton depth_slices = region.dstSubresource.layerCount; // Slice count from 2D subresource 177478ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton slice_override = (depth_slices != 1); 177578ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton } else if ((VK_IMAGE_TYPE_3D == dst_image_state->createInfo.imageType) && 177678ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton (VK_IMAGE_TYPE_3D != src_image_state->createInfo.imageType)) { 17773d7012402fcdac8d98db8f65a0eb3958b7d63297Dave Houlton depth_slices = region.srcSubresource.layerCount; // Slice count from 2D subresource 177878ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton slice_override = (depth_slices != 1); 177978ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton } 178078ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton 17813d7012402fcdac8d98db8f65a0eb3958b7d63297Dave Houlton if (region.srcSubresource.layerCount == 0) { 17826a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski std::stringstream ss; 17836a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski ss << "vkCmdCopyImage: number of layers in pRegions[" << i << "] srcSubresource is zero"; 17849b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus skip |= 17859b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus log_msg(report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 17869b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(command_buffer), __LINE__, DRAWSTATE_INVALID_IMAGE_ASPECT, "IMAGE", "%s", ss.str().c_str()); 17876a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski } 1788ff309c48cf48eec4599c9bf83f5b5cd802fa2db0Mark Lobodzinski 17893d7012402fcdac8d98db8f65a0eb3958b7d63297Dave Houlton if (region.dstSubresource.layerCount == 0) { 17906a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski std::stringstream ss; 17916a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski ss << "vkCmdCopyImage: number of layers in pRegions[" << i << "] dstSubresource is zero"; 17929b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus skip |= 17939b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus log_msg(report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 17949b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(command_buffer), __LINE__, DRAWSTATE_INVALID_IMAGE_ASPECT, "IMAGE", "%s", ss.str().c_str()); 17956a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski } 1796ff309c48cf48eec4599c9bf83f5b5cd802fa2db0Mark Lobodzinski 1797d4eaca34eca7f4b4e34190c441a579347bb2016aMark Lobodzinski if (GetDeviceExtensions(device_data)->vk_khr_maintenance1) { 179878ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton // No chance of mismatch if we're overriding depth slice count 179978ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton if (!slice_override) { 180078ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton // The number of depth slices in srcSubresource and dstSubresource must match 180178ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton // Depth comes from layerCount for 1D,2D resources, from extent.depth for 3D 180278ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton uint32_t src_slices = 18033d7012402fcdac8d98db8f65a0eb3958b7d63297Dave Houlton (VK_IMAGE_TYPE_3D == src_image_state->createInfo.imageType ? src_copy_extent.depth 18043d7012402fcdac8d98db8f65a0eb3958b7d63297Dave Houlton : region.srcSubresource.layerCount); 180578ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton uint32_t dst_slices = 18063d7012402fcdac8d98db8f65a0eb3958b7d63297Dave Houlton (VK_IMAGE_TYPE_3D == dst_image_state->createInfo.imageType ? dst_copy_extent.depth 18073d7012402fcdac8d98db8f65a0eb3958b7d63297Dave Houlton : region.dstSubresource.layerCount); 180878ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton if (src_slices != dst_slices) { 180978ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton std::stringstream ss; 181078ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton ss << "vkCmdCopyImage: number of depth slices in source and destination subresources for pRegions[" << i 181178ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton << "] do not match"; 181278ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 1813055fc8fd459f0da279d4814f927ea7090dd0f7e9Petr Kraus HandleToUint64(command_buffer), __LINE__, VALIDATION_ERROR_09c00118, "IMAGE", "%s. %s", 1814055fc8fd459f0da279d4814f927ea7090dd0f7e9Petr Kraus ss.str().c_str(), validation_error_map[VALIDATION_ERROR_09c00118]); 181578ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton } 181678ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton } 181778ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton } else { 181857eda737eea95dd728f6dce5c78d6b00fb126076Mike Schuchardt // For each region the layerCount member of srcSubresource and dstSubresource must match 18193d7012402fcdac8d98db8f65a0eb3958b7d63297Dave Houlton if (region.srcSubresource.layerCount != region.dstSubresource.layerCount) { 182057eda737eea95dd728f6dce5c78d6b00fb126076Mike Schuchardt std::stringstream ss; 182157eda737eea95dd728f6dce5c78d6b00fb126076Mike Schuchardt ss << "vkCmdCopyImage: number of layers in source and destination subresources for pRegions[" << i 182257eda737eea95dd728f6dce5c78d6b00fb126076Mike Schuchardt << "] do not match"; 182357eda737eea95dd728f6dce5c78d6b00fb126076Mike Schuchardt skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 1824315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(command_buffer), __LINE__, VALIDATION_ERROR_09c00118, "IMAGE", "%s. %s", 1825315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis ss.str().c_str(), validation_error_map[VALIDATION_ERROR_09c00118]); 182657eda737eea95dd728f6dce5c78d6b00fb126076Mike Schuchardt } 18276a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski } 1828ff309c48cf48eec4599c9bf83f5b5cd802fa2db0Mark Lobodzinski 18296a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski // For each region, the aspectMask member of srcSubresource and dstSubresource must match 18303d7012402fcdac8d98db8f65a0eb3958b7d63297Dave Houlton if (region.srcSubresource.aspectMask != region.dstSubresource.aspectMask) { 18316a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski char const str[] = "vkCmdCopyImage: Src and dest aspectMasks for each region must match"; 18326a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 1833315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(command_buffer), __LINE__, VALIDATION_ERROR_09c00112, "IMAGE", "%s. %s", str, 1834315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_09c00112]); 18356a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski } 1836ff309c48cf48eec4599c9bf83f5b5cd802fa2db0Mark Lobodzinski 1837e9d74ac8e13687c1be3ee147efce42e8215a049eDave Houlton // For each region, the aspectMask member of srcSubresource must be present in the source image 18383d7012402fcdac8d98db8f65a0eb3958b7d63297Dave Houlton if (!VerifyAspectsPresent(region.srcSubresource.aspectMask, src_image_state->createInfo.format)) { 1839e9d74ac8e13687c1be3ee147efce42e8215a049eDave Houlton std::stringstream ss; 1840e9d74ac8e13687c1be3ee147efce42e8215a049eDave Houlton ss << "vkCmdCopyImage: pRegion[" << i 1841e9d74ac8e13687c1be3ee147efce42e8215a049eDave Houlton << "] srcSubresource.aspectMask cannot specify aspects not present in source image"; 1842e9d74ac8e13687c1be3ee147efce42e8215a049eDave Houlton skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 1843315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(command_buffer), __LINE__, VALIDATION_ERROR_09c0011c, "IMAGE", "%s. %s", 1844315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis ss.str().c_str(), validation_error_map[VALIDATION_ERROR_09c0011c]); 1845e9d74ac8e13687c1be3ee147efce42e8215a049eDave Houlton } 1846e9d74ac8e13687c1be3ee147efce42e8215a049eDave Houlton 1847e9d74ac8e13687c1be3ee147efce42e8215a049eDave Houlton // For each region, the aspectMask member of dstSubresource must be present in the destination image 18483d7012402fcdac8d98db8f65a0eb3958b7d63297Dave Houlton if (!VerifyAspectsPresent(region.dstSubresource.aspectMask, dst_image_state->createInfo.format)) { 1849e9d74ac8e13687c1be3ee147efce42e8215a049eDave Houlton std::stringstream ss; 1850e9d74ac8e13687c1be3ee147efce42e8215a049eDave Houlton ss << "vkCmdCopyImage: pRegion[" << i << "] dstSubresource.aspectMask cannot specify aspects not present in dest image"; 1851e9d74ac8e13687c1be3ee147efce42e8215a049eDave Houlton skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 1852315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(command_buffer), __LINE__, VALIDATION_ERROR_09c0011e, "IMAGE", "%s. %s", 1853315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis ss.str().c_str(), validation_error_map[VALIDATION_ERROR_09c0011e]); 1854e9d74ac8e13687c1be3ee147efce42e8215a049eDave Houlton } 1855e9d74ac8e13687c1be3ee147efce42e8215a049eDave Houlton 18566a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski // AspectMask must not contain VK_IMAGE_ASPECT_METADATA_BIT 18573d7012402fcdac8d98db8f65a0eb3958b7d63297Dave Houlton if ((region.srcSubresource.aspectMask & VK_IMAGE_ASPECT_METADATA_BIT) || 18583d7012402fcdac8d98db8f65a0eb3958b7d63297Dave Houlton (region.dstSubresource.aspectMask & VK_IMAGE_ASPECT_METADATA_BIT)) { 18596a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski std::stringstream ss; 18606a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski ss << "vkCmdCopyImage: pRegions[" << i << "] may not specify aspectMask containing VK_IMAGE_ASPECT_METADATA_BIT"; 18616a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 1862315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(command_buffer), __LINE__, VALIDATION_ERROR_0a600150, "IMAGE", "%s. %s", 1863315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis ss.str().c_str(), validation_error_map[VALIDATION_ERROR_0a600150]); 18646a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski } 1865ff309c48cf48eec4599c9bf83f5b5cd802fa2db0Mark Lobodzinski 18666a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski // For each region, if aspectMask contains VK_IMAGE_ASPECT_COLOR_BIT, it must not contain either of 18676a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski // VK_IMAGE_ASPECT_DEPTH_BIT or VK_IMAGE_ASPECT_STENCIL_BIT 18683d7012402fcdac8d98db8f65a0eb3958b7d63297Dave Houlton if ((region.srcSubresource.aspectMask & VK_IMAGE_ASPECT_COLOR_BIT) && 18693d7012402fcdac8d98db8f65a0eb3958b7d63297Dave Houlton (region.srcSubresource.aspectMask & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT))) { 18706a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski char const str[] = "vkCmdCopyImage aspectMask cannot specify both COLOR and DEPTH/STENCIL aspects"; 18716a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 1872315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(command_buffer), __LINE__, VALIDATION_ERROR_0a60014e, "IMAGE", "%s. %s", str, 1873315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_0a60014e]); 18746a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski } 1875ff309c48cf48eec4599c9bf83f5b5cd802fa2db0Mark Lobodzinski 18766a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski // MipLevel must be less than the mipLevels specified in VkImageCreateInfo when the image was created 18773d7012402fcdac8d98db8f65a0eb3958b7d63297Dave Houlton if (region.srcSubresource.mipLevel >= src_image_state->createInfo.mipLevels) { 18786a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski std::stringstream ss; 18796a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski ss << "vkCmdCopyImage: pRegions[" << i 18806a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski << "] specifies a src mipLevel greater than the number specified when the srcImage was created."; 18816a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 1882315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(command_buffer), __LINE__, VALIDATION_ERROR_0a600152, "IMAGE", "%s. %s", 1883315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis ss.str().c_str(), validation_error_map[VALIDATION_ERROR_0a600152]); 18846a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski } 18853d7012402fcdac8d98db8f65a0eb3958b7d63297Dave Houlton if (region.dstSubresource.mipLevel >= dst_image_state->createInfo.mipLevels) { 18866a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski std::stringstream ss; 18876a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski ss << "vkCmdCopyImage: pRegions[" << i 18886a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski << "] specifies a dst mipLevel greater than the number specified when the dstImage was created."; 18896a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 1890315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(command_buffer), __LINE__, VALIDATION_ERROR_0a600152, "IMAGE", "%s. %s", 1891315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis ss.str().c_str(), validation_error_map[VALIDATION_ERROR_0a600152]); 18926a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski } 1893ff309c48cf48eec4599c9bf83f5b5cd802fa2db0Mark Lobodzinski 18946a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski // (baseArrayLayer + layerCount) must be less than or equal to the arrayLayers specified in VkImageCreateInfo when the 18956a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski // image was created 18963d7012402fcdac8d98db8f65a0eb3958b7d63297Dave Houlton if ((region.srcSubresource.baseArrayLayer + region.srcSubresource.layerCount) > src_image_state->createInfo.arrayLayers) { 18976a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski std::stringstream ss; 18986a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski ss << "vkCmdCopyImage: srcImage arrayLayers was " << src_image_state->createInfo.arrayLayers << " but subRegion[" << i 18993d7012402fcdac8d98db8f65a0eb3958b7d63297Dave Houlton << "] baseArrayLayer + layerCount is " << (region.srcSubresource.baseArrayLayer + region.srcSubresource.layerCount); 19006a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 1901315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(command_buffer), __LINE__, VALIDATION_ERROR_0a600154, "IMAGE", "%s. %s", 1902315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis ss.str().c_str(), validation_error_map[VALIDATION_ERROR_0a600154]); 19036a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski } 19043d7012402fcdac8d98db8f65a0eb3958b7d63297Dave Houlton if ((region.dstSubresource.baseArrayLayer + region.dstSubresource.layerCount) > dst_image_state->createInfo.arrayLayers) { 19056a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski std::stringstream ss; 19066a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski ss << "vkCmdCopyImage: dstImage arrayLayers was " << dst_image_state->createInfo.arrayLayers << " but subRegion[" << i 19073d7012402fcdac8d98db8f65a0eb3958b7d63297Dave Houlton << "] baseArrayLayer + layerCount is " << (region.dstSubresource.baseArrayLayer + region.dstSubresource.layerCount); 19086a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 1909315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(command_buffer), __LINE__, VALIDATION_ERROR_0a600154, "IMAGE", "%s. %s", 1910315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis ss.str().c_str(), validation_error_map[VALIDATION_ERROR_0a600154]); 19116a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski } 1912ff309c48cf48eec4599c9bf83f5b5cd802fa2db0Mark Lobodzinski 191357eda737eea95dd728f6dce5c78d6b00fb126076Mike Schuchardt // Check region extents for 1D-1D, 2D-2D, and 3D-3D copies 191457eda737eea95dd728f6dce5c78d6b00fb126076Mike Schuchardt if (src_image_state->createInfo.imageType == dst_image_state->createInfo.imageType) { 191557eda737eea95dd728f6dce5c78d6b00fb126076Mike Schuchardt // The source region specified by a given element of regions must be a region that is contained within srcImage 19163d7012402fcdac8d98db8f65a0eb3958b7d63297Dave Houlton VkExtent3D img_extent = GetImageSubresourceExtent(src_image_state, &(region.srcSubresource)); 19173d7012402fcdac8d98db8f65a0eb3958b7d63297Dave Houlton if (0 != ExceedsBounds(®ion.srcOffset, &src_copy_extent, &img_extent)) { 191857eda737eea95dd728f6dce5c78d6b00fb126076Mike Schuchardt std::stringstream ss; 19193d7012402fcdac8d98db8f65a0eb3958b7d63297Dave Houlton ss << "vkCmdCopyImage: Source pRegion[" << i << "] with mipLevel [ " << region.srcSubresource.mipLevel 19203d7012402fcdac8d98db8f65a0eb3958b7d63297Dave Houlton << " ], offset [ " << region.srcOffset.x << ", " << region.srcOffset.y << ", " << region.srcOffset.z 19213d7012402fcdac8d98db8f65a0eb3958b7d63297Dave Houlton << " ], extent [ " << src_copy_extent.width << ", " << src_copy_extent.height << ", " << src_copy_extent.depth 19223d7012402fcdac8d98db8f65a0eb3958b7d63297Dave Houlton << " ] exceeds the source image dimensions"; 192357eda737eea95dd728f6dce5c78d6b00fb126076Mike Schuchardt skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 1924315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(command_buffer), __LINE__, VALIDATION_ERROR_190000f4, "IMAGE", "%s. %s", 1925315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis ss.str().c_str(), validation_error_map[VALIDATION_ERROR_190000f4]); 192657eda737eea95dd728f6dce5c78d6b00fb126076Mike Schuchardt } 1927ff309c48cf48eec4599c9bf83f5b5cd802fa2db0Mark Lobodzinski 192857eda737eea95dd728f6dce5c78d6b00fb126076Mike Schuchardt // The destination region specified by a given element of regions must be a region that is contained within dst_image 19293d7012402fcdac8d98db8f65a0eb3958b7d63297Dave Houlton img_extent = GetImageSubresourceExtent(dst_image_state, &(region.dstSubresource)); 19303d7012402fcdac8d98db8f65a0eb3958b7d63297Dave Houlton if (0 != ExceedsBounds(®ion.dstOffset, &dst_copy_extent, &img_extent)) { 193157eda737eea95dd728f6dce5c78d6b00fb126076Mike Schuchardt std::stringstream ss; 19323d7012402fcdac8d98db8f65a0eb3958b7d63297Dave Houlton ss << "vkCmdCopyImage: Dest pRegion[" << i << "] with mipLevel [ " << region.dstSubresource.mipLevel 19333d7012402fcdac8d98db8f65a0eb3958b7d63297Dave Houlton << " ], offset [ " << region.dstOffset.x << ", " << region.dstOffset.y << ", " << region.dstOffset.z 19343d7012402fcdac8d98db8f65a0eb3958b7d63297Dave Houlton << " ], extent [ " << dst_copy_extent.width << ", " << dst_copy_extent.height << ", " << dst_copy_extent.depth 19353d7012402fcdac8d98db8f65a0eb3958b7d63297Dave Houlton << " ] exceeds the destination image dimensions"; 193657eda737eea95dd728f6dce5c78d6b00fb126076Mike Schuchardt skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 1937315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(command_buffer), __LINE__, VALIDATION_ERROR_190000f6, "IMAGE", "%s. %s", 1938315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis ss.str().c_str(), validation_error_map[VALIDATION_ERROR_190000f6]); 193957eda737eea95dd728f6dce5c78d6b00fb126076Mike Schuchardt } 19406a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski } 1941ff309c48cf48eec4599c9bf83f5b5cd802fa2db0Mark Lobodzinski 19423fb79e4c87829ef090622d69a117f33ec7d4ded5Dave Houlton // Each dimension offset + extent limits must fall with image subresource extent 19433d7012402fcdac8d98db8f65a0eb3958b7d63297Dave Houlton VkExtent3D subresource_extent = GetImageSubresourceExtent(src_image_state, &(region.srcSubresource)); 19443d7012402fcdac8d98db8f65a0eb3958b7d63297Dave Houlton if (slice_override) src_copy_extent.depth = depth_slices; 19453d7012402fcdac8d98db8f65a0eb3958b7d63297Dave Houlton uint32_t extent_check = ExceedsBounds(&(region.srcOffset), &src_copy_extent, &subresource_extent); 19463fb79e4c87829ef090622d69a117f33ec7d4ded5Dave Houlton if (extent_check & x_bit) { 19473fb79e4c87829ef090622d69a117f33ec7d4ded5Dave Houlton skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 1948315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(command_buffer), __LINE__, VALIDATION_ERROR_09c00120, "IMAGE", 19493fb79e4c87829ef090622d69a117f33ec7d4ded5Dave Houlton "vkCmdCopyImage: Source image pRegion %1d x-dimension offset [%1d] + extent [%1d] exceeds subResource " 19503fb79e4c87829ef090622d69a117f33ec7d4ded5Dave Houlton "width [%1d]. %s", 19513d7012402fcdac8d98db8f65a0eb3958b7d63297Dave Houlton i, region.srcOffset.x, src_copy_extent.width, subresource_extent.width, 1952315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_09c00120]); 19533fb79e4c87829ef090622d69a117f33ec7d4ded5Dave Houlton } 19543fb79e4c87829ef090622d69a117f33ec7d4ded5Dave Houlton 19553fb79e4c87829ef090622d69a117f33ec7d4ded5Dave Houlton if (extent_check & y_bit) { 19563fb79e4c87829ef090622d69a117f33ec7d4ded5Dave Houlton skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 1957315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(command_buffer), __LINE__, VALIDATION_ERROR_09c00122, "IMAGE", 19583fb79e4c87829ef090622d69a117f33ec7d4ded5Dave Houlton "vkCmdCopyImage: Source image pRegion %1d y-dimension offset [%1d] + extent [%1d] exceeds subResource " 19593fb79e4c87829ef090622d69a117f33ec7d4ded5Dave Houlton "height [%1d]. %s", 19603d7012402fcdac8d98db8f65a0eb3958b7d63297Dave Houlton i, region.srcOffset.y, src_copy_extent.height, subresource_extent.height, 1961315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_09c00122]); 19623fb79e4c87829ef090622d69a117f33ec7d4ded5Dave Houlton } 19633fb79e4c87829ef090622d69a117f33ec7d4ded5Dave Houlton if (extent_check & z_bit) { 19643fb79e4c87829ef090622d69a117f33ec7d4ded5Dave Houlton skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 1965315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(command_buffer), __LINE__, VALIDATION_ERROR_09c00126, "IMAGE", 19663fb79e4c87829ef090622d69a117f33ec7d4ded5Dave Houlton "vkCmdCopyImage: Source image pRegion %1d z-dimension offset [%1d] + extent [%1d] exceeds subResource " 19673fb79e4c87829ef090622d69a117f33ec7d4ded5Dave Houlton "depth [%1d]. %s", 19683d7012402fcdac8d98db8f65a0eb3958b7d63297Dave Houlton i, region.srcOffset.z, src_copy_extent.depth, subresource_extent.depth, 1969315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_09c00126]); 19703fb79e4c87829ef090622d69a117f33ec7d4ded5Dave Houlton } 19713fb79e4c87829ef090622d69a117f33ec7d4ded5Dave Houlton 19723d7012402fcdac8d98db8f65a0eb3958b7d63297Dave Houlton // Adjust dest extent if necessary 19733d7012402fcdac8d98db8f65a0eb3958b7d63297Dave Houlton subresource_extent = GetImageSubresourceExtent(dst_image_state, &(region.dstSubresource)); 19743d7012402fcdac8d98db8f65a0eb3958b7d63297Dave Houlton if (slice_override) dst_copy_extent.depth = depth_slices; 19753d7012402fcdac8d98db8f65a0eb3958b7d63297Dave Houlton 19763d7012402fcdac8d98db8f65a0eb3958b7d63297Dave Houlton extent_check = ExceedsBounds(&(region.dstOffset), &dst_copy_extent, &subresource_extent); 19773fb79e4c87829ef090622d69a117f33ec7d4ded5Dave Houlton if (extent_check & x_bit) { 19783fb79e4c87829ef090622d69a117f33ec7d4ded5Dave Houlton skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 1979315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(command_buffer), __LINE__, VALIDATION_ERROR_09c0012c, "IMAGE", 19803fb79e4c87829ef090622d69a117f33ec7d4ded5Dave Houlton "vkCmdCopyImage: Dest image pRegion %1d x-dimension offset [%1d] + extent [%1d] exceeds subResource " 19813fb79e4c87829ef090622d69a117f33ec7d4ded5Dave Houlton "width [%1d]. %s", 19823d7012402fcdac8d98db8f65a0eb3958b7d63297Dave Houlton i, region.dstOffset.x, dst_copy_extent.width, subresource_extent.width, 1983315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_09c0012c]); 19843fb79e4c87829ef090622d69a117f33ec7d4ded5Dave Houlton } 19853fb79e4c87829ef090622d69a117f33ec7d4ded5Dave Houlton if (extent_check & y_bit) { 19863fb79e4c87829ef090622d69a117f33ec7d4ded5Dave Houlton skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 1987315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(command_buffer), __LINE__, VALIDATION_ERROR_09c0012e, "IMAGE", 19883fb79e4c87829ef090622d69a117f33ec7d4ded5Dave Houlton "vkCmdCopyImage: Dest image pRegion %1d y-dimension offset [%1d] + extent [%1d] exceeds subResource " 19893fb79e4c87829ef090622d69a117f33ec7d4ded5Dave Houlton "height [%1d]. %s", 19903d7012402fcdac8d98db8f65a0eb3958b7d63297Dave Houlton i, region.dstOffset.y, dst_copy_extent.height, subresource_extent.height, 1991315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_09c0012e]); 19923fb79e4c87829ef090622d69a117f33ec7d4ded5Dave Houlton } 19933fb79e4c87829ef090622d69a117f33ec7d4ded5Dave Houlton if (extent_check & z_bit) { 19943fb79e4c87829ef090622d69a117f33ec7d4ded5Dave Houlton skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 1995315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(command_buffer), __LINE__, VALIDATION_ERROR_09c00132, "IMAGE", 19963fb79e4c87829ef090622d69a117f33ec7d4ded5Dave Houlton "vkCmdCopyImage: Dest image pRegion %1d z-dimension offset [%1d] + extent [%1d] exceeds subResource " 19973fb79e4c87829ef090622d69a117f33ec7d4ded5Dave Houlton "depth [%1d]. %s", 19983d7012402fcdac8d98db8f65a0eb3958b7d63297Dave Houlton i, region.dstOffset.z, dst_copy_extent.depth, subresource_extent.depth, 1999315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_09c00132]); 20003fb79e4c87829ef090622d69a117f33ec7d4ded5Dave Houlton } 20013fb79e4c87829ef090622d69a117f33ec7d4ded5Dave Houlton 20026a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski // The union of all source regions, and the union of all destination regions, specified by the elements of regions, 20036a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski // must not overlap in memory 20046a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski if (src_image_state->image == dst_image_state->image) { 20056a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski for (uint32_t j = 0; j < region_count; j++) { 20063d7012402fcdac8d98db8f65a0eb3958b7d63297Dave Houlton if (RegionIntersects(®ion, ®ions[j], src_image_state->createInfo.imageType)) { 20076a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski std::stringstream ss; 20086a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski ss << "vkCmdCopyImage: pRegions[" << i << "] src overlaps with pRegions[" << j << "]."; 20096a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 2010315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(command_buffer), __LINE__, VALIDATION_ERROR_190000f8, "IMAGE", "%s. %s", 2011315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis ss.str().c_str(), validation_error_map[VALIDATION_ERROR_190000f8]); 2012ff309c48cf48eec4599c9bf83f5b5cd802fa2db0Mark Lobodzinski } 2013ff309c48cf48eec4599c9bf83f5b5cd802fa2db0Mark Lobodzinski } 2014ff309c48cf48eec4599c9bf83f5b5cd802fa2db0Mark Lobodzinski } 20156a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski } 2016ff309c48cf48eec4599c9bf83f5b5cd802fa2db0Mark Lobodzinski 20176a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski // The formats of src_image and dst_image must be compatible. Formats are considered compatible if their texel size in bytes 20186a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski // is the same between both formats. For example, VK_FORMAT_R8G8B8A8_UNORM is compatible with VK_FORMAT_R32_UINT because 20196a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski // because both texels are 4 bytes in size. Depth/stencil formats must match exactly. 2020cf2ce8673669ca1111e333bdea272c4dd57cb5c2Dave Houlton if (FormatIsDepthOrStencil(src_image_state->createInfo.format) || FormatIsDepthOrStencil(dst_image_state->createInfo.format)) { 20216a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski if (src_image_state->createInfo.format != dst_image_state->createInfo.format) { 20226a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski char const str[] = "vkCmdCopyImage called with unmatched source and dest image depth/stencil formats."; 20239b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 20249b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(command_buffer), __LINE__, DRAWSTATE_MISMATCHED_IMAGE_FORMAT, "IMAGE", str); 20256a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski } 20266a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski } else { 202716769f6b2a7721e391952a97f010cbb530e4f211Dave Houlton size_t srcSize = FormatSize(src_image_state->createInfo.format); 202816769f6b2a7721e391952a97f010cbb530e4f211Dave Houlton size_t destSize = FormatSize(dst_image_state->createInfo.format); 20296a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski if (srcSize != destSize) { 20306a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski char const str[] = "vkCmdCopyImage called with unmatched source and dest image format sizes."; 20316a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 2032315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(command_buffer), __LINE__, VALIDATION_ERROR_1900010e, "IMAGE", "%s. %s", str, 2033315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_1900010e]); 2034ff309c48cf48eec4599c9bf83f5b5cd802fa2db0Mark Lobodzinski } 2035ff309c48cf48eec4599c9bf83f5b5cd802fa2db0Mark Lobodzinski } 20366a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski 203792c9c5dfbd0dec1d76ca18faa487fa8c2d302a65Dave Houlton // Source and dest image sample counts must match 203892c9c5dfbd0dec1d76ca18faa487fa8c2d302a65Dave Houlton if (src_image_state->createInfo.samples != dst_image_state->createInfo.samples) { 203992c9c5dfbd0dec1d76ca18faa487fa8c2d302a65Dave Houlton char const str[] = "vkCmdCopyImage() called on image pair with non-identical sample counts."; 204092c9c5dfbd0dec1d76ca18faa487fa8c2d302a65Dave Houlton skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 2041315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(command_buffer), __LINE__, VALIDATION_ERROR_19000110, "IMAGE", "%s %s", str, 2042315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_19000110]); 204392c9c5dfbd0dec1d76ca18faa487fa8c2d302a65Dave Houlton } 204492c9c5dfbd0dec1d76ca18faa487fa8c2d302a65Dave Houlton 2045315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= ValidateMemoryIsBoundToImage(device_data, src_image_state, "vkCmdCopyImage()", VALIDATION_ERROR_190000fe); 2046315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= ValidateMemoryIsBoundToImage(device_data, dst_image_state, "vkCmdCopyImage()", VALIDATION_ERROR_19000108); 20476a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski // Validate that SRC & DST images have correct usage flags set 2048315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= ValidateImageUsageFlags(device_data, src_image_state, VK_IMAGE_USAGE_TRANSFER_SRC_BIT, true, VALIDATION_ERROR_190000fc, 20496a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski "vkCmdCopyImage()", "VK_IMAGE_USAGE_TRANSFER_SRC_BIT"); 2050315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= ValidateImageUsageFlags(device_data, dst_image_state, VK_IMAGE_USAGE_TRANSFER_DST_BIT, true, VALIDATION_ERROR_19000106, 20516a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski "vkCmdCopyImage()", "VK_IMAGE_USAGE_TRANSFER_DST_BIT"); 2052baa50ccc5a8cf7a6f7474148f301802c5480e715Mike Schuchardt skip |= ValidateCmdQueueFlags(device_data, cb_node, "vkCmdCopyImage()", 2053315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis VK_QUEUE_TRANSFER_BIT | VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT, VALIDATION_ERROR_19002415); 20546a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski skip |= ValidateCmd(device_data, cb_node, CMD_COPYIMAGE, "vkCmdCopyImage()"); 2055315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= insideRenderPass(device_data, cb_node, "vkCmdCopyImage()", VALIDATION_ERROR_19000017); 20560db18ab1345f9e10907913b22ea5d57bd48077ebTobin Ehlis bool hit_error = false; 20576a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski for (uint32_t i = 0; i < region_count; ++i) { 2058fab4fd84d0d187bc73b5bc6709d8ed6370bb7cc3Tobin Ehlis skip |= VerifyImageLayout(device_data, cb_node, src_image_state, regions[i].srcSubresource, src_image_layout, 2059315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, "vkCmdCopyImage()", VALIDATION_ERROR_19000102, &hit_error); 2060fab4fd84d0d187bc73b5bc6709d8ed6370bb7cc3Tobin Ehlis skip |= VerifyImageLayout(device_data, cb_node, dst_image_state, regions[i].dstSubresource, dst_image_layout, 2061315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, "vkCmdCopyImage()", VALIDATION_ERROR_1900010c, &hit_error); 206278ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton skip |= ValidateCopyImageTransferGranularityRequirements(device_data, cb_node, src_image_state, dst_image_state, 206378ab91073f6d67b85f667f7f409390a93c2239e7Dave Houlton ®ions[i], i, "vkCmdCopyImage()"); 20646a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski } 20656a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski 2066ff309c48cf48eec4599c9bf83f5b5cd802fa2db0Mark Lobodzinski return skip; 2067ff309c48cf48eec4599c9bf83f5b5cd802fa2db0Mark Lobodzinski} 2068a6b0aebe9298e0dfc98174423f78bb7d06f1da97Mark Lobodzinski 20696a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinskivoid PreCallRecordCmdCopyImage(layer_data *device_data, GLOBAL_CB_NODE *cb_node, IMAGE_STATE *src_image_state, 2070a07ae8bd5f566eb9b073498dd4280efdb0b838b9Tobin Ehlis IMAGE_STATE *dst_image_state, uint32_t region_count, const VkImageCopy *regions, 2071a07ae8bd5f566eb9b073498dd4280efdb0b838b9Tobin Ehlis VkImageLayout src_image_layout, VkImageLayout dst_image_layout) { 2072a07ae8bd5f566eb9b073498dd4280efdb0b838b9Tobin Ehlis // Make sure that all image slices are updated to correct layout 2073a07ae8bd5f566eb9b073498dd4280efdb0b838b9Tobin Ehlis for (uint32_t i = 0; i < region_count; ++i) { 2074a07ae8bd5f566eb9b073498dd4280efdb0b838b9Tobin Ehlis SetImageLayout(device_data, cb_node, src_image_state, regions[i].srcSubresource, src_image_layout); 2075a07ae8bd5f566eb9b073498dd4280efdb0b838b9Tobin Ehlis SetImageLayout(device_data, cb_node, dst_image_state, regions[i].dstSubresource, dst_image_layout); 2076a07ae8bd5f566eb9b073498dd4280efdb0b838b9Tobin Ehlis } 20776a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski // Update bindings between images and cmd buffer 20786a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski AddCommandBufferBindingImage(device_data, cb_node, src_image_state); 20796a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski AddCommandBufferBindingImage(device_data, cb_node, dst_image_state); 20803f97578f1f51ffcb797a9feef4e5c8a600711a94Dave Houlton std::function<bool()> function = [=]() { return ValidateImageMemoryIsValid(device_data, src_image_state, "vkCmdCopyImage()"); }; 2081d807198f24437c1b2478ff1d06a33ce4873a1451Tobin Ehlis cb_node->queue_submit_functions.push_back(function); 20826a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski function = [=]() { 20836a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski SetImageMemoryValid(device_data, dst_image_state, true); 20846a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski return false; 20856a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski }; 2086d807198f24437c1b2478ff1d06a33ce4873a1451Tobin Ehlis cb_node->queue_submit_functions.push_back(function); 20876a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski} 20886a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski 2089a6b0aebe9298e0dfc98174423f78bb7d06f1da97Mark Lobodzinski// Returns true if sub_rect is entirely contained within rect 2090a6b0aebe9298e0dfc98174423f78bb7d06f1da97Mark Lobodzinskistatic inline bool ContainsRect(VkRect2D rect, VkRect2D sub_rect) { 2091a6b0aebe9298e0dfc98174423f78bb7d06f1da97Mark Lobodzinski if ((sub_rect.offset.x < rect.offset.x) || (sub_rect.offset.x + sub_rect.extent.width > rect.offset.x + rect.extent.width) || 2092a6b0aebe9298e0dfc98174423f78bb7d06f1da97Mark Lobodzinski (sub_rect.offset.y < rect.offset.y) || (sub_rect.offset.y + sub_rect.extent.height > rect.offset.y + rect.extent.height)) 2093a6b0aebe9298e0dfc98174423f78bb7d06f1da97Mark Lobodzinski return false; 2094a6b0aebe9298e0dfc98174423f78bb7d06f1da97Mark Lobodzinski return true; 2095a6b0aebe9298e0dfc98174423f78bb7d06f1da97Mark Lobodzinski} 2096a6b0aebe9298e0dfc98174423f78bb7d06f1da97Mark Lobodzinski 2097e40189d4deab674240cd9baf4c063bab4567c212Tobin Ehlisbool PreCallValidateCmdClearAttachments(layer_data *device_data, VkCommandBuffer commandBuffer, uint32_t attachmentCount, 2098e40189d4deab674240cd9baf4c063bab4567c212Tobin Ehlis const VkClearAttachment *pAttachments, uint32_t rectCount, const VkClearRect *pRects) { 20999a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis GLOBAL_CB_NODE *cb_node = GetCBNode(device_data, commandBuffer); 2100a6b0aebe9298e0dfc98174423f78bb7d06f1da97Mark Lobodzinski const debug_report_data *report_data = core_validation::GetReportData(device_data); 2101a6b0aebe9298e0dfc98174423f78bb7d06f1da97Mark Lobodzinski 2102a6b0aebe9298e0dfc98174423f78bb7d06f1da97Mark Lobodzinski bool skip = false; 2103a6b0aebe9298e0dfc98174423f78bb7d06f1da97Mark Lobodzinski if (cb_node) { 2104315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= ValidateCmdQueueFlags(device_data, cb_node, "vkCmdClearAttachments()", VK_QUEUE_GRAPHICS_BIT, 2105315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis VALIDATION_ERROR_18602415); 2106a6b0aebe9298e0dfc98174423f78bb7d06f1da97Mark Lobodzinski skip |= ValidateCmd(device_data, cb_node, CMD_CLEARATTACHMENTS, "vkCmdClearAttachments()"); 2107a6b0aebe9298e0dfc98174423f78bb7d06f1da97Mark Lobodzinski // Warn if this is issued prior to Draw Cmd and clearing the entire attachment 2108b68b13ed4952bce61f6ebb0023542660c26b0562Chris Forbes if (!cb_node->hasDrawCmd && (cb_node->activeRenderPassBeginInfo.renderArea.extent.width == pRects[0].rect.extent.width) && 2109a6b0aebe9298e0dfc98174423f78bb7d06f1da97Mark Lobodzinski (cb_node->activeRenderPassBeginInfo.renderArea.extent.height == pRects[0].rect.extent.height)) { 2110a6b0aebe9298e0dfc98174423f78bb7d06f1da97Mark Lobodzinski // There are times where app needs to use ClearAttachments (generally when reusing a buffer inside of a render pass) 21118e0190bd5904b8a8f044dae2c6ae23a891eb5e11Mark 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 21128e0190bd5904b8a8f044dae2c6ae23a891eb5e11Mark Lobodzinski // CmdClearAttachments. 21135f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton skip |= log_msg( 21145f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton report_data, VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 21155f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton HandleToUint64(commandBuffer), 0, DRAWSTATE_CLEAR_CMD_BEFORE_DRAW, "DS", 21165f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton "vkCmdClearAttachments() issued on command buffer object 0x%" PRIx64 21175f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton " prior to any Draw Cmds. It is recommended you use RenderPass LOAD_OP_CLEAR on Attachments prior to any Draw.", 21185f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton HandleToUint64(commandBuffer)); 2119a6b0aebe9298e0dfc98174423f78bb7d06f1da97Mark Lobodzinski } 2120315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= outsideRenderPass(device_data, cb_node, "vkCmdClearAttachments()", VALIDATION_ERROR_18600017); 2121a6b0aebe9298e0dfc98174423f78bb7d06f1da97Mark Lobodzinski } 2122a6b0aebe9298e0dfc98174423f78bb7d06f1da97Mark Lobodzinski 2123a6b0aebe9298e0dfc98174423f78bb7d06f1da97Mark Lobodzinski // Validate that attachment is in reference list of active subpass 2124a6b0aebe9298e0dfc98174423f78bb7d06f1da97Mark Lobodzinski if (cb_node->activeRenderPass) { 2125a6b0aebe9298e0dfc98174423f78bb7d06f1da97Mark Lobodzinski const VkRenderPassCreateInfo *renderpass_create_info = cb_node->activeRenderPass->createInfo.ptr(); 2126a6b0aebe9298e0dfc98174423f78bb7d06f1da97Mark Lobodzinski const VkSubpassDescription *subpass_desc = &renderpass_create_info->pSubpasses[cb_node->activeSubpass]; 21279a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto framebuffer = GetFramebufferState(device_data, cb_node->activeFramebuffer); 2128a6b0aebe9298e0dfc98174423f78bb7d06f1da97Mark Lobodzinski 2129a6b0aebe9298e0dfc98174423f78bb7d06f1da97Mark Lobodzinski for (uint32_t i = 0; i < attachmentCount; i++) { 2130a6b0aebe9298e0dfc98174423f78bb7d06f1da97Mark Lobodzinski auto clear_desc = &pAttachments[i]; 2131a6b0aebe9298e0dfc98174423f78bb7d06f1da97Mark Lobodzinski VkImageView image_view = VK_NULL_HANDLE; 2132a6b0aebe9298e0dfc98174423f78bb7d06f1da97Mark Lobodzinski 213373f044278acc4f663257c463f9032b603a5f1be7Mark Lobodzinski if (0 == clear_desc->aspectMask) { 213473f044278acc4f663257c463f9032b603a5f1be7Mark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 2135315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(commandBuffer), __LINE__, VALIDATION_ERROR_01c00c03, "IMAGE", "%s", 2136315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_01c00c03]); 213773f044278acc4f663257c463f9032b603a5f1be7Mark Lobodzinski } else if (clear_desc->aspectMask & VK_IMAGE_ASPECT_METADATA_BIT) { 213873f044278acc4f663257c463f9032b603a5f1be7Mark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 2139315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(commandBuffer), __LINE__, VALIDATION_ERROR_01c00028, "IMAGE", "%s", 2140315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_01c00028]); 214173f044278acc4f663257c463f9032b603a5f1be7Mark Lobodzinski } else if (clear_desc->aspectMask & VK_IMAGE_ASPECT_COLOR_BIT) { 2142a6b0aebe9298e0dfc98174423f78bb7d06f1da97Mark Lobodzinski if (clear_desc->colorAttachment >= subpass_desc->colorAttachmentCount) { 2143315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 2144315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(commandBuffer), __LINE__, VALIDATION_ERROR_1860001e, "DS", 2145315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis "vkCmdClearAttachments() color attachment index %d out of range for active subpass %d. %s", 2146315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis clear_desc->colorAttachment, cb_node->activeSubpass, 2147315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_1860001e]); 2148a6b0aebe9298e0dfc98174423f78bb7d06f1da97Mark Lobodzinski } else if (subpass_desc->pColorAttachments[clear_desc->colorAttachment].attachment == VK_ATTACHMENT_UNUSED) { 2149a6b0aebe9298e0dfc98174423f78bb7d06f1da97Mark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT, 21509b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, HandleToUint64(commandBuffer), __LINE__, 21519b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus DRAWSTATE_MISSING_ATTACHMENT_REFERENCE, "DS", 215273f044278acc4f663257c463f9032b603a5f1be7Mark Lobodzinski "vkCmdClearAttachments() color attachment index %d is VK_ATTACHMENT_UNUSED; ignored.", 215373f044278acc4f663257c463f9032b603a5f1be7Mark Lobodzinski clear_desc->colorAttachment); 2154a6b0aebe9298e0dfc98174423f78bb7d06f1da97Mark Lobodzinski } else { 2155a6b0aebe9298e0dfc98174423f78bb7d06f1da97Mark Lobodzinski image_view = framebuffer->createInfo 215673f044278acc4f663257c463f9032b603a5f1be7Mark Lobodzinski .pAttachments[subpass_desc->pColorAttachments[clear_desc->colorAttachment].attachment]; 2157a6b0aebe9298e0dfc98174423f78bb7d06f1da97Mark Lobodzinski } 215873f044278acc4f663257c463f9032b603a5f1be7Mark Lobodzinski if ((clear_desc->aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT) || 215973f044278acc4f663257c463f9032b603a5f1be7Mark Lobodzinski (clear_desc->aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT)) { 216073f044278acc4f663257c463f9032b603a5f1be7Mark Lobodzinski char const str[] = 216173f044278acc4f663257c463f9032b603a5f1be7Mark Lobodzinski "vkCmdClearAttachments aspectMask [%d] must set only VK_IMAGE_ASPECT_COLOR_BIT of a color attachment. %s"; 216273f044278acc4f663257c463f9032b603a5f1be7Mark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 2163315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(commandBuffer), __LINE__, VALIDATION_ERROR_01c00026, "IMAGE", str, i, 2164315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_01c00026]); 216573f044278acc4f663257c463f9032b603a5f1be7Mark Lobodzinski } 216673f044278acc4f663257c463f9032b603a5f1be7Mark Lobodzinski } else { // Must be depth and/or stencil 216773f044278acc4f663257c463f9032b603a5f1be7Mark Lobodzinski if (((clear_desc->aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT) != VK_IMAGE_ASPECT_DEPTH_BIT) && 216873f044278acc4f663257c463f9032b603a5f1be7Mark Lobodzinski ((clear_desc->aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT) != VK_IMAGE_ASPECT_STENCIL_BIT)) { 216973f044278acc4f663257c463f9032b603a5f1be7Mark Lobodzinski char const str[] = "vkCmdClearAttachments aspectMask [%d] is not a valid combination of bits. %s"; 217073f044278acc4f663257c463f9032b603a5f1be7Mark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 2171315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(commandBuffer), __LINE__, VALIDATION_ERROR_01c00c01, "IMAGE", str, i, 2172315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_01c00c01]); 217373f044278acc4f663257c463f9032b603a5f1be7Mark Lobodzinski } 217473f044278acc4f663257c463f9032b603a5f1be7Mark Lobodzinski if (!subpass_desc->pDepthStencilAttachment || 217573f044278acc4f663257c463f9032b603a5f1be7Mark Lobodzinski (subpass_desc->pDepthStencilAttachment->attachment == VK_ATTACHMENT_UNUSED)) { 217673f044278acc4f663257c463f9032b603a5f1be7Mark Lobodzinski skip |= log_msg( 217773f044278acc4f663257c463f9032b603a5f1be7Mark Lobodzinski report_data, VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 21789b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(commandBuffer), __LINE__, DRAWSTATE_MISSING_ATTACHMENT_REFERENCE, "DS", 217973f044278acc4f663257c463f9032b603a5f1be7Mark Lobodzinski "vkCmdClearAttachments() depth/stencil clear with no depth/stencil attachment in subpass; ignored"); 2180a6b0aebe9298e0dfc98174423f78bb7d06f1da97Mark Lobodzinski } else { 2181a6b0aebe9298e0dfc98174423f78bb7d06f1da97Mark Lobodzinski image_view = framebuffer->createInfo.pAttachments[subpass_desc->pDepthStencilAttachment->attachment]; 2182a6b0aebe9298e0dfc98174423f78bb7d06f1da97Mark Lobodzinski } 2183a6b0aebe9298e0dfc98174423f78bb7d06f1da97Mark Lobodzinski } 2184a6b0aebe9298e0dfc98174423f78bb7d06f1da97Mark Lobodzinski if (image_view) { 21859a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto image_view_state = GetImageViewState(device_data, image_view); 2186a6b0aebe9298e0dfc98174423f78bb7d06f1da97Mark Lobodzinski for (uint32_t j = 0; j < rectCount; j++) { 218773f044278acc4f663257c463f9032b603a5f1be7Mark Lobodzinski // The rectangular region specified by a given element of pRects must be contained within the render area of 218873f044278acc4f663257c463f9032b603a5f1be7Mark Lobodzinski // the current render pass instance 21898e0190bd5904b8a8f044dae2c6ae23a891eb5e11Mark Lobodzinski // TODO: This check should be moved to CmdExecuteCommands or QueueSubmit to cover secondary CB cases 21908e0190bd5904b8a8f044dae2c6ae23a891eb5e11Mark Lobodzinski if ((cb_node->createInfo.level == VK_COMMAND_BUFFER_LEVEL_PRIMARY) && 21918e0190bd5904b8a8f044dae2c6ae23a891eb5e11Mark Lobodzinski (false == ContainsRect(cb_node->activeRenderPassBeginInfo.renderArea, pRects[j].rect))) { 2192fdc75c21ced997fbbc180734bef87bf6d5811d4bMark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 2193315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(commandBuffer), __LINE__, VALIDATION_ERROR_18600020, "DS", 219473f044278acc4f663257c463f9032b603a5f1be7Mark Lobodzinski "vkCmdClearAttachments(): The area defined by pRects[%d] is not contained in the area of " 219573f044278acc4f663257c463f9032b603a5f1be7Mark Lobodzinski "the current render pass instance. %s", 2196315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis j, validation_error_map[VALIDATION_ERROR_18600020]); 2197a6b0aebe9298e0dfc98174423f78bb7d06f1da97Mark Lobodzinski } 2198a6b0aebe9298e0dfc98174423f78bb7d06f1da97Mark Lobodzinski // The layers specified by a given element of pRects must be contained within every attachment that 2199a6b0aebe9298e0dfc98174423f78bb7d06f1da97Mark Lobodzinski // pAttachments refers to 2200a6b0aebe9298e0dfc98174423f78bb7d06f1da97Mark Lobodzinski auto attachment_layer_count = image_view_state->create_info.subresourceRange.layerCount; 22010025f5cb69a4e6457254db9b93da4f30b86413f2Dave Houlton if ((pRects[j].baseArrayLayer >= attachment_layer_count) || 22020025f5cb69a4e6457254db9b93da4f30b86413f2Dave Houlton (pRects[j].baseArrayLayer + pRects[j].layerCount > attachment_layer_count)) { 22035f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 22045f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton HandleToUint64(commandBuffer), __LINE__, VALIDATION_ERROR_18600022, "DS", 22055f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton "vkCmdClearAttachments(): The layers defined in pRects[%d] are not contained in the layers " 22065f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton "of pAttachment[%d]. %s", 22075f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton j, i, validation_error_map[VALIDATION_ERROR_18600022]); 2208a6b0aebe9298e0dfc98174423f78bb7d06f1da97Mark Lobodzinski } 2209a6b0aebe9298e0dfc98174423f78bb7d06f1da97Mark Lobodzinski } 2210a6b0aebe9298e0dfc98174423f78bb7d06f1da97Mark Lobodzinski } 2211a6b0aebe9298e0dfc98174423f78bb7d06f1da97Mark Lobodzinski } 2212a6b0aebe9298e0dfc98174423f78bb7d06f1da97Mark Lobodzinski } 2213a6b0aebe9298e0dfc98174423f78bb7d06f1da97Mark Lobodzinski return skip; 221460568995aca225f81acda8ce40cfabbea2c19397Mark Lobodzinski} 221560568995aca225f81acda8ce40cfabbea2c19397Mark Lobodzinski 2216e40189d4deab674240cd9baf4c063bab4567c212Tobin Ehlisbool PreCallValidateCmdResolveImage(layer_data *device_data, GLOBAL_CB_NODE *cb_node, IMAGE_STATE *src_image_state, 221754c03b0fa365789b242e680223bd30c940f1abb3Mark Lobodzinski IMAGE_STATE *dst_image_state, uint32_t regionCount, const VkImageResolve *pRegions) { 221825f7873c9ce3ed39d18bba8750d7538905e150dfMark Lobodzinski const debug_report_data *report_data = core_validation::GetReportData(device_data); 221960568995aca225f81acda8ce40cfabbea2c19397Mark Lobodzinski bool skip = false; 222060568995aca225f81acda8ce40cfabbea2c19397Mark Lobodzinski if (cb_node && src_image_state && dst_image_state) { 2221315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= ValidateMemoryIsBoundToImage(device_data, src_image_state, "vkCmdResolveImage()", VALIDATION_ERROR_1c800200); 2222315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= ValidateMemoryIsBoundToImage(device_data, dst_image_state, "vkCmdResolveImage()", VALIDATION_ERROR_1c800204); 2223315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= 2224315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis ValidateCmdQueueFlags(device_data, cb_node, "vkCmdResolveImage()", VK_QUEUE_GRAPHICS_BIT, VALIDATION_ERROR_1c802415); 222560568995aca225f81acda8ce40cfabbea2c19397Mark Lobodzinski skip |= ValidateCmd(device_data, cb_node, CMD_RESOLVEIMAGE, "vkCmdResolveImage()"); 2226315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= insideRenderPass(device_data, cb_node, "vkCmdResolveImage()", VALIDATION_ERROR_1c800017); 222725f7873c9ce3ed39d18bba8750d7538905e150dfMark Lobodzinski 222825f7873c9ce3ed39d18bba8750d7538905e150dfMark Lobodzinski // For each region, the number of layers in the image subresource should not be zero 222925f7873c9ce3ed39d18bba8750d7538905e150dfMark Lobodzinski // For each region, src and dest image aspect must be color only 223025f7873c9ce3ed39d18bba8750d7538905e150dfMark Lobodzinski for (uint32_t i = 0; i < regionCount; i++) { 223125f7873c9ce3ed39d18bba8750d7538905e150dfMark Lobodzinski if (pRegions[i].srcSubresource.layerCount == 0) { 223225f7873c9ce3ed39d18bba8750d7538905e150dfMark Lobodzinski char const str[] = "vkCmdResolveImage: number of layers in source subresource is zero"; 223354c03b0fa365789b242e680223bd30c940f1abb3Mark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 22349b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(cb_node->commandBuffer), __LINE__, DRAWSTATE_MISMATCHED_IMAGE_ASPECT, "IMAGE", str); 223525f7873c9ce3ed39d18bba8750d7538905e150dfMark Lobodzinski } 223625f7873c9ce3ed39d18bba8750d7538905e150dfMark Lobodzinski if (pRegions[i].dstSubresource.layerCount == 0) { 223725f7873c9ce3ed39d18bba8750d7538905e150dfMark Lobodzinski char const str[] = "vkCmdResolveImage: number of layers in destination subresource is zero"; 223854c03b0fa365789b242e680223bd30c940f1abb3Mark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 22399b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(cb_node->commandBuffer), __LINE__, DRAWSTATE_MISMATCHED_IMAGE_ASPECT, "IMAGE", str); 224025f7873c9ce3ed39d18bba8750d7538905e150dfMark Lobodzinski } 224154c03b0fa365789b242e680223bd30c940f1abb3Mark Lobodzinski if (pRegions[i].srcSubresource.layerCount != pRegions[i].dstSubresource.layerCount) { 224254c03b0fa365789b242e680223bd30c940f1abb3Mark Lobodzinski skip |= log_msg( 224354c03b0fa365789b242e680223bd30c940f1abb3Mark Lobodzinski report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 2244315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(cb_node->commandBuffer), __LINE__, VALIDATION_ERROR_0a200216, "IMAGE", 224554c03b0fa365789b242e680223bd30c940f1abb3Mark Lobodzinski "vkCmdResolveImage: layerCount in source and destination subresource of pRegions[%d] does not match. %s", i, 2246315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_0a200216]); 224754c03b0fa365789b242e680223bd30c940f1abb3Mark Lobodzinski } 224825f7873c9ce3ed39d18bba8750d7538905e150dfMark Lobodzinski if ((pRegions[i].srcSubresource.aspectMask != VK_IMAGE_ASPECT_COLOR_BIT) || 224925f7873c9ce3ed39d18bba8750d7538905e150dfMark Lobodzinski (pRegions[i].dstSubresource.aspectMask != VK_IMAGE_ASPECT_COLOR_BIT)) { 225025f7873c9ce3ed39d18bba8750d7538905e150dfMark Lobodzinski char const str[] = 225125f7873c9ce3ed39d18bba8750d7538905e150dfMark Lobodzinski "vkCmdResolveImage: src and dest aspectMasks for each region must specify only VK_IMAGE_ASPECT_COLOR_BIT"; 225225f7873c9ce3ed39d18bba8750d7538905e150dfMark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 2253315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(cb_node->commandBuffer), __LINE__, VALIDATION_ERROR_0a200214, "IMAGE", "%s. %s", str, 2254315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_0a200214]); 225525f7873c9ce3ed39d18bba8750d7538905e150dfMark Lobodzinski } 225625f7873c9ce3ed39d18bba8750d7538905e150dfMark Lobodzinski } 225725f7873c9ce3ed39d18bba8750d7538905e150dfMark Lobodzinski 225825f7873c9ce3ed39d18bba8750d7538905e150dfMark Lobodzinski if (src_image_state->createInfo.format != dst_image_state->createInfo.format) { 225925f7873c9ce3ed39d18bba8750d7538905e150dfMark Lobodzinski char const str[] = "vkCmdResolveImage called with unmatched source and dest formats."; 226054c03b0fa365789b242e680223bd30c940f1abb3Mark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 22619b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(cb_node->commandBuffer), __LINE__, DRAWSTATE_MISMATCHED_IMAGE_FORMAT, "IMAGE", str); 226225f7873c9ce3ed39d18bba8750d7538905e150dfMark Lobodzinski } 226325f7873c9ce3ed39d18bba8750d7538905e150dfMark Lobodzinski if (src_image_state->createInfo.imageType != dst_image_state->createInfo.imageType) { 226425f7873c9ce3ed39d18bba8750d7538905e150dfMark Lobodzinski char const str[] = "vkCmdResolveImage called with unmatched source and dest image types."; 226554c03b0fa365789b242e680223bd30c940f1abb3Mark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 22669b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(cb_node->commandBuffer), __LINE__, DRAWSTATE_MISMATCHED_IMAGE_TYPE, "IMAGE", str); 226725f7873c9ce3ed39d18bba8750d7538905e150dfMark Lobodzinski } 226825f7873c9ce3ed39d18bba8750d7538905e150dfMark Lobodzinski if (src_image_state->createInfo.samples == VK_SAMPLE_COUNT_1_BIT) { 226925f7873c9ce3ed39d18bba8750d7538905e150dfMark Lobodzinski char const str[] = "vkCmdResolveImage called with source sample count less than 2."; 227025f7873c9ce3ed39d18bba8750d7538905e150dfMark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 2271315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(cb_node->commandBuffer), __LINE__, VALIDATION_ERROR_1c800202, "IMAGE", "%s. %s", str, 2272315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_1c800202]); 227325f7873c9ce3ed39d18bba8750d7538905e150dfMark Lobodzinski } 227425f7873c9ce3ed39d18bba8750d7538905e150dfMark Lobodzinski if (dst_image_state->createInfo.samples != VK_SAMPLE_COUNT_1_BIT) { 227525f7873c9ce3ed39d18bba8750d7538905e150dfMark Lobodzinski char const str[] = "vkCmdResolveImage called with dest sample count greater than 1."; 227625f7873c9ce3ed39d18bba8750d7538905e150dfMark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 2277315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(cb_node->commandBuffer), __LINE__, VALIDATION_ERROR_1c800206, "IMAGE", "%s. %s", str, 2278315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_1c800206]); 227925f7873c9ce3ed39d18bba8750d7538905e150dfMark Lobodzinski } 228087a57d8e822316de46ee97f514187331b1f4f09dTobin Ehlis // TODO: Need to validate image layouts, which will include layout validation for shared presentable images 228160568995aca225f81acda8ce40cfabbea2c19397Mark Lobodzinski } else { 228260568995aca225f81acda8ce40cfabbea2c19397Mark Lobodzinski assert(0); 228360568995aca225f81acda8ce40cfabbea2c19397Mark Lobodzinski } 228460568995aca225f81acda8ce40cfabbea2c19397Mark Lobodzinski return skip; 228560568995aca225f81acda8ce40cfabbea2c19397Mark Lobodzinski} 228660568995aca225f81acda8ce40cfabbea2c19397Mark Lobodzinski 2287e40189d4deab674240cd9baf4c063bab4567c212Tobin Ehlisvoid PreCallRecordCmdResolveImage(layer_data *device_data, GLOBAL_CB_NODE *cb_node, IMAGE_STATE *src_image_state, 2288e40189d4deab674240cd9baf4c063bab4567c212Tobin Ehlis IMAGE_STATE *dst_image_state) { 228960568995aca225f81acda8ce40cfabbea2c19397Mark Lobodzinski // Update bindings between images and cmd buffer 229060568995aca225f81acda8ce40cfabbea2c19397Mark Lobodzinski AddCommandBufferBindingImage(device_data, cb_node, src_image_state); 229160568995aca225f81acda8ce40cfabbea2c19397Mark Lobodzinski AddCommandBufferBindingImage(device_data, cb_node, dst_image_state); 229260568995aca225f81acda8ce40cfabbea2c19397Mark Lobodzinski 229360568995aca225f81acda8ce40cfabbea2c19397Mark Lobodzinski std::function<bool()> function = [=]() { 229460568995aca225f81acda8ce40cfabbea2c19397Mark Lobodzinski return ValidateImageMemoryIsValid(device_data, src_image_state, "vkCmdResolveImage()"); 229560568995aca225f81acda8ce40cfabbea2c19397Mark Lobodzinski }; 2296d807198f24437c1b2478ff1d06a33ce4873a1451Tobin Ehlis cb_node->queue_submit_functions.push_back(function); 229760568995aca225f81acda8ce40cfabbea2c19397Mark Lobodzinski function = [=]() { 229860568995aca225f81acda8ce40cfabbea2c19397Mark Lobodzinski SetImageMemoryValid(device_data, dst_image_state, true); 229960568995aca225f81acda8ce40cfabbea2c19397Mark Lobodzinski return false; 230060568995aca225f81acda8ce40cfabbea2c19397Mark Lobodzinski }; 2301d807198f24437c1b2478ff1d06a33ce4873a1451Tobin Ehlis cb_node->queue_submit_functions.push_back(function); 230260568995aca225f81acda8ce40cfabbea2c19397Mark Lobodzinski} 230360568995aca225f81acda8ce40cfabbea2c19397Mark Lobodzinski 2304e40189d4deab674240cd9baf4c063bab4567c212Tobin Ehlisbool PreCallValidateCmdBlitImage(layer_data *device_data, GLOBAL_CB_NODE *cb_node, IMAGE_STATE *src_image_state, 2305a99ceeafb2acc8ef0e18af2d1b24d5e1e68d5ee3Norbert Garnys IMAGE_STATE *dst_image_state, uint32_t region_count, const VkImageBlit *regions, 2306a99ceeafb2acc8ef0e18af2d1b24d5e1e68d5ee3Norbert Garnys VkImageLayout src_image_layout, VkImageLayout dst_image_layout, VkFilter filter) { 2307055112ec99304db71d55b69a60e1da14e8af8f60Mark Lobodzinski const debug_report_data *report_data = core_validation::GetReportData(device_data); 2308055112ec99304db71d55b69a60e1da14e8af8f60Mark Lobodzinski 230960568995aca225f81acda8ce40cfabbea2c19397Mark Lobodzinski bool skip = false; 2310647670f9a4a7942fa16b9ffa8f0086c9bd9c1235John Zulauf if (cb_node) { 2311647670f9a4a7942fa16b9ffa8f0086c9bd9c1235John Zulauf skip |= ValidateCmd(device_data, cb_node, CMD_BLITIMAGE, "vkCmdBlitImage()"); 2312647670f9a4a7942fa16b9ffa8f0086c9bd9c1235John Zulauf } 231360568995aca225f81acda8ce40cfabbea2c19397Mark Lobodzinski if (cb_node && src_image_state && dst_image_state) { 231460568995aca225f81acda8ce40cfabbea2c19397Mark Lobodzinski skip |= ValidateImageSampleCount(device_data, src_image_state, VK_SAMPLE_COUNT_1_BIT, "vkCmdBlitImage(): srcImage", 2315315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis VALIDATION_ERROR_184001d2); 231660568995aca225f81acda8ce40cfabbea2c19397Mark Lobodzinski skip |= ValidateImageSampleCount(device_data, dst_image_state, VK_SAMPLE_COUNT_1_BIT, "vkCmdBlitImage(): dstImage", 2317315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis VALIDATION_ERROR_184001d4); 2318315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= ValidateMemoryIsBoundToImage(device_data, src_image_state, "vkCmdBlitImage()", VALIDATION_ERROR_184001b8); 2319315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= ValidateMemoryIsBoundToImage(device_data, dst_image_state, "vkCmdBlitImage()", VALIDATION_ERROR_184001c2); 2320315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= ValidateImageUsageFlags(device_data, src_image_state, VK_IMAGE_USAGE_TRANSFER_SRC_BIT, true, 2321315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis VALIDATION_ERROR_184001b6, "vkCmdBlitImage()", "VK_IMAGE_USAGE_TRANSFER_SRC_BIT"); 2322315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= ValidateImageUsageFlags(device_data, dst_image_state, VK_IMAGE_USAGE_TRANSFER_DST_BIT, true, 2323315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis VALIDATION_ERROR_184001c0, "vkCmdBlitImage()", "VK_IMAGE_USAGE_TRANSFER_DST_BIT"); 2324315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= ValidateCmdQueueFlags(device_data, cb_node, "vkCmdBlitImage()", VK_QUEUE_GRAPHICS_BIT, VALIDATION_ERROR_18402415); 232560568995aca225f81acda8ce40cfabbea2c19397Mark Lobodzinski skip |= ValidateCmd(device_data, cb_node, CMD_BLITIMAGE, "vkCmdBlitImage()"); 2326315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= insideRenderPass(device_data, cb_node, "vkCmdBlitImage()", VALIDATION_ERROR_18400017); 232787a57d8e822316de46ee97f514187331b1f4f09dTobin Ehlis // TODO: Need to validate image layouts, which will include layout validation for shared presentable images 2328055112ec99304db71d55b69a60e1da14e8af8f60Mark Lobodzinski 23291007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton VkFormat src_format = src_image_state->createInfo.format; 23301007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton VkFormat dst_format = dst_image_state->createInfo.format; 23311007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton VkImageType src_type = src_image_state->createInfo.imageType; 23321007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton VkImageType dst_type = dst_image_state->createInfo.imageType; 23331007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton 233457f0da98098689f3624c5503cfe1a4b5fede885aJeremy Kniager VkFormatProperties props = GetFormatProperties(device_data, src_format); 23351007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton VkImageTiling tiling = src_image_state->createInfo.tiling; 23365f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton VkFormatFeatureFlags flags = (tiling == VK_IMAGE_TILING_LINEAR ? props.linearTilingFeatures : props.optimalTilingFeatures); 23371007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton if (VK_FORMAT_FEATURE_BLIT_SRC_BIT != (flags & VK_FORMAT_FEATURE_BLIT_SRC_BIT)) { 23381007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 23391007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton HandleToUint64(cb_node->commandBuffer), __LINE__, VALIDATION_ERROR_184001b4, "IMAGE", 23401007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton "vkCmdBlitImage: source image format %s does not support VK_FORMAT_FEATURE_BLIT_SRC_BIT feature. %s", 23411007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton string_VkFormat(src_format), validation_error_map[VALIDATION_ERROR_184001b4]); 23421007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton } 23431007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton 23441007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton if ((VK_FILTER_LINEAR == filter) && 23451007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton (VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT != (flags & VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT))) { 23461007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 23471007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton HandleToUint64(cb_node->commandBuffer), __LINE__, VALIDATION_ERROR_184001d6, "IMAGE", 23481007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton "vkCmdBlitImage: source image format %s does not support linear filtering. %s", 23491007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton string_VkFormat(src_format), validation_error_map[VALIDATION_ERROR_184001d6]); 23501007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton } 23511007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton 23521007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton if ((VK_FILTER_CUBIC_IMG == filter) && (VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_CUBIC_BIT_IMG != 23531007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton (flags & VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_CUBIC_BIT_IMG))) { 23541007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 23551007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton HandleToUint64(cb_node->commandBuffer), __LINE__, VALIDATION_ERROR_184001d8, "IMAGE", 23561007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton "vkCmdBlitImage: source image format %s does not support cubic filtering. %s", 23571007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton string_VkFormat(src_format), validation_error_map[VALIDATION_ERROR_184001d8]); 23581007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton } 23591007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton 23601007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton if ((VK_FILTER_CUBIC_IMG == filter) && (VK_IMAGE_TYPE_3D != src_type)) { 23611007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 23621007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton HandleToUint64(cb_node->commandBuffer), __LINE__, VALIDATION_ERROR_184001da, "IMAGE", 23631007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton "vkCmdBlitImage: source image type must be VK_IMAGE_TYPE_3D when cubic filtering is specified. %s", 23641007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton validation_error_map[VALIDATION_ERROR_184001da]); 23651007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton } 23661007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton 23671007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton props = GetFormatProperties(device_data, dst_format); 23681007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton tiling = dst_image_state->createInfo.tiling; 236957f0da98098689f3624c5503cfe1a4b5fede885aJeremy Kniager flags = (tiling == VK_IMAGE_TILING_LINEAR ? props.linearTilingFeatures : props.optimalTilingFeatures); 23701007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton if (VK_FORMAT_FEATURE_BLIT_DST_BIT != (flags & VK_FORMAT_FEATURE_BLIT_DST_BIT)) { 23711007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton skip |= 23721007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 23731007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton HandleToUint64(cb_node->commandBuffer), __LINE__, VALIDATION_ERROR_184001be, "IMAGE", 23741007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton "vkCmdBlitImage: destination image format %s does not support VK_FORMAT_FEATURE_BLIT_DST_BIT feature. %s", 23751007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton string_VkFormat(dst_format), validation_error_map[VALIDATION_ERROR_184001be]); 23761007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton } 23771007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton 23781007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton if ((VK_SAMPLE_COUNT_1_BIT != src_image_state->createInfo.samples) || 23791007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton (VK_SAMPLE_COUNT_1_BIT != dst_image_state->createInfo.samples)) { 23801007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 23811007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton HandleToUint64(cb_node->commandBuffer), __LINE__, VALIDATION_ERROR_184001c8, "IMAGE", 23821007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton "vkCmdBlitImage: source or dest image has sample count other than VK_SAMPLE_COUNT_1_BIT. %s", 23831007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton validation_error_map[VALIDATION_ERROR_184001c8]); 23841007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton } 23851007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton 23861007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton // Validate consistency for unsigned formats 23871007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton if (FormatIsUInt(src_format) != FormatIsUInt(dst_format)) { 23881007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton std::stringstream ss; 23891007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton ss << "vkCmdBlitImage: If one of srcImage and dstImage images has unsigned integer format, " 23901007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton << "the other one must also have unsigned integer format. " 23911007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton << "Source format is " << string_VkFormat(src_format) << " Destination format is " << string_VkFormat(dst_format); 23921007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 23931007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton HandleToUint64(cb_node->commandBuffer), __LINE__, VALIDATION_ERROR_184001cc, "IMAGE", "%s. %s", 23941007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton ss.str().c_str(), validation_error_map[VALIDATION_ERROR_184001cc]); 23951007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton } 23961007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton 23971007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton // Validate consistency for signed formats 23981007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton if (FormatIsSInt(src_format) != FormatIsSInt(dst_format)) { 23991007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton std::stringstream ss; 24001007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton ss << "vkCmdBlitImage: If one of srcImage and dstImage images has signed integer format, " 24011007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton << "the other one must also have signed integer format. " 24021007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton << "Source format is " << string_VkFormat(src_format) << " Destination format is " << string_VkFormat(dst_format); 24031007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 24041007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton HandleToUint64(cb_node->commandBuffer), __LINE__, VALIDATION_ERROR_184001ca, "IMAGE", "%s. %s", 24051007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton ss.str().c_str(), validation_error_map[VALIDATION_ERROR_184001ca]); 24061007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton } 24071007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton 24081007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton // Validate filter for Depth/Stencil formats 24091007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton if (FormatIsDepthOrStencil(src_format) && (filter != VK_FILTER_NEAREST)) { 24101007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton std::stringstream ss; 24111007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton ss << "vkCmdBlitImage: If the format of srcImage is a depth, stencil, or depth stencil " 24121007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton << "then filter must be VK_FILTER_NEAREST."; 24131007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 24141007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton HandleToUint64(cb_node->commandBuffer), __LINE__, VALIDATION_ERROR_184001d0, "IMAGE", "%s. %s", 24151007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton ss.str().c_str(), validation_error_map[VALIDATION_ERROR_184001d0]); 24161007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton } 24171007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton 24181007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton // Validate aspect bits and formats for depth/stencil images 24191007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton if (FormatIsDepthOrStencil(src_format) || FormatIsDepthOrStencil(dst_format)) { 24201007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton if (src_format != dst_format) { 24211007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton std::stringstream ss; 24221007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton ss << "vkCmdBlitImage: If one of srcImage and dstImage images has a format of depth, stencil or depth " 24231007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton << "stencil, the other one must have exactly the same format. " 24241007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton << "Source format is " << string_VkFormat(src_format) << " Destination format is " 24251007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton << string_VkFormat(dst_format); 24261007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 24271007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton HandleToUint64(cb_node->commandBuffer), __LINE__, VALIDATION_ERROR_184001ce, "IMAGE", "%s. %s", 24281007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton ss.str().c_str(), validation_error_map[VALIDATION_ERROR_184001ce]); 24291007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton } 24301007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton 24311007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton#if 0 // TODO: Cannot find VU statements or spec language for these in CmdBlitImage. Verify or remove. 24321007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton for (uint32_t i = 0; i < regionCount; i++) { 24331007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton VkImageAspectFlags srcAspect = pRegions[i].srcSubresource.aspectMask; 24341007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton 24351007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton if (FormatIsDepthAndStencil(src_format)) { 24361007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton if ((srcAspect != VK_IMAGE_ASPECT_DEPTH_BIT) && (srcAspect != VK_IMAGE_ASPECT_STENCIL_BIT)) { 24371007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton std::stringstream ss; 24385f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton ss << "vkCmdBlitImage: Combination depth/stencil image formats must have only one of VK_IMAGE_ASPECT_DEPTH_BIT " 24391007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton << "and VK_IMAGE_ASPECT_STENCIL_BIT set in srcImage and dstImage"; 24401007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 24411007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton HandleToUint64(cb_node->commandBuffer), __LINE__, DRAWSTATE_INVALID_IMAGE_ASPECT, "IMAGE", 24421007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton "%s", ss.str().c_str()); 24431007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton } 24441007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton } 24451007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton else if (FormatIsStencilOnly(src_format)) { 24461007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton if (srcAspect != VK_IMAGE_ASPECT_STENCIL_BIT) { 24471007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton std::stringstream ss; 24481007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton ss << "vkCmdBlitImage: Stencil-only image formats must have only the VK_IMAGE_ASPECT_STENCIL_BIT " 24491007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton << "set in both the srcImage and dstImage"; 24501007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 24511007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton HandleToUint64(cb_node->commandBuffer), __LINE__, DRAWSTATE_INVALID_IMAGE_ASPECT, "IMAGE", 24521007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton "%s", ss.str().c_str()); 24531007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton } 24541007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton } 24551007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton else if (FormatIsDepthOnly(src_format)) { 24561007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton if (srcAspect != VK_IMAGE_ASPECT_DEPTH_BIT) { 24571007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton std::stringstream ss; 24581007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton ss << "vkCmdBlitImage: Depth-only image formats must have only the VK_IMAGE_ASPECT_DEPTH " 24591007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton << "set in both the srcImage and dstImage"; 24601007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 24611007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton HandleToUint64(cb_node->commandBuffer), __LINE__, DRAWSTATE_INVALID_IMAGE_ASPECT, "IMAGE", 24621007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton "%s", ss.str().c_str()); 24631007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton } 24641007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton } 24651007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton } 24661007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton#endif 24671007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton } // Depth or Stencil 24681007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton 24691007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton // Do per-region checks 2470a99ceeafb2acc8ef0e18af2d1b24d5e1e68d5ee3Norbert Garnys for (uint32_t i = 0; i < region_count; i++) { 2471a99ceeafb2acc8ef0e18af2d1b24d5e1e68d5ee3Norbert Garnys const VkImageBlit rgn = regions[i]; 2472a99ceeafb2acc8ef0e18af2d1b24d5e1e68d5ee3Norbert Garnys bool hit_error = false; 2473a99ceeafb2acc8ef0e18af2d1b24d5e1e68d5ee3Norbert Garnys skip |= 2474a99ceeafb2acc8ef0e18af2d1b24d5e1e68d5ee3Norbert Garnys VerifyImageLayout(device_data, cb_node, src_image_state, rgn.srcSubresource, src_image_layout, 2475a99ceeafb2acc8ef0e18af2d1b24d5e1e68d5ee3Norbert Garnys VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, "vkCmdBlitImage()", VALIDATION_ERROR_184001bc, &hit_error); 2476a99ceeafb2acc8ef0e18af2d1b24d5e1e68d5ee3Norbert Garnys skip |= 2477a99ceeafb2acc8ef0e18af2d1b24d5e1e68d5ee3Norbert Garnys VerifyImageLayout(device_data, cb_node, dst_image_state, rgn.dstSubresource, dst_image_layout, 2478a99ceeafb2acc8ef0e18af2d1b24d5e1e68d5ee3Norbert Garnys VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, "vkCmdBlitImage()", VALIDATION_ERROR_184001c6, &hit_error); 247943a02ff3ea4bf0a6d308abc05dd5f4346bc13311Dave Houlton 2480d81f107590290d41d3e39fcbf3f077658be0f5a6Mark Lobodzinski // Warn for zero-sized regions 248143a02ff3ea4bf0a6d308abc05dd5f4346bc13311Dave Houlton if ((rgn.srcOffsets[0].x == rgn.srcOffsets[1].x) || (rgn.srcOffsets[0].y == rgn.srcOffsets[1].y) || 248243a02ff3ea4bf0a6d308abc05dd5f4346bc13311Dave Houlton (rgn.srcOffsets[0].z == rgn.srcOffsets[1].z)) { 2483055112ec99304db71d55b69a60e1da14e8af8f60Mark Lobodzinski std::stringstream ss; 2484055112ec99304db71d55b69a60e1da14e8af8f60Mark Lobodzinski ss << "vkCmdBlitImage: pRegions[" << i << "].srcOffsets specify a zero-volume area."; 2485055112ec99304db71d55b69a60e1da14e8af8f60Mark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 24869b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(cb_node->commandBuffer), __LINE__, DRAWSTATE_INVALID_EXTENTS, "IMAGE", "%s", 24879b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus ss.str().c_str()); 2488055112ec99304db71d55b69a60e1da14e8af8f60Mark Lobodzinski } 248943a02ff3ea4bf0a6d308abc05dd5f4346bc13311Dave Houlton if ((rgn.dstOffsets[0].x == rgn.dstOffsets[1].x) || (rgn.dstOffsets[0].y == rgn.dstOffsets[1].y) || 249043a02ff3ea4bf0a6d308abc05dd5f4346bc13311Dave Houlton (rgn.dstOffsets[0].z == rgn.dstOffsets[1].z)) { 2491055112ec99304db71d55b69a60e1da14e8af8f60Mark Lobodzinski std::stringstream ss; 2492055112ec99304db71d55b69a60e1da14e8af8f60Mark Lobodzinski ss << "vkCmdBlitImage: pRegions[" << i << "].dstOffsets specify a zero-volume area."; 2493055112ec99304db71d55b69a60e1da14e8af8f60Mark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 24949b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(cb_node->commandBuffer), __LINE__, DRAWSTATE_INVALID_EXTENTS, "IMAGE", "%s", 24959b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus ss.str().c_str()); 2496055112ec99304db71d55b69a60e1da14e8af8f60Mark Lobodzinski } 249743a02ff3ea4bf0a6d308abc05dd5f4346bc13311Dave Houlton if (rgn.srcSubresource.layerCount == 0) { 2498d81f107590290d41d3e39fcbf3f077658be0f5a6Mark Lobodzinski char const str[] = "vkCmdBlitImage: number of layers in source subresource is zero"; 2499d81f107590290d41d3e39fcbf3f077658be0f5a6Mark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 25009b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(cb_node->commandBuffer), __LINE__, DRAWSTATE_MISMATCHED_IMAGE_ASPECT, "IMAGE", str); 2501d81f107590290d41d3e39fcbf3f077658be0f5a6Mark Lobodzinski } 250243a02ff3ea4bf0a6d308abc05dd5f4346bc13311Dave Houlton if (rgn.dstSubresource.layerCount == 0) { 2503d81f107590290d41d3e39fcbf3f077658be0f5a6Mark Lobodzinski char const str[] = "vkCmdBlitImage: number of layers in destination subresource is zero"; 2504d81f107590290d41d3e39fcbf3f077658be0f5a6Mark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 25059b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(cb_node->commandBuffer), __LINE__, DRAWSTATE_MISMATCHED_IMAGE_ASPECT, "IMAGE", str); 2506d81f107590290d41d3e39fcbf3f077658be0f5a6Mark Lobodzinski } 2507d81f107590290d41d3e39fcbf3f077658be0f5a6Mark Lobodzinski 2508d81f107590290d41d3e39fcbf3f077658be0f5a6Mark Lobodzinski // Check that src/dst layercounts match 250943a02ff3ea4bf0a6d308abc05dd5f4346bc13311Dave Houlton if (rgn.srcSubresource.layerCount != rgn.dstSubresource.layerCount) { 2510d81f107590290d41d3e39fcbf3f077658be0f5a6Mark Lobodzinski skip |= 2511d81f107590290d41d3e39fcbf3f077658be0f5a6Mark Lobodzinski log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 2512315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(cb_node->commandBuffer), __LINE__, VALIDATION_ERROR_09a001de, "IMAGE", 2513d81f107590290d41d3e39fcbf3f077658be0f5a6Mark Lobodzinski "vkCmdBlitImage: layerCount in source and destination subresource of pRegions[%d] does not match. %s", 2514315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis i, validation_error_map[VALIDATION_ERROR_09a001de]); 2515d81f107590290d41d3e39fcbf3f077658be0f5a6Mark Lobodzinski } 25168068cb0f90422b6789d0c120f0831f55eb76b71aMark Lobodzinski 251743a02ff3ea4bf0a6d308abc05dd5f4346bc13311Dave Houlton if (rgn.srcSubresource.aspectMask != rgn.dstSubresource.aspectMask) { 25188068cb0f90422b6789d0c120f0831f55eb76b71aMark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 2519315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(cb_node->commandBuffer), __LINE__, VALIDATION_ERROR_09a001dc, "IMAGE", 25208068cb0f90422b6789d0c120f0831f55eb76b71aMark Lobodzinski "vkCmdBlitImage: aspectMask members for pRegion[%d] do not match. %s", i, 2521315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_09a001dc]); 25228068cb0f90422b6789d0c120f0831f55eb76b71aMark Lobodzinski } 252343a02ff3ea4bf0a6d308abc05dd5f4346bc13311Dave Houlton 25241007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton if (!VerifyAspectsPresent(rgn.srcSubresource.aspectMask, src_format)) { 25251007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 25261007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton HandleToUint64(cb_node->commandBuffer), __LINE__, VALIDATION_ERROR_09a001e2, "IMAGE", 25271007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton "vkCmdBlitImage: region [%d] source aspectMask (0x%x) specifies aspects not present in source " 25281007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton "image format %s. %s", 25291007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton i, rgn.srcSubresource.aspectMask, string_VkFormat(src_format), 25301007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton validation_error_map[VALIDATION_ERROR_09a001e2]); 25311007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton } 25321007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton 25331007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton if (!VerifyAspectsPresent(rgn.dstSubresource.aspectMask, dst_format)) { 25341007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton skip |= log_msg( 25351007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 25361007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton HandleToUint64(cb_node->commandBuffer), __LINE__, VALIDATION_ERROR_09a001e4, "IMAGE", 25371007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton "vkCmdBlitImage: region [%d] dest aspectMask (0x%x) specifies aspects not present in dest image format %s. %s", 25381007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton i, rgn.dstSubresource.aspectMask, string_VkFormat(dst_format), validation_error_map[VALIDATION_ERROR_09a001e4]); 25391007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton } 25401007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton 254143a02ff3ea4bf0a6d308abc05dd5f4346bc13311Dave Houlton // Validate source image offsets 254243a02ff3ea4bf0a6d308abc05dd5f4346bc13311Dave Houlton VkExtent3D src_extent = GetImageSubresourceExtent(src_image_state, &(rgn.srcSubresource)); 25431007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton if (VK_IMAGE_TYPE_1D == src_type) { 254443a02ff3ea4bf0a6d308abc05dd5f4346bc13311Dave Houlton if ((0 != rgn.srcOffsets[0].y) || (1 != rgn.srcOffsets[1].y)) { 254543a02ff3ea4bf0a6d308abc05dd5f4346bc13311Dave Houlton skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 254643a02ff3ea4bf0a6d308abc05dd5f4346bc13311Dave Houlton HandleToUint64(cb_node->commandBuffer), __LINE__, VALIDATION_ERROR_09a001ea, "IMAGE", 254743a02ff3ea4bf0a6d308abc05dd5f4346bc13311Dave Houlton "vkCmdBlitImage: region [%d], source image of type VK_IMAGE_TYPE_1D with srcOffset[].y values " 254843a02ff3ea4bf0a6d308abc05dd5f4346bc13311Dave Houlton "of (%1d, %1d). These must be (0, 1). %s", 254943a02ff3ea4bf0a6d308abc05dd5f4346bc13311Dave Houlton i, rgn.srcOffsets[0].y, rgn.srcOffsets[1].y, validation_error_map[VALIDATION_ERROR_09a001ea]); 255043a02ff3ea4bf0a6d308abc05dd5f4346bc13311Dave Houlton } 255143a02ff3ea4bf0a6d308abc05dd5f4346bc13311Dave Houlton } 255243a02ff3ea4bf0a6d308abc05dd5f4346bc13311Dave Houlton 25531007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton if ((VK_IMAGE_TYPE_1D == src_type) || (VK_IMAGE_TYPE_2D == src_type)) { 255443a02ff3ea4bf0a6d308abc05dd5f4346bc13311Dave Houlton if ((0 != rgn.srcOffsets[0].z) || (1 != rgn.srcOffsets[1].z)) { 255543a02ff3ea4bf0a6d308abc05dd5f4346bc13311Dave Houlton skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 255643a02ff3ea4bf0a6d308abc05dd5f4346bc13311Dave Houlton HandleToUint64(cb_node->commandBuffer), __LINE__, VALIDATION_ERROR_09a001ee, "IMAGE", 255743a02ff3ea4bf0a6d308abc05dd5f4346bc13311Dave Houlton "vkCmdBlitImage: region [%d], source image of type VK_IMAGE_TYPE_1D or VK_IMAGE_TYPE_2D with " 255843a02ff3ea4bf0a6d308abc05dd5f4346bc13311Dave Houlton "srcOffset[].z values of (%1d, %1d). These must be (0, 1). %s", 255943a02ff3ea4bf0a6d308abc05dd5f4346bc13311Dave Houlton i, rgn.srcOffsets[0].z, rgn.srcOffsets[1].z, validation_error_map[VALIDATION_ERROR_09a001ee]); 256043a02ff3ea4bf0a6d308abc05dd5f4346bc13311Dave Houlton } 256143a02ff3ea4bf0a6d308abc05dd5f4346bc13311Dave Houlton } 256243a02ff3ea4bf0a6d308abc05dd5f4346bc13311Dave Houlton 25631007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton bool oob = false; 256443a02ff3ea4bf0a6d308abc05dd5f4346bc13311Dave Houlton if ((rgn.srcOffsets[0].x < 0) || (rgn.srcOffsets[0].x > static_cast<int32_t>(src_extent.width)) || 256543a02ff3ea4bf0a6d308abc05dd5f4346bc13311Dave Houlton (rgn.srcOffsets[1].x < 0) || (rgn.srcOffsets[1].x > static_cast<int32_t>(src_extent.width))) { 25661007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton oob = true; 256743a02ff3ea4bf0a6d308abc05dd5f4346bc13311Dave Houlton skip |= log_msg( 256843a02ff3ea4bf0a6d308abc05dd5f4346bc13311Dave Houlton report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 256943a02ff3ea4bf0a6d308abc05dd5f4346bc13311Dave Houlton HandleToUint64(cb_node->commandBuffer), __LINE__, VALIDATION_ERROR_09a001e6, "IMAGE", 257043a02ff3ea4bf0a6d308abc05dd5f4346bc13311Dave Houlton "vkCmdBlitImage: region [%d] srcOffset[].x values (%1d, %1d) exceed srcSubresource width extent (%1d). %s", i, 257143a02ff3ea4bf0a6d308abc05dd5f4346bc13311Dave Houlton rgn.srcOffsets[0].x, rgn.srcOffsets[1].x, src_extent.width, validation_error_map[VALIDATION_ERROR_09a001e6]); 257243a02ff3ea4bf0a6d308abc05dd5f4346bc13311Dave Houlton } 257343a02ff3ea4bf0a6d308abc05dd5f4346bc13311Dave Houlton if ((rgn.srcOffsets[0].y < 0) || (rgn.srcOffsets[0].y > static_cast<int32_t>(src_extent.height)) || 257443a02ff3ea4bf0a6d308abc05dd5f4346bc13311Dave Houlton (rgn.srcOffsets[1].y < 0) || (rgn.srcOffsets[1].y > static_cast<int32_t>(src_extent.height))) { 25751007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton oob = true; 257643a02ff3ea4bf0a6d308abc05dd5f4346bc13311Dave Houlton skip |= log_msg( 257743a02ff3ea4bf0a6d308abc05dd5f4346bc13311Dave Houlton report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 257843a02ff3ea4bf0a6d308abc05dd5f4346bc13311Dave Houlton HandleToUint64(cb_node->commandBuffer), __LINE__, VALIDATION_ERROR_09a001e8, "IMAGE", 257943a02ff3ea4bf0a6d308abc05dd5f4346bc13311Dave Houlton "vkCmdBlitImage: region [%d] srcOffset[].y values (%1d, %1d) exceed srcSubresource height extent (%1d). %s", i, 258043a02ff3ea4bf0a6d308abc05dd5f4346bc13311Dave Houlton rgn.srcOffsets[0].y, rgn.srcOffsets[1].y, src_extent.height, validation_error_map[VALIDATION_ERROR_09a001e8]); 258143a02ff3ea4bf0a6d308abc05dd5f4346bc13311Dave Houlton } 258243a02ff3ea4bf0a6d308abc05dd5f4346bc13311Dave Houlton if ((rgn.srcOffsets[0].z < 0) || (rgn.srcOffsets[0].z > static_cast<int32_t>(src_extent.depth)) || 258343a02ff3ea4bf0a6d308abc05dd5f4346bc13311Dave Houlton (rgn.srcOffsets[1].z < 0) || (rgn.srcOffsets[1].z > static_cast<int32_t>(src_extent.depth))) { 25841007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton oob = true; 258543a02ff3ea4bf0a6d308abc05dd5f4346bc13311Dave Houlton skip |= log_msg( 258643a02ff3ea4bf0a6d308abc05dd5f4346bc13311Dave Houlton report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 258743a02ff3ea4bf0a6d308abc05dd5f4346bc13311Dave Houlton HandleToUint64(cb_node->commandBuffer), __LINE__, VALIDATION_ERROR_09a001ec, "IMAGE", 258843a02ff3ea4bf0a6d308abc05dd5f4346bc13311Dave Houlton "vkCmdBlitImage: region [%d] srcOffset[].z values (%1d, %1d) exceed srcSubresource depth extent (%1d). %s", i, 258943a02ff3ea4bf0a6d308abc05dd5f4346bc13311Dave Houlton rgn.srcOffsets[0].z, rgn.srcOffsets[1].z, src_extent.depth, validation_error_map[VALIDATION_ERROR_09a001ec]); 259043a02ff3ea4bf0a6d308abc05dd5f4346bc13311Dave Houlton } 25911007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton if (rgn.srcSubresource.mipLevel >= src_image_state->createInfo.mipLevels) { 25921007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 25931007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton HandleToUint64(cb_node->commandBuffer), __LINE__, VALIDATION_ERROR_184001ae, "IMAGE", 25941007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton "vkCmdBlitImage: region [%d] source image, attempt to access a non-existant mip level %1d. %s", i, 25951007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton rgn.srcSubresource.mipLevel, validation_error_map[VALIDATION_ERROR_184001ae]); 25961007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton } else if (oob) { 25971007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 25981007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton HandleToUint64(cb_node->commandBuffer), __LINE__, VALIDATION_ERROR_184001ae, "IMAGE", 25991007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton "vkCmdBlitImage: region [%d] source image blit region exceeds image dimensions. %s", i, 26001007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton validation_error_map[VALIDATION_ERROR_184001ae]); 26011007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton } 260243a02ff3ea4bf0a6d308abc05dd5f4346bc13311Dave Houlton 260343a02ff3ea4bf0a6d308abc05dd5f4346bc13311Dave Houlton // Validate dest image offsets 260443a02ff3ea4bf0a6d308abc05dd5f4346bc13311Dave Houlton VkExtent3D dst_extent = GetImageSubresourceExtent(dst_image_state, &(rgn.dstSubresource)); 26051007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton if (VK_IMAGE_TYPE_1D == dst_type) { 260643a02ff3ea4bf0a6d308abc05dd5f4346bc13311Dave Houlton if ((0 != rgn.dstOffsets[0].y) || (1 != rgn.dstOffsets[1].y)) { 260743a02ff3ea4bf0a6d308abc05dd5f4346bc13311Dave Houlton skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 260843a02ff3ea4bf0a6d308abc05dd5f4346bc13311Dave Houlton HandleToUint64(cb_node->commandBuffer), __LINE__, VALIDATION_ERROR_09a001f4, "IMAGE", 260943a02ff3ea4bf0a6d308abc05dd5f4346bc13311Dave Houlton "vkCmdBlitImage: region [%d], dest image of type VK_IMAGE_TYPE_1D with dstOffset[].y values of " 261043a02ff3ea4bf0a6d308abc05dd5f4346bc13311Dave Houlton "(%1d, %1d). These must be (0, 1). %s", 261143a02ff3ea4bf0a6d308abc05dd5f4346bc13311Dave Houlton i, rgn.dstOffsets[0].y, rgn.dstOffsets[1].y, validation_error_map[VALIDATION_ERROR_09a001f4]); 261243a02ff3ea4bf0a6d308abc05dd5f4346bc13311Dave Houlton } 261343a02ff3ea4bf0a6d308abc05dd5f4346bc13311Dave Houlton } 261443a02ff3ea4bf0a6d308abc05dd5f4346bc13311Dave Houlton 26151007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton if ((VK_IMAGE_TYPE_1D == dst_type) || (VK_IMAGE_TYPE_2D == dst_type)) { 261643a02ff3ea4bf0a6d308abc05dd5f4346bc13311Dave Houlton if ((0 != rgn.dstOffsets[0].z) || (1 != rgn.dstOffsets[1].z)) { 261743a02ff3ea4bf0a6d308abc05dd5f4346bc13311Dave Houlton skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 261843a02ff3ea4bf0a6d308abc05dd5f4346bc13311Dave Houlton HandleToUint64(cb_node->commandBuffer), __LINE__, VALIDATION_ERROR_09a001f8, "IMAGE", 261943a02ff3ea4bf0a6d308abc05dd5f4346bc13311Dave Houlton "vkCmdBlitImage: region [%d], dest image of type VK_IMAGE_TYPE_1D or VK_IMAGE_TYPE_2D with " 262043a02ff3ea4bf0a6d308abc05dd5f4346bc13311Dave Houlton "dstOffset[].z values of (%1d, %1d). These must be (0, 1). %s", 262143a02ff3ea4bf0a6d308abc05dd5f4346bc13311Dave Houlton i, rgn.dstOffsets[0].z, rgn.dstOffsets[1].z, validation_error_map[VALIDATION_ERROR_09a001f8]); 262243a02ff3ea4bf0a6d308abc05dd5f4346bc13311Dave Houlton } 262343a02ff3ea4bf0a6d308abc05dd5f4346bc13311Dave Houlton } 262443a02ff3ea4bf0a6d308abc05dd5f4346bc13311Dave Houlton 26251007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton oob = false; 262643a02ff3ea4bf0a6d308abc05dd5f4346bc13311Dave Houlton if ((rgn.dstOffsets[0].x < 0) || (rgn.dstOffsets[0].x > static_cast<int32_t>(dst_extent.width)) || 262743a02ff3ea4bf0a6d308abc05dd5f4346bc13311Dave Houlton (rgn.dstOffsets[1].x < 0) || (rgn.dstOffsets[1].x > static_cast<int32_t>(dst_extent.width))) { 26281007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton oob = true; 262943a02ff3ea4bf0a6d308abc05dd5f4346bc13311Dave Houlton skip |= log_msg( 263043a02ff3ea4bf0a6d308abc05dd5f4346bc13311Dave Houlton report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 263143a02ff3ea4bf0a6d308abc05dd5f4346bc13311Dave Houlton HandleToUint64(cb_node->commandBuffer), __LINE__, VALIDATION_ERROR_09a001f0, "IMAGE", 263243a02ff3ea4bf0a6d308abc05dd5f4346bc13311Dave Houlton "vkCmdBlitImage: region [%d] dstOffset[].x values (%1d, %1d) exceed dstSubresource width extent (%1d). %s", i, 263343a02ff3ea4bf0a6d308abc05dd5f4346bc13311Dave Houlton rgn.dstOffsets[0].x, rgn.dstOffsets[1].x, dst_extent.width, validation_error_map[VALIDATION_ERROR_09a001f0]); 263443a02ff3ea4bf0a6d308abc05dd5f4346bc13311Dave Houlton } 263543a02ff3ea4bf0a6d308abc05dd5f4346bc13311Dave Houlton if ((rgn.dstOffsets[0].y < 0) || (rgn.dstOffsets[0].y > static_cast<int32_t>(dst_extent.height)) || 263643a02ff3ea4bf0a6d308abc05dd5f4346bc13311Dave Houlton (rgn.dstOffsets[1].y < 0) || (rgn.dstOffsets[1].y > static_cast<int32_t>(dst_extent.height))) { 26371007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton oob = true; 263843a02ff3ea4bf0a6d308abc05dd5f4346bc13311Dave Houlton skip |= log_msg( 263943a02ff3ea4bf0a6d308abc05dd5f4346bc13311Dave Houlton report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 264043a02ff3ea4bf0a6d308abc05dd5f4346bc13311Dave Houlton HandleToUint64(cb_node->commandBuffer), __LINE__, VALIDATION_ERROR_09a001f2, "IMAGE", 264143a02ff3ea4bf0a6d308abc05dd5f4346bc13311Dave Houlton "vkCmdBlitImage: region [%d] dstOffset[].y values (%1d, %1d) exceed dstSubresource height extent (%1d). %s", i, 264243a02ff3ea4bf0a6d308abc05dd5f4346bc13311Dave Houlton rgn.dstOffsets[0].y, rgn.dstOffsets[1].y, dst_extent.height, validation_error_map[VALIDATION_ERROR_09a001f2]); 264343a02ff3ea4bf0a6d308abc05dd5f4346bc13311Dave Houlton } 264443a02ff3ea4bf0a6d308abc05dd5f4346bc13311Dave Houlton if ((rgn.dstOffsets[0].z < 0) || (rgn.dstOffsets[0].z > static_cast<int32_t>(dst_extent.depth)) || 264543a02ff3ea4bf0a6d308abc05dd5f4346bc13311Dave Houlton (rgn.dstOffsets[1].z < 0) || (rgn.dstOffsets[1].z > static_cast<int32_t>(dst_extent.depth))) { 26461007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton oob = true; 264743a02ff3ea4bf0a6d308abc05dd5f4346bc13311Dave Houlton skip |= log_msg( 264843a02ff3ea4bf0a6d308abc05dd5f4346bc13311Dave Houlton report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 264943a02ff3ea4bf0a6d308abc05dd5f4346bc13311Dave Houlton HandleToUint64(cb_node->commandBuffer), __LINE__, VALIDATION_ERROR_09a001f6, "IMAGE", 265043a02ff3ea4bf0a6d308abc05dd5f4346bc13311Dave Houlton "vkCmdBlitImage: region [%d] dstOffset[].z values (%1d, %1d) exceed dstSubresource depth extent (%1d). %s", i, 265143a02ff3ea4bf0a6d308abc05dd5f4346bc13311Dave Houlton rgn.dstOffsets[0].z, rgn.dstOffsets[1].z, dst_extent.depth, validation_error_map[VALIDATION_ERROR_09a001f6]); 265243a02ff3ea4bf0a6d308abc05dd5f4346bc13311Dave Houlton } 26531007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton if (rgn.dstSubresource.mipLevel >= dst_image_state->createInfo.mipLevels) { 2654055112ec99304db71d55b69a60e1da14e8af8f60Mark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 26551007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton HandleToUint64(cb_node->commandBuffer), __LINE__, VALIDATION_ERROR_184001b0, "IMAGE", 26561007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton "vkCmdBlitImage: region [%d] destination image, attempt to access a non-existant mip level %1d. %s", 26571007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton i, rgn.dstSubresource.mipLevel, validation_error_map[VALIDATION_ERROR_184001b0]); 26581007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton } else if (oob) { 26591007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 26601007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton HandleToUint64(cb_node->commandBuffer), __LINE__, VALIDATION_ERROR_184001b0, "IMAGE", 26611007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton "vkCmdBlitImage: region [%d] destination image blit region exceeds image dimensions. %s", i, 26621007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton validation_error_map[VALIDATION_ERROR_184001b0]); 2663055112ec99304db71d55b69a60e1da14e8af8f60Mark Lobodzinski } 2664055112ec99304db71d55b69a60e1da14e8af8f60Mark Lobodzinski 26651007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton if ((VK_IMAGE_TYPE_3D == src_type) || (VK_IMAGE_TYPE_3D == dst_type)) { 26661007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton if ((0 != rgn.srcSubresource.baseArrayLayer) || (1 != rgn.srcSubresource.layerCount) || 26671007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton (0 != rgn.dstSubresource.baseArrayLayer) || (1 != rgn.dstSubresource.layerCount)) { 26681007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 26691007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton HandleToUint64(cb_node->commandBuffer), __LINE__, VALIDATION_ERROR_09a001e0, "IMAGE", 26701007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton "vkCmdBlitImage: region [%d] blit to/from a 3D image type with a non-zero baseArrayLayer, or a " 26711007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton "layerCount other than 1. %s", 26721007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton i, validation_error_map[VALIDATION_ERROR_09a001e0]); 2673055112ec99304db71d55b69a60e1da14e8af8f60Mark Lobodzinski } 2674055112ec99304db71d55b69a60e1da14e8af8f60Mark Lobodzinski } 26751007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton } // per-region checks 267660568995aca225f81acda8ce40cfabbea2c19397Mark Lobodzinski } else { 267760568995aca225f81acda8ce40cfabbea2c19397Mark Lobodzinski assert(0); 267860568995aca225f81acda8ce40cfabbea2c19397Mark Lobodzinski } 267960568995aca225f81acda8ce40cfabbea2c19397Mark Lobodzinski return skip; 268060568995aca225f81acda8ce40cfabbea2c19397Mark Lobodzinski} 268160568995aca225f81acda8ce40cfabbea2c19397Mark Lobodzinski 2682e40189d4deab674240cd9baf4c063bab4567c212Tobin Ehlisvoid PreCallRecordCmdBlitImage(layer_data *device_data, GLOBAL_CB_NODE *cb_node, IMAGE_STATE *src_image_state, 2683a99ceeafb2acc8ef0e18af2d1b24d5e1e68d5ee3Norbert Garnys IMAGE_STATE *dst_image_state, uint32_t region_count, const VkImageBlit *regions, 2684a99ceeafb2acc8ef0e18af2d1b24d5e1e68d5ee3Norbert Garnys VkImageLayout src_image_layout, VkImageLayout dst_image_layout) { 2685a99ceeafb2acc8ef0e18af2d1b24d5e1e68d5ee3Norbert Garnys // Make sure that all image slices are updated to correct layout 2686a99ceeafb2acc8ef0e18af2d1b24d5e1e68d5ee3Norbert Garnys for (uint32_t i = 0; i < region_count; ++i) { 2687a99ceeafb2acc8ef0e18af2d1b24d5e1e68d5ee3Norbert Garnys SetImageLayout(device_data, cb_node, src_image_state, regions[i].srcSubresource, src_image_layout); 2688a99ceeafb2acc8ef0e18af2d1b24d5e1e68d5ee3Norbert Garnys SetImageLayout(device_data, cb_node, dst_image_state, regions[i].dstSubresource, dst_image_layout); 2689a99ceeafb2acc8ef0e18af2d1b24d5e1e68d5ee3Norbert Garnys } 269060568995aca225f81acda8ce40cfabbea2c19397Mark Lobodzinski // Update bindings between images and cmd buffer 269160568995aca225f81acda8ce40cfabbea2c19397Mark Lobodzinski AddCommandBufferBindingImage(device_data, cb_node, src_image_state); 269260568995aca225f81acda8ce40cfabbea2c19397Mark Lobodzinski AddCommandBufferBindingImage(device_data, cb_node, dst_image_state); 269360568995aca225f81acda8ce40cfabbea2c19397Mark Lobodzinski 269460568995aca225f81acda8ce40cfabbea2c19397Mark Lobodzinski std::function<bool()> function = [=]() { return ValidateImageMemoryIsValid(device_data, src_image_state, "vkCmdBlitImage()"); }; 2695d807198f24437c1b2478ff1d06a33ce4873a1451Tobin Ehlis cb_node->queue_submit_functions.push_back(function); 269660568995aca225f81acda8ce40cfabbea2c19397Mark Lobodzinski function = [=]() { 269760568995aca225f81acda8ce40cfabbea2c19397Mark Lobodzinski SetImageMemoryValid(device_data, dst_image_state, true); 269860568995aca225f81acda8ce40cfabbea2c19397Mark Lobodzinski return false; 269960568995aca225f81acda8ce40cfabbea2c19397Mark Lobodzinski }; 2700d807198f24437c1b2478ff1d06a33ce4873a1451Tobin Ehlis cb_node->queue_submit_functions.push_back(function); 270160568995aca225f81acda8ce40cfabbea2c19397Mark Lobodzinski} 270260568995aca225f81acda8ce40cfabbea2c19397Mark Lobodzinski 270351920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour// This validates that the initial layout specified in the command buffer for 270451920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour// the IMAGE is the same 270551920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour// as the global IMAGE layout 2706440bdd357701497c3442e3515f12ac1cfffc180aTony Barbourbool ValidateCmdBufImageLayouts(layer_data *device_data, GLOBAL_CB_NODE *pCB, 27075f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton std::unordered_map<ImageSubresourcePair, IMAGE_LAYOUT_NODE> const &globalImageLayoutMap, 27085f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton std::unordered_map<ImageSubresourcePair, IMAGE_LAYOUT_NODE> &overlayLayoutMap) { 270990e629846621a0d870212dc0cebfbc83431cc5b8Mark Lobodzinski bool skip = false; 271051920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour const debug_report_data *report_data = core_validation::GetReportData(device_data); 2711788ff59d81fc816f451414dcf2a9d6c29456ff63Mark Lobodzinski for (auto cb_image_data : pCB->imageLayoutMap) { 2712788ff59d81fc816f451414dcf2a9d6c29456ff63Mark Lobodzinski VkImageLayout imageLayout; 271351920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour 2714c25ac48846c975d698243e53750c6bca28bba33eChris Forbes if (FindLayout(overlayLayoutMap, cb_image_data.first, imageLayout) || 2715c25ac48846c975d698243e53750c6bca28bba33eChris Forbes FindLayout(globalImageLayoutMap, cb_image_data.first, imageLayout)) { 2716788ff59d81fc816f451414dcf2a9d6c29456ff63Mark Lobodzinski if (cb_image_data.second.initialLayout == VK_IMAGE_LAYOUT_UNDEFINED) { 2717788ff59d81fc816f451414dcf2a9d6c29456ff63Mark Lobodzinski // TODO: Set memory invalid which is in mem_tracker currently 2718788ff59d81fc816f451414dcf2a9d6c29456ff63Mark Lobodzinski } else if (imageLayout != cb_image_data.second.initialLayout) { 2719788ff59d81fc816f451414dcf2a9d6c29456ff63Mark Lobodzinski if (cb_image_data.first.hasSubresource) { 27205f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton skip |= log_msg( 27215f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 27225f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton HandleToUint64(pCB->commandBuffer), __LINE__, DRAWSTATE_INVALID_IMAGE_LAYOUT, "DS", 27235f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton "Cannot submit cmd buffer using image (0x%" PRIx64 27245f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton ") [sub-resource: aspectMask 0x%X array layer %u, mip level %u], with layout %s when first use is %s.", 27255f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton HandleToUint64(cb_image_data.first.image), cb_image_data.first.subresource.aspectMask, 27265f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton cb_image_data.first.subresource.arrayLayer, cb_image_data.first.subresource.mipLevel, 27275f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton string_VkImageLayout(imageLayout), string_VkImageLayout(cb_image_data.second.initialLayout)); 2728788ff59d81fc816f451414dcf2a9d6c29456ff63Mark Lobodzinski } else { 27299b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 27309b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(pCB->commandBuffer), __LINE__, DRAWSTATE_INVALID_IMAGE_LAYOUT, "DS", 27315f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton "Cannot submit cmd buffer using image (0x%" PRIx64 ") with layout %s when first use is %s.", 27329b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(cb_image_data.first.image), string_VkImageLayout(imageLayout), 27339b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus string_VkImageLayout(cb_image_data.second.initialLayout)); 2734788ff59d81fc816f451414dcf2a9d6c29456ff63Mark Lobodzinski } 2735788ff59d81fc816f451414dcf2a9d6c29456ff63Mark Lobodzinski } 2736c25ac48846c975d698243e53750c6bca28bba33eChris Forbes SetLayout(overlayLayoutMap, cb_image_data.first, cb_image_data.second.layout); 2737788ff59d81fc816f451414dcf2a9d6c29456ff63Mark Lobodzinski } 2738788ff59d81fc816f451414dcf2a9d6c29456ff63Mark Lobodzinski } 273990e629846621a0d870212dc0cebfbc83431cc5b8Mark Lobodzinski return skip; 2740788ff59d81fc816f451414dcf2a9d6c29456ff63Mark Lobodzinski} 2741940eb407cf288675f9bc7552dca723cd7028edacMark Lobodzinski 274251920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbourvoid UpdateCmdBufImageLayouts(layer_data *device_data, GLOBAL_CB_NODE *pCB) { 274351920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour for (auto cb_image_data : pCB->imageLayoutMap) { 274451920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour VkImageLayout imageLayout; 274551920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour FindGlobalLayout(device_data, cb_image_data.first, imageLayout); 274651920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour SetGlobalLayout(device_data, cb_image_data.first, cb_image_data.second.layout); 274751920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour } 274851920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour} 274951920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour 2750940eb407cf288675f9bc7552dca723cd7028edacMark Lobodzinski// Print readable FlagBits in FlagMask 2751940eb407cf288675f9bc7552dca723cd7028edacMark Lobodzinskistatic std::string string_VkAccessFlags(VkAccessFlags accessMask) { 2752940eb407cf288675f9bc7552dca723cd7028edacMark Lobodzinski std::string result; 2753940eb407cf288675f9bc7552dca723cd7028edacMark Lobodzinski std::string separator; 2754940eb407cf288675f9bc7552dca723cd7028edacMark Lobodzinski 2755940eb407cf288675f9bc7552dca723cd7028edacMark Lobodzinski if (accessMask == 0) { 2756940eb407cf288675f9bc7552dca723cd7028edacMark Lobodzinski result = "[None]"; 2757940eb407cf288675f9bc7552dca723cd7028edacMark Lobodzinski } else { 2758940eb407cf288675f9bc7552dca723cd7028edacMark Lobodzinski result = "["; 2759940eb407cf288675f9bc7552dca723cd7028edacMark Lobodzinski for (auto i = 0; i < 32; i++) { 2760940eb407cf288675f9bc7552dca723cd7028edacMark Lobodzinski if (accessMask & (1 << i)) { 2761940eb407cf288675f9bc7552dca723cd7028edacMark Lobodzinski result = result + separator + string_VkAccessFlagBits((VkAccessFlagBits)(1 << i)); 2762940eb407cf288675f9bc7552dca723cd7028edacMark Lobodzinski separator = " | "; 2763940eb407cf288675f9bc7552dca723cd7028edacMark Lobodzinski } 2764940eb407cf288675f9bc7552dca723cd7028edacMark Lobodzinski } 2765940eb407cf288675f9bc7552dca723cd7028edacMark Lobodzinski result = result + "]"; 2766940eb407cf288675f9bc7552dca723cd7028edacMark Lobodzinski } 2767940eb407cf288675f9bc7552dca723cd7028edacMark Lobodzinski return result; 2768940eb407cf288675f9bc7552dca723cd7028edacMark Lobodzinski} 2769940eb407cf288675f9bc7552dca723cd7028edacMark Lobodzinski 27708fefffdd7f4b8a91b65b50dedb70ad4be159e998Mark Lobodzinski// AccessFlags MUST have 'required_bit' set, and may have one or more of 'optional_bits' set. If required_bit is zero, accessMask 27718fefffdd7f4b8a91b65b50dedb70ad4be159e998Mark Lobodzinski// must have at least one of 'optional_bits' set 2772940eb407cf288675f9bc7552dca723cd7028edacMark Lobodzinski// TODO: Add tracking to ensure that at least one barrier has been set for these layout transitions 27738fefffdd7f4b8a91b65b50dedb70ad4be159e998Mark Lobodzinskistatic bool ValidateMaskBits(core_validation::layer_data *device_data, VkCommandBuffer cmdBuffer, const VkAccessFlags &accessMask, 27748fefffdd7f4b8a91b65b50dedb70ad4be159e998Mark Lobodzinski const VkImageLayout &layout, VkAccessFlags required_bit, VkAccessFlags optional_bits, 27758fefffdd7f4b8a91b65b50dedb70ad4be159e998Mark Lobodzinski const char *type) { 27768fefffdd7f4b8a91b65b50dedb70ad4be159e998Mark Lobodzinski const debug_report_data *report_data = core_validation::GetReportData(device_data); 27778fefffdd7f4b8a91b65b50dedb70ad4be159e998Mark Lobodzinski bool skip = false; 2778940eb407cf288675f9bc7552dca723cd7028edacMark Lobodzinski 2779940eb407cf288675f9bc7552dca723cd7028edacMark Lobodzinski if ((accessMask & required_bit) || (!required_bit && (accessMask & optional_bits))) { 2780940eb407cf288675f9bc7552dca723cd7028edacMark Lobodzinski if (accessMask & ~(required_bit | optional_bits)) { 2781940eb407cf288675f9bc7552dca723cd7028edacMark Lobodzinski // TODO: Verify against Valid Use 2782fdc75c21ced997fbbc180734bef87bf6d5811d4bMark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 27839b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(cmdBuffer), __LINE__, DRAWSTATE_INVALID_BARRIER, "DS", 27848fefffdd7f4b8a91b65b50dedb70ad4be159e998Mark Lobodzinski "Additional bits in %s accessMask 0x%X %s are specified when layout is %s.", type, accessMask, 27858fefffdd7f4b8a91b65b50dedb70ad4be159e998Mark Lobodzinski string_VkAccessFlags(accessMask).c_str(), string_VkImageLayout(layout)); 2786940eb407cf288675f9bc7552dca723cd7028edacMark Lobodzinski } 2787940eb407cf288675f9bc7552dca723cd7028edacMark Lobodzinski } else { 2788940eb407cf288675f9bc7552dca723cd7028edacMark Lobodzinski if (!required_bit) { 2789fdc75c21ced997fbbc180734bef87bf6d5811d4bMark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 27909b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(cmdBuffer), __LINE__, DRAWSTATE_INVALID_BARRIER, "DS", 27915f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton "%s AccessMask %d %s must contain at least one of access bits %d %s when layout is %s, unless the app " 27925f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton "has previously added a barrier for this transition.", 27938fefffdd7f4b8a91b65b50dedb70ad4be159e998Mark Lobodzinski type, accessMask, string_VkAccessFlags(accessMask).c_str(), optional_bits, 27948fefffdd7f4b8a91b65b50dedb70ad4be159e998Mark Lobodzinski string_VkAccessFlags(optional_bits).c_str(), string_VkImageLayout(layout)); 2795940eb407cf288675f9bc7552dca723cd7028edacMark Lobodzinski } else { 2796940eb407cf288675f9bc7552dca723cd7028edacMark Lobodzinski std::string opt_bits; 2797940eb407cf288675f9bc7552dca723cd7028edacMark Lobodzinski if (optional_bits != 0) { 2798940eb407cf288675f9bc7552dca723cd7028edacMark Lobodzinski std::stringstream ss; 2799940eb407cf288675f9bc7552dca723cd7028edacMark Lobodzinski ss << optional_bits; 2800940eb407cf288675f9bc7552dca723cd7028edacMark Lobodzinski opt_bits = "and may have optional bits " + ss.str() + ' ' + string_VkAccessFlags(optional_bits); 2801940eb407cf288675f9bc7552dca723cd7028edacMark Lobodzinski } 2802fdc75c21ced997fbbc180734bef87bf6d5811d4bMark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 28039b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(cmdBuffer), __LINE__, DRAWSTATE_INVALID_BARRIER, "DS", 28045f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton "%s AccessMask %d %s must have required access bit %d %s %s when layout is %s, unless the app has " 28055f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton "previously added a barrier for this transition.", 28068fefffdd7f4b8a91b65b50dedb70ad4be159e998Mark Lobodzinski type, accessMask, string_VkAccessFlags(accessMask).c_str(), required_bit, 28078fefffdd7f4b8a91b65b50dedb70ad4be159e998Mark Lobodzinski string_VkAccessFlags(required_bit).c_str(), opt_bits.c_str(), string_VkImageLayout(layout)); 2808940eb407cf288675f9bc7552dca723cd7028edacMark Lobodzinski } 2809940eb407cf288675f9bc7552dca723cd7028edacMark Lobodzinski } 28108fefffdd7f4b8a91b65b50dedb70ad4be159e998Mark Lobodzinski return skip; 2811940eb407cf288675f9bc7552dca723cd7028edacMark Lobodzinski} 2812940eb407cf288675f9bc7552dca723cd7028edacMark Lobodzinski 2813d76960c655c53f47aaf2e16538ea0c40e6d527ecMark Lobodzinski// ValidateLayoutVsAttachmentDescription is a general function where we can validate various state associated with the 2814374d6151f9db5d62891ffdbe833bcbb51848db6bMark Lobodzinski// VkAttachmentDescription structs that are used by the sub-passes of a renderpass. Initial check is to make sure that READ_ONLY 2815374d6151f9db5d62891ffdbe833bcbb51848db6bMark Lobodzinski// layout attachments don't have CLEAR as their loadOp. 2816d76960c655c53f47aaf2e16538ea0c40e6d527ecMark Lobodzinskibool ValidateLayoutVsAttachmentDescription(const debug_report_data *report_data, const VkImageLayout first_layout, 2817374d6151f9db5d62891ffdbe833bcbb51848db6bMark Lobodzinski const uint32_t attachment, const VkAttachmentDescription &attachment_description) { 2818374d6151f9db5d62891ffdbe833bcbb51848db6bMark Lobodzinski bool skip = false; 2819d76960c655c53f47aaf2e16538ea0c40e6d527ecMark Lobodzinski // Verify that initial loadOp on READ_ONLY attachments is not CLEAR 2820d76960c655c53f47aaf2e16538ea0c40e6d527ecMark Lobodzinski if (attachment_description.loadOp == VK_ATTACHMENT_LOAD_OP_CLEAR) { 2821d76960c655c53f47aaf2e16538ea0c40e6d527ecMark Lobodzinski if ((first_layout == VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL) || 2822d76960c655c53f47aaf2e16538ea0c40e6d527ecMark Lobodzinski (first_layout == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL)) { 28235b9ab1fb8720c30edfbe8dd974e2364425471ad5Mark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, 2824315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis VALIDATION_ERROR_12200688, "DS", "Cannot clear attachment %d with invalid first layout %s. %s", 2825315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis attachment, string_VkImageLayout(first_layout), validation_error_map[VALIDATION_ERROR_12200688]); 2826d76960c655c53f47aaf2e16538ea0c40e6d527ecMark Lobodzinski } 2827d76960c655c53f47aaf2e16538ea0c40e6d527ecMark Lobodzinski } 2828374d6151f9db5d62891ffdbe833bcbb51848db6bMark Lobodzinski return skip; 2829d76960c655c53f47aaf2e16538ea0c40e6d527ecMark Lobodzinski} 2830d76960c655c53f47aaf2e16538ea0c40e6d527ecMark Lobodzinski 2831374d6151f9db5d62891ffdbe833bcbb51848db6bMark Lobodzinskibool ValidateLayouts(core_validation::layer_data *device_data, VkDevice device, const VkRenderPassCreateInfo *pCreateInfo) { 2832374d6151f9db5d62891ffdbe833bcbb51848db6bMark Lobodzinski const debug_report_data *report_data = core_validation::GetReportData(device_data); 2833d76960c655c53f47aaf2e16538ea0c40e6d527ecMark Lobodzinski bool skip = false; 2834d76960c655c53f47aaf2e16538ea0c40e6d527ecMark Lobodzinski 28359929d6c30c30e2c06d6c6998cbf3fd7b8ebde12aJason Ekstrand for (uint32_t i = 0; i < pCreateInfo->attachmentCount; ++i) { 28369929d6c30c30e2c06d6c6998cbf3fd7b8ebde12aJason Ekstrand VkFormat format = pCreateInfo->pAttachments[i].format; 28379929d6c30c30e2c06d6c6998cbf3fd7b8ebde12aJason Ekstrand if (pCreateInfo->pAttachments[i].initialLayout == VK_IMAGE_LAYOUT_UNDEFINED) { 28389929d6c30c30e2c06d6c6998cbf3fd7b8ebde12aJason Ekstrand if ((FormatIsColor(format) || FormatHasDepth(format)) && 28399929d6c30c30e2c06d6c6998cbf3fd7b8ebde12aJason Ekstrand pCreateInfo->pAttachments[i].loadOp == VK_ATTACHMENT_LOAD_OP_LOAD) { 2840a467c7a713ccfbae00664fff9113bddf7ebf1774Tobin Ehlis skip |= log_msg(report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, 2841a467c7a713ccfbae00664fff9113bddf7ebf1774Tobin Ehlis DRAWSTATE_INVALID_RENDERPASS, "DS", 28425f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton "Render pass has an attachment with loadOp == VK_ATTACHMENT_LOAD_OP_LOAD and initialLayout == " 28435f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton "VK_IMAGE_LAYOUT_UNDEFINED. This is probably not what you intended. Consider using " 28445f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton "VK_ATTACHMENT_LOAD_OP_DONT_CARE instead if the image truely is undefined at the start of the " 28455f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton "render pass."); 28469929d6c30c30e2c06d6c6998cbf3fd7b8ebde12aJason Ekstrand } 28475f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton if (FormatHasStencil(format) && pCreateInfo->pAttachments[i].stencilLoadOp == VK_ATTACHMENT_LOAD_OP_LOAD) { 2848a467c7a713ccfbae00664fff9113bddf7ebf1774Tobin Ehlis skip |= log_msg(report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, 2849a467c7a713ccfbae00664fff9113bddf7ebf1774Tobin Ehlis DRAWSTATE_INVALID_RENDERPASS, "DS", 28505f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton "Render pass has an attachment with stencilLoadOp == VK_ATTACHMENT_LOAD_OP_LOAD and initialLayout " 28515f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton "== VK_IMAGE_LAYOUT_UNDEFINED. This is probably not what you intended. Consider using " 28525f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton "VK_ATTACHMENT_LOAD_OP_DONT_CARE instead if the image truely is undefined at the start of the " 28535f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton "render pass."); 28549929d6c30c30e2c06d6c6998cbf3fd7b8ebde12aJason Ekstrand } 28559929d6c30c30e2c06d6c6998cbf3fd7b8ebde12aJason Ekstrand } 28569929d6c30c30e2c06d6c6998cbf3fd7b8ebde12aJason Ekstrand } 28579929d6c30c30e2c06d6c6998cbf3fd7b8ebde12aJason Ekstrand 2858d76960c655c53f47aaf2e16538ea0c40e6d527ecMark Lobodzinski // Track when we're observing the first use of an attachment 2859d76960c655c53f47aaf2e16538ea0c40e6d527ecMark Lobodzinski std::vector<bool> attach_first_use(pCreateInfo->attachmentCount, true); 2860d76960c655c53f47aaf2e16538ea0c40e6d527ecMark Lobodzinski for (uint32_t i = 0; i < pCreateInfo->subpassCount; ++i) { 2861d76960c655c53f47aaf2e16538ea0c40e6d527ecMark Lobodzinski const VkSubpassDescription &subpass = pCreateInfo->pSubpasses[i]; 2862ce7bf009f8fc7e268efdc76ba61e3491d290ebd9Cort Stratton 2863ce7bf009f8fc7e268efdc76ba61e3491d290ebd9Cort Stratton // Check input attachments first, so we can detect first-use-as-input for VU #00349 2864ce7bf009f8fc7e268efdc76ba61e3491d290ebd9Cort Stratton for (uint32_t j = 0; j < subpass.inputAttachmentCount; ++j) { 2865ce7bf009f8fc7e268efdc76ba61e3491d290ebd9Cort Stratton auto attach_index = subpass.pInputAttachments[j].attachment; 2866ce7bf009f8fc7e268efdc76ba61e3491d290ebd9Cort Stratton if (attach_index == VK_ATTACHMENT_UNUSED) continue; 2867ce7bf009f8fc7e268efdc76ba61e3491d290ebd9Cort Stratton 2868ce7bf009f8fc7e268efdc76ba61e3491d290ebd9Cort Stratton switch (subpass.pInputAttachments[j].layout) { 2869ce7bf009f8fc7e268efdc76ba61e3491d290ebd9Cort Stratton case VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL: 2870ce7bf009f8fc7e268efdc76ba61e3491d290ebd9Cort Stratton case VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL: 2871ce7bf009f8fc7e268efdc76ba61e3491d290ebd9Cort Stratton // These are ideal. 2872ce7bf009f8fc7e268efdc76ba61e3491d290ebd9Cort Stratton break; 2873ce7bf009f8fc7e268efdc76ba61e3491d290ebd9Cort Stratton 2874ce7bf009f8fc7e268efdc76ba61e3491d290ebd9Cort Stratton case VK_IMAGE_LAYOUT_GENERAL: 2875ce7bf009f8fc7e268efdc76ba61e3491d290ebd9Cort Stratton // May not be optimal. TODO: reconsider this warning based on other constraints. 2876ce7bf009f8fc7e268efdc76ba61e3491d290ebd9Cort Stratton skip |= log_msg(report_data, VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT, 2877ce7bf009f8fc7e268efdc76ba61e3491d290ebd9Cort Stratton VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, DRAWSTATE_INVALID_IMAGE_LAYOUT, "DS", 2878ce7bf009f8fc7e268efdc76ba61e3491d290ebd9Cort Stratton "Layout for input attachment is GENERAL but should be READ_ONLY_OPTIMAL."); 2879ce7bf009f8fc7e268efdc76ba61e3491d290ebd9Cort Stratton break; 2880ce7bf009f8fc7e268efdc76ba61e3491d290ebd9Cort Stratton 2881ce7bf009f8fc7e268efdc76ba61e3491d290ebd9Cort Stratton default: 2882ce7bf009f8fc7e268efdc76ba61e3491d290ebd9Cort Stratton // No other layouts are acceptable 2883ce7bf009f8fc7e268efdc76ba61e3491d290ebd9Cort Stratton skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, 2884ce7bf009f8fc7e268efdc76ba61e3491d290ebd9Cort Stratton __LINE__, DRAWSTATE_INVALID_IMAGE_LAYOUT, "DS", 2885ce7bf009f8fc7e268efdc76ba61e3491d290ebd9Cort Stratton "Layout for input attachment is %s but can only be READ_ONLY_OPTIMAL or GENERAL.", 2886ce7bf009f8fc7e268efdc76ba61e3491d290ebd9Cort Stratton string_VkImageLayout(subpass.pInputAttachments[j].layout)); 2887ce7bf009f8fc7e268efdc76ba61e3491d290ebd9Cort Stratton } 2888ce7bf009f8fc7e268efdc76ba61e3491d290ebd9Cort Stratton 2889ce7bf009f8fc7e268efdc76ba61e3491d290ebd9Cort Stratton VkImageLayout layout = subpass.pInputAttachments[j].layout; 2890ce7bf009f8fc7e268efdc76ba61e3491d290ebd9Cort Stratton bool found_layout_mismatch = subpass.pDepthStencilAttachment && 2891ce7bf009f8fc7e268efdc76ba61e3491d290ebd9Cort Stratton subpass.pDepthStencilAttachment->attachment == attach_index && 2892ce7bf009f8fc7e268efdc76ba61e3491d290ebd9Cort Stratton subpass.pDepthStencilAttachment->layout != layout; 2893ce7bf009f8fc7e268efdc76ba61e3491d290ebd9Cort Stratton for (uint32_t c = 0; !found_layout_mismatch && c < subpass.colorAttachmentCount; ++c) { 2894ce7bf009f8fc7e268efdc76ba61e3491d290ebd9Cort Stratton found_layout_mismatch = 2895ce7bf009f8fc7e268efdc76ba61e3491d290ebd9Cort Stratton (subpass.pColorAttachments[c].attachment == attach_index && subpass.pColorAttachments[c].layout != layout); 2896ce7bf009f8fc7e268efdc76ba61e3491d290ebd9Cort Stratton } 2897ce7bf009f8fc7e268efdc76ba61e3491d290ebd9Cort Stratton if (found_layout_mismatch) { 28985f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, 28995f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton VALIDATION_ERROR_140006ae, "DS", 29005f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton "CreateRenderPass: Subpass %u pInputAttachments[%u] (%u) has layout %u, but is also used as a " 29015f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton "depth/color attachment with a different layout. %s", 29025f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton i, j, attach_index, layout, validation_error_map[VALIDATION_ERROR_140006ae]); 2903ce7bf009f8fc7e268efdc76ba61e3491d290ebd9Cort Stratton } 2904ce7bf009f8fc7e268efdc76ba61e3491d290ebd9Cort Stratton 2905ce7bf009f8fc7e268efdc76ba61e3491d290ebd9Cort Stratton if (attach_first_use[attach_index]) { 2906ce7bf009f8fc7e268efdc76ba61e3491d290ebd9Cort Stratton skip |= ValidateLayoutVsAttachmentDescription(report_data, subpass.pInputAttachments[j].layout, attach_index, 2907ce7bf009f8fc7e268efdc76ba61e3491d290ebd9Cort Stratton pCreateInfo->pAttachments[attach_index]); 2908ce7bf009f8fc7e268efdc76ba61e3491d290ebd9Cort Stratton 2909ce7bf009f8fc7e268efdc76ba61e3491d290ebd9Cort Stratton bool used_as_depth = 2910ce7bf009f8fc7e268efdc76ba61e3491d290ebd9Cort Stratton (subpass.pDepthStencilAttachment != NULL && subpass.pDepthStencilAttachment->attachment == attach_index); 2911ce7bf009f8fc7e268efdc76ba61e3491d290ebd9Cort Stratton bool used_as_color = false; 2912ce7bf009f8fc7e268efdc76ba61e3491d290ebd9Cort Stratton for (uint32_t k = 0; !used_as_depth && !used_as_color && k < subpass.colorAttachmentCount; ++k) { 2913ce7bf009f8fc7e268efdc76ba61e3491d290ebd9Cort Stratton used_as_color = (subpass.pColorAttachments[k].attachment == attach_index); 2914ce7bf009f8fc7e268efdc76ba61e3491d290ebd9Cort Stratton } 2915ce7bf009f8fc7e268efdc76ba61e3491d290ebd9Cort Stratton if (!used_as_depth && !used_as_color && 2916ce7bf009f8fc7e268efdc76ba61e3491d290ebd9Cort Stratton pCreateInfo->pAttachments[attach_index].loadOp == VK_ATTACHMENT_LOAD_OP_CLEAR) { 2917ce7bf009f8fc7e268efdc76ba61e3491d290ebd9Cort Stratton skip |= log_msg( 2918ce7bf009f8fc7e268efdc76ba61e3491d290ebd9Cort Stratton report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, 2919315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis VALIDATION_ERROR_1400069c, "DS", 2920ce7bf009f8fc7e268efdc76ba61e3491d290ebd9Cort Stratton "CreateRenderPass: attachment %u is first used as an input attachment in subpass %u with loadOp=CLEAR. %s", 2921315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis attach_index, attach_index, validation_error_map[VALIDATION_ERROR_1400069c]); 2922ce7bf009f8fc7e268efdc76ba61e3491d290ebd9Cort Stratton } 2923ce7bf009f8fc7e268efdc76ba61e3491d290ebd9Cort Stratton } 2924ce7bf009f8fc7e268efdc76ba61e3491d290ebd9Cort Stratton attach_first_use[attach_index] = false; 2925ce7bf009f8fc7e268efdc76ba61e3491d290ebd9Cort Stratton } 2926d76960c655c53f47aaf2e16538ea0c40e6d527ecMark Lobodzinski for (uint32_t j = 0; j < subpass.colorAttachmentCount; ++j) { 2927d76960c655c53f47aaf2e16538ea0c40e6d527ecMark Lobodzinski auto attach_index = subpass.pColorAttachments[j].attachment; 2928d76960c655c53f47aaf2e16538ea0c40e6d527ecMark Lobodzinski if (attach_index == VK_ATTACHMENT_UNUSED) continue; 2929d76960c655c53f47aaf2e16538ea0c40e6d527ecMark Lobodzinski 293087a57d8e822316de46ee97f514187331b1f4f09dTobin Ehlis // TODO: Need a way to validate shared presentable images here, currently just allowing 293187a57d8e822316de46ee97f514187331b1f4f09dTobin Ehlis // VK_IMAGE_LAYOUT_SHARED_PRESENT_KHR 293287a57d8e822316de46ee97f514187331b1f4f09dTobin Ehlis // as an acceptable layout, but need to make sure shared presentable images ONLY use that layout 2933d76960c655c53f47aaf2e16538ea0c40e6d527ecMark Lobodzinski switch (subpass.pColorAttachments[j].layout) { 2934374d6151f9db5d62891ffdbe833bcbb51848db6bMark Lobodzinski case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL: 29351007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton // This is ideal. 293687a57d8e822316de46ee97f514187331b1f4f09dTobin Ehlis case VK_IMAGE_LAYOUT_SHARED_PRESENT_KHR: 293787a57d8e822316de46ee97f514187331b1f4f09dTobin Ehlis // TODO: See note above, just assuming that attachment is shared presentable and allowing this for now. 2938374d6151f9db5d62891ffdbe833bcbb51848db6bMark Lobodzinski break; 2939d76960c655c53f47aaf2e16538ea0c40e6d527ecMark Lobodzinski 2940374d6151f9db5d62891ffdbe833bcbb51848db6bMark Lobodzinski case VK_IMAGE_LAYOUT_GENERAL: 2941374d6151f9db5d62891ffdbe833bcbb51848db6bMark Lobodzinski // May not be optimal; TODO: reconsider this warning based on other constraints? 2942374d6151f9db5d62891ffdbe833bcbb51848db6bMark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT, 2943374d6151f9db5d62891ffdbe833bcbb51848db6bMark Lobodzinski VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, DRAWSTATE_INVALID_IMAGE_LAYOUT, "DS", 2944374d6151f9db5d62891ffdbe833bcbb51848db6bMark Lobodzinski "Layout for color attachment is GENERAL but should be COLOR_ATTACHMENT_OPTIMAL."); 2945374d6151f9db5d62891ffdbe833bcbb51848db6bMark Lobodzinski break; 2946374d6151f9db5d62891ffdbe833bcbb51848db6bMark Lobodzinski 2947374d6151f9db5d62891ffdbe833bcbb51848db6bMark Lobodzinski default: 2948374d6151f9db5d62891ffdbe833bcbb51848db6bMark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, 2949374d6151f9db5d62891ffdbe833bcbb51848db6bMark Lobodzinski __LINE__, DRAWSTATE_INVALID_IMAGE_LAYOUT, "DS", 2950374d6151f9db5d62891ffdbe833bcbb51848db6bMark Lobodzinski "Layout for color attachment is %s but can only be COLOR_ATTACHMENT_OPTIMAL or GENERAL.", 2951374d6151f9db5d62891ffdbe833bcbb51848db6bMark Lobodzinski string_VkImageLayout(subpass.pColorAttachments[j].layout)); 2952d76960c655c53f47aaf2e16538ea0c40e6d527ecMark Lobodzinski } 2953d76960c655c53f47aaf2e16538ea0c40e6d527ecMark Lobodzinski 2954d76960c655c53f47aaf2e16538ea0c40e6d527ecMark Lobodzinski if (attach_first_use[attach_index]) { 2955374d6151f9db5d62891ffdbe833bcbb51848db6bMark Lobodzinski skip |= ValidateLayoutVsAttachmentDescription(report_data, subpass.pColorAttachments[j].layout, attach_index, 2956374d6151f9db5d62891ffdbe833bcbb51848db6bMark Lobodzinski pCreateInfo->pAttachments[attach_index]); 2957d76960c655c53f47aaf2e16538ea0c40e6d527ecMark Lobodzinski } 2958d76960c655c53f47aaf2e16538ea0c40e6d527ecMark Lobodzinski attach_first_use[attach_index] = false; 2959d76960c655c53f47aaf2e16538ea0c40e6d527ecMark Lobodzinski } 2960093e327fb28d5083306dcc66cd71b7809771f496Lenny Komow 2961d76960c655c53f47aaf2e16538ea0c40e6d527ecMark Lobodzinski if (subpass.pDepthStencilAttachment && subpass.pDepthStencilAttachment->attachment != VK_ATTACHMENT_UNUSED) { 2962d76960c655c53f47aaf2e16538ea0c40e6d527ecMark Lobodzinski switch (subpass.pDepthStencilAttachment->layout) { 29635f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton case VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL: 29645f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton case VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL: 29655f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton // These are ideal. 29665f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton break; 2967093e327fb28d5083306dcc66cd71b7809771f496Lenny Komow 29685f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton case VK_IMAGE_LAYOUT_GENERAL: 29695f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton // May not be optimal; TODO: reconsider this warning based on other constraints? GENERAL can be better than 29705f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton // doing a bunch of transitions. 29715f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton skip |= log_msg(report_data, VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT, 29725f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, DRAWSTATE_INVALID_IMAGE_LAYOUT, "DS", 29735f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton "GENERAL layout for depth attachment may not give optimal performance."); 2974374d6151f9db5d62891ffdbe833bcbb51848db6bMark Lobodzinski break; 2975374d6151f9db5d62891ffdbe833bcbb51848db6bMark Lobodzinski 29765f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton case VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL_KHR: 29775f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton case VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL_KHR: 29785f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton if (GetDeviceExtensions(device_data)->vk_khr_maintenance2) { 29795f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton break; 29805f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton } else { 29815f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton // Intentionally fall through to generic error message 29825f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton } 29835f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton 29845f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton default: 29855f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton // No other layouts are acceptable 29865f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, 29875f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton __LINE__, DRAWSTATE_INVALID_IMAGE_LAYOUT, "DS", 29885f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton "Layout for depth attachment is %s but can only be DEPTH_STENCIL_ATTACHMENT_OPTIMAL, " 29895f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton "DEPTH_STENCIL_READ_ONLY_OPTIMAL or GENERAL.", 29905f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton string_VkImageLayout(subpass.pDepthStencilAttachment->layout)); 2991d76960c655c53f47aaf2e16538ea0c40e6d527ecMark Lobodzinski } 2992d76960c655c53f47aaf2e16538ea0c40e6d527ecMark Lobodzinski 2993d76960c655c53f47aaf2e16538ea0c40e6d527ecMark Lobodzinski auto attach_index = subpass.pDepthStencilAttachment->attachment; 2994d76960c655c53f47aaf2e16538ea0c40e6d527ecMark Lobodzinski if (attach_first_use[attach_index]) { 2995374d6151f9db5d62891ffdbe833bcbb51848db6bMark Lobodzinski skip |= ValidateLayoutVsAttachmentDescription(report_data, subpass.pDepthStencilAttachment->layout, attach_index, 2996374d6151f9db5d62891ffdbe833bcbb51848db6bMark Lobodzinski pCreateInfo->pAttachments[attach_index]); 2997d76960c655c53f47aaf2e16538ea0c40e6d527ecMark Lobodzinski } 2998d76960c655c53f47aaf2e16538ea0c40e6d527ecMark Lobodzinski attach_first_use[attach_index] = false; 2999d76960c655c53f47aaf2e16538ea0c40e6d527ecMark Lobodzinski } 3000d76960c655c53f47aaf2e16538ea0c40e6d527ecMark Lobodzinski } 3001d76960c655c53f47aaf2e16538ea0c40e6d527ecMark Lobodzinski return skip; 3002d76960c655c53f47aaf2e16538ea0c40e6d527ecMark Lobodzinski} 3003c3340a06ecac4d7b9540592cae339f8fc224d0b1Mark Lobodzinski 3004c3340a06ecac4d7b9540592cae339f8fc224d0b1Mark Lobodzinski// For any image objects that overlap mapped memory, verify that their layouts are PREINIT or GENERAL 300509cd2c76808f1485206baeda9864f7ed907d7e05Mark Lobodzinskibool ValidateMapImageLayouts(core_validation::layer_data *device_data, VkDevice device, DEVICE_MEM_INFO const *mem_info, 300609cd2c76808f1485206baeda9864f7ed907d7e05Mark Lobodzinski VkDeviceSize offset, VkDeviceSize end_offset) { 300709cd2c76808f1485206baeda9864f7ed907d7e05Mark Lobodzinski const debug_report_data *report_data = core_validation::GetReportData(device_data); 300809cd2c76808f1485206baeda9864f7ed907d7e05Mark Lobodzinski bool skip = false; 300909cd2c76808f1485206baeda9864f7ed907d7e05Mark Lobodzinski // Iterate over all bound image ranges and verify that for any that overlap the map ranges, the layouts are 301009cd2c76808f1485206baeda9864f7ed907d7e05Mark Lobodzinski // VK_IMAGE_LAYOUT_PREINITIALIZED or VK_IMAGE_LAYOUT_GENERAL 3011c3340a06ecac4d7b9540592cae339f8fc224d0b1Mark Lobodzinski // TODO : This can be optimized if we store ranges based on starting address and early exit when we pass our range 3012c3340a06ecac4d7b9540592cae339f8fc224d0b1Mark Lobodzinski for (auto image_handle : mem_info->bound_images) { 3013c3340a06ecac4d7b9540592cae339f8fc224d0b1Mark Lobodzinski auto img_it = mem_info->bound_ranges.find(image_handle); 3014c3340a06ecac4d7b9540592cae339f8fc224d0b1Mark Lobodzinski if (img_it != mem_info->bound_ranges.end()) { 301509cd2c76808f1485206baeda9864f7ed907d7e05Mark Lobodzinski if (rangesIntersect(device_data, &img_it->second, offset, end_offset)) { 3016c3340a06ecac4d7b9540592cae339f8fc224d0b1Mark Lobodzinski std::vector<VkImageLayout> layouts; 301709cd2c76808f1485206baeda9864f7ed907d7e05Mark Lobodzinski if (FindLayouts(device_data, VkImage(image_handle), layouts)) { 3018c3340a06ecac4d7b9540592cae339f8fc224d0b1Mark Lobodzinski for (auto layout : layouts) { 3019c3340a06ecac4d7b9540592cae339f8fc224d0b1Mark Lobodzinski if (layout != VK_IMAGE_LAYOUT_PREINITIALIZED && layout != VK_IMAGE_LAYOUT_GENERAL) { 30209b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus skip |= 30219b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus log_msg(report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT, 30229b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(mem_info->mem), __LINE__, DRAWSTATE_INVALID_IMAGE_LAYOUT, "DS", 30235f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton "Mapping an image with layout %s can result in undefined behavior if this memory is used " 30245f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton "by the device. Only GENERAL or PREINITIALIZED should be used.", 30259b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus string_VkImageLayout(layout)); 3026c3340a06ecac4d7b9540592cae339f8fc224d0b1Mark Lobodzinski } 3027c3340a06ecac4d7b9540592cae339f8fc224d0b1Mark Lobodzinski } 3028c3340a06ecac4d7b9540592cae339f8fc224d0b1Mark Lobodzinski } 3029c3340a06ecac4d7b9540592cae339f8fc224d0b1Mark Lobodzinski } 3030c3340a06ecac4d7b9540592cae339f8fc224d0b1Mark Lobodzinski } 3031c3340a06ecac4d7b9540592cae339f8fc224d0b1Mark Lobodzinski } 303209cd2c76808f1485206baeda9864f7ed907d7e05Mark Lobodzinski return skip; 3033c3340a06ecac4d7b9540592cae339f8fc224d0b1Mark Lobodzinski} 30343683836d93195a82dfd2c715ce9d56b030801598Mark Lobodzinski 30353683836d93195a82dfd2c715ce9d56b030801598Mark Lobodzinski// Helper function to validate correct usage bits set for buffers or images. Verify that (actual & desired) flags != 0 or, if strict 30363683836d93195a82dfd2c715ce9d56b030801598Mark Lobodzinski// is true, verify that (actual & desired) flags == desired 3037abfd2f0c07bb8ff00d48dbe6127819eaf839c9aeMark Lobodzinskistatic bool validate_usage_flags(layer_data *device_data, VkFlags actual, VkFlags desired, VkBool32 strict, uint64_t obj_handle, 30387a9423788398dbeb6d1fe0354a66123b61afda96Mark Lobodzinski VulkanObjectType obj_type, int32_t const msgCode, char const *func_name, char const *usage_str) { 3039abfd2f0c07bb8ff00d48dbe6127819eaf839c9aeMark Lobodzinski const debug_report_data *report_data = core_validation::GetReportData(device_data); 30403683836d93195a82dfd2c715ce9d56b030801598Mark Lobodzinski 30413683836d93195a82dfd2c715ce9d56b030801598Mark Lobodzinski bool correct_usage = false; 3042abfd2f0c07bb8ff00d48dbe6127819eaf839c9aeMark Lobodzinski bool skip = false; 30437a9423788398dbeb6d1fe0354a66123b61afda96Mark Lobodzinski const char *type_str = object_string[obj_type]; 30443683836d93195a82dfd2c715ce9d56b030801598Mark Lobodzinski if (strict) { 30453683836d93195a82dfd2c715ce9d56b030801598Mark Lobodzinski correct_usage = ((actual & desired) == desired); 30463683836d93195a82dfd2c715ce9d56b030801598Mark Lobodzinski } else { 30473683836d93195a82dfd2c715ce9d56b030801598Mark Lobodzinski correct_usage = ((actual & desired) != 0); 30483683836d93195a82dfd2c715ce9d56b030801598Mark Lobodzinski } 30493683836d93195a82dfd2c715ce9d56b030801598Mark Lobodzinski if (!correct_usage) { 30503683836d93195a82dfd2c715ce9d56b030801598Mark Lobodzinski if (msgCode == -1) { 30513683836d93195a82dfd2c715ce9d56b030801598Mark Lobodzinski // TODO: Fix callers with msgCode == -1 to use correct validation checks. 30525f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton skip = 30535f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, get_debug_report_enum[obj_type], obj_handle, __LINE__, 30545f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton MEMTRACK_INVALID_USAGE_FLAG, "MEM", 30555f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton "Invalid usage flag for %s 0x%" PRIx64 " used by %s. In this case, %s should have %s set during creation.", 30565f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton type_str, obj_handle, func_name, type_str, usage_str); 30573683836d93195a82dfd2c715ce9d56b030801598Mark Lobodzinski } else { 30583683836d93195a82dfd2c715ce9d56b030801598Mark Lobodzinski const char *valid_usage = (msgCode == -1) ? "" : validation_error_map[msgCode]; 30595f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton skip = log_msg( 30605f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, get_debug_report_enum[obj_type], obj_handle, __LINE__, msgCode, "MEM", 30615f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton "Invalid usage flag for %s 0x%" PRIx64 " used by %s. In this case, %s should have %s set during creation. %s", 30625f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton type_str, obj_handle, func_name, type_str, usage_str, valid_usage); 30633683836d93195a82dfd2c715ce9d56b030801598Mark Lobodzinski } 30643683836d93195a82dfd2c715ce9d56b030801598Mark Lobodzinski } 3065abfd2f0c07bb8ff00d48dbe6127819eaf839c9aeMark Lobodzinski return skip; 30663683836d93195a82dfd2c715ce9d56b030801598Mark Lobodzinski} 30673683836d93195a82dfd2c715ce9d56b030801598Mark Lobodzinski 30683683836d93195a82dfd2c715ce9d56b030801598Mark Lobodzinski// Helper function to validate usage flags for buffers. For given buffer_state send actual vs. desired usage off to helper above 30693683836d93195a82dfd2c715ce9d56b030801598Mark Lobodzinski// where an error will be flagged if usage is not correct 30700bcfcca3af64ac0214112949aa68496914b8d7a9Chris Forbesbool ValidateImageUsageFlags(layer_data *device_data, IMAGE_STATE const *image_state, VkFlags desired, bool strict, 30713683836d93195a82dfd2c715ce9d56b030801598Mark Lobodzinski int32_t const msgCode, char const *func_name, char const *usage_string) { 30729b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus return validate_usage_flags(device_data, image_state->createInfo.usage, desired, strict, HandleToUint64(image_state->image), 30739b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus kVulkanObjectTypeImage, msgCode, func_name, usage_string); 30743683836d93195a82dfd2c715ce9d56b030801598Mark Lobodzinski} 30753683836d93195a82dfd2c715ce9d56b030801598Mark Lobodzinski 30763683836d93195a82dfd2c715ce9d56b030801598Mark Lobodzinski// Helper function to validate usage flags for buffers. For given buffer_state send actual vs. desired usage off to helper above 30773683836d93195a82dfd2c715ce9d56b030801598Mark Lobodzinski// where an error will be flagged if usage is not correct 30780bcfcca3af64ac0214112949aa68496914b8d7a9Chris Forbesbool ValidateBufferUsageFlags(layer_data *device_data, BUFFER_STATE const *buffer_state, VkFlags desired, bool strict, 30793683836d93195a82dfd2c715ce9d56b030801598Mark Lobodzinski int32_t const msgCode, char const *func_name, char const *usage_string) { 30809b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus return validate_usage_flags(device_data, buffer_state->createInfo.usage, desired, strict, HandleToUint64(buffer_state->buffer), 30819b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus kVulkanObjectTypeBuffer, msgCode, func_name, usage_string); 30823683836d93195a82dfd2c715ce9d56b030801598Mark Lobodzinski} 30833683836d93195a82dfd2c715ce9d56b030801598Mark Lobodzinski 3084abfd2f0c07bb8ff00d48dbe6127819eaf839c9aeMark Lobodzinskibool PreCallValidateCreateBuffer(layer_data *device_data, const VkBufferCreateInfo *pCreateInfo) { 30853683836d93195a82dfd2c715ce9d56b030801598Mark Lobodzinski bool skip = false; 308601363bf3d84ba5841a6870b40c041c2f53d76583Mark Lobodzinski const debug_report_data *report_data = core_validation::GetReportData(device_data); 308701363bf3d84ba5841a6870b40c041c2f53d76583Mark Lobodzinski 3088fbe5dfacbf68145cd1543b60decb6204ed81faffChris Forbes // TODO: Add check for VALIDATION_ERROR_1ec0071e (sparse address space accounting) 308901363bf3d84ba5841a6870b40c041c2f53d76583Mark Lobodzinski 309001363bf3d84ba5841a6870b40c041c2f53d76583Mark Lobodzinski if ((pCreateInfo->flags & VK_BUFFER_CREATE_SPARSE_BINDING_BIT) && (!GetEnabledFeatures(device_data)->sparseBinding)) { 309101363bf3d84ba5841a6870b40c041c2f53d76583Mark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, 3092315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis VALIDATION_ERROR_01400726, "DS", 309301363bf3d84ba5841a6870b40c041c2f53d76583Mark Lobodzinski "vkCreateBuffer(): the sparseBinding device feature is disabled: Buffers cannot be created with the " 309401363bf3d84ba5841a6870b40c041c2f53d76583Mark Lobodzinski "VK_BUFFER_CREATE_SPARSE_BINDING_BIT set. %s", 3095315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_01400726]); 309601363bf3d84ba5841a6870b40c041c2f53d76583Mark Lobodzinski } 3097f575247dabffb70e4de1a6f9522db3f09a55492eMark Lobodzinski 3098f575247dabffb70e4de1a6f9522db3f09a55492eMark Lobodzinski if ((pCreateInfo->flags & VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT) && (!GetEnabledFeatures(device_data)->sparseResidencyBuffer)) { 30995f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, 31005f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton VALIDATION_ERROR_01400728, "DS", 31015f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton "vkCreateBuffer(): the sparseResidencyBuffer device feature is disabled: Buffers cannot be created with " 31025f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton "the VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT set. %s", 31035f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton validation_error_map[VALIDATION_ERROR_01400728]); 3104f575247dabffb70e4de1a6f9522db3f09a55492eMark Lobodzinski } 31057e105b26dcb40aff4f9776b8f5b5f1326aa1e36cMark Lobodzinski 31067e105b26dcb40aff4f9776b8f5b5f1326aa1e36cMark Lobodzinski if ((pCreateInfo->flags & VK_BUFFER_CREATE_SPARSE_ALIASED_BIT) && (!GetEnabledFeatures(device_data)->sparseResidencyAliased)) { 31075f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, 31085f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton VALIDATION_ERROR_0140072a, "DS", 31095f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton "vkCreateBuffer(): the sparseResidencyAliased device feature is disabled: Buffers cannot be created with " 31105f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton "the VK_BUFFER_CREATE_SPARSE_ALIASED_BIT set. %s", 31115f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton validation_error_map[VALIDATION_ERROR_0140072a]); 31127e105b26dcb40aff4f9776b8f5b5f1326aa1e36cMark Lobodzinski } 31133683836d93195a82dfd2c715ce9d56b030801598Mark Lobodzinski return skip; 31143683836d93195a82dfd2c715ce9d56b030801598Mark Lobodzinski} 31153683836d93195a82dfd2c715ce9d56b030801598Mark Lobodzinski 31163683836d93195a82dfd2c715ce9d56b030801598Mark Lobodzinskivoid PostCallRecordCreateBuffer(layer_data *device_data, const VkBufferCreateInfo *pCreateInfo, VkBuffer *pBuffer) { 31173683836d93195a82dfd2c715ce9d56b030801598Mark Lobodzinski // TODO : This doesn't create deep copy of pQueueFamilyIndices so need to fix that if/when we want that data to be valid 31183683836d93195a82dfd2c715ce9d56b030801598Mark Lobodzinski GetBufferMap(device_data) 31193683836d93195a82dfd2c715ce9d56b030801598Mark Lobodzinski ->insert(std::make_pair(*pBuffer, std::unique_ptr<BUFFER_STATE>(new BUFFER_STATE(*pBuffer, pCreateInfo)))); 31203683836d93195a82dfd2c715ce9d56b030801598Mark Lobodzinski} 31213683836d93195a82dfd2c715ce9d56b030801598Mark Lobodzinski 3122abfd2f0c07bb8ff00d48dbe6127819eaf839c9aeMark Lobodzinskibool PreCallValidateCreateBufferView(layer_data *device_data, const VkBufferViewCreateInfo *pCreateInfo) { 3123abfd2f0c07bb8ff00d48dbe6127819eaf839c9aeMark Lobodzinski bool skip = false; 3124abfd2f0c07bb8ff00d48dbe6127819eaf839c9aeMark Lobodzinski BUFFER_STATE *buffer_state = GetBufferState(device_data, pCreateInfo->buffer); 31253683836d93195a82dfd2c715ce9d56b030801598Mark Lobodzinski // If this isn't a sparse buffer, it needs to have memory backing it at CreateBufferView time 31263683836d93195a82dfd2c715ce9d56b030801598Mark Lobodzinski if (buffer_state) { 3127315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= ValidateMemoryIsBoundToBuffer(device_data, buffer_state, "vkCreateBufferView()", VALIDATION_ERROR_01a0074e); 31283683836d93195a82dfd2c715ce9d56b030801598Mark Lobodzinski // In order to create a valid buffer view, the buffer must have been created with at least one of the following flags: 31293683836d93195a82dfd2c715ce9d56b030801598Mark Lobodzinski // UNIFORM_TEXEL_BUFFER_BIT or STORAGE_TEXEL_BUFFER_BIT 3130abfd2f0c07bb8ff00d48dbe6127819eaf839c9aeMark Lobodzinski skip |= ValidateBufferUsageFlags( 3131abfd2f0c07bb8ff00d48dbe6127819eaf839c9aeMark Lobodzinski device_data, buffer_state, VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT | VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT, false, 3132315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis VALIDATION_ERROR_01a00748, "vkCreateBufferView()", "VK_BUFFER_USAGE_[STORAGE|UNIFORM]_TEXEL_BUFFER_BIT"); 31333683836d93195a82dfd2c715ce9d56b030801598Mark Lobodzinski } 3134abfd2f0c07bb8ff00d48dbe6127819eaf839c9aeMark Lobodzinski return skip; 31353683836d93195a82dfd2c715ce9d56b030801598Mark Lobodzinski} 31363683836d93195a82dfd2c715ce9d56b030801598Mark Lobodzinski 31373683836d93195a82dfd2c715ce9d56b030801598Mark Lobodzinskivoid PostCallRecordCreateBufferView(layer_data *device_data, const VkBufferViewCreateInfo *pCreateInfo, VkBufferView *pView) { 31383683836d93195a82dfd2c715ce9d56b030801598Mark Lobodzinski (*GetBufferViewMap(device_data))[*pView] = std::unique_ptr<BUFFER_VIEW_STATE>(new BUFFER_VIEW_STATE(*pView, pCreateInfo)); 31393683836d93195a82dfd2c715ce9d56b030801598Mark Lobodzinski} 31401c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski 31411c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski// For the given format verify that the aspect masks make sense 31421c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinskibool ValidateImageAspectMask(layer_data *device_data, VkImage image, VkFormat format, VkImageAspectFlags aspect_mask, 31431c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski const char *func_name) { 31441c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski const debug_report_data *report_data = core_validation::GetReportData(device_data); 31451c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski bool skip = false; 314616769f6b2a7721e391952a97f010cbb530e4f211Dave Houlton if (FormatIsColor(format)) { 31471c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski if ((aspect_mask & VK_IMAGE_ASPECT_COLOR_BIT) != VK_IMAGE_ASPECT_COLOR_BIT) { 31489b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, 3149315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(image), __LINE__, VALIDATION_ERROR_0a400c01, "IMAGE", 31501c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski "%s: Color image formats must have the VK_IMAGE_ASPECT_COLOR_BIT set. %s", func_name, 3151315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_0a400c01]); 31521c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski } else if ((aspect_mask & VK_IMAGE_ASPECT_COLOR_BIT) != aspect_mask) { 31539b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, 3154315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(image), __LINE__, VALIDATION_ERROR_0a400c01, "IMAGE", 31551c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski "%s: Color image formats must have ONLY the VK_IMAGE_ASPECT_COLOR_BIT set. %s", func_name, 3156315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_0a400c01]); 31571c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski } 315816769f6b2a7721e391952a97f010cbb530e4f211Dave Houlton } else if (FormatIsDepthAndStencil(format)) { 31591c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski if ((aspect_mask & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) == 0) { 31609b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, 3161315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(image), __LINE__, VALIDATION_ERROR_0a400c01, "IMAGE", 31625f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton "%s: Depth/stencil image formats must have at least one of VK_IMAGE_ASPECT_DEPTH_BIT and " 31635f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton "VK_IMAGE_ASPECT_STENCIL_BIT set. %s", 3164315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis func_name, validation_error_map[VALIDATION_ERROR_0a400c01]); 31651c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski } else if ((aspect_mask & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) != aspect_mask) { 31669b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, 3167315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(image), __LINE__, VALIDATION_ERROR_0a400c01, "IMAGE", 31681c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski "%s: Combination depth/stencil image formats can have only the VK_IMAGE_ASPECT_DEPTH_BIT and " 31691c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski "VK_IMAGE_ASPECT_STENCIL_BIT set. %s", 3170315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis func_name, validation_error_map[VALIDATION_ERROR_0a400c01]); 31711c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski } 317216769f6b2a7721e391952a97f010cbb530e4f211Dave Houlton } else if (FormatIsDepthOnly(format)) { 31731c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski if ((aspect_mask & VK_IMAGE_ASPECT_DEPTH_BIT) != VK_IMAGE_ASPECT_DEPTH_BIT) { 31749b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, 3175315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(image), __LINE__, VALIDATION_ERROR_0a400c01, "IMAGE", 31761c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski "%s: Depth-only image formats must have the VK_IMAGE_ASPECT_DEPTH_BIT set. %s", func_name, 3177315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_0a400c01]); 31781c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski } else if ((aspect_mask & VK_IMAGE_ASPECT_DEPTH_BIT) != aspect_mask) { 31799b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, 3180315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(image), __LINE__, VALIDATION_ERROR_0a400c01, "IMAGE", 31811c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski "%s: Depth-only image formats can have only the VK_IMAGE_ASPECT_DEPTH_BIT set. %s", func_name, 3182315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_0a400c01]); 31831c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski } 318416769f6b2a7721e391952a97f010cbb530e4f211Dave Houlton } else if (FormatIsStencilOnly(format)) { 31851c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski if ((aspect_mask & VK_IMAGE_ASPECT_STENCIL_BIT) != VK_IMAGE_ASPECT_STENCIL_BIT) { 31869b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, 3187315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(image), __LINE__, VALIDATION_ERROR_0a400c01, "IMAGE", 31881c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski "%s: Stencil-only image formats must have the VK_IMAGE_ASPECT_STENCIL_BIT set. %s", func_name, 3189315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_0a400c01]); 31901c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski } else if ((aspect_mask & VK_IMAGE_ASPECT_STENCIL_BIT) != aspect_mask) { 31919b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, 3192315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(image), __LINE__, VALIDATION_ERROR_0a400c01, "IMAGE", 31931c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski "%s: Stencil-only image formats can have only the VK_IMAGE_ASPECT_STENCIL_BIT set. %s", func_name, 3194315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_0a400c01]); 31951c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski } 31961c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski } 31971c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski return skip; 31981c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski} 31991c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski 3200e25e057866af155bd456003120aa6155530a0e5fPetr Krausstruct SubresourceRangeErrorCodes { 3201e25e057866af155bd456003120aa6155530a0e5fPetr Kraus UNIQUE_VALIDATION_ERROR_CODE base_mip_err, mip_count_err, base_layer_err, layer_count_err; 3202e25e057866af155bd456003120aa6155530a0e5fPetr Kraus}; 3203e25e057866af155bd456003120aa6155530a0e5fPetr Kraus 3204e25e057866af155bd456003120aa6155530a0e5fPetr Krausbool ValidateImageSubresourceRange(const layer_data *device_data, const uint32_t image_mip_count, const uint32_t image_layer_count, 3205e25e057866af155bd456003120aa6155530a0e5fPetr Kraus const VkImageSubresourceRange &subresourceRange, const char *cmd_name, const char *param_name, 3206e25e057866af155bd456003120aa6155530a0e5fPetr Kraus const char *image_layer_count_var_name, const uint64_t image_handle, 3207e25e057866af155bd456003120aa6155530a0e5fPetr Kraus SubresourceRangeErrorCodes errorCodes) { 32081c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski const debug_report_data *report_data = core_validation::GetReportData(device_data); 32091c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski bool skip = false; 321023c5a2092f724fef497a5c87a489f32c8fa51e58Petr Kraus 321123c5a2092f724fef497a5c87a489f32c8fa51e58Petr Kraus // Validate mip levels 3212e25e057866af155bd456003120aa6155530a0e5fPetr Kraus if (subresourceRange.baseMipLevel >= image_mip_count) { 3213e25e057866af155bd456003120aa6155530a0e5fPetr Kraus skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, image_handle, __LINE__, 3214e25e057866af155bd456003120aa6155530a0e5fPetr Kraus errorCodes.base_mip_err, "IMAGE", 3215e25e057866af155bd456003120aa6155530a0e5fPetr Kraus "%s: %s.baseMipLevel (= %" PRIu32 3216e25e057866af155bd456003120aa6155530a0e5fPetr Kraus ") is greater or equal to the mip level count of the image (i.e. greater or equal to %" PRIu32 "). %s", 3217e25e057866af155bd456003120aa6155530a0e5fPetr Kraus cmd_name, param_name, subresourceRange.baseMipLevel, image_mip_count, 3218e25e057866af155bd456003120aa6155530a0e5fPetr Kraus validation_error_map[errorCodes.base_mip_err]); 3219e25e057866af155bd456003120aa6155530a0e5fPetr Kraus } 3220e25e057866af155bd456003120aa6155530a0e5fPetr Kraus 3221e25e057866af155bd456003120aa6155530a0e5fPetr Kraus if (subresourceRange.levelCount != VK_REMAINING_MIP_LEVELS) { 3222e25e057866af155bd456003120aa6155530a0e5fPetr Kraus if (subresourceRange.levelCount == 0) { 3223e25e057866af155bd456003120aa6155530a0e5fPetr Kraus skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, image_handle, 3224e25e057866af155bd456003120aa6155530a0e5fPetr Kraus __LINE__, errorCodes.mip_count_err, "IMAGE", "%s: %s.levelCount is 0. %s", cmd_name, param_name, 3225e25e057866af155bd456003120aa6155530a0e5fPetr Kraus validation_error_map[errorCodes.mip_count_err]); 3226e25e057866af155bd456003120aa6155530a0e5fPetr Kraus } else { 3227e25e057866af155bd456003120aa6155530a0e5fPetr Kraus const uint64_t necessary_mip_count = uint64_t{subresourceRange.baseMipLevel} + uint64_t{subresourceRange.levelCount}; 322823c5a2092f724fef497a5c87a489f32c8fa51e58Petr Kraus 3229e25e057866af155bd456003120aa6155530a0e5fPetr Kraus if (necessary_mip_count > image_mip_count) { 3230e25e057866af155bd456003120aa6155530a0e5fPetr Kraus skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, image_handle, 3231e25e057866af155bd456003120aa6155530a0e5fPetr Kraus __LINE__, errorCodes.mip_count_err, "IMAGE", 3232e25e057866af155bd456003120aa6155530a0e5fPetr Kraus "%s: %s.baseMipLevel + .levelCount (= %" PRIu32 " + %" PRIu32 " = %" PRIu64 3233e25e057866af155bd456003120aa6155530a0e5fPetr Kraus ") is greater than the mip level count of the image (i.e. greater than %" PRIu32 "). %s", 3234e25e057866af155bd456003120aa6155530a0e5fPetr Kraus cmd_name, param_name, subresourceRange.baseMipLevel, subresourceRange.levelCount, 3235e25e057866af155bd456003120aa6155530a0e5fPetr Kraus necessary_mip_count, image_mip_count, validation_error_map[errorCodes.mip_count_err]); 3236e25e057866af155bd456003120aa6155530a0e5fPetr Kraus } 323723c5a2092f724fef497a5c87a489f32c8fa51e58Petr Kraus } 3238e25e057866af155bd456003120aa6155530a0e5fPetr Kraus } 323923c5a2092f724fef497a5c87a489f32c8fa51e58Petr Kraus 3240e25e057866af155bd456003120aa6155530a0e5fPetr Kraus // Validate array layers 3241e25e057866af155bd456003120aa6155530a0e5fPetr Kraus if (subresourceRange.baseArrayLayer >= image_layer_count) { 3242e25e057866af155bd456003120aa6155530a0e5fPetr Kraus skip |= 3243e25e057866af155bd456003120aa6155530a0e5fPetr Kraus log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, image_handle, __LINE__, 3244e25e057866af155bd456003120aa6155530a0e5fPetr Kraus errorCodes.base_layer_err, "IMAGE", 3245e25e057866af155bd456003120aa6155530a0e5fPetr Kraus "%s: %s.baseArrayLayer (= %" PRIu32 3246e25e057866af155bd456003120aa6155530a0e5fPetr Kraus ") is greater or equal to the %s of the image when it was created (i.e. greater or equal to %" PRIu32 "). %s", 3247e25e057866af155bd456003120aa6155530a0e5fPetr Kraus cmd_name, param_name, subresourceRange.baseArrayLayer, image_layer_count_var_name, image_layer_count, 3248e25e057866af155bd456003120aa6155530a0e5fPetr Kraus validation_error_map[errorCodes.base_layer_err]); 3249e25e057866af155bd456003120aa6155530a0e5fPetr Kraus } 3250e25e057866af155bd456003120aa6155530a0e5fPetr Kraus 3251e25e057866af155bd456003120aa6155530a0e5fPetr Kraus if (subresourceRange.layerCount != VK_REMAINING_ARRAY_LAYERS) { 3252e25e057866af155bd456003120aa6155530a0e5fPetr Kraus if (subresourceRange.layerCount == 0) { 3253e25e057866af155bd456003120aa6155530a0e5fPetr Kraus skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, image_handle, 3254e25e057866af155bd456003120aa6155530a0e5fPetr Kraus __LINE__, errorCodes.layer_count_err, "IMAGE", "%s: %s.layerCount is 0. %s", cmd_name, param_name, 3255e25e057866af155bd456003120aa6155530a0e5fPetr Kraus validation_error_map[errorCodes.layer_count_err]); 3256e25e057866af155bd456003120aa6155530a0e5fPetr Kraus } else { 3257e25e057866af155bd456003120aa6155530a0e5fPetr Kraus const uint64_t necessary_layer_count = 3258e25e057866af155bd456003120aa6155530a0e5fPetr Kraus uint64_t{subresourceRange.baseArrayLayer} + uint64_t{subresourceRange.layerCount}; 3259e25e057866af155bd456003120aa6155530a0e5fPetr Kraus 3260e25e057866af155bd456003120aa6155530a0e5fPetr Kraus if (necessary_layer_count > image_layer_count) { 3261e25e057866af155bd456003120aa6155530a0e5fPetr Kraus skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, image_handle, 3262e25e057866af155bd456003120aa6155530a0e5fPetr Kraus __LINE__, errorCodes.layer_count_err, "IMAGE", 3263e25e057866af155bd456003120aa6155530a0e5fPetr Kraus "%s: %s.baseArrayLayer + .layerCount (= %" PRIu32 " + %" PRIu32 " = %" PRIu64 3264e25e057866af155bd456003120aa6155530a0e5fPetr Kraus ") is greater than the %s of the image when it was created (i.e. greater than %" PRIu32 "). %s", 3265e25e057866af155bd456003120aa6155530a0e5fPetr Kraus cmd_name, param_name, subresourceRange.baseArrayLayer, subresourceRange.layerCount, 3266e25e057866af155bd456003120aa6155530a0e5fPetr Kraus necessary_layer_count, image_layer_count_var_name, image_layer_count, 3267e25e057866af155bd456003120aa6155530a0e5fPetr Kraus validation_error_map[errorCodes.layer_count_err]); 3268e25e057866af155bd456003120aa6155530a0e5fPetr Kraus } 326923c5a2092f724fef497a5c87a489f32c8fa51e58Petr Kraus } 32701c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski } 327123c5a2092f724fef497a5c87a489f32c8fa51e58Petr Kraus 3272e25e057866af155bd456003120aa6155530a0e5fPetr Kraus return skip; 3273e25e057866af155bd456003120aa6155530a0e5fPetr Kraus} 3274e25e057866af155bd456003120aa6155530a0e5fPetr Kraus 3275e25e057866af155bd456003120aa6155530a0e5fPetr Krausbool ValidateCreateImageViewSubresourceRange(const layer_data *device_data, const IMAGE_STATE *image_state, 3276e25e057866af155bd456003120aa6155530a0e5fPetr Kraus bool is_imageview_2d_type, const VkImageSubresourceRange &subresourceRange) { 3277dab32891b91206a5bef7a3929b781e44fc1b7268Petr Kraus bool is_khr_maintenance1 = GetDeviceExtensions(device_data)->vk_khr_maintenance1; 3278e25e057866af155bd456003120aa6155530a0e5fPetr Kraus bool is_image_slicable = image_state->createInfo.imageType == VK_IMAGE_TYPE_3D && 3279e25e057866af155bd456003120aa6155530a0e5fPetr Kraus (image_state->createInfo.flags & VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT_KHR); 3280e25e057866af155bd456003120aa6155530a0e5fPetr Kraus bool is_3D_to_2D_map = is_khr_maintenance1 && is_image_slicable && is_imageview_2d_type; 328123c5a2092f724fef497a5c87a489f32c8fa51e58Petr Kraus 328223c5a2092f724fef497a5c87a489f32c8fa51e58Petr Kraus const auto image_layer_count = is_3D_to_2D_map ? image_state->createInfo.extent.depth : image_state->createInfo.arrayLayers; 328323c5a2092f724fef497a5c87a489f32c8fa51e58Petr Kraus const auto image_layer_count_var_name = is_3D_to_2D_map ? "extent.depth" : "arrayLayers"; 3284dab32891b91206a5bef7a3929b781e44fc1b7268Petr Kraus 3285e25e057866af155bd456003120aa6155530a0e5fPetr Kraus SubresourceRangeErrorCodes subresourceRangeErrorCodes = {}; 3286e25e057866af155bd456003120aa6155530a0e5fPetr Kraus subresourceRangeErrorCodes.base_mip_err = VALIDATION_ERROR_0ac00b8c; 3287e25e057866af155bd456003120aa6155530a0e5fPetr Kraus subresourceRangeErrorCodes.mip_count_err = VALIDATION_ERROR_0ac00b8e; 3288e25e057866af155bd456003120aa6155530a0e5fPetr Kraus subresourceRangeErrorCodes.base_layer_err = 3289e25e057866af155bd456003120aa6155530a0e5fPetr Kraus is_khr_maintenance1 ? (is_3D_to_2D_map ? VALIDATION_ERROR_0ac00b98 : VALIDATION_ERROR_0ac00b94) : VALIDATION_ERROR_0ac00b90; 3290e25e057866af155bd456003120aa6155530a0e5fPetr Kraus subresourceRangeErrorCodes.layer_count_err = 3291e25e057866af155bd456003120aa6155530a0e5fPetr Kraus is_khr_maintenance1 ? (is_3D_to_2D_map ? VALIDATION_ERROR_0ac00b9a : VALIDATION_ERROR_0ac00b96) : VALIDATION_ERROR_0ac00b92; 329223c5a2092f724fef497a5c87a489f32c8fa51e58Petr Kraus 3293e25e057866af155bd456003120aa6155530a0e5fPetr Kraus return ValidateImageSubresourceRange(device_data, image_state->createInfo.mipLevels, image_layer_count, subresourceRange, 3294e25e057866af155bd456003120aa6155530a0e5fPetr Kraus "vkCreateImageView", "pCreateInfo->subresourceRange", image_layer_count_var_name, 3295e25e057866af155bd456003120aa6155530a0e5fPetr Kraus HandleToUint64(image_state->image), subresourceRangeErrorCodes); 3296e25e057866af155bd456003120aa6155530a0e5fPetr Kraus} 329723c5a2092f724fef497a5c87a489f32c8fa51e58Petr Kraus 3298e25e057866af155bd456003120aa6155530a0e5fPetr Krausbool ValidateCmdClearColorSubresourceRange(const layer_data *device_data, const IMAGE_STATE *image_state, 3299e25e057866af155bd456003120aa6155530a0e5fPetr Kraus const VkImageSubresourceRange &subresourceRange, const char *param_name) { 3300e25e057866af155bd456003120aa6155530a0e5fPetr Kraus SubresourceRangeErrorCodes subresourceRangeErrorCodes = {}; 3301e25e057866af155bd456003120aa6155530a0e5fPetr Kraus subresourceRangeErrorCodes.base_mip_err = VALIDATION_ERROR_18800b7c; 3302e25e057866af155bd456003120aa6155530a0e5fPetr Kraus subresourceRangeErrorCodes.mip_count_err = VALIDATION_ERROR_18800b7e; 3303e25e057866af155bd456003120aa6155530a0e5fPetr Kraus subresourceRangeErrorCodes.base_layer_err = VALIDATION_ERROR_18800b80; 3304e25e057866af155bd456003120aa6155530a0e5fPetr Kraus subresourceRangeErrorCodes.layer_count_err = VALIDATION_ERROR_18800b82; 330523c5a2092f724fef497a5c87a489f32c8fa51e58Petr Kraus 3306e25e057866af155bd456003120aa6155530a0e5fPetr Kraus return ValidateImageSubresourceRange(device_data, image_state->createInfo.mipLevels, image_state->createInfo.arrayLayers, 3307e25e057866af155bd456003120aa6155530a0e5fPetr Kraus subresourceRange, "vkCmdClearColorImage", param_name, "arrayLayers", 3308e25e057866af155bd456003120aa6155530a0e5fPetr Kraus HandleToUint64(image_state->image), subresourceRangeErrorCodes); 3309e25e057866af155bd456003120aa6155530a0e5fPetr Kraus} 3310e25e057866af155bd456003120aa6155530a0e5fPetr Kraus 3311e25e057866af155bd456003120aa6155530a0e5fPetr Krausbool ValidateCmdClearDepthSubresourceRange(const layer_data *device_data, const IMAGE_STATE *image_state, 3312e25e057866af155bd456003120aa6155530a0e5fPetr Kraus const VkImageSubresourceRange &subresourceRange, const char *param_name) { 3313e25e057866af155bd456003120aa6155530a0e5fPetr Kraus SubresourceRangeErrorCodes subresourceRangeErrorCodes = {}; 3314e25e057866af155bd456003120aa6155530a0e5fPetr Kraus subresourceRangeErrorCodes.base_mip_err = VALIDATION_ERROR_18a00b84; 3315e25e057866af155bd456003120aa6155530a0e5fPetr Kraus subresourceRangeErrorCodes.mip_count_err = VALIDATION_ERROR_18a00b86; 3316e25e057866af155bd456003120aa6155530a0e5fPetr Kraus subresourceRangeErrorCodes.base_layer_err = VALIDATION_ERROR_18a00b88; 3317e25e057866af155bd456003120aa6155530a0e5fPetr Kraus subresourceRangeErrorCodes.layer_count_err = VALIDATION_ERROR_18a00b8a; 3318e25e057866af155bd456003120aa6155530a0e5fPetr Kraus 3319e25e057866af155bd456003120aa6155530a0e5fPetr Kraus return ValidateImageSubresourceRange(device_data, image_state->createInfo.mipLevels, image_state->createInfo.arrayLayers, 3320e25e057866af155bd456003120aa6155530a0e5fPetr Kraus subresourceRange, "vkCmdClearDepthStencilImage", param_name, "arrayLayers", 3321e25e057866af155bd456003120aa6155530a0e5fPetr Kraus HandleToUint64(image_state->image), subresourceRangeErrorCodes); 3322e25e057866af155bd456003120aa6155530a0e5fPetr Kraus} 3323e25e057866af155bd456003120aa6155530a0e5fPetr Kraus 3324e25e057866af155bd456003120aa6155530a0e5fPetr Krausbool ValidateImageBarrierSubresourceRange(const layer_data *device_data, const IMAGE_STATE *image_state, 3325e25e057866af155bd456003120aa6155530a0e5fPetr Kraus const VkImageSubresourceRange &subresourceRange, const char *cmd_name, 3326e25e057866af155bd456003120aa6155530a0e5fPetr Kraus const char *param_name) { 3327e25e057866af155bd456003120aa6155530a0e5fPetr Kraus SubresourceRangeErrorCodes subresourceRangeErrorCodes = {}; 3328e25e057866af155bd456003120aa6155530a0e5fPetr Kraus subresourceRangeErrorCodes.base_mip_err = VALIDATION_ERROR_0a000b9c; 3329e25e057866af155bd456003120aa6155530a0e5fPetr Kraus subresourceRangeErrorCodes.mip_count_err = VALIDATION_ERROR_0a000b9e; 3330e25e057866af155bd456003120aa6155530a0e5fPetr Kraus subresourceRangeErrorCodes.base_layer_err = VALIDATION_ERROR_0a000ba0; 3331e25e057866af155bd456003120aa6155530a0e5fPetr Kraus subresourceRangeErrorCodes.layer_count_err = VALIDATION_ERROR_0a000ba2; 3332e25e057866af155bd456003120aa6155530a0e5fPetr Kraus 3333e25e057866af155bd456003120aa6155530a0e5fPetr Kraus return ValidateImageSubresourceRange(device_data, image_state->createInfo.mipLevels, image_state->createInfo.arrayLayers, 3334e25e057866af155bd456003120aa6155530a0e5fPetr Kraus subresourceRange, cmd_name, param_name, "arrayLayers", HandleToUint64(image_state->image), 3335e25e057866af155bd456003120aa6155530a0e5fPetr Kraus subresourceRangeErrorCodes); 33361c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski} 33371c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski 33381c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinskibool PreCallValidateCreateImageView(layer_data *device_data, const VkImageViewCreateInfo *create_info) { 33391c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski const debug_report_data *report_data = core_validation::GetReportData(device_data); 33401c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski bool skip = false; 33411c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski IMAGE_STATE *image_state = GetImageState(device_data, create_info->image); 33421c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski if (image_state) { 33431c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski skip |= ValidateImageUsageFlags( 33441c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski device_data, image_state, 33451c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | 33465f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, 33471c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski false, -1, "vkCreateImageView()", 33481c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski "VK_IMAGE_USAGE_[SAMPLED|STORAGE|COLOR_ATTACHMENT|DEPTH_STENCIL_ATTACHMENT|INPUT_ATTACHMENT]_BIT"); 33491c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski // If this isn't a sparse image, it needs to have memory backing it at CreateImageView time 3350315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= ValidateMemoryIsBoundToImage(device_data, image_state, "vkCreateImageView()", VALIDATION_ERROR_0ac007f8); 33511c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski // Checks imported from image layer 3352e25e057866af155bd456003120aa6155530a0e5fPetr Kraus skip |= ValidateCreateImageViewSubresourceRange( 3353e25e057866af155bd456003120aa6155530a0e5fPetr Kraus device_data, image_state, 3354e25e057866af155bd456003120aa6155530a0e5fPetr Kraus create_info->viewType == VK_IMAGE_VIEW_TYPE_2D || create_info->viewType == VK_IMAGE_VIEW_TYPE_2D_ARRAY, 3355e25e057866af155bd456003120aa6155530a0e5fPetr Kraus create_info->subresourceRange); 33561c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski 33571c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski VkImageCreateFlags image_flags = image_state->createInfo.flags; 33581c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski VkFormat image_format = image_state->createInfo.format; 33598202587b4dc6705dfb9e5a51130ea83eff048d9dJeremy Kniager VkImageUsageFlags image_usage = image_state->createInfo.usage; 33608202587b4dc6705dfb9e5a51130ea83eff048d9dJeremy Kniager VkImageTiling image_tiling = image_state->createInfo.tiling; 33611c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski VkFormat view_format = create_info->format; 33621c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski VkImageAspectFlags aspect_mask = create_info->subresourceRange.aspectMask; 3363659e7b35da26a3c2483b5073f19972f60057d27fJeremy Kniager VkImageType image_type = image_state->createInfo.imageType; 3364659e7b35da26a3c2483b5073f19972f60057d27fJeremy Kniager VkImageViewType view_type = create_info->viewType; 33651c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski 33661c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski // Validate VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT state 33671c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski if (image_flags & VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT) { 3368093e327fb28d5083306dcc66cd71b7809771f496Lenny Komow if ((!GetDeviceExtensions(device_data)->vk_khr_maintenance2 || 3369093e327fb28d5083306dcc66cd71b7809771f496Lenny Komow !(image_flags & VK_IMAGE_CREATE_BLOCK_TEXEL_VIEW_COMPATIBLE_BIT_KHR))) { 3370093e327fb28d5083306dcc66cd71b7809771f496Lenny Komow // Format MUST be compatible (in the same format compatibility class) as the format the image was created with 3371093e327fb28d5083306dcc66cd71b7809771f496Lenny Komow if (FormatCompatibilityClass(image_format) != FormatCompatibilityClass(view_format)) { 3372093e327fb28d5083306dcc66cd71b7809771f496Lenny Komow std::stringstream ss; 3373093e327fb28d5083306dcc66cd71b7809771f496Lenny Komow ss << "vkCreateImageView(): ImageView format " << string_VkFormat(view_format) 3374093e327fb28d5083306dcc66cd71b7809771f496Lenny Komow << " is not in the same format compatibility class as image (" << HandleToUint64(create_info->image) 3375093e327fb28d5083306dcc66cd71b7809771f496Lenny Komow << ") format " << string_VkFormat(image_format) 3376093e327fb28d5083306dcc66cd71b7809771f496Lenny Komow << ". Images created with the VK_IMAGE_CREATE_MUTABLE_FORMAT BIT " 3377093e327fb28d5083306dcc66cd71b7809771f496Lenny Komow << "can support ImageViews with differing formats but they must be in the same compatibility class."; 3378093e327fb28d5083306dcc66cd71b7809771f496Lenny Komow skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, 3379093e327fb28d5083306dcc66cd71b7809771f496Lenny Komow __LINE__, VALIDATION_ERROR_0ac007f4, "IMAGE", "%s %s", ss.str().c_str(), 3380093e327fb28d5083306dcc66cd71b7809771f496Lenny Komow validation_error_map[VALIDATION_ERROR_0ac007f4]); 3381093e327fb28d5083306dcc66cd71b7809771f496Lenny Komow } 33821c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski } 33831c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski } else { 33841c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski // Format MUST be IDENTICAL to the format the image was created with 33851c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski if (image_format != view_format) { 33861c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski std::stringstream ss; 33871c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski ss << "vkCreateImageView() format " << string_VkFormat(view_format) << " differs from image " 33889b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus << HandleToUint64(create_info->image) << " format " << string_VkFormat(image_format) 33891c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski << ". Formats MUST be IDENTICAL unless VK_IMAGE_CREATE_MUTABLE_FORMAT BIT was set on image creation."; 3390fdc75c21ced997fbbc180734bef87bf6d5811d4bMark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, 3391315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis VALIDATION_ERROR_0ac007f6, "IMAGE", "%s %s", ss.str().c_str(), 3392315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_0ac007f6]); 33931c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski } 33941c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski } 33951c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski 33961c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski // Validate correct image aspect bits for desired formats and format consistency 33971c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski skip |= ValidateImageAspectMask(device_data, image_state->image, image_format, aspect_mask, "vkCreateImageView()"); 3398659e7b35da26a3c2483b5073f19972f60057d27fJeremy Kniager 3399659e7b35da26a3c2483b5073f19972f60057d27fJeremy Kniager switch (image_type) { 3400659e7b35da26a3c2483b5073f19972f60057d27fJeremy Kniager case VK_IMAGE_TYPE_1D: 3401659e7b35da26a3c2483b5073f19972f60057d27fJeremy Kniager if (view_type != VK_IMAGE_VIEW_TYPE_1D && view_type != VK_IMAGE_VIEW_TYPE_1D_ARRAY) { 3402659e7b35da26a3c2483b5073f19972f60057d27fJeremy Kniager skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, 3403659e7b35da26a3c2483b5073f19972f60057d27fJeremy Kniager __LINE__, VALIDATION_ERROR_0ac007fa, "IMAGE", 3404659e7b35da26a3c2483b5073f19972f60057d27fJeremy Kniager "vkCreateImageView(): pCreateInfo->viewType %s is not compatible with image type %s. %s", 3405659e7b35da26a3c2483b5073f19972f60057d27fJeremy Kniager string_VkImageViewType(view_type), string_VkImageType(image_type), 3406659e7b35da26a3c2483b5073f19972f60057d27fJeremy Kniager validation_error_map[VALIDATION_ERROR_0ac007fa]); 3407659e7b35da26a3c2483b5073f19972f60057d27fJeremy Kniager } 3408659e7b35da26a3c2483b5073f19972f60057d27fJeremy Kniager break; 3409659e7b35da26a3c2483b5073f19972f60057d27fJeremy Kniager case VK_IMAGE_TYPE_2D: 3410659e7b35da26a3c2483b5073f19972f60057d27fJeremy Kniager if (view_type != VK_IMAGE_VIEW_TYPE_2D && view_type != VK_IMAGE_VIEW_TYPE_2D_ARRAY) { 3411659e7b35da26a3c2483b5073f19972f60057d27fJeremy Kniager if ((view_type == VK_IMAGE_VIEW_TYPE_CUBE || view_type == VK_IMAGE_VIEW_TYPE_CUBE_ARRAY) && 3412659e7b35da26a3c2483b5073f19972f60057d27fJeremy Kniager !(image_flags & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT)) { 3413659e7b35da26a3c2483b5073f19972f60057d27fJeremy Kniager skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, 3414659e7b35da26a3c2483b5073f19972f60057d27fJeremy Kniager __LINE__, VALIDATION_ERROR_0ac007d6, "IMAGE", 3415659e7b35da26a3c2483b5073f19972f60057d27fJeremy Kniager "vkCreateImageView(): pCreateInfo->viewType %s is not compatible with image type %s. %s", 3416659e7b35da26a3c2483b5073f19972f60057d27fJeremy Kniager string_VkImageViewType(view_type), string_VkImageType(image_type), 3417659e7b35da26a3c2483b5073f19972f60057d27fJeremy Kniager validation_error_map[VALIDATION_ERROR_0ac007d6]); 3418659e7b35da26a3c2483b5073f19972f60057d27fJeremy Kniager } else if (view_type != VK_IMAGE_VIEW_TYPE_CUBE && view_type != VK_IMAGE_VIEW_TYPE_CUBE_ARRAY) { 3419659e7b35da26a3c2483b5073f19972f60057d27fJeremy Kniager skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, 3420659e7b35da26a3c2483b5073f19972f60057d27fJeremy Kniager __LINE__, VALIDATION_ERROR_0ac007fa, "IMAGE", 3421659e7b35da26a3c2483b5073f19972f60057d27fJeremy Kniager "vkCreateImageView(): pCreateInfo->viewType %s is not compatible with image type %s. %s", 3422659e7b35da26a3c2483b5073f19972f60057d27fJeremy Kniager string_VkImageViewType(view_type), string_VkImageType(image_type), 3423659e7b35da26a3c2483b5073f19972f60057d27fJeremy Kniager validation_error_map[VALIDATION_ERROR_0ac007fa]); 3424659e7b35da26a3c2483b5073f19972f60057d27fJeremy Kniager } 3425659e7b35da26a3c2483b5073f19972f60057d27fJeremy Kniager } 3426659e7b35da26a3c2483b5073f19972f60057d27fJeremy Kniager break; 3427659e7b35da26a3c2483b5073f19972f60057d27fJeremy Kniager case VK_IMAGE_TYPE_3D: 3428659e7b35da26a3c2483b5073f19972f60057d27fJeremy Kniager if (GetDeviceExtensions(device_data)->vk_khr_maintenance1) { 3429659e7b35da26a3c2483b5073f19972f60057d27fJeremy Kniager if (view_type != VK_IMAGE_VIEW_TYPE_3D) { 3430659e7b35da26a3c2483b5073f19972f60057d27fJeremy Kniager if ((view_type == VK_IMAGE_VIEW_TYPE_2D || view_type == VK_IMAGE_VIEW_TYPE_2D_ARRAY)) { 3431659e7b35da26a3c2483b5073f19972f60057d27fJeremy Kniager if (!(image_flags & VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT_KHR)) { 3432659e7b35da26a3c2483b5073f19972f60057d27fJeremy Kniager skip |= log_msg( 3433659e7b35da26a3c2483b5073f19972f60057d27fJeremy Kniager report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, 3434659e7b35da26a3c2483b5073f19972f60057d27fJeremy Kniager __LINE__, VALIDATION_ERROR_0ac007da, "IMAGE", 3435659e7b35da26a3c2483b5073f19972f60057d27fJeremy Kniager "vkCreateImageView(): pCreateInfo->viewType %s is not compatible with image type %s. %s", 3436659e7b35da26a3c2483b5073f19972f60057d27fJeremy Kniager string_VkImageViewType(view_type), string_VkImageType(image_type), 3437659e7b35da26a3c2483b5073f19972f60057d27fJeremy Kniager validation_error_map[VALIDATION_ERROR_0ac007da]); 3438659e7b35da26a3c2483b5073f19972f60057d27fJeremy Kniager } else if ((image_flags & (VK_IMAGE_CREATE_SPARSE_BINDING_BIT | VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT | 3439659e7b35da26a3c2483b5073f19972f60057d27fJeremy Kniager VK_IMAGE_CREATE_SPARSE_ALIASED_BIT))) { 34405f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton skip |= 34415f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, 34425f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton __LINE__, VALIDATION_ERROR_0ac007fa, "IMAGE", 34435f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton "vkCreateImageView(): pCreateInfo->viewType %s is not compatible with image type %s " 34445f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton "when the VK_IMAGE_CREATE_SPARSE_BINDING_BIT, VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT, or " 34455f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton "VK_IMAGE_CREATE_SPARSE_ALIASED_BIT flags are enabled. %s", 34465f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton string_VkImageViewType(view_type), string_VkImageType(image_type), 34475f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton validation_error_map[VALIDATION_ERROR_0ac007fa]); 3448659e7b35da26a3c2483b5073f19972f60057d27fJeremy Kniager } 3449659e7b35da26a3c2483b5073f19972f60057d27fJeremy Kniager } else { 3450659e7b35da26a3c2483b5073f19972f60057d27fJeremy Kniager skip |= 3451659e7b35da26a3c2483b5073f19972f60057d27fJeremy Kniager log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, 3452659e7b35da26a3c2483b5073f19972f60057d27fJeremy Kniager __LINE__, VALIDATION_ERROR_0ac007fa, "IMAGE", 3453659e7b35da26a3c2483b5073f19972f60057d27fJeremy Kniager "vkCreateImageView(): pCreateInfo->viewType %s is not compatible with image type %s. %s", 3454659e7b35da26a3c2483b5073f19972f60057d27fJeremy Kniager string_VkImageViewType(view_type), string_VkImageType(image_type), 3455659e7b35da26a3c2483b5073f19972f60057d27fJeremy Kniager validation_error_map[VALIDATION_ERROR_0ac007fa]); 3456659e7b35da26a3c2483b5073f19972f60057d27fJeremy Kniager } 3457659e7b35da26a3c2483b5073f19972f60057d27fJeremy Kniager } 3458659e7b35da26a3c2483b5073f19972f60057d27fJeremy Kniager } else { 3459659e7b35da26a3c2483b5073f19972f60057d27fJeremy Kniager if (view_type != VK_IMAGE_VIEW_TYPE_3D) { 3460659e7b35da26a3c2483b5073f19972f60057d27fJeremy Kniager skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, 3461659e7b35da26a3c2483b5073f19972f60057d27fJeremy Kniager __LINE__, VALIDATION_ERROR_0ac007fa, "IMAGE", 3462659e7b35da26a3c2483b5073f19972f60057d27fJeremy Kniager "vkCreateImageView(): pCreateInfo->viewType %s is not compatible with image type %s. %s", 3463659e7b35da26a3c2483b5073f19972f60057d27fJeremy Kniager string_VkImageViewType(view_type), string_VkImageType(image_type), 3464659e7b35da26a3c2483b5073f19972f60057d27fJeremy Kniager validation_error_map[VALIDATION_ERROR_0ac007fa]); 3465659e7b35da26a3c2483b5073f19972f60057d27fJeremy Kniager } 3466659e7b35da26a3c2483b5073f19972f60057d27fJeremy Kniager } 3467659e7b35da26a3c2483b5073f19972f60057d27fJeremy Kniager break; 3468659e7b35da26a3c2483b5073f19972f60057d27fJeremy Kniager default: 3469659e7b35da26a3c2483b5073f19972f60057d27fJeremy Kniager break; 3470659e7b35da26a3c2483b5073f19972f60057d27fJeremy Kniager } 34718202587b4dc6705dfb9e5a51130ea83eff048d9dJeremy Kniager 347257f0da98098689f3624c5503cfe1a4b5fede885aJeremy Kniager VkFormatProperties format_properties = GetFormatProperties(device_data, view_format); 34738202587b4dc6705dfb9e5a51130ea83eff048d9dJeremy Kniager bool check_tiling_features = false; 34748202587b4dc6705dfb9e5a51130ea83eff048d9dJeremy Kniager VkFormatFeatureFlags tiling_features = 0; 34758202587b4dc6705dfb9e5a51130ea83eff048d9dJeremy Kniager UNIQUE_VALIDATION_ERROR_CODE linear_error_codes[] = { 34768202587b4dc6705dfb9e5a51130ea83eff048d9dJeremy Kniager VALIDATION_ERROR_0ac007dc, VALIDATION_ERROR_0ac007e0, VALIDATION_ERROR_0ac007e2, 34778202587b4dc6705dfb9e5a51130ea83eff048d9dJeremy Kniager VALIDATION_ERROR_0ac007e4, VALIDATION_ERROR_0ac007e6, 34788202587b4dc6705dfb9e5a51130ea83eff048d9dJeremy Kniager }; 34798202587b4dc6705dfb9e5a51130ea83eff048d9dJeremy Kniager UNIQUE_VALIDATION_ERROR_CODE optimal_error_codes[] = { 34808202587b4dc6705dfb9e5a51130ea83eff048d9dJeremy Kniager VALIDATION_ERROR_0ac007e8, VALIDATION_ERROR_0ac007ea, VALIDATION_ERROR_0ac007ec, 34818202587b4dc6705dfb9e5a51130ea83eff048d9dJeremy Kniager VALIDATION_ERROR_0ac007ee, VALIDATION_ERROR_0ac007f0, 34828202587b4dc6705dfb9e5a51130ea83eff048d9dJeremy Kniager }; 34838202587b4dc6705dfb9e5a51130ea83eff048d9dJeremy Kniager UNIQUE_VALIDATION_ERROR_CODE *error_codes = nullptr; 34848202587b4dc6705dfb9e5a51130ea83eff048d9dJeremy Kniager if (image_tiling == VK_IMAGE_TILING_LINEAR) { 348557f0da98098689f3624c5503cfe1a4b5fede885aJeremy Kniager tiling_features = format_properties.linearTilingFeatures; 34868202587b4dc6705dfb9e5a51130ea83eff048d9dJeremy Kniager error_codes = linear_error_codes; 34878202587b4dc6705dfb9e5a51130ea83eff048d9dJeremy Kniager check_tiling_features = true; 34888202587b4dc6705dfb9e5a51130ea83eff048d9dJeremy Kniager } else if (image_tiling == VK_IMAGE_TILING_OPTIMAL) { 348957f0da98098689f3624c5503cfe1a4b5fede885aJeremy Kniager tiling_features = format_properties.optimalTilingFeatures; 34908202587b4dc6705dfb9e5a51130ea83eff048d9dJeremy Kniager error_codes = optimal_error_codes; 34918202587b4dc6705dfb9e5a51130ea83eff048d9dJeremy Kniager check_tiling_features = true; 34928202587b4dc6705dfb9e5a51130ea83eff048d9dJeremy Kniager } 34938202587b4dc6705dfb9e5a51130ea83eff048d9dJeremy Kniager 34948202587b4dc6705dfb9e5a51130ea83eff048d9dJeremy Kniager if (check_tiling_features) { 34958202587b4dc6705dfb9e5a51130ea83eff048d9dJeremy Kniager if (tiling_features == 0) { 34968202587b4dc6705dfb9e5a51130ea83eff048d9dJeremy Kniager skip |= 34978202587b4dc6705dfb9e5a51130ea83eff048d9dJeremy Kniager log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, 34988202587b4dc6705dfb9e5a51130ea83eff048d9dJeremy Kniager error_codes[0], "IMAGE", 34995f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton "vkCreateImageView() pCreateInfo->format %s cannot be used with an image having the %s flag set. %s", 35008202587b4dc6705dfb9e5a51130ea83eff048d9dJeremy Kniager string_VkFormat(view_format), string_VkImageTiling(image_tiling), validation_error_map[error_codes[0]]); 35018202587b4dc6705dfb9e5a51130ea83eff048d9dJeremy Kniager } else if ((image_usage & VK_IMAGE_USAGE_SAMPLED_BIT) && !(tiling_features & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT)) { 35028202587b4dc6705dfb9e5a51130ea83eff048d9dJeremy Kniager skip |= 35038202587b4dc6705dfb9e5a51130ea83eff048d9dJeremy Kniager log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, 35048202587b4dc6705dfb9e5a51130ea83eff048d9dJeremy Kniager error_codes[1], "IMAGE", 35055f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton "vkCreateImageView() pCreateInfo->format %s cannot be used with an image having the %s and " 35065f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton "VK_IMAGE_USAGE_SAMPLED_BIT flags set. %s", 35078202587b4dc6705dfb9e5a51130ea83eff048d9dJeremy Kniager string_VkFormat(view_format), string_VkImageTiling(image_tiling), validation_error_map[error_codes[1]]); 35088202587b4dc6705dfb9e5a51130ea83eff048d9dJeremy Kniager } else if ((image_usage & VK_IMAGE_USAGE_STORAGE_BIT) && !(tiling_features & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT)) { 35098202587b4dc6705dfb9e5a51130ea83eff048d9dJeremy Kniager skip |= 35108202587b4dc6705dfb9e5a51130ea83eff048d9dJeremy Kniager log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, 35118202587b4dc6705dfb9e5a51130ea83eff048d9dJeremy Kniager error_codes[2], "IMAGE", 35125f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton "vkCreateImageView() pCreateInfo->format %s cannot be used with an image having the %s and " 35135f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton "VK_IMAGE_USAGE_STORAGE_BIT flags set. %s", 35148202587b4dc6705dfb9e5a51130ea83eff048d9dJeremy Kniager string_VkFormat(view_format), string_VkImageTiling(image_tiling), validation_error_map[error_codes[2]]); 35158202587b4dc6705dfb9e5a51130ea83eff048d9dJeremy Kniager } else if ((image_usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) && 35168202587b4dc6705dfb9e5a51130ea83eff048d9dJeremy Kniager !(tiling_features & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT)) { 35178202587b4dc6705dfb9e5a51130ea83eff048d9dJeremy Kniager skip |= 35188202587b4dc6705dfb9e5a51130ea83eff048d9dJeremy Kniager log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, 35198202587b4dc6705dfb9e5a51130ea83eff048d9dJeremy Kniager error_codes[3], "IMAGE", 35205f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton "vkCreateImageView() pCreateInfo->format %s cannot be used with an image having the %s and " 35215f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton "VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT flags set. %s", 35228202587b4dc6705dfb9e5a51130ea83eff048d9dJeremy Kniager string_VkFormat(view_format), string_VkImageTiling(image_tiling), validation_error_map[error_codes[3]]); 35238202587b4dc6705dfb9e5a51130ea83eff048d9dJeremy Kniager } else if ((image_usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) && 35248202587b4dc6705dfb9e5a51130ea83eff048d9dJeremy Kniager !(tiling_features & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT)) { 35258202587b4dc6705dfb9e5a51130ea83eff048d9dJeremy Kniager skip |= 35268202587b4dc6705dfb9e5a51130ea83eff048d9dJeremy Kniager log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, 35278202587b4dc6705dfb9e5a51130ea83eff048d9dJeremy Kniager error_codes[4], "IMAGE", 35285f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton "vkCreateImageView() pCreateInfo->format %s cannot be used with an image having the %s and " 35295f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton "VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT flags set. %s", 35308202587b4dc6705dfb9e5a51130ea83eff048d9dJeremy Kniager string_VkFormat(view_format), string_VkImageTiling(image_tiling), validation_error_map[error_codes[4]]); 35318202587b4dc6705dfb9e5a51130ea83eff048d9dJeremy Kniager } 35328202587b4dc6705dfb9e5a51130ea83eff048d9dJeremy Kniager } 35331c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski } 35341c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski return skip; 35351c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski} 35361c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski 3537d0b59d0aabea9048c518840e762c7a510927c132Mark Lobodzinskivoid PostCallRecordCreateImageView(layer_data *device_data, const VkImageViewCreateInfo *create_info, VkImageView view) { 3538d0b59d0aabea9048c518840e762c7a510927c132Mark Lobodzinski auto image_view_map = GetImageViewMap(device_data); 3539d0b59d0aabea9048c518840e762c7a510927c132Mark Lobodzinski (*image_view_map)[view] = std::unique_ptr<IMAGE_VIEW_STATE>(new IMAGE_VIEW_STATE(view, create_info)); 3540d0b59d0aabea9048c518840e762c7a510927c132Mark Lobodzinski 3541d0b59d0aabea9048c518840e762c7a510927c132Mark Lobodzinski auto image_state = GetImageState(device_data, create_info->image); 3542e9d74ac8e13687c1be3ee147efce42e8215a049eDave Houlton auto &sub_res_range = (*image_view_map)[view].get()->create_info.subresourceRange; 354395b7894efd5e101e410da92fc697429aec3ffa7bMark Lobodzinski sub_res_range.levelCount = ResolveRemainingLevels(&sub_res_range, image_state->createInfo.mipLevels); 354495b7894efd5e101e410da92fc697429aec3ffa7bMark Lobodzinski sub_res_range.layerCount = ResolveRemainingLayers(&sub_res_range, image_state->createInfo.arrayLayers); 35451c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski} 35466a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski 3547c40a396f8341e1e1e5fdf1d023a987b874763446Mark Lobodzinskibool PreCallValidateCmdCopyBuffer(layer_data *device_data, GLOBAL_CB_NODE *cb_node, BUFFER_STATE *src_buffer_state, 3548c40a396f8341e1e1e5fdf1d023a987b874763446Mark Lobodzinski BUFFER_STATE *dst_buffer_state) { 3549c40a396f8341e1e1e5fdf1d023a987b874763446Mark Lobodzinski bool skip = false; 3550315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= ValidateMemoryIsBoundToBuffer(device_data, src_buffer_state, "vkCmdCopyBuffer()", VALIDATION_ERROR_18c000ee); 3551315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= ValidateMemoryIsBoundToBuffer(device_data, dst_buffer_state, "vkCmdCopyBuffer()", VALIDATION_ERROR_18c000f2); 3552c40a396f8341e1e1e5fdf1d023a987b874763446Mark Lobodzinski // Validate that SRC & DST buffers have correct usage flags set 3553315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= ValidateBufferUsageFlags(device_data, src_buffer_state, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, true, 3554315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis VALIDATION_ERROR_18c000ec, "vkCmdCopyBuffer()", "VK_BUFFER_USAGE_TRANSFER_SRC_BIT"); 3555315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= ValidateBufferUsageFlags(device_data, dst_buffer_state, VK_BUFFER_USAGE_TRANSFER_DST_BIT, true, 3556315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis VALIDATION_ERROR_18c000f0, "vkCmdCopyBuffer()", "VK_BUFFER_USAGE_TRANSFER_DST_BIT"); 3557baa50ccc5a8cf7a6f7474148f301802c5480e715Mike Schuchardt skip |= ValidateCmdQueueFlags(device_data, cb_node, "vkCmdCopyBuffer()", 3558315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis VK_QUEUE_TRANSFER_BIT | VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT, VALIDATION_ERROR_18c02415); 3559c40a396f8341e1e1e5fdf1d023a987b874763446Mark Lobodzinski skip |= ValidateCmd(device_data, cb_node, CMD_COPYBUFFER, "vkCmdCopyBuffer()"); 3560315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= insideRenderPass(device_data, cb_node, "vkCmdCopyBuffer()", VALIDATION_ERROR_18c00017); 3561c40a396f8341e1e1e5fdf1d023a987b874763446Mark Lobodzinski return skip; 3562c40a396f8341e1e1e5fdf1d023a987b874763446Mark Lobodzinski} 35636a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski 3564c40a396f8341e1e1e5fdf1d023a987b874763446Mark Lobodzinskivoid PreCallRecordCmdCopyBuffer(layer_data *device_data, GLOBAL_CB_NODE *cb_node, BUFFER_STATE *src_buffer_state, 3565c40a396f8341e1e1e5fdf1d023a987b874763446Mark Lobodzinski BUFFER_STATE *dst_buffer_state) { 3566c40a396f8341e1e1e5fdf1d023a987b874763446Mark Lobodzinski // Update bindings between buffers and cmd buffer 3567c40a396f8341e1e1e5fdf1d023a987b874763446Mark Lobodzinski AddCommandBufferBindingBuffer(device_data, cb_node, src_buffer_state); 3568c40a396f8341e1e1e5fdf1d023a987b874763446Mark Lobodzinski AddCommandBufferBindingBuffer(device_data, cb_node, dst_buffer_state); 3569c40a396f8341e1e1e5fdf1d023a987b874763446Mark Lobodzinski 3570c40a396f8341e1e1e5fdf1d023a987b874763446Mark Lobodzinski std::function<bool()> function = [=]() { 3571c40a396f8341e1e1e5fdf1d023a987b874763446Mark Lobodzinski return ValidateBufferMemoryIsValid(device_data, src_buffer_state, "vkCmdCopyBuffer()"); 3572c40a396f8341e1e1e5fdf1d023a987b874763446Mark Lobodzinski }; 3573d807198f24437c1b2478ff1d06a33ce4873a1451Tobin Ehlis cb_node->queue_submit_functions.push_back(function); 3574c40a396f8341e1e1e5fdf1d023a987b874763446Mark Lobodzinski function = [=]() { 3575c40a396f8341e1e1e5fdf1d023a987b874763446Mark Lobodzinski SetBufferMemoryValid(device_data, dst_buffer_state, true); 3576c40a396f8341e1e1e5fdf1d023a987b874763446Mark Lobodzinski return false; 3577c40a396f8341e1e1e5fdf1d023a987b874763446Mark Lobodzinski }; 3578d807198f24437c1b2478ff1d06a33ce4873a1451Tobin Ehlis cb_node->queue_submit_functions.push_back(function); 3579c40a396f8341e1e1e5fdf1d023a987b874763446Mark Lobodzinski} 3580842b2d28ded1c6e2c38491a81213d0e1d1b7295aMark Lobodzinski 3581842b2d28ded1c6e2c38491a81213d0e1d1b7295aMark Lobodzinskistatic bool validateIdleBuffer(layer_data *device_data, VkBuffer buffer) { 3582842b2d28ded1c6e2c38491a81213d0e1d1b7295aMark Lobodzinski const debug_report_data *report_data = core_validation::GetReportData(device_data); 3583842b2d28ded1c6e2c38491a81213d0e1d1b7295aMark Lobodzinski bool skip = false; 3584842b2d28ded1c6e2c38491a81213d0e1d1b7295aMark Lobodzinski auto buffer_state = GetBufferState(device_data, buffer); 3585842b2d28ded1c6e2c38491a81213d0e1d1b7295aMark Lobodzinski if (!buffer_state) { 35869b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT, HandleToUint64(buffer), 3587055fc8fd459f0da279d4814f927ea7090dd0f7e9Petr Kraus __LINE__, DRAWSTATE_DOUBLE_DESTROY, "DS", "Cannot free buffer 0x%" PRIx64 " that has not been allocated.", 3588055fc8fd459f0da279d4814f927ea7090dd0f7e9Petr Kraus HandleToUint64(buffer)); 3589842b2d28ded1c6e2c38491a81213d0e1d1b7295aMark Lobodzinski } else { 3590842b2d28ded1c6e2c38491a81213d0e1d1b7295aMark Lobodzinski if (buffer_state->in_use.load()) { 35919b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT, 3592315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(buffer), __LINE__, VALIDATION_ERROR_23c00734, "DS", 3593055fc8fd459f0da279d4814f927ea7090dd0f7e9Petr Kraus "Cannot free buffer 0x%" PRIx64 " that is in use by a command buffer. %s", HandleToUint64(buffer), 3594315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_23c00734]); 3595842b2d28ded1c6e2c38491a81213d0e1d1b7295aMark Lobodzinski } 3596842b2d28ded1c6e2c38491a81213d0e1d1b7295aMark Lobodzinski } 3597842b2d28ded1c6e2c38491a81213d0e1d1b7295aMark Lobodzinski return skip; 3598842b2d28ded1c6e2c38491a81213d0e1d1b7295aMark Lobodzinski} 3599842b2d28ded1c6e2c38491a81213d0e1d1b7295aMark Lobodzinski 3600842b2d28ded1c6e2c38491a81213d0e1d1b7295aMark Lobodzinskibool PreCallValidateDestroyImageView(layer_data *device_data, VkImageView image_view, IMAGE_VIEW_STATE **image_view_state, 3601842b2d28ded1c6e2c38491a81213d0e1d1b7295aMark Lobodzinski VK_OBJECT *obj_struct) { 3602842b2d28ded1c6e2c38491a81213d0e1d1b7295aMark Lobodzinski *image_view_state = GetImageViewState(device_data, image_view); 36039b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus *obj_struct = {HandleToUint64(image_view), kVulkanObjectTypeImageView}; 3604842b2d28ded1c6e2c38491a81213d0e1d1b7295aMark Lobodzinski if (GetDisables(device_data)->destroy_image_view) return false; 3605842b2d28ded1c6e2c38491a81213d0e1d1b7295aMark Lobodzinski bool skip = false; 3606842b2d28ded1c6e2c38491a81213d0e1d1b7295aMark Lobodzinski if (*image_view_state) { 360769ea2c79d7b3f9c987671a10686afac066b275b9Mike Schuchardt skip |= 360869ea2c79d7b3f9c987671a10686afac066b275b9Mike Schuchardt ValidateObjectNotInUse(device_data, *image_view_state, *obj_struct, "vkDestroyImageView", VALIDATION_ERROR_25400804); 3609842b2d28ded1c6e2c38491a81213d0e1d1b7295aMark Lobodzinski } 3610842b2d28ded1c6e2c38491a81213d0e1d1b7295aMark Lobodzinski return skip; 3611842b2d28ded1c6e2c38491a81213d0e1d1b7295aMark Lobodzinski} 3612842b2d28ded1c6e2c38491a81213d0e1d1b7295aMark Lobodzinski 3613842b2d28ded1c6e2c38491a81213d0e1d1b7295aMark Lobodzinskivoid PostCallRecordDestroyImageView(layer_data *device_data, VkImageView image_view, IMAGE_VIEW_STATE *image_view_state, 3614842b2d28ded1c6e2c38491a81213d0e1d1b7295aMark Lobodzinski VK_OBJECT obj_struct) { 3615842b2d28ded1c6e2c38491a81213d0e1d1b7295aMark Lobodzinski // Any bound cmd buffers are now invalid 3616842b2d28ded1c6e2c38491a81213d0e1d1b7295aMark Lobodzinski invalidateCommandBuffers(device_data, image_view_state->cb_bindings, obj_struct); 3617842b2d28ded1c6e2c38491a81213d0e1d1b7295aMark Lobodzinski (*GetImageViewMap(device_data)).erase(image_view); 3618842b2d28ded1c6e2c38491a81213d0e1d1b7295aMark Lobodzinski} 3619842b2d28ded1c6e2c38491a81213d0e1d1b7295aMark Lobodzinski 3620842b2d28ded1c6e2c38491a81213d0e1d1b7295aMark Lobodzinskibool PreCallValidateDestroyBuffer(layer_data *device_data, VkBuffer buffer, BUFFER_STATE **buffer_state, VK_OBJECT *obj_struct) { 3621842b2d28ded1c6e2c38491a81213d0e1d1b7295aMark Lobodzinski *buffer_state = GetBufferState(device_data, buffer); 36229b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus *obj_struct = {HandleToUint64(buffer), kVulkanObjectTypeBuffer}; 3623842b2d28ded1c6e2c38491a81213d0e1d1b7295aMark Lobodzinski if (GetDisables(device_data)->destroy_buffer) return false; 3624842b2d28ded1c6e2c38491a81213d0e1d1b7295aMark Lobodzinski bool skip = false; 3625842b2d28ded1c6e2c38491a81213d0e1d1b7295aMark Lobodzinski if (*buffer_state) { 3626842b2d28ded1c6e2c38491a81213d0e1d1b7295aMark Lobodzinski skip |= validateIdleBuffer(device_data, buffer); 3627842b2d28ded1c6e2c38491a81213d0e1d1b7295aMark Lobodzinski } 3628842b2d28ded1c6e2c38491a81213d0e1d1b7295aMark Lobodzinski return skip; 3629842b2d28ded1c6e2c38491a81213d0e1d1b7295aMark Lobodzinski} 3630842b2d28ded1c6e2c38491a81213d0e1d1b7295aMark Lobodzinski 3631842b2d28ded1c6e2c38491a81213d0e1d1b7295aMark Lobodzinskivoid PostCallRecordDestroyBuffer(layer_data *device_data, VkBuffer buffer, BUFFER_STATE *buffer_state, VK_OBJECT obj_struct) { 3632842b2d28ded1c6e2c38491a81213d0e1d1b7295aMark Lobodzinski invalidateCommandBuffers(device_data, buffer_state->cb_bindings, obj_struct); 3633842b2d28ded1c6e2c38491a81213d0e1d1b7295aMark Lobodzinski for (auto mem_binding : buffer_state->GetBoundMemory()) { 3634842b2d28ded1c6e2c38491a81213d0e1d1b7295aMark Lobodzinski auto mem_info = GetMemObjInfo(device_data, mem_binding); 3635842b2d28ded1c6e2c38491a81213d0e1d1b7295aMark Lobodzinski if (mem_info) { 36369b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus core_validation::RemoveBufferMemoryRange(HandleToUint64(buffer), mem_info); 3637842b2d28ded1c6e2c38491a81213d0e1d1b7295aMark Lobodzinski } 3638842b2d28ded1c6e2c38491a81213d0e1d1b7295aMark Lobodzinski } 36399b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus ClearMemoryObjectBindings(device_data, HandleToUint64(buffer), kVulkanObjectTypeBuffer); 3640842b2d28ded1c6e2c38491a81213d0e1d1b7295aMark Lobodzinski GetBufferMap(device_data)->erase(buffer_state->buffer); 3641842b2d28ded1c6e2c38491a81213d0e1d1b7295aMark Lobodzinski} 3642842b2d28ded1c6e2c38491a81213d0e1d1b7295aMark Lobodzinski 3643842b2d28ded1c6e2c38491a81213d0e1d1b7295aMark Lobodzinskibool PreCallValidateDestroyBufferView(layer_data *device_data, VkBufferView buffer_view, BUFFER_VIEW_STATE **buffer_view_state, 3644842b2d28ded1c6e2c38491a81213d0e1d1b7295aMark Lobodzinski VK_OBJECT *obj_struct) { 3645842b2d28ded1c6e2c38491a81213d0e1d1b7295aMark Lobodzinski *buffer_view_state = GetBufferViewState(device_data, buffer_view); 36469b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus *obj_struct = {HandleToUint64(buffer_view), kVulkanObjectTypeBufferView}; 3647842b2d28ded1c6e2c38491a81213d0e1d1b7295aMark Lobodzinski if (GetDisables(device_data)->destroy_buffer_view) return false; 3648842b2d28ded1c6e2c38491a81213d0e1d1b7295aMark Lobodzinski bool skip = false; 3649842b2d28ded1c6e2c38491a81213d0e1d1b7295aMark Lobodzinski if (*buffer_view_state) { 365069ea2c79d7b3f9c987671a10686afac066b275b9Mike Schuchardt skip |= 365169ea2c79d7b3f9c987671a10686afac066b275b9Mike Schuchardt ValidateObjectNotInUse(device_data, *buffer_view_state, *obj_struct, "vkDestroyBufferView", VALIDATION_ERROR_23e00750); 3652842b2d28ded1c6e2c38491a81213d0e1d1b7295aMark Lobodzinski } 3653842b2d28ded1c6e2c38491a81213d0e1d1b7295aMark Lobodzinski return skip; 3654842b2d28ded1c6e2c38491a81213d0e1d1b7295aMark Lobodzinski} 3655842b2d28ded1c6e2c38491a81213d0e1d1b7295aMark Lobodzinski 3656842b2d28ded1c6e2c38491a81213d0e1d1b7295aMark Lobodzinskivoid PostCallRecordDestroyBufferView(layer_data *device_data, VkBufferView buffer_view, BUFFER_VIEW_STATE *buffer_view_state, 3657842b2d28ded1c6e2c38491a81213d0e1d1b7295aMark Lobodzinski VK_OBJECT obj_struct) { 3658842b2d28ded1c6e2c38491a81213d0e1d1b7295aMark Lobodzinski // Any bound cmd buffers are now invalid 3659842b2d28ded1c6e2c38491a81213d0e1d1b7295aMark Lobodzinski invalidateCommandBuffers(device_data, buffer_view_state->cb_bindings, obj_struct); 3660842b2d28ded1c6e2c38491a81213d0e1d1b7295aMark Lobodzinski GetBufferViewMap(device_data)->erase(buffer_view); 3661842b2d28ded1c6e2c38491a81213d0e1d1b7295aMark Lobodzinski} 366223bb5a2fd221f6788daf2dd976bf19a5e9b20fb9Mark Lobodzinski 366323bb5a2fd221f6788daf2dd976bf19a5e9b20fb9Mark Lobodzinskibool PreCallValidateCmdFillBuffer(layer_data *device_data, GLOBAL_CB_NODE *cb_node, BUFFER_STATE *buffer_state) { 366423bb5a2fd221f6788daf2dd976bf19a5e9b20fb9Mark Lobodzinski bool skip = false; 3665315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= ValidateMemoryIsBoundToBuffer(device_data, buffer_state, "vkCmdFillBuffer()", VALIDATION_ERROR_1b40003e); 3666baa50ccc5a8cf7a6f7474148f301802c5480e715Mike Schuchardt skip |= ValidateCmdQueueFlags(device_data, cb_node, "vkCmdFillBuffer()", 3667315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis VK_QUEUE_TRANSFER_BIT | VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT, VALIDATION_ERROR_1b402415); 366823bb5a2fd221f6788daf2dd976bf19a5e9b20fb9Mark Lobodzinski skip |= ValidateCmd(device_data, cb_node, CMD_FILLBUFFER, "vkCmdFillBuffer()"); 366923bb5a2fd221f6788daf2dd976bf19a5e9b20fb9Mark Lobodzinski // Validate that DST buffer has correct usage flags set 3670315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= ValidateBufferUsageFlags(device_data, buffer_state, VK_BUFFER_USAGE_TRANSFER_DST_BIT, true, VALIDATION_ERROR_1b40003a, 367123bb5a2fd221f6788daf2dd976bf19a5e9b20fb9Mark Lobodzinski "vkCmdFillBuffer()", "VK_BUFFER_USAGE_TRANSFER_DST_BIT"); 3672315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= insideRenderPass(device_data, cb_node, "vkCmdFillBuffer()", VALIDATION_ERROR_1b400017); 367323bb5a2fd221f6788daf2dd976bf19a5e9b20fb9Mark Lobodzinski return skip; 367423bb5a2fd221f6788daf2dd976bf19a5e9b20fb9Mark Lobodzinski} 367523bb5a2fd221f6788daf2dd976bf19a5e9b20fb9Mark Lobodzinski 367623bb5a2fd221f6788daf2dd976bf19a5e9b20fb9Mark Lobodzinskivoid PreCallRecordCmdFillBuffer(layer_data *device_data, GLOBAL_CB_NODE *cb_node, BUFFER_STATE *buffer_state) { 367723bb5a2fd221f6788daf2dd976bf19a5e9b20fb9Mark Lobodzinski std::function<bool()> function = [=]() { 367823bb5a2fd221f6788daf2dd976bf19a5e9b20fb9Mark Lobodzinski SetBufferMemoryValid(device_data, buffer_state, true); 367923bb5a2fd221f6788daf2dd976bf19a5e9b20fb9Mark Lobodzinski return false; 368023bb5a2fd221f6788daf2dd976bf19a5e9b20fb9Mark Lobodzinski }; 3681d807198f24437c1b2478ff1d06a33ce4873a1451Tobin Ehlis cb_node->queue_submit_functions.push_back(function); 368223bb5a2fd221f6788daf2dd976bf19a5e9b20fb9Mark Lobodzinski // Update bindings between buffer and cmd buffer 368323bb5a2fd221f6788daf2dd976bf19a5e9b20fb9Mark Lobodzinski AddCommandBufferBindingBuffer(device_data, cb_node, buffer_state); 368423bb5a2fd221f6788daf2dd976bf19a5e9b20fb9Mark Lobodzinski} 3685877577537c1f97bf8d50e32aecd7d3ca09a230a2Mark Lobodzinski 368671c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinskibool ValidateBufferImageCopyData(const debug_report_data *report_data, uint32_t regionCount, const VkBufferImageCopy *pRegions, 368771c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski IMAGE_STATE *image_state, const char *function) { 3688877577537c1f97bf8d50e32aecd7d3ca09a230a2Mark Lobodzinski bool skip = false; 3689877577537c1f97bf8d50e32aecd7d3ca09a230a2Mark Lobodzinski 3690877577537c1f97bf8d50e32aecd7d3ca09a230a2Mark Lobodzinski for (uint32_t i = 0; i < regionCount; i++) { 36915971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton if (image_state->createInfo.imageType == VK_IMAGE_TYPE_1D) { 36925971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton if ((pRegions[i].imageOffset.y != 0) || (pRegions[i].imageExtent.height != 1)) { 36935971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, 3694315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(image_state->image), __LINE__, VALIDATION_ERROR_0160018e, "IMAGE", 36955f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton "%s(): pRegion[%d] imageOffset.y is %d and imageExtent.height is %d. For 1D images these must be 0 " 36965f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton "and 1, respectively. %s", 36975971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton function, i, pRegions[i].imageOffset.y, pRegions[i].imageExtent.height, 3698315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_0160018e]); 3699877577537c1f97bf8d50e32aecd7d3ca09a230a2Mark Lobodzinski } 37005971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton } 3701877577537c1f97bf8d50e32aecd7d3ca09a230a2Mark Lobodzinski 37025971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton if ((image_state->createInfo.imageType == VK_IMAGE_TYPE_1D) || (image_state->createInfo.imageType == VK_IMAGE_TYPE_2D)) { 37035971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton if ((pRegions[i].imageOffset.z != 0) || (pRegions[i].imageExtent.depth != 1)) { 3704877577537c1f97bf8d50e32aecd7d3ca09a230a2Mark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, 3705315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(image_state->image), __LINE__, VALIDATION_ERROR_01600192, "IMAGE", 37065971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton "%s(): pRegion[%d] imageOffset.z is %d and imageExtent.depth is %d. For 1D and 2D images these " 37075971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton "must be 0 and 1, respectively. %s", 37085971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton function, i, pRegions[i].imageOffset.z, pRegions[i].imageExtent.depth, 3709315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_01600192]); 3710877577537c1f97bf8d50e32aecd7d3ca09a230a2Mark Lobodzinski } 37115971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton } 3712877577537c1f97bf8d50e32aecd7d3ca09a230a2Mark Lobodzinski 37135971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton if (image_state->createInfo.imageType == VK_IMAGE_TYPE_3D) { 37145971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton if ((0 != pRegions[i].imageSubresource.baseArrayLayer) || (1 != pRegions[i].imageSubresource.layerCount)) { 3715877577537c1f97bf8d50e32aecd7d3ca09a230a2Mark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, 3716315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(image_state->image), __LINE__, VALIDATION_ERROR_016001aa, "IMAGE", 37175f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton "%s(): pRegion[%d] imageSubresource.baseArrayLayer is %d and imageSubresource.layerCount is %d. " 37185f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton "For 3D images these must be 0 and 1, respectively. %s", 37195971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton function, i, pRegions[i].imageSubresource.baseArrayLayer, pRegions[i].imageSubresource.layerCount, 3720315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_016001aa]); 3721877577537c1f97bf8d50e32aecd7d3ca09a230a2Mark Lobodzinski } 37225971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton } 3723877577537c1f97bf8d50e32aecd7d3ca09a230a2Mark Lobodzinski 37245971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton // If the the calling command's VkImage parameter's format is not a depth/stencil format, 37255971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton // then bufferOffset must be a multiple of the calling command's VkImage parameter's texel size 372616769f6b2a7721e391952a97f010cbb530e4f211Dave Houlton auto texel_size = FormatSize(image_state->createInfo.format); 3727cf2ce8673669ca1111e333bdea272c4dd57cb5c2Dave Houlton if (!FormatIsDepthAndStencil(image_state->createInfo.format) && SafeModulo(pRegions[i].bufferOffset, texel_size) != 0) { 37285971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, 3729315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(image_state->image), __LINE__, VALIDATION_ERROR_01600182, "IMAGE", 37305971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton "%s(): pRegion[%d] bufferOffset 0x%" PRIxLEAST64 37315971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton " must be a multiple of this format's texel size (" PRINTF_SIZE_T_SPECIFIER "). %s", 3732315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis function, i, pRegions[i].bufferOffset, texel_size, validation_error_map[VALIDATION_ERROR_01600182]); 37335971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton } 37345971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton 37355971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton // BufferOffset must be a multiple of 4 373616769f6b2a7721e391952a97f010cbb530e4f211Dave Houlton if (SafeModulo(pRegions[i].bufferOffset, 4) != 0) { 37375971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, 3738315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(image_state->image), __LINE__, VALIDATION_ERROR_01600184, "IMAGE", 37395971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton "%s(): pRegion[%d] bufferOffset 0x%" PRIxLEAST64 " must be a multiple of 4. %s", function, i, 3740315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis pRegions[i].bufferOffset, validation_error_map[VALIDATION_ERROR_01600184]); 37415971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton } 37425971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton 37435971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton // BufferRowLength must be 0, or greater than or equal to the width member of imageExtent 37445971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton if ((pRegions[i].bufferRowLength != 0) && (pRegions[i].bufferRowLength < pRegions[i].imageExtent.width)) { 37455971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton skip |= log_msg( 37465971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, 3747315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(image_state->image), __LINE__, VALIDATION_ERROR_01600186, "IMAGE", 37485971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton "%s(): pRegion[%d] bufferRowLength (%d) must be zero or greater-than-or-equal-to imageExtent.width (%d). %s", 37495971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton function, i, pRegions[i].bufferRowLength, pRegions[i].imageExtent.width, 3750315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_01600186]); 37515971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton } 37525971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton 37535971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton // BufferImageHeight must be 0, or greater than or equal to the height member of imageExtent 37545971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton if ((pRegions[i].bufferImageHeight != 0) && (pRegions[i].bufferImageHeight < pRegions[i].imageExtent.height)) { 37555971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton skip |= log_msg( 37565971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, 3757315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(image_state->image), __LINE__, VALIDATION_ERROR_01600188, "IMAGE", 37585971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton "%s(): pRegion[%d] bufferImageHeight (%d) must be zero or greater-than-or-equal-to imageExtent.height (%d). %s", 37595971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton function, i, pRegions[i].bufferImageHeight, pRegions[i].imageExtent.height, 3760315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_01600188]); 37615971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton } 37625971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton 37635971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton // subresource aspectMask must have exactly 1 bit set 37645971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton const int num_bits = sizeof(VkFlags) * CHAR_BIT; 37655971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton std::bitset<num_bits> aspect_mask_bits(pRegions[i].imageSubresource.aspectMask); 37665971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton if (aspect_mask_bits.count() != 1) { 37675971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, 3768315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(image_state->image), __LINE__, VALIDATION_ERROR_016001a8, "IMAGE", 37695971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton "%s: aspectMasks for imageSubresource in each region must have only a single bit set. %s", function, 3770315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_016001a8]); 37715971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton } 37725971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton 37735971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton // image subresource aspect bit must match format 3774e9d74ac8e13687c1be3ee147efce42e8215a049eDave Houlton if (!VerifyAspectsPresent(pRegions[i].imageSubresource.aspectMask, image_state->createInfo.format)) { 37755971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton skip |= log_msg( 37765971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, 3777315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(image_state->image), __LINE__, VALIDATION_ERROR_016001a6, "IMAGE", 37785971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton "%s(): pRegion[%d] subresource aspectMask 0x%x specifies aspects that are not present in image format 0x%x. %s", 37795971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton function, i, pRegions[i].imageSubresource.aspectMask, image_state->createInfo.format, 3780315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_016001a6]); 37815971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton } 37825971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton 37835971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton // Checks that apply only to compressed images 37845971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton // TODO: there is a comment in ValidateCopyBufferImageTransferGranularityRequirements() in core_validation.cpp that 37855971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton // reserves a place for these compressed image checks. This block of code could move there once the image 37865971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton // stuff is moved into core validation. 378716769f6b2a7721e391952a97f010cbb530e4f211Dave Houlton if (FormatIsCompressed(image_state->createInfo.format)) { 378816769f6b2a7721e391952a97f010cbb530e4f211Dave Houlton auto block_size = FormatCompressedTexelBlockExtent(image_state->createInfo.format); 3789877577537c1f97bf8d50e32aecd7d3ca09a230a2Mark Lobodzinski 37905971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton // BufferRowLength must be a multiple of block width 379116769f6b2a7721e391952a97f010cbb530e4f211Dave Houlton if (SafeModulo(pRegions[i].bufferRowLength, block_size.width) != 0) { 3792877577537c1f97bf8d50e32aecd7d3ca09a230a2Mark Lobodzinski skip |= log_msg( 3793877577537c1f97bf8d50e32aecd7d3ca09a230a2Mark Lobodzinski report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, 3794315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(image_state->image), __LINE__, VALIDATION_ERROR_01600196, "IMAGE", 37955971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton "%s(): pRegion[%d] bufferRowLength (%d) must be a multiple of the compressed image's texel width (%d). %s.", 3796315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis function, i, pRegions[i].bufferRowLength, block_size.width, validation_error_map[VALIDATION_ERROR_01600196]); 3797877577537c1f97bf8d50e32aecd7d3ca09a230a2Mark Lobodzinski } 3798877577537c1f97bf8d50e32aecd7d3ca09a230a2Mark Lobodzinski 37995971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton // BufferRowHeight must be a multiple of block height 380016769f6b2a7721e391952a97f010cbb530e4f211Dave Houlton if (SafeModulo(pRegions[i].bufferImageHeight, block_size.height) != 0) { 38015f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton skip |= log_msg( 38025f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, 38035f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton HandleToUint64(image_state->image), __LINE__, VALIDATION_ERROR_01600198, "IMAGE", 38045f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton "%s(): pRegion[%d] bufferImageHeight (%d) must be a multiple of the compressed image's texel height (%d). %s.", 38055f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton function, i, pRegions[i].bufferImageHeight, block_size.height, validation_error_map[VALIDATION_ERROR_01600198]); 3806877577537c1f97bf8d50e32aecd7d3ca09a230a2Mark Lobodzinski } 3807877577537c1f97bf8d50e32aecd7d3ca09a230a2Mark Lobodzinski 38085971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton // image offsets must be multiples of block dimensions 380916769f6b2a7721e391952a97f010cbb530e4f211Dave Houlton if ((SafeModulo(pRegions[i].imageOffset.x, block_size.width) != 0) || 381016769f6b2a7721e391952a97f010cbb530e4f211Dave Houlton (SafeModulo(pRegions[i].imageOffset.y, block_size.height) != 0) || 381116769f6b2a7721e391952a97f010cbb530e4f211Dave Houlton (SafeModulo(pRegions[i].imageOffset.z, block_size.depth) != 0)) { 38125971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, 3813315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(image_state->image), __LINE__, VALIDATION_ERROR_0160019a, "IMAGE", 38145971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton "%s(): pRegion[%d] imageOffset(x,y) (%d, %d) must be multiples of the compressed image's texel " 38155971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton "width & height (%d, %d). %s.", 38165971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton function, i, pRegions[i].imageOffset.x, pRegions[i].imageOffset.y, block_size.width, 3817315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis block_size.height, validation_error_map[VALIDATION_ERROR_0160019a]); 3818877577537c1f97bf8d50e32aecd7d3ca09a230a2Mark Lobodzinski } 3819877577537c1f97bf8d50e32aecd7d3ca09a230a2Mark Lobodzinski 38205971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton // bufferOffset must be a multiple of block size (linear bytes) 382116769f6b2a7721e391952a97f010cbb530e4f211Dave Houlton size_t block_size_in_bytes = FormatSize(image_state->createInfo.format); 382216769f6b2a7721e391952a97f010cbb530e4f211Dave Houlton if (SafeModulo(pRegions[i].bufferOffset, block_size_in_bytes) != 0) { 38235f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton skip |= log_msg( 38245f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, 38255f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton HandleToUint64(image_state->image), __LINE__, VALIDATION_ERROR_0160019c, "IMAGE", 38265f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton "%s(): pRegion[%d] bufferOffset (0x%" PRIxLEAST64 38275f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton ") must be a multiple of the compressed image's texel block size (" PRINTF_SIZE_T_SPECIFIER "). %s.", 38285f6b7bf3dab2c213b407e1dc16129c04e4405ff3Dave Houlton function, i, pRegions[i].bufferOffset, block_size_in_bytes, validation_error_map[VALIDATION_ERROR_0160019c]); 3829877577537c1f97bf8d50e32aecd7d3ca09a230a2Mark Lobodzinski } 38302cd49094dcd399721f50c123413b8f55693348d7Dave Houlton 38312cd49094dcd399721f50c123413b8f55693348d7Dave Houlton // imageExtent width must be a multiple of block width, or extent+offset width must equal subresource width 3832045a77f666b6efc8a229481b2a7a351f725e3725Dave Houlton VkExtent3D mip_extent = GetImageSubresourceExtent(image_state, &(pRegions[i].imageSubresource)); 383316769f6b2a7721e391952a97f010cbb530e4f211Dave Houlton if ((SafeModulo(pRegions[i].imageExtent.width, block_size.width) != 0) && 3834045a77f666b6efc8a229481b2a7a351f725e3725Dave Houlton (pRegions[i].imageExtent.width + pRegions[i].imageOffset.x != mip_extent.width)) { 3835045a77f666b6efc8a229481b2a7a351f725e3725Dave Houlton skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, 3836315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(image_state->image), __LINE__, VALIDATION_ERROR_0160019e, "IMAGE", 3837045a77f666b6efc8a229481b2a7a351f725e3725Dave Houlton "%s(): pRegion[%d] extent width (%d) must be a multiple of the compressed texture block width " 3838045a77f666b6efc8a229481b2a7a351f725e3725Dave Houlton "(%d), or when added to offset.x (%d) must equal the image subresource width (%d). %s.", 3839045a77f666b6efc8a229481b2a7a351f725e3725Dave Houlton function, i, pRegions[i].imageExtent.width, block_size.width, pRegions[i].imageOffset.x, 3840315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis mip_extent.width, validation_error_map[VALIDATION_ERROR_0160019e]); 38412cd49094dcd399721f50c123413b8f55693348d7Dave Houlton } 38422cd49094dcd399721f50c123413b8f55693348d7Dave Houlton 38432cd49094dcd399721f50c123413b8f55693348d7Dave Houlton // imageExtent height must be a multiple of block height, or extent+offset height must equal subresource height 384416769f6b2a7721e391952a97f010cbb530e4f211Dave Houlton if ((SafeModulo(pRegions[i].imageExtent.height, block_size.height) != 0) && 3845045a77f666b6efc8a229481b2a7a351f725e3725Dave Houlton (pRegions[i].imageExtent.height + pRegions[i].imageOffset.y != mip_extent.height)) { 3846045a77f666b6efc8a229481b2a7a351f725e3725Dave Houlton skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, 3847315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(image_state->image), __LINE__, VALIDATION_ERROR_016001a0, "IMAGE", 3848045a77f666b6efc8a229481b2a7a351f725e3725Dave Houlton "%s(): pRegion[%d] extent height (%d) must be a multiple of the compressed texture block height " 3849045a77f666b6efc8a229481b2a7a351f725e3725Dave Houlton "(%d), or when added to offset.y (%d) must equal the image subresource height (%d). %s.", 3850045a77f666b6efc8a229481b2a7a351f725e3725Dave Houlton function, i, pRegions[i].imageExtent.height, block_size.height, pRegions[i].imageOffset.y, 3851315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis mip_extent.height, validation_error_map[VALIDATION_ERROR_016001a0]); 38522cd49094dcd399721f50c123413b8f55693348d7Dave Houlton } 38532cd49094dcd399721f50c123413b8f55693348d7Dave Houlton 38542cd49094dcd399721f50c123413b8f55693348d7Dave Houlton // imageExtent depth must be a multiple of block depth, or extent+offset depth must equal subresource depth 385516769f6b2a7721e391952a97f010cbb530e4f211Dave Houlton if ((SafeModulo(pRegions[i].imageExtent.depth, block_size.depth) != 0) && 3856045a77f666b6efc8a229481b2a7a351f725e3725Dave Houlton (pRegions[i].imageExtent.depth + pRegions[i].imageOffset.z != mip_extent.depth)) { 3857045a77f666b6efc8a229481b2a7a351f725e3725Dave Houlton skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, 3858315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(image_state->image), __LINE__, VALIDATION_ERROR_016001a2, "IMAGE", 3859045a77f666b6efc8a229481b2a7a351f725e3725Dave Houlton "%s(): pRegion[%d] extent width (%d) must be a multiple of the compressed texture block depth " 3860045a77f666b6efc8a229481b2a7a351f725e3725Dave Houlton "(%d), or when added to offset.z (%d) must equal the image subresource depth (%d). %s.", 3861045a77f666b6efc8a229481b2a7a351f725e3725Dave Houlton function, i, pRegions[i].imageExtent.depth, block_size.depth, pRegions[i].imageOffset.z, 3862315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis mip_extent.depth, validation_error_map[VALIDATION_ERROR_016001a2]); 38632cd49094dcd399721f50c123413b8f55693348d7Dave Houlton } 38645971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton } 386571c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski } 386671c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski 386771c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski return skip; 386871c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski} 386971c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski 38705971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houltonstatic bool ValidateImageBounds(const debug_report_data *report_data, const IMAGE_STATE *image_state, const uint32_t regionCount, 38715971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton const VkBufferImageCopy *pRegions, const char *func_name, UNIQUE_VALIDATION_ERROR_CODE msg_code) { 387271c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski bool skip = false; 38735971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton const VkImageCreateInfo *image_info = &(image_state->createInfo); 387471c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski 387571c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski for (uint32_t i = 0; i < regionCount; i++) { 387671c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski VkExtent3D extent = pRegions[i].imageExtent; 387771c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski VkOffset3D offset = pRegions[i].imageOffset; 387871c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski 38795971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton if (IsExtentSizeZero(&extent)) // Warn on zero area subresource 38805971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton { 38815971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton skip |= log_msg(report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 38825971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton (uint64_t)0, __LINE__, IMAGE_ZERO_AREA_SUBREGION, "IMAGE", 38835971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton "%s: pRegion[%d] imageExtent of {%1d, %1d, %1d} has zero area", func_name, i, extent.width, 38845971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton extent.height, extent.depth); 388571c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski } 388671c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski 38875971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton VkExtent3D image_extent = GetImageSubresourceExtent(image_state, &(pRegions[i].imageSubresource)); 38885971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton 38895971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton // If we're using a compressed format, valid extent is rounded up to multiple of block size (per 18.1) 389016769f6b2a7721e391952a97f010cbb530e4f211Dave Houlton if (FormatIsCompressed(image_info->format)) { 389116769f6b2a7721e391952a97f010cbb530e4f211Dave Houlton auto block_extent = FormatCompressedTexelBlockExtent(image_info->format); 38925971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton if (image_extent.width % block_extent.width) { 38935971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton image_extent.width += (block_extent.width - (image_extent.width % block_extent.width)); 38945971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton } 38955971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton if (image_extent.height % block_extent.height) { 38965971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton image_extent.height += (block_extent.height - (image_extent.height % block_extent.height)); 38975971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton } 38985971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton if (image_extent.depth % block_extent.depth) { 38995971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton image_extent.depth += (block_extent.depth - (image_extent.depth % block_extent.depth)); 39005971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton } 390171c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski } 390271c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski 39033fb79e4c87829ef090622d69a117f33ec7d4ded5Dave Houlton if (0 != ExceedsBounds(&offset, &extent, &image_extent)) { 390471c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, (uint64_t)0, 39055971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton __LINE__, msg_code, "IMAGE", "%s: pRegion[%d] exceeds image bounds. %s.", func_name, i, 390671c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski validation_error_map[msg_code]); 3907877577537c1f97bf8d50e32aecd7d3ca09a230a2Mark Lobodzinski } 3908877577537c1f97bf8d50e32aecd7d3ca09a230a2Mark Lobodzinski } 3909877577537c1f97bf8d50e32aecd7d3ca09a230a2Mark Lobodzinski 3910877577537c1f97bf8d50e32aecd7d3ca09a230a2Mark Lobodzinski return skip; 3911877577537c1f97bf8d50e32aecd7d3ca09a230a2Mark Lobodzinski} 3912877577537c1f97bf8d50e32aecd7d3ca09a230a2Mark Lobodzinski 3913a72d7c6cce872aacc993f014dfd7963ca14675f4Chris Forbesstatic inline bool ValidateBufferBounds(const debug_report_data *report_data, IMAGE_STATE *image_state, BUFFER_STATE *buff_state, 39141007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton uint32_t regionCount, const VkBufferImageCopy *pRegions, const char *func_name, 39151007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton UNIQUE_VALIDATION_ERROR_CODE msg_code) { 391671c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski bool skip = false; 391771c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski 391871c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski VkDeviceSize buffer_size = buff_state->createInfo.size; 391971c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski 392071c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski for (uint32_t i = 0; i < regionCount; i++) { 392171c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski VkExtent3D copy_extent = pRegions[i].imageExtent; 392271c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski 392371c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski VkDeviceSize buffer_width = (0 == pRegions[i].bufferRowLength ? copy_extent.width : pRegions[i].bufferRowLength); 392471c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski VkDeviceSize buffer_height = (0 == pRegions[i].bufferImageHeight ? copy_extent.height : pRegions[i].bufferImageHeight); 392516769f6b2a7721e391952a97f010cbb530e4f211Dave Houlton VkDeviceSize unit_size = FormatSize(image_state->createInfo.format); // size (bytes) of texel or block 392671c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski 39271dc764a1d9155b6fb137006f21e7f6a354aad310Dave Houlton // Handle special buffer packing rules for specific depth/stencil formats 39281dc764a1d9155b6fb137006f21e7f6a354aad310Dave Houlton if (pRegions[i].imageSubresource.aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT) { 392916769f6b2a7721e391952a97f010cbb530e4f211Dave Houlton unit_size = FormatSize(VK_FORMAT_S8_UINT); 39301dc764a1d9155b6fb137006f21e7f6a354aad310Dave Houlton } else if (pRegions[i].imageSubresource.aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT) { 39311dc764a1d9155b6fb137006f21e7f6a354aad310Dave Houlton switch (image_state->createInfo.format) { 39321dc764a1d9155b6fb137006f21e7f6a354aad310Dave Houlton case VK_FORMAT_D16_UNORM_S8_UINT: 393316769f6b2a7721e391952a97f010cbb530e4f211Dave Houlton unit_size = FormatSize(VK_FORMAT_D16_UNORM); 39341dc764a1d9155b6fb137006f21e7f6a354aad310Dave Houlton break; 39351dc764a1d9155b6fb137006f21e7f6a354aad310Dave Houlton case VK_FORMAT_D32_SFLOAT_S8_UINT: 393616769f6b2a7721e391952a97f010cbb530e4f211Dave Houlton unit_size = FormatSize(VK_FORMAT_D32_SFLOAT); 39371dc764a1d9155b6fb137006f21e7f6a354aad310Dave Houlton break; 39385971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton case VK_FORMAT_X8_D24_UNORM_PACK32: // Fall through 39391dc764a1d9155b6fb137006f21e7f6a354aad310Dave Houlton case VK_FORMAT_D24_UNORM_S8_UINT: 39401dc764a1d9155b6fb137006f21e7f6a354aad310Dave Houlton unit_size = 4; 39411dc764a1d9155b6fb137006f21e7f6a354aad310Dave Houlton break; 39421dc764a1d9155b6fb137006f21e7f6a354aad310Dave Houlton default: 39431dc764a1d9155b6fb137006f21e7f6a354aad310Dave Houlton break; 39441dc764a1d9155b6fb137006f21e7f6a354aad310Dave Houlton } 39451dc764a1d9155b6fb137006f21e7f6a354aad310Dave Houlton } 39461dc764a1d9155b6fb137006f21e7f6a354aad310Dave Houlton 394716769f6b2a7721e391952a97f010cbb530e4f211Dave Houlton if (FormatIsCompressed(image_state->createInfo.format)) { 39485971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton // Switch to texel block units, rounding up for any partially-used blocks 394916769f6b2a7721e391952a97f010cbb530e4f211Dave Houlton auto block_dim = FormatCompressedTexelBlockExtent(image_state->createInfo.format); 39505971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton buffer_width = (buffer_width + block_dim.width - 1) / block_dim.width; 39515971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton buffer_height = (buffer_height + block_dim.height - 1) / block_dim.height; 395271c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski 39535971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton copy_extent.width = (copy_extent.width + block_dim.width - 1) / block_dim.width; 39545971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton copy_extent.height = (copy_extent.height + block_dim.height - 1) / block_dim.height; 39555971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton copy_extent.depth = (copy_extent.depth + block_dim.depth - 1) / block_dim.depth; 39565971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton } 395771c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski 39585971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton // Either depth or layerCount may be greater than 1 (not both). This is the number of 'slices' to copy 39595971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton uint32_t z_copies = std::max(copy_extent.depth, pRegions[i].imageSubresource.layerCount); 39605971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton if (IsExtentSizeZero(©_extent) || (0 == z_copies)) { 3961a72d7c6cce872aacc993f014dfd7963ca14675f4Chris Forbes // TODO: Issue warning here? Already warned in ValidateImageBounds()... 39625971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton } else { 39635971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton // Calculate buffer offset of final copied byte, + 1. 39645971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton VkDeviceSize max_buffer_offset = (z_copies - 1) * buffer_height * buffer_width; // offset to slice 39655971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton max_buffer_offset += ((copy_extent.height - 1) * buffer_width) + copy_extent.width; // add row,col 39665971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton max_buffer_offset *= unit_size; // convert to bytes 39675971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton max_buffer_offset += pRegions[i].bufferOffset; // add initial offset (bytes) 396871c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski 39695971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton if (buffer_size < max_buffer_offset) { 39705971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton skip |= 39715971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, (uint64_t)0, 39725971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton __LINE__, msg_code, "IMAGE", "%s: pRegion[%d] exceeds buffer size of %" PRIu64 " bytes. %s.", func_name, 39735971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton i, buffer_size, validation_error_map[msg_code]); 39745971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton } 397571c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski } 397671c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski } 397771c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski 397871c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski return skip; 397971c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski} 398071c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski 398171c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinskibool PreCallValidateCmdCopyImageToBuffer(layer_data *device_data, VkImageLayout srcImageLayout, GLOBAL_CB_NODE *cb_node, 3982940f70f1340803d185c67633b05ef048d277952eMark Lobodzinski IMAGE_STATE *src_image_state, BUFFER_STATE *dst_buffer_state, uint32_t regionCount, 3983877577537c1f97bf8d50e32aecd7d3ca09a230a2Mark Lobodzinski const VkBufferImageCopy *pRegions, const char *func_name) { 398471c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski const debug_report_data *report_data = core_validation::GetReportData(device_data); 398571c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski bool skip = ValidateBufferImageCopyData(report_data, regionCount, pRegions, src_image_state, "vkCmdCopyImageToBuffer"); 398671c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski 398771c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski // Validate command buffer state 3988647670f9a4a7942fa16b9ffa8f0086c9bd9c1235John Zulauf skip |= ValidateCmd(device_data, cb_node, CMD_COPYIMAGETOBUFFER, "vkCmdCopyImageToBuffer()"); 398971c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski 399071c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski // Command pool must support graphics, compute, or transfer operations 399171c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski auto pPool = GetCommandPoolNode(device_data, cb_node->createInfo.commandPool); 399271c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski 399371c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski VkQueueFlags queue_flags = GetPhysDevProperties(device_data)->queue_family_properties[pPool->queueFamilyIndex].queueFlags; 399471c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski if (0 == (queue_flags & (VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT | VK_QUEUE_TRANSFER_BIT))) { 399571c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 3996315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(cb_node->createInfo.commandPool), __LINE__, VALIDATION_ERROR_19202415, "DS", 399771c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski "Cannot call vkCmdCopyImageToBuffer() on a command buffer allocated from a pool without graphics, compute, " 399871c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski "or transfer capabilities. %s.", 3999315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_19202415]); 400071c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski } 40015971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton skip |= ValidateImageBounds(report_data, src_image_state, regionCount, pRegions, "vkCmdCopyBufferToImage()", 4002315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis VALIDATION_ERROR_1920016c); 4003a72d7c6cce872aacc993f014dfd7963ca14675f4Chris Forbes skip |= ValidateBufferBounds(report_data, src_image_state, dst_buffer_state, regionCount, pRegions, "vkCmdCopyImageToBuffer()", 40041007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton VALIDATION_ERROR_1920016e); 400571c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski 400671c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski skip |= ValidateImageSampleCount(device_data, src_image_state, VK_SAMPLE_COUNT_1_BIT, "vkCmdCopyImageToBuffer(): srcImage", 4007315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis VALIDATION_ERROR_19200178); 4008315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= ValidateMemoryIsBoundToImage(device_data, src_image_state, "vkCmdCopyImageToBuffer()", VALIDATION_ERROR_19200176); 4009315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= ValidateMemoryIsBoundToBuffer(device_data, dst_buffer_state, "vkCmdCopyImageToBuffer()", VALIDATION_ERROR_19200180); 4010d5cde34b61eb694c6fe1d5e53de61bb87bf6936aMark Lobodzinski 401171c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski // Validate that SRC image & DST buffer have correct usage flags set 4012315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= ValidateImageUsageFlags(device_data, src_image_state, VK_IMAGE_USAGE_TRANSFER_SRC_BIT, true, VALIDATION_ERROR_19200174, 401371c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski "vkCmdCopyImageToBuffer()", "VK_IMAGE_USAGE_TRANSFER_SRC_BIT"); 4014315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= ValidateBufferUsageFlags(device_data, dst_buffer_state, VK_BUFFER_USAGE_TRANSFER_DST_BIT, true, 4015315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis VALIDATION_ERROR_1920017e, "vkCmdCopyImageToBuffer()", "VK_BUFFER_USAGE_TRANSFER_DST_BIT"); 4016315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= insideRenderPass(device_data, cb_node, "vkCmdCopyImageToBuffer()", VALIDATION_ERROR_19200017); 40170db18ab1345f9e10907913b22ea5d57bd48077ebTobin Ehlis bool hit_error = false; 4018d5cde34b61eb694c6fe1d5e53de61bb87bf6936aMark Lobodzinski for (uint32_t i = 0; i < regionCount; ++i) { 4019315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= VerifyImageLayout(device_data, cb_node, src_image_state, pRegions[i].imageSubresource, srcImageLayout, 4020315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, "vkCmdCopyImageToBuffer()", VALIDATION_ERROR_1920017c, 4021315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis &hit_error); 4022d5cde34b61eb694c6fe1d5e53de61bb87bf6936aMark Lobodzinski skip |= ValidateCopyBufferImageTransferGranularityRequirements(device_data, cb_node, src_image_state, &pRegions[i], i, 4023fab4fd84d0d187bc73b5bc6709d8ed6370bb7cc3Tobin Ehlis "vkCmdCopyImageToBuffer()"); 4024d5cde34b61eb694c6fe1d5e53de61bb87bf6936aMark Lobodzinski } 4025d5cde34b61eb694c6fe1d5e53de61bb87bf6936aMark Lobodzinski return skip; 4026d5cde34b61eb694c6fe1d5e53de61bb87bf6936aMark Lobodzinski} 4027d5cde34b61eb694c6fe1d5e53de61bb87bf6936aMark Lobodzinski 4028d5cde34b61eb694c6fe1d5e53de61bb87bf6936aMark Lobodzinskivoid PreCallRecordCmdCopyImageToBuffer(layer_data *device_data, GLOBAL_CB_NODE *cb_node, IMAGE_STATE *src_image_state, 4029a07ae8bd5f566eb9b073498dd4280efdb0b838b9Tobin Ehlis BUFFER_STATE *dst_buffer_state, uint32_t region_count, const VkBufferImageCopy *regions, 4030a07ae8bd5f566eb9b073498dd4280efdb0b838b9Tobin Ehlis VkImageLayout src_image_layout) { 4031a07ae8bd5f566eb9b073498dd4280efdb0b838b9Tobin Ehlis // Make sure that all image slices are updated to correct layout 4032a07ae8bd5f566eb9b073498dd4280efdb0b838b9Tobin Ehlis for (uint32_t i = 0; i < region_count; ++i) { 4033a07ae8bd5f566eb9b073498dd4280efdb0b838b9Tobin Ehlis SetImageLayout(device_data, cb_node, src_image_state, regions[i].imageSubresource, src_image_layout); 4034a07ae8bd5f566eb9b073498dd4280efdb0b838b9Tobin Ehlis } 4035d5cde34b61eb694c6fe1d5e53de61bb87bf6936aMark Lobodzinski // Update bindings between buffer/image and cmd buffer 4036d5cde34b61eb694c6fe1d5e53de61bb87bf6936aMark Lobodzinski AddCommandBufferBindingImage(device_data, cb_node, src_image_state); 4037940f70f1340803d185c67633b05ef048d277952eMark Lobodzinski AddCommandBufferBindingBuffer(device_data, cb_node, dst_buffer_state); 4038d5cde34b61eb694c6fe1d5e53de61bb87bf6936aMark Lobodzinski 403971c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski std::function<bool()> function = [=]() { 404071c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski return ValidateImageMemoryIsValid(device_data, src_image_state, "vkCmdCopyImageToBuffer()"); 404171c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski }; 4042d807198f24437c1b2478ff1d06a33ce4873a1451Tobin Ehlis cb_node->queue_submit_functions.push_back(function); 404371c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski function = [=]() { 4044940f70f1340803d185c67633b05ef048d277952eMark Lobodzinski SetBufferMemoryValid(device_data, dst_buffer_state, true); 404571c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski return false; 404671c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski }; 4047d807198f24437c1b2478ff1d06a33ce4873a1451Tobin Ehlis cb_node->queue_submit_functions.push_back(function); 4048877577537c1f97bf8d50e32aecd7d3ca09a230a2Mark Lobodzinski} 4049877577537c1f97bf8d50e32aecd7d3ca09a230a2Mark Lobodzinski 405071c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinskibool PreCallValidateCmdCopyBufferToImage(layer_data *device_data, VkImageLayout dstImageLayout, GLOBAL_CB_NODE *cb_node, 4051940f70f1340803d185c67633b05ef048d277952eMark Lobodzinski BUFFER_STATE *src_buffer_state, IMAGE_STATE *dst_image_state, uint32_t regionCount, 4052877577537c1f97bf8d50e32aecd7d3ca09a230a2Mark Lobodzinski const VkBufferImageCopy *pRegions, const char *func_name) { 405371c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski const debug_report_data *report_data = core_validation::GetReportData(device_data); 405471c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski bool skip = ValidateBufferImageCopyData(report_data, regionCount, pRegions, dst_image_state, "vkCmdCopyBufferToImage"); 405571c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski 405671c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski // Validate command buffer state 4057647670f9a4a7942fa16b9ffa8f0086c9bd9c1235John Zulauf skip |= ValidateCmd(device_data, cb_node, CMD_COPYBUFFERTOIMAGE, "vkCmdCopyBufferToImage()"); 405871c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski 405971c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski // Command pool must support graphics, compute, or transfer operations 406071c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski auto pPool = GetCommandPoolNode(device_data, cb_node->createInfo.commandPool); 406171c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski VkQueueFlags queue_flags = GetPhysDevProperties(device_data)->queue_family_properties[pPool->queueFamilyIndex].queueFlags; 406271c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski if (0 == (queue_flags & (VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT | VK_QUEUE_TRANSFER_BIT))) { 406371c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 4064315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(cb_node->createInfo.commandPool), __LINE__, VALIDATION_ERROR_18e02415, "DS", 406571c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski "Cannot call vkCmdCopyBufferToImage() on a command buffer allocated from a pool without graphics, compute, " 406671c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski "or transfer capabilities. %s.", 4067315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_18e02415]); 406871c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski } 40695971c8e986a756c19a66a86d5faf5bd48a2c22c2Dave Houlton skip |= ValidateImageBounds(report_data, dst_image_state, regionCount, pRegions, "vkCmdCopyBufferToImage()", 4070315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis VALIDATION_ERROR_18e00158); 4071a72d7c6cce872aacc993f014dfd7963ca14675f4Chris Forbes skip |= ValidateBufferBounds(report_data, dst_image_state, src_buffer_state, regionCount, pRegions, "vkCmdCopyBufferToImage()", 40721007016f1ad79cd026da6cd8e086805475e8cb19Dave Houlton VALIDATION_ERROR_18e00156); 407371c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski skip |= ValidateImageSampleCount(device_data, dst_image_state, VK_SAMPLE_COUNT_1_BIT, "vkCmdCopyBufferToImage(): dstImage", 4074315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis VALIDATION_ERROR_18e00166); 4075315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= ValidateMemoryIsBoundToBuffer(device_data, src_buffer_state, "vkCmdCopyBufferToImage()", VALIDATION_ERROR_18e00160); 4076315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= ValidateMemoryIsBoundToImage(device_data, dst_image_state, "vkCmdCopyBufferToImage()", VALIDATION_ERROR_18e00164); 4077315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= ValidateBufferUsageFlags(device_data, src_buffer_state, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, true, 4078315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis VALIDATION_ERROR_18e0015c, "vkCmdCopyBufferToImage()", "VK_BUFFER_USAGE_TRANSFER_SRC_BIT"); 4079315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= ValidateImageUsageFlags(device_data, dst_image_state, VK_IMAGE_USAGE_TRANSFER_DST_BIT, true, VALIDATION_ERROR_18e00162, 408071c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski "vkCmdCopyBufferToImage()", "VK_IMAGE_USAGE_TRANSFER_DST_BIT"); 4081315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= insideRenderPass(device_data, cb_node, "vkCmdCopyBufferToImage()", VALIDATION_ERROR_18e00017); 40820db18ab1345f9e10907913b22ea5d57bd48077ebTobin Ehlis bool hit_error = false; 4083d5cde34b61eb694c6fe1d5e53de61bb87bf6936aMark Lobodzinski for (uint32_t i = 0; i < regionCount; ++i) { 4084315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= VerifyImageLayout(device_data, cb_node, dst_image_state, pRegions[i].imageSubresource, dstImageLayout, 4085315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, "vkCmdCopyBufferToImage()", VALIDATION_ERROR_18e0016a, 4086315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis &hit_error); 4087d5cde34b61eb694c6fe1d5e53de61bb87bf6936aMark Lobodzinski skip |= ValidateCopyBufferImageTransferGranularityRequirements(device_data, cb_node, dst_image_state, &pRegions[i], i, 4088d5cde34b61eb694c6fe1d5e53de61bb87bf6936aMark Lobodzinski "vkCmdCopyBufferToImage()"); 4089d5cde34b61eb694c6fe1d5e53de61bb87bf6936aMark Lobodzinski } 4090d5cde34b61eb694c6fe1d5e53de61bb87bf6936aMark Lobodzinski return skip; 4091d5cde34b61eb694c6fe1d5e53de61bb87bf6936aMark Lobodzinski} 4092d5cde34b61eb694c6fe1d5e53de61bb87bf6936aMark Lobodzinski 4093940f70f1340803d185c67633b05ef048d277952eMark Lobodzinskivoid PreCallRecordCmdCopyBufferToImage(layer_data *device_data, GLOBAL_CB_NODE *cb_node, BUFFER_STATE *src_buffer_state, 4094a07ae8bd5f566eb9b073498dd4280efdb0b838b9Tobin Ehlis IMAGE_STATE *dst_image_state, uint32_t region_count, const VkBufferImageCopy *regions, 4095a07ae8bd5f566eb9b073498dd4280efdb0b838b9Tobin Ehlis VkImageLayout dst_image_layout) { 4096a07ae8bd5f566eb9b073498dd4280efdb0b838b9Tobin Ehlis // Make sure that all image slices are updated to correct layout 4097a07ae8bd5f566eb9b073498dd4280efdb0b838b9Tobin Ehlis for (uint32_t i = 0; i < region_count; ++i) { 4098a07ae8bd5f566eb9b073498dd4280efdb0b838b9Tobin Ehlis SetImageLayout(device_data, cb_node, dst_image_state, regions[i].imageSubresource, dst_image_layout); 4099a07ae8bd5f566eb9b073498dd4280efdb0b838b9Tobin Ehlis } 4100940f70f1340803d185c67633b05ef048d277952eMark Lobodzinski AddCommandBufferBindingBuffer(device_data, cb_node, src_buffer_state); 4101d5cde34b61eb694c6fe1d5e53de61bb87bf6936aMark Lobodzinski AddCommandBufferBindingImage(device_data, cb_node, dst_image_state); 410271c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski std::function<bool()> function = [=]() { 410371c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski SetImageMemoryValid(device_data, dst_image_state, true); 410471c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski return false; 410571c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski }; 4106d807198f24437c1b2478ff1d06a33ce4873a1451Tobin Ehlis cb_node->queue_submit_functions.push_back(function); 4107940f70f1340803d185c67633b05ef048d277952eMark Lobodzinski function = [=]() { return ValidateBufferMemoryIsValid(device_data, src_buffer_state, "vkCmdCopyBufferToImage()"); }; 4108d807198f24437c1b2478ff1d06a33ce4873a1451Tobin Ehlis cb_node->queue_submit_functions.push_back(function); 4109877577537c1f97bf8d50e32aecd7d3ca09a230a2Mark Lobodzinski} 4110e6e50fcd129baea00fd5eb908cad29b252abaaa7Mike Weiblen 4111e6e50fcd129baea00fd5eb908cad29b252abaaa7Mike Weiblenbool PreCallValidateGetImageSubresourceLayout(layer_data *device_data, VkImage image, const VkImageSubresource *pSubresource) { 4112e6e50fcd129baea00fd5eb908cad29b252abaaa7Mike Weiblen const auto report_data = core_validation::GetReportData(device_data); 4113e6e50fcd129baea00fd5eb908cad29b252abaaa7Mike Weiblen bool skip = false; 4114e6e50fcd129baea00fd5eb908cad29b252abaaa7Mike Weiblen const VkImageAspectFlags sub_aspect = pSubresource->aspectMask; 4115e6e50fcd129baea00fd5eb908cad29b252abaaa7Mike Weiblen 4116f1811ff56d1ba5fce039ede9328b3e7006abd1b6Dave Houlton // The aspectMask member of pSubresource must only have a single bit set 4117e6e50fcd129baea00fd5eb908cad29b252abaaa7Mike Weiblen const int num_bits = sizeof(sub_aspect) * CHAR_BIT; 4118e6e50fcd129baea00fd5eb908cad29b252abaaa7Mike Weiblen std::bitset<num_bits> aspect_mask_bits(sub_aspect); 4119e6e50fcd129baea00fd5eb908cad29b252abaaa7Mike Weiblen if (aspect_mask_bits.count() != 1) { 41209b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, HandleToUint64(image), 4121315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis __LINE__, VALIDATION_ERROR_2a6007ca, "IMAGE", 4122e6e50fcd129baea00fd5eb908cad29b252abaaa7Mike Weiblen "vkGetImageSubresourceLayout(): VkImageSubresource.aspectMask must have exactly 1 bit set. %s", 4123315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_2a6007ca]); 4124e6e50fcd129baea00fd5eb908cad29b252abaaa7Mike Weiblen } 4125e6e50fcd129baea00fd5eb908cad29b252abaaa7Mike Weiblen 4126e6e50fcd129baea00fd5eb908cad29b252abaaa7Mike Weiblen IMAGE_STATE *image_entry = GetImageState(device_data, image); 4127e6e50fcd129baea00fd5eb908cad29b252abaaa7Mike Weiblen if (!image_entry) { 4128e6e50fcd129baea00fd5eb908cad29b252abaaa7Mike Weiblen return skip; 4129e6e50fcd129baea00fd5eb908cad29b252abaaa7Mike Weiblen } 4130e6e50fcd129baea00fd5eb908cad29b252abaaa7Mike Weiblen 4131f1811ff56d1ba5fce039ede9328b3e7006abd1b6Dave Houlton // image must have been created with tiling equal to VK_IMAGE_TILING_LINEAR 4132e6e50fcd129baea00fd5eb908cad29b252abaaa7Mike Weiblen if (image_entry->createInfo.tiling != VK_IMAGE_TILING_LINEAR) { 41339b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, HandleToUint64(image), 4134315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis __LINE__, VALIDATION_ERROR_2a6007c8, "IMAGE", 4135e6e50fcd129baea00fd5eb908cad29b252abaaa7Mike Weiblen "vkGetImageSubresourceLayout(): Image must have tiling of VK_IMAGE_TILING_LINEAR. %s", 4136315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_2a6007c8]); 4137e6e50fcd129baea00fd5eb908cad29b252abaaa7Mike Weiblen } 4138e6e50fcd129baea00fd5eb908cad29b252abaaa7Mike Weiblen 4139f1811ff56d1ba5fce039ede9328b3e7006abd1b6Dave Houlton // mipLevel must be less than the mipLevels specified in VkImageCreateInfo when the image was created 4140e6e50fcd129baea00fd5eb908cad29b252abaaa7Mike Weiblen if (pSubresource->mipLevel >= image_entry->createInfo.mipLevels) { 41419b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, HandleToUint64(image), 4142315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis __LINE__, VALIDATION_ERROR_0a4007cc, "IMAGE", 4143e6e50fcd129baea00fd5eb908cad29b252abaaa7Mike Weiblen "vkGetImageSubresourceLayout(): pSubresource.mipLevel (%d) must be less than %d. %s", 4144315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis pSubresource->mipLevel, image_entry->createInfo.mipLevels, validation_error_map[VALIDATION_ERROR_0a4007cc]); 4145e6e50fcd129baea00fd5eb908cad29b252abaaa7Mike Weiblen } 4146e6e50fcd129baea00fd5eb908cad29b252abaaa7Mike Weiblen 4147f1811ff56d1ba5fce039ede9328b3e7006abd1b6Dave Houlton // arrayLayer must be less than the arrayLayers specified in VkImageCreateInfo when the image was created 4148e6e50fcd129baea00fd5eb908cad29b252abaaa7Mike Weiblen if (pSubresource->arrayLayer >= image_entry->createInfo.arrayLayers) { 4149315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= 4150315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, HandleToUint64(image), 4151315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis __LINE__, VALIDATION_ERROR_0a4007ce, "IMAGE", 4152315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis "vkGetImageSubresourceLayout(): pSubresource.arrayLayer (%d) must be less than %d. %s", 4153315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis pSubresource->arrayLayer, image_entry->createInfo.arrayLayers, validation_error_map[VALIDATION_ERROR_0a4007ce]); 4154e6e50fcd129baea00fd5eb908cad29b252abaaa7Mike Weiblen } 4155e6e50fcd129baea00fd5eb908cad29b252abaaa7Mike Weiblen 4156f1811ff56d1ba5fce039ede9328b3e7006abd1b6Dave Houlton // subresource's aspect must be compatible with image's format. 4157e6e50fcd129baea00fd5eb908cad29b252abaaa7Mike Weiblen const VkFormat img_format = image_entry->createInfo.format; 4158f1811ff56d1ba5fce039ede9328b3e7006abd1b6Dave Houlton if (FormatIsMultiplane(img_format)) { 4159f1811ff56d1ba5fce039ede9328b3e7006abd1b6Dave Houlton VkImageAspectFlags allowed_flags = (VK_IMAGE_ASPECT_PLANE_0_BIT_KHR | VK_IMAGE_ASPECT_PLANE_1_BIT_KHR); 4160f1811ff56d1ba5fce039ede9328b3e7006abd1b6Dave Houlton UNIQUE_VALIDATION_ERROR_CODE vuid = VALIDATION_ERROR_2a600c5a; // 2-plane version 4161f1811ff56d1ba5fce039ede9328b3e7006abd1b6Dave Houlton if (FormatPlaneCount(img_format) > 2u) { 4162f1811ff56d1ba5fce039ede9328b3e7006abd1b6Dave Houlton allowed_flags |= VK_IMAGE_ASPECT_PLANE_2_BIT_KHR; 4163f1811ff56d1ba5fce039ede9328b3e7006abd1b6Dave Houlton vuid = VALIDATION_ERROR_2a600c5c; // 3-plane version 4164f1811ff56d1ba5fce039ede9328b3e7006abd1b6Dave Houlton } 4165f1811ff56d1ba5fce039ede9328b3e7006abd1b6Dave Houlton if (sub_aspect != (sub_aspect & allowed_flags)) { 4166f1811ff56d1ba5fce039ede9328b3e7006abd1b6Dave Houlton skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, 4167f1811ff56d1ba5fce039ede9328b3e7006abd1b6Dave Houlton HandleToUint64(image), __LINE__, vuid, "IMAGE", 4168f1811ff56d1ba5fce039ede9328b3e7006abd1b6Dave Houlton "vkGetImageSubresourceLayout(): For multi-planar images, VkImageSubresource.aspectMask (0x%" PRIx32 4169f1811ff56d1ba5fce039ede9328b3e7006abd1b6Dave Houlton ") must be a single-plane specifier flag. %s", 4170f1811ff56d1ba5fce039ede9328b3e7006abd1b6Dave Houlton sub_aspect, validation_error_map[vuid]); 4171f1811ff56d1ba5fce039ede9328b3e7006abd1b6Dave Houlton } 4172f1811ff56d1ba5fce039ede9328b3e7006abd1b6Dave Houlton } else if (FormatIsColor(img_format)) { 4173e6e50fcd129baea00fd5eb908cad29b252abaaa7Mike Weiblen if (sub_aspect != VK_IMAGE_ASPECT_COLOR_BIT) { 41743aed09356cf956132dacc4cd23c39be9b6d01f08Dave Houlton skip |= log_msg( 41753aed09356cf956132dacc4cd23c39be9b6d01f08Dave Houlton report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, HandleToUint64(image), __LINE__, 41763aed09356cf956132dacc4cd23c39be9b6d01f08Dave Houlton VALIDATION_ERROR_0a400c01, "IMAGE", 41773aed09356cf956132dacc4cd23c39be9b6d01f08Dave Houlton "vkGetImageSubresourceLayout(): For color formats, VkImageSubresource.aspectMask must be VK_IMAGE_ASPECT_COLOR. %s", 41783aed09356cf956132dacc4cd23c39be9b6d01f08Dave Houlton validation_error_map[VALIDATION_ERROR_0a400c01]); 4179e6e50fcd129baea00fd5eb908cad29b252abaaa7Mike Weiblen } 418016769f6b2a7721e391952a97f010cbb530e4f211Dave Houlton } else if (FormatIsDepthOrStencil(img_format)) { 4181e6e50fcd129baea00fd5eb908cad29b252abaaa7Mike Weiblen if ((sub_aspect != VK_IMAGE_ASPECT_DEPTH_BIT) && (sub_aspect != VK_IMAGE_ASPECT_STENCIL_BIT)) { 4182fdc75c21ced997fbbc180734bef87bf6d5811d4bMark Lobodzinski skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, 4183315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(image), __LINE__, VALIDATION_ERROR_0a400c01, "IMAGE", 4184e6e50fcd129baea00fd5eb908cad29b252abaaa7Mike Weiblen "vkGetImageSubresourceLayout(): For depth/stencil formats, VkImageSubresource.aspectMask must be " 4185e6e50fcd129baea00fd5eb908cad29b252abaaa7Mike Weiblen "either VK_IMAGE_ASPECT_DEPTH_BIT or VK_IMAGE_ASPECT_STENCIL_BIT. %s", 4186315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_0a400c01]); 4187e6e50fcd129baea00fd5eb908cad29b252abaaa7Mike Weiblen } 4188e6e50fcd129baea00fd5eb908cad29b252abaaa7Mike Weiblen } 4189e6e50fcd129baea00fd5eb908cad29b252abaaa7Mike Weiblen return skip; 4190e6e50fcd129baea00fd5eb908cad29b252abaaa7Mike Weiblen} 4191