blob: 04b6fb6eb5e91c19b9a3ac020938144b0b36689a [file] [log] [blame]
Mark Lobodzinski6eda00a2016-02-02 15:55:36 -07001/* Copyright (c) 2015-2016 The Khronos Group Inc.
2 * Copyright (c) 2015-2016 Valve Corporation
3 * Copyright (c) 2015-2016 LunarG, Inc.
4 * Copyright (C) 2015-2016 Google Inc.
Jeremy Hayes9cc31582015-06-18 10:12:39 -06005 *
Jon Ashburn3ebf1252016-04-19 11:30:31 -06006 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
Jeremy Hayes9cc31582015-06-18 10:12:39 -06009 *
Jon Ashburn3ebf1252016-04-19 11:30:31 -060010 * http://www.apache.org/licenses/LICENSE-2.0
Jeremy Hayes9cc31582015-06-18 10:12:39 -060011 *
Jon Ashburn3ebf1252016-04-19 11:30:31 -060012 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
Courtney Goeltzenleuchter05559522015-10-30 11:14:30 -060017 *
18 * Author: Jeremy Hayes <jeremy@lunarg.com>
19 * Author: Mark Lobodzinski <mark@lunarg.com>
20 * Author: Mike Stroyan <mike@LunarG.com>
21 * Author: Tobin Ehlis <tobin@lunarg.com>
Jeremy Hayes9cc31582015-06-18 10:12:39 -060022 */
23
Mark Lobodzinskib2ad7022016-03-29 17:10:14 -060024// Allow use of STL min and max functions in Windows
25#define NOMINMAX
26
Jeremy Hayese0ed6a22016-04-08 09:53:54 -060027#include <algorithm>
28#include <assert.h>
Courtney Goeltzenleuchter8f8367e2015-10-07 08:38:30 -060029#include <inttypes.h>
Jeremy Hayese0ed6a22016-04-08 09:53:54 -060030#include <memory>
31#include <mutex>
Jeremy Hayes9cc31582015-06-18 10:12:39 -060032#include <stdio.h>
33#include <stdlib.h>
34#include <string.h>
Jeremy Hayes9cc31582015-06-18 10:12:39 -060035#include <unordered_map>
Jeremy Hayese0ed6a22016-04-08 09:53:54 -060036#include <vector>
Jeremy Hayes9cc31582015-06-18 10:12:39 -060037
Tobin Ehlisb835d1b2015-07-03 10:34:49 -060038#include "vk_loader_platform.h"
Courtney Goeltzenleuchter8f8367e2015-10-07 08:38:30 -060039#include "vk_dispatch_table_helper.h"
40#include "vk_struct_string_helper_cpp.h"
Jeremy Hayes9cc31582015-06-18 10:12:39 -060041#include "vk_enum_validate_helper.h"
Courtney Goeltzenleuchter8f8367e2015-10-07 08:38:30 -060042#include "image.h"
43#include "vk_layer_config.h"
44#include "vk_layer_extension_utils.h"
Tobin Ehlisa0cb02e2015-07-03 10:15:26 -060045#include "vk_layer_table.h"
46#include "vk_layer_data.h"
Courtney Goeltzenleuchter426e1872015-07-07 11:18:30 -060047#include "vk_layer_extension_utils.h"
Mike Stroyana3082432015-09-25 13:39:21 -060048#include "vk_layer_utils.h"
Courtney Goeltzenleuchter8f8367e2015-10-07 08:38:30 -060049#include "vk_layer_logging.h"
Jeremy Hayes9cc31582015-06-18 10:12:39 -060050
Cody Northrop55443ef2015-09-28 15:09:32 -060051struct layer_data {
Jon Ashburn5484e0c2016-03-08 17:48:44 -070052 debug_report_data *report_data;
53 vector<VkDebugReportCallbackEXT> logging_callback;
54 VkLayerDispatchTable *device_dispatch_table;
Mark Lobodzinskid5a23822015-11-12 15:14:35 -070055 VkLayerInstanceDispatchTable *instance_dispatch_table;
Jon Ashburn5484e0c2016-03-08 17:48:44 -070056 VkPhysicalDevice physicalDevice;
57 VkPhysicalDeviceProperties physicalDeviceProperties;
Mark Lobodzinskid5a23822015-11-12 15:14:35 -070058
Chia-I Wue2fc5522015-10-26 20:04:44 +080059 unordered_map<VkImage, IMAGE_STATE> imageMap;
Cody Northrop55443ef2015-09-28 15:09:32 -060060
Jon Ashburn5484e0c2016-03-08 17:48:44 -070061 layer_data()
62 : report_data(nullptr), device_dispatch_table(nullptr), instance_dispatch_table(nullptr), physicalDevice(0),
63 physicalDeviceProperties(){};
Cody Northrop55443ef2015-09-28 15:09:32 -060064};
Jeremy Hayes9cc31582015-06-18 10:12:39 -060065
Jon Ashburn5484e0c2016-03-08 17:48:44 -070066static unordered_map<void *, layer_data *> layer_data_map;
Jeremy Hayese0ed6a22016-04-08 09:53:54 -060067static std::mutex global_lock;
Jeremy Hayes9cc31582015-06-18 10:12:39 -060068
Mark Lobodzinski1079e1b2016-03-15 14:21:59 -060069static void init_image(layer_data *my_data, const VkAllocationCallbacks *pAllocator) {
Mark Lobodzinski1079e1b2016-03-15 14:21:59 -060070 layer_debug_actions(my_data->report_data, my_data->logging_callback, pAllocator, "lunarg_image");
Jeremy Hayes9cc31582015-06-18 10:12:39 -060071}
72
Jon Ashburn5484e0c2016-03-08 17:48:44 -070073VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
74vkCreateDebugReportCallbackEXT(VkInstance instance, const VkDebugReportCallbackCreateInfoEXT *pCreateInfo,
75 const VkAllocationCallbacks *pAllocator, VkDebugReportCallbackEXT *pMsgCallback) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -070076 layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
77 VkResult res = my_data->instance_dispatch_table->CreateDebugReportCallbackEXT(instance, pCreateInfo, pAllocator, pMsgCallback);
Jeremy Hayes9cc31582015-06-18 10:12:39 -060078 if (res == VK_SUCCESS) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -070079 res = layer_create_msg_callback(my_data->report_data, pCreateInfo, pAllocator, pMsgCallback);
Jeremy Hayes9cc31582015-06-18 10:12:39 -060080 }
81 return res;
82}
83
Jon Ashburn5484e0c2016-03-08 17:48:44 -070084VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL vkDestroyDebugReportCallbackEXT(VkInstance instance,
85 VkDebugReportCallbackEXT msgCallback,
86 const VkAllocationCallbacks *pAllocator) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -070087 layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
88 my_data->instance_dispatch_table->DestroyDebugReportCallbackEXT(instance, msgCallback, pAllocator);
Courtney Goeltzenleuchter05854bf2015-11-30 12:13:14 -070089 layer_destroy_msg_callback(my_data->report_data, msgCallback, pAllocator);
Jeremy Hayes9cc31582015-06-18 10:12:39 -060090}
91
Jon Ashburn5484e0c2016-03-08 17:48:44 -070092VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL
93vkDebugReportMessageEXT(VkInstance instance, VkDebugReportFlagsEXT flags, VkDebugReportObjectTypeEXT objType, uint64_t object,
94 size_t location, int32_t msgCode, const char *pLayerPrefix, const char *pMsg) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -070095 layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
Jon Ashburn5484e0c2016-03-08 17:48:44 -070096 my_data->instance_dispatch_table->DebugReportMessageEXT(instance, flags, objType, object, location, msgCode, pLayerPrefix,
97 pMsg);
Courtney Goeltzenleuchterf0de7242015-12-01 14:10:55 -070098}
99
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700100VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
101vkCreateInstance(const VkInstanceCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkInstance *pInstance) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700102 VkLayerInstanceCreateInfo *chain_info = get_chain_info(pCreateInfo, VK_LAYER_LINK_INFO);
Jeremy Hayes9cc31582015-06-18 10:12:39 -0600103
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -0700104 assert(chain_info->u.pLayerInfo);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700105 PFN_vkGetInstanceProcAddr fpGetInstanceProcAddr = chain_info->u.pLayerInfo->pfnNextGetInstanceProcAddr;
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700106 PFN_vkCreateInstance fpCreateInstance = (PFN_vkCreateInstance)fpGetInstanceProcAddr(NULL, "vkCreateInstance");
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -0700107 if (fpCreateInstance == NULL) {
108 return VK_ERROR_INITIALIZATION_FAILED;
Jeremy Hayes9cc31582015-06-18 10:12:39 -0600109 }
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -0700110
111 // Advance the link info for the next element on the chain
112 chain_info->u.pLayerInfo = chain_info->u.pLayerInfo->pNext;
113
114 VkResult result = fpCreateInstance(pCreateInfo, pAllocator, pInstance);
115 if (result != VK_SUCCESS)
116 return result;
117
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700118 layer_data *my_data = get_my_data_ptr(get_dispatch_key(*pInstance), layer_data_map);
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -0700119 my_data->instance_dispatch_table = new VkLayerInstanceDispatchTable;
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700120 layer_init_instance_dispatch_table(*pInstance, my_data->instance_dispatch_table, fpGetInstanceProcAddr);
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -0700121
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700122 my_data->report_data = debug_report_create_instance(my_data->instance_dispatch_table, *pInstance,
123 pCreateInfo->enabledExtensionCount, pCreateInfo->ppEnabledExtensionNames);
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -0700124
Mark Lobodzinski1079e1b2016-03-15 14:21:59 -0600125 init_image(my_data, pAllocator);
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -0700126
Jeremy Hayes9cc31582015-06-18 10:12:39 -0600127 return result;
128}
129
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700130VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL vkDestroyInstance(VkInstance instance, const VkAllocationCallbacks *pAllocator) {
Jeremy Hayes9cc31582015-06-18 10:12:39 -0600131 // Grab the key before the instance is destroyed.
132 dispatch_key key = get_dispatch_key(instance);
Tobin Ehlisb74f6ab2015-10-29 14:19:18 -0600133 layer_data *my_data = get_my_data_ptr(key, layer_data_map);
134 VkLayerInstanceDispatchTable *pTable = my_data->instance_dispatch_table;
Chia-I Wuf7458c52015-10-26 21:10:41 +0800135 pTable->DestroyInstance(instance, pAllocator);
Jeremy Hayes9cc31582015-06-18 10:12:39 -0600136
137 // Clean up logging callback, if any
Courtney Goeltzenleuchterffcdd8b2015-10-05 15:59:11 -0600138 while (my_data->logging_callback.size() > 0) {
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -0700139 VkDebugReportCallbackEXT callback = my_data->logging_callback.back();
Courtney Goeltzenleuchter05854bf2015-11-30 12:13:14 -0700140 layer_destroy_msg_callback(my_data->report_data, callback, pAllocator);
Courtney Goeltzenleuchterffcdd8b2015-10-05 15:59:11 -0600141 my_data->logging_callback.pop_back();
Jeremy Hayes9cc31582015-06-18 10:12:39 -0600142 }
143
Tobin Ehlisb74f6ab2015-10-29 14:19:18 -0600144 layer_debug_report_destroy_instance(my_data->report_data);
145 delete my_data->instance_dispatch_table;
146 layer_data_map.erase(key);
Jeremy Hayes9cc31582015-06-18 10:12:39 -0600147}
148
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700149VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateDevice(VkPhysicalDevice physicalDevice,
150 const VkDeviceCreateInfo *pCreateInfo,
151 const VkAllocationCallbacks *pAllocator, VkDevice *pDevice) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700152 VkLayerDeviceCreateInfo *chain_info = get_chain_info(pCreateInfo, VK_LAYER_LINK_INFO);
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -0700153
154 assert(chain_info->u.pLayerInfo);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700155 PFN_vkGetInstanceProcAddr fpGetInstanceProcAddr = chain_info->u.pLayerInfo->pfnNextGetInstanceProcAddr;
156 PFN_vkGetDeviceProcAddr fpGetDeviceProcAddr = chain_info->u.pLayerInfo->pfnNextGetDeviceProcAddr;
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700157 PFN_vkCreateDevice fpCreateDevice = (PFN_vkCreateDevice)fpGetInstanceProcAddr(NULL, "vkCreateDevice");
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -0700158 if (fpCreateDevice == NULL) {
159 return VK_ERROR_INITIALIZATION_FAILED;
Jeremy Hayes9cc31582015-06-18 10:12:39 -0600160 }
161
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -0700162 // Advance the link info for the next element on the chain
163 chain_info->u.pLayerInfo = chain_info->u.pLayerInfo->pNext;
164
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700165 VkResult result = fpCreateDevice(physicalDevice, pCreateInfo, pAllocator, pDevice);
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -0700166 if (result != VK_SUCCESS) {
167 return result;
168 }
169
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700170 layer_data *my_instance_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);
171 layer_data *my_device_data = get_my_data_ptr(get_dispatch_key(*pDevice), layer_data_map);
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -0700172
173 // Setup device dispatch table
174 my_device_data->device_dispatch_table = new VkLayerDispatchTable;
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700175 layer_init_device_dispatch_table(*pDevice, my_device_data->device_dispatch_table, fpGetDeviceProcAddr);
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -0700176
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700177 my_device_data->report_data = layer_debug_report_create_device(my_instance_data->report_data, *pDevice);
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -0700178 my_device_data->physicalDevice = physicalDevice;
179
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700180 my_instance_data->instance_dispatch_table->GetPhysicalDeviceProperties(physicalDevice,
181 &(my_device_data->physicalDeviceProperties));
Mark Lobodzinskid5a23822015-11-12 15:14:35 -0700182
Jeremy Hayes9cc31582015-06-18 10:12:39 -0600183 return result;
184}
185
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700186VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL vkDestroyDevice(VkDevice device, const VkAllocationCallbacks *pAllocator) {
Jeremy Hayes9cc31582015-06-18 10:12:39 -0600187 dispatch_key key = get_dispatch_key(device);
Tobin Ehlisb74f6ab2015-10-29 14:19:18 -0600188 layer_data *my_data = get_my_data_ptr(key, layer_data_map);
Chia-I Wuf7458c52015-10-26 21:10:41 +0800189 my_data->device_dispatch_table->DestroyDevice(device, pAllocator);
Tobin Ehlisb74f6ab2015-10-29 14:19:18 -0600190 delete my_data->device_dispatch_table;
191 layer_data_map.erase(key);
Jeremy Hayes9cc31582015-06-18 10:12:39 -0600192}
193
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700194static const VkExtensionProperties instance_extensions[] = {{VK_EXT_DEBUG_REPORT_EXTENSION_NAME, VK_EXT_DEBUG_REPORT_SPEC_VERSION}};
Jeremy Hayes9cc31582015-06-18 10:12:39 -0600195
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700196VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
197vkEnumerateInstanceExtensionProperties(const char *pLayerName, uint32_t *pCount, VkExtensionProperties *pProperties) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700198 return util_GetExtensionProperties(1, instance_extensions, pCount, pProperties);
Jeremy Hayes9cc31582015-06-18 10:12:39 -0600199}
200
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700201static const VkLayerProperties pc_global_layers[] = {{
Jon Ashburndc9111c2016-03-22 12:57:13 -0600202 "VK_LAYER_LUNARG_image", VK_LAYER_API_VERSION, 1, "LunarG Validation Layer",
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700203}};
Courtney Goeltzenleuchter52857662015-12-01 14:08:28 -0700204
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700205VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
206vkEnumerateInstanceLayerProperties(uint32_t *pCount, VkLayerProperties *pProperties) {
207 return util_GetLayerProperties(ARRAY_SIZE(pc_global_layers), pc_global_layers, pCount, pProperties);
Tony Barbour59a47322015-06-24 16:06:58 -0600208}
209
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700210VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateDeviceExtensionProperties(VkPhysicalDevice physicalDevice,
211 const char *pLayerName, uint32_t *pCount,
212 VkExtensionProperties *pProperties) {
Jon Ashburn751c4842015-11-02 17:37:20 -0700213 // Image does not have any physical device extensions
214 if (pLayerName == NULL) {
215 dispatch_key key = get_dispatch_key(physicalDevice);
216 layer_data *my_data = get_my_data_ptr(key, layer_data_map);
217 VkLayerInstanceDispatchTable *pTable = my_data->instance_dispatch_table;
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700218 return pTable->EnumerateDeviceExtensionProperties(physicalDevice, NULL, pCount, pProperties);
Jon Ashburn751c4842015-11-02 17:37:20 -0700219 } else {
220 return util_GetExtensionProperties(0, NULL, pCount, pProperties);
221 }
Courtney Goeltzenleuchter426e1872015-07-07 11:18:30 -0600222}
Jeremy Hayes9cc31582015-06-18 10:12:39 -0600223
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700224VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
225vkEnumerateDeviceLayerProperties(VkPhysicalDevice physicalDevice, uint32_t *pCount, VkLayerProperties *pProperties) {
Mark Lobodzinskidc86b852015-10-23 14:20:31 -0600226 // ParamChecker's physical device layers are the same as global
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700227 return util_GetLayerProperties(ARRAY_SIZE(pc_global_layers), pc_global_layers, pCount, pProperties);
Jeremy Hayes9cc31582015-06-18 10:12:39 -0600228}
229
Mark Lobodzinski2fd634c2015-07-29 09:21:22 -0600230// Start of the Image layer proper
231
232// Returns TRUE if a format is a depth-compatible format
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700233bool is_depth_format(VkFormat format) {
Dustin Graves080069b2016-04-05 13:48:15 -0600234 bool result = false;
Mark Lobodzinski2fd634c2015-07-29 09:21:22 -0600235 switch (format) {
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700236 case VK_FORMAT_D16_UNORM:
237 case VK_FORMAT_X8_D24_UNORM_PACK32:
238 case VK_FORMAT_D32_SFLOAT:
239 case VK_FORMAT_S8_UINT:
240 case VK_FORMAT_D16_UNORM_S8_UINT:
241 case VK_FORMAT_D24_UNORM_S8_UINT:
242 case VK_FORMAT_D32_SFLOAT_S8_UINT:
Dustin Graves080069b2016-04-05 13:48:15 -0600243 result = true;
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700244 break;
245 default:
246 break;
Mark Lobodzinski2fd634c2015-07-29 09:21:22 -0600247 }
248 return result;
249}
250
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700251static inline uint32_t validate_VkImageLayoutKHR(VkImageLayout input_value) {
252 return ((validate_VkImageLayout(input_value) == 1) || (input_value == VK_IMAGE_LAYOUT_PRESENT_SRC_KHR));
Mark Lobodzinski601ed152015-11-10 11:01:32 -0700253}
254
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700255VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
256vkCreateImage(VkDevice device, const VkImageCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkImage *pImage) {
Dustin Graves080069b2016-04-05 13:48:15 -0600257 bool skipCall = false;
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700258 VkResult result = VK_ERROR_VALIDATION_FAILED_EXT;
Michael Lentine0a369f62016-02-03 16:51:46 -0600259 VkImageFormatProperties ImageFormatProperties;
Mark Lobodzinskid5a23822015-11-12 15:14:35 -0700260
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700261 layer_data *device_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
262 VkPhysicalDevice physicalDevice = device_data->physicalDevice;
263 layer_data *phy_dev_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);
Mark Lobodzinskid5a23822015-11-12 15:14:35 -0700264
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700265 if (pCreateInfo->format != VK_FORMAT_UNDEFINED) {
Jeremy Hayes9cc31582015-06-18 10:12:39 -0600266 VkFormatProperties properties;
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700267 phy_dev_data->instance_dispatch_table->GetPhysicalDeviceFormatProperties(device_data->physicalDevice, pCreateInfo->format,
268 &properties);
Jeremy Hayes9cc31582015-06-18 10:12:39 -0600269
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700270 if ((properties.linearTilingFeatures) == 0 && (properties.optimalTilingFeatures == 0)) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700271 char const str[] = "vkCreateImage parameter, VkFormat pCreateInfo->format, contains unsupported format";
272 // TODO: Verify against Valid Use section of spec. Generally if something yield an undefined result, it's invalid
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700273 skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
274 IMAGE_FORMAT_UNSUPPORTED, "IMAGE", str);
Jeremy Hayes9cc31582015-06-18 10:12:39 -0600275 }
276 }
277
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700278 // Internal call to get format info. Still goes through layers, could potentially go directly to ICD.
279 phy_dev_data->instance_dispatch_table->GetPhysicalDeviceImageFormatProperties(
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700280 physicalDevice, pCreateInfo->format, pCreateInfo->imageType, pCreateInfo->tiling, pCreateInfo->usage, pCreateInfo->flags,
281 &ImageFormatProperties);
Jeremy Hayes9cc31582015-06-18 10:12:39 -0600282
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700283 VkDeviceSize imageGranularity = device_data->physicalDeviceProperties.limits.bufferImageGranularity;
Mark Lobodzinskid5a23822015-11-12 15:14:35 -0700284 imageGranularity = imageGranularity == 1 ? 0 : imageGranularity;
285
Mark Youngc48c4c12016-04-11 14:26:49 -0600286 // Make sure all required dimension are non-zero at least.
287 bool failedMinSize = false;
288 switch (pCreateInfo->imageType) {
289 case VK_IMAGE_TYPE_3D:
290 if (pCreateInfo->extent.depth == 0) {
291 failedMinSize = true;
292 }
293 // Intentional fall-through
294 case VK_IMAGE_TYPE_2D:
295 if (pCreateInfo->extent.height == 0) {
296 failedMinSize = true;
297 }
298 // Intentional fall-through
299 case VK_IMAGE_TYPE_1D:
300 if (pCreateInfo->extent.width == 0) {
301 failedMinSize = true;
302 }
303 break;
304 default:
305 break;
306 }
307 if (failedMinSize) {
308 skipCall |=
309 log_msg(phy_dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT,
310 (uint64_t)pImage, __LINE__, IMAGE_INVALID_FORMAT_LIMITS_VIOLATION, "Image",
311 "CreateImage extents is 0 for at least one required dimension for image of type %d: "
312 "Width = %d Height = %d Depth = %d.",
313 pCreateInfo->imageType, pCreateInfo->extent.width, pCreateInfo->extent.height, pCreateInfo->extent.depth);
314 }
315
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700316 if ((pCreateInfo->extent.depth > ImageFormatProperties.maxExtent.depth) ||
317 (pCreateInfo->extent.width > ImageFormatProperties.maxExtent.width) ||
Mark Lobodzinskid5a23822015-11-12 15:14:35 -0700318 (pCreateInfo->extent.height > ImageFormatProperties.maxExtent.height)) {
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700319 skipCall |= log_msg(phy_dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT,
320 (uint64_t)pImage, __LINE__, IMAGE_INVALID_FORMAT_LIMITS_VIOLATION, "Image",
321 "CreateImage extents exceed allowable limits for format: "
322 "Width = %d Height = %d Depth = %d: Limits for Width = %d Height = %d Depth = %d for format %s.",
323 pCreateInfo->extent.width, pCreateInfo->extent.height, pCreateInfo->extent.depth,
324 ImageFormatProperties.maxExtent.width, ImageFormatProperties.maxExtent.height,
325 ImageFormatProperties.maxExtent.depth, string_VkFormat(pCreateInfo->format));
Mark Lobodzinskid5a23822015-11-12 15:14:35 -0700326 }
327
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700328 uint64_t totalSize = ((uint64_t)pCreateInfo->extent.width * (uint64_t)pCreateInfo->extent.height *
329 (uint64_t)pCreateInfo->extent.depth * (uint64_t)pCreateInfo->arrayLayers *
330 (uint64_t)pCreateInfo->samples * (uint64_t)vk_format_get_size(pCreateInfo->format) +
331 (uint64_t)imageGranularity) &
332 ~(uint64_t)imageGranularity;
Mark Lobodzinskid5a23822015-11-12 15:14:35 -0700333
334 if (totalSize > ImageFormatProperties.maxResourceSize) {
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700335 skipCall |= log_msg(phy_dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT,
336 (uint64_t)pImage, __LINE__, IMAGE_INVALID_FORMAT_LIMITS_VIOLATION, "Image",
337 "CreateImage resource size exceeds allowable maximum "
338 "Image resource size = %#" PRIxLEAST64 ", maximum resource size = %#" PRIxLEAST64 " ",
339 totalSize, ImageFormatProperties.maxResourceSize);
Mark Lobodzinskid5a23822015-11-12 15:14:35 -0700340 }
341
342 if (pCreateInfo->mipLevels > ImageFormatProperties.maxMipLevels) {
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700343 skipCall |= log_msg(phy_dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT,
344 (uint64_t)pImage, __LINE__, IMAGE_INVALID_FORMAT_LIMITS_VIOLATION, "Image",
345 "CreateImage mipLevels=%d exceeds allowable maximum supported by format of %d", pCreateInfo->mipLevels,
346 ImageFormatProperties.maxMipLevels);
Mark Lobodzinskid5a23822015-11-12 15:14:35 -0700347 }
348
349 if (pCreateInfo->arrayLayers > ImageFormatProperties.maxArrayLayers) {
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700350 skipCall |= log_msg(phy_dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT,
351 (uint64_t)pImage, __LINE__, IMAGE_INVALID_FORMAT_LIMITS_VIOLATION, "Image",
352 "CreateImage arrayLayers=%d exceeds allowable maximum supported by format of %d",
353 pCreateInfo->arrayLayers, ImageFormatProperties.maxArrayLayers);
Mark Lobodzinskid5a23822015-11-12 15:14:35 -0700354 }
355
356 if ((pCreateInfo->samples & ImageFormatProperties.sampleCounts) == 0) {
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700357 skipCall |= log_msg(phy_dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT,
358 (uint64_t)pImage, __LINE__, IMAGE_INVALID_FORMAT_LIMITS_VIOLATION, "Image",
359 "CreateImage samples %s is not supported by format 0x%.8X",
360 string_VkSampleCountFlagBits(pCreateInfo->samples), ImageFormatProperties.sampleCounts);
Mark Lobodzinskid5a23822015-11-12 15:14:35 -0700361 }
362
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700363 if (pCreateInfo->initialLayout != VK_IMAGE_LAYOUT_UNDEFINED && pCreateInfo->initialLayout != VK_IMAGE_LAYOUT_PREINITIALIZED) {
Jeremy Hayesffc8a702016-03-01 14:01:45 -0700364 skipCall |= log_msg(phy_dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT,
365 (uint64_t)pImage, __LINE__, IMAGE_INVALID_LAYOUT, "Image",
366 "vkCreateImage parameter, pCreateInfo->initialLayout, must be VK_IMAGE_LAYOUT_UNDEFINED or "
367 "VK_IMAGE_LAYOUT_PREINITIALIZED");
368 }
369
Dustin Graves080069b2016-04-05 13:48:15 -0600370 if (!skipCall) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700371 result = device_data->device_dispatch_table->CreateImage(device, pCreateInfo, pAllocator, pImage);
Mark Lobodzinskid5a23822015-11-12 15:14:35 -0700372 }
373 if (result == VK_SUCCESS) {
Jeremy Hayese0ed6a22016-04-08 09:53:54 -0600374 std::lock_guard<std::mutex> lock(global_lock);
Chia-I Wue2fc5522015-10-26 20:04:44 +0800375 device_data->imageMap[*pImage] = IMAGE_STATE(pCreateInfo);
Tobin Ehlisad8c4462015-09-21 15:20:28 -0600376 }
Jeremy Hayes9cc31582015-06-18 10:12:39 -0600377 return result;
378}
379
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700380VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL vkDestroyImage(VkDevice device, VkImage image, const VkAllocationCallbacks *pAllocator) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700381 layer_data *device_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
Jeremy Hayese0ed6a22016-04-08 09:53:54 -0600382 std::unique_lock<std::mutex> lock(global_lock);
Chia-I Wue2fc5522015-10-26 20:04:44 +0800383 device_data->imageMap.erase(image);
Jeremy Hayese0ed6a22016-04-08 09:53:54 -0600384 lock.unlock();
Chia-I Wuf7458c52015-10-26 21:10:41 +0800385 device_data->device_dispatch_table->DestroyImage(device, image, pAllocator);
Tobin Ehlisad8c4462015-09-21 15:20:28 -0600386}
387
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700388VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateRenderPass(VkDevice device, const VkRenderPassCreateInfo *pCreateInfo,
389 const VkAllocationCallbacks *pAllocator,
390 VkRenderPass *pRenderPass) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700391 layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
Dustin Graves080069b2016-04-05 13:48:15 -0600392 bool skipCall = false;
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700393 for (uint32_t i = 0; i < pCreateInfo->attachmentCount; ++i) {
394 if (pCreateInfo->pAttachments[i].format != VK_FORMAT_UNDEFINED) {
Jeremy Hayes9cc31582015-06-18 10:12:39 -0600395 VkFormatProperties properties;
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700396 get_my_data_ptr(get_dispatch_key(my_data->physicalDevice), layer_data_map)
397 ->instance_dispatch_table->GetPhysicalDeviceFormatProperties(my_data->physicalDevice,
398 pCreateInfo->pAttachments[i].format, &properties);
Jeremy Hayes9cc31582015-06-18 10:12:39 -0600399
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700400 if ((properties.linearTilingFeatures) == 0 && (properties.optimalTilingFeatures == 0)) {
Jeremy Hayes9cc31582015-06-18 10:12:39 -0600401 std::stringstream ss;
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700402 ss << "vkCreateRenderPass parameter, VkFormat in pCreateInfo->pAttachments[" << i
403 << "], contains unsupported format";
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700404 // TODO: Verify against Valid Use section of spec. Generally if something yield an undefined result, it's invalid
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700405 skipCall |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
406 IMAGE_FORMAT_UNSUPPORTED, "IMAGE", "%s", ss.str().c_str());
Jeremy Hayes9cc31582015-06-18 10:12:39 -0600407 }
408 }
409 }
410
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700411 for (uint32_t i = 0; i < pCreateInfo->attachmentCount; ++i) {
412 if (!validate_VkImageLayoutKHR(pCreateInfo->pAttachments[i].initialLayout) ||
413 !validate_VkImageLayoutKHR(pCreateInfo->pAttachments[i].finalLayout)) {
Jeremy Hayes9cc31582015-06-18 10:12:39 -0600414 std::stringstream ss;
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700415 ss << "vkCreateRenderPass parameter, VkImageLayout in pCreateInfo->pAttachments[" << i << "], is unrecognized";
416 // TODO: Verify against Valid Use section of spec. Generally if something yield an undefined result, it's invalid
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700417 skipCall |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
418 IMAGE_RENDERPASS_INVALID_ATTACHMENT, "IMAGE", "%s", ss.str().c_str());
Jeremy Hayes9cc31582015-06-18 10:12:39 -0600419 }
420 }
421
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700422 for (uint32_t i = 0; i < pCreateInfo->attachmentCount; ++i) {
423 if (!validate_VkAttachmentLoadOp(pCreateInfo->pAttachments[i].loadOp)) {
Jeremy Hayes9cc31582015-06-18 10:12:39 -0600424 std::stringstream ss;
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700425 ss << "vkCreateRenderPass parameter, VkAttachmentLoadOp in pCreateInfo->pAttachments[" << i << "], is unrecognized";
426 // TODO: Verify against Valid Use section of spec. Generally if something yield an undefined result, it's invalid
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700427 skipCall |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
428 IMAGE_RENDERPASS_INVALID_ATTACHMENT, "IMAGE", "%s", ss.str().c_str());
Jeremy Hayes9cc31582015-06-18 10:12:39 -0600429 }
430 }
431
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700432 for (uint32_t i = 0; i < pCreateInfo->attachmentCount; ++i) {
433 if (!validate_VkAttachmentStoreOp(pCreateInfo->pAttachments[i].storeOp)) {
Jeremy Hayes9cc31582015-06-18 10:12:39 -0600434 std::stringstream ss;
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700435 ss << "vkCreateRenderPass parameter, VkAttachmentStoreOp in pCreateInfo->pAttachments[" << i << "], is unrecognized";
436 // TODO: Verify against Valid Use section of spec. Generally if something yield an undefined result, it's invalid
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700437 skipCall |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
438 IMAGE_RENDERPASS_INVALID_ATTACHMENT, "IMAGE", "%s", ss.str().c_str());
Jeremy Hayes9cc31582015-06-18 10:12:39 -0600439 }
440 }
441
Mark Lobodzinski2fd634c2015-07-29 09:21:22 -0600442 // Any depth buffers specified as attachments?
Dustin Graves080069b2016-04-05 13:48:15 -0600443 bool depthFormatPresent = false;
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700444 for (uint32_t i = 0; i < pCreateInfo->attachmentCount; ++i) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700445 depthFormatPresent |= is_depth_format(pCreateInfo->pAttachments[i].format);
Mark Lobodzinski2fd634c2015-07-29 09:21:22 -0600446 }
447
Dustin Graves080069b2016-04-05 13:48:15 -0600448 if (!depthFormatPresent) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700449 // No depth attachment is present, validate that subpasses set depthStencilAttachment to VK_ATTACHMENT_UNUSED;
Mark Lobodzinski2fd634c2015-07-29 09:21:22 -0600450 for (uint32_t i = 0; i < pCreateInfo->subpassCount; i++) {
Chia-I Wu1efb7e52015-10-26 17:32:47 +0800451 if (pCreateInfo->pSubpasses[i].pDepthStencilAttachment &&
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700452 pCreateInfo->pSubpasses[i].pDepthStencilAttachment->attachment != VK_ATTACHMENT_UNUSED) {
Mark Lobodzinski2fd634c2015-07-29 09:21:22 -0600453 std::stringstream ss;
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700454 ss << "vkCreateRenderPass has no depth/stencil attachment, yet subpass[" << i
455 << "] has VkSubpassDescription::depthStencilAttachment value that is not VK_ATTACHMENT_UNUSED";
456 skipCall |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
457 IMAGE_RENDERPASS_INVALID_DS_ATTACHMENT, "IMAGE", "%s", ss.str().c_str());
Mark Lobodzinski2fd634c2015-07-29 09:21:22 -0600458 }
459 }
460 }
Tobin Ehlisdea00952015-09-22 08:40:52 -0600461 if (skipCall)
Courtney Goeltzenleuchter52fee652015-12-10 16:41:22 -0700462 return VK_ERROR_VALIDATION_FAILED_EXT;
Mark Lobodzinski2fd634c2015-07-29 09:21:22 -0600463
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700464 VkResult result = my_data->device_dispatch_table->CreateRenderPass(device, pCreateInfo, pAllocator, pRenderPass);
Jeremy Hayes9cc31582015-06-18 10:12:39 -0600465
466 return result;
467}
468
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700469VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateImageView(VkDevice device, const VkImageViewCreateInfo *pCreateInfo,
470 const VkAllocationCallbacks *pAllocator, VkImageView *pView) {
Dustin Graves080069b2016-04-05 13:48:15 -0600471 bool skipCall = false;
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700472 layer_data *device_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
Chia-I Wue2fc5522015-10-26 20:04:44 +0800473 auto imageEntry = device_data->imageMap.find(pCreateInfo->image);
Tobin Ehlisad8c4462015-09-21 15:20:28 -0600474 if (imageEntry != device_data->imageMap.end()) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700475 if (pCreateInfo->subresourceRange.baseMipLevel >= imageEntry->second.mipLevels) {
Tobin Ehlisad8c4462015-09-21 15:20:28 -0600476 std::stringstream ss;
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700477 ss << "vkCreateImageView called with baseMipLevel " << pCreateInfo->subresourceRange.baseMipLevel << " for image "
478 << pCreateInfo->image << " that only has " << imageEntry->second.mipLevels << " mip levels.";
479 skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
480 IMAGE_VIEW_CREATE_ERROR, "IMAGE", "%s", ss.str().c_str());
Tobin Ehlisad8c4462015-09-21 15:20:28 -0600481 }
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700482 if (pCreateInfo->subresourceRange.baseArrayLayer >= imageEntry->second.arraySize) {
Tobin Ehlisad8c4462015-09-21 15:20:28 -0600483 std::stringstream ss;
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700484 ss << "vkCreateImageView called with baseArrayLayer " << pCreateInfo->subresourceRange.baseArrayLayer << " for image "
Michael Lentinee5ca1132016-03-21 10:01:33 -0500485 << pCreateInfo->image << " that only has " << imageEntry->second.arraySize << " array layers.";
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700486 skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
487 IMAGE_VIEW_CREATE_ERROR, "IMAGE", "%s", ss.str().c_str());
Tobin Ehlisad8c4462015-09-21 15:20:28 -0600488 }
Chia-I Wu3432a0c2015-10-27 18:04:07 +0800489 if (!pCreateInfo->subresourceRange.levelCount) {
Tobin Ehlisad8c4462015-09-21 15:20:28 -0600490 std::stringstream ss;
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700491 ss << "vkCreateImageView called with 0 in pCreateInfo->subresourceRange.levelCount.";
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700492 skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
493 IMAGE_VIEW_CREATE_ERROR, "IMAGE", "%s", ss.str().c_str());
Tobin Ehlisad8c4462015-09-21 15:20:28 -0600494 }
Chia-I Wu3432a0c2015-10-27 18:04:07 +0800495 if (!pCreateInfo->subresourceRange.layerCount) {
Tobin Ehlisad8c4462015-09-21 15:20:28 -0600496 std::stringstream ss;
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700497 ss << "vkCreateImageView called with 0 in pCreateInfo->subresourceRange.layerCount.";
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700498 skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
499 IMAGE_VIEW_CREATE_ERROR, "IMAGE", "%s", ss.str().c_str());
Tobin Ehlisad8c4462015-09-21 15:20:28 -0600500 }
Mark Lobodzinskia5eabe72015-10-05 17:16:05 -0600501
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700502 VkImageCreateFlags imageFlags = imageEntry->second.flags;
503 VkFormat imageFormat = imageEntry->second.format;
504 VkFormat ivciFormat = pCreateInfo->format;
505 VkImageAspectFlags aspectMask = pCreateInfo->subresourceRange.aspectMask;
Mark Lobodzinskidc86b852015-10-23 14:20:31 -0600506
Mark Lobodzinskiadaac9d2016-01-08 11:07:56 -0700507 // Validate VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT state
Mark Lobodzinski1e638c62016-01-11 16:50:30 -0700508 if (imageFlags & VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700509 // Format MUST be compatible (in the same format compatibility class) as the format the image was created with
510 if (vk_format_get_compatibility_class(imageFormat) != vk_format_get_compatibility_class(ivciFormat)) {
Mark Lobodzinskiadaac9d2016-01-08 11:07:56 -0700511 std::stringstream ss;
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700512 ss << "vkCreateImageView(): ImageView format " << string_VkFormat(ivciFormat)
513 << " is not in the same format compatibility class as image (" << (uint64_t)pCreateInfo->image << ") format "
514 << string_VkFormat(imageFormat) << ". Images created with the VK_IMAGE_CREATE_MUTABLE_FORMAT BIT "
515 << "can support ImageViews with differing formats but they must be in the same compatibility class.";
516 skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0,
517 __LINE__, IMAGE_VIEW_CREATE_ERROR, "IMAGE", "%s", ss.str().c_str());
Mark Lobodzinskiadaac9d2016-01-08 11:07:56 -0700518 }
519 } else {
520 // Format MUST be IDENTICAL to the format the image was created with
521 if (imageFormat != ivciFormat) {
522 std::stringstream ss;
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700523 ss << "vkCreateImageView() format " << string_VkFormat(ivciFormat) << " differs from image "
524 << (uint64_t)pCreateInfo->image << " format " << string_VkFormat(imageFormat)
525 << ". Formats MUST be IDENTICAL unless VK_IMAGE_CREATE_MUTABLE_FORMAT BIT was set on image creation.";
526 skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0,
527 __LINE__, IMAGE_VIEW_CREATE_ERROR, "IMAGE", "%s", ss.str().c_str());
Mark Lobodzinskiadaac9d2016-01-08 11:07:56 -0700528 }
529 }
530
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700531 // Validate correct image aspect bits for desired formats and format consistency
Mark Lobodzinskidc86b852015-10-23 14:20:31 -0600532 if (vk_format_is_color(imageFormat)) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700533 if ((aspectMask & VK_IMAGE_ASPECT_COLOR_BIT) != VK_IMAGE_ASPECT_COLOR_BIT) {
Mark Lobodzinskidc86b852015-10-23 14:20:31 -0600534 std::stringstream ss;
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700535 ss << "vkCreateImageView: Color image formats must have the VK_IMAGE_ASPECT_COLOR_BIT set";
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700536 skipCall |=
537 log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT,
538 (uint64_t)pCreateInfo->image, __LINE__, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", "%s", ss.str().c_str());
Mark Lobodzinskidc86b852015-10-23 14:20:31 -0600539 }
540 if ((aspectMask & VK_IMAGE_ASPECT_COLOR_BIT) != aspectMask) {
541 std::stringstream ss;
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700542 ss << "vkCreateImageView: Color image formats must have ONLY the VK_IMAGE_ASPECT_COLOR_BIT set";
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700543 skipCall |=
544 log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT,
545 (uint64_t)pCreateInfo->image, __LINE__, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", "%s", ss.str().c_str());
Mark Lobodzinskidc86b852015-10-23 14:20:31 -0600546 }
Dustin Graves080069b2016-04-05 13:48:15 -0600547 if (!vk_format_is_color(ivciFormat)) {
Mark Lobodzinskidc86b852015-10-23 14:20:31 -0600548 std::stringstream ss;
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700549 ss << "vkCreateImageView: The image view's format can differ from the parent image's format, but both must be "
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700550 << "color formats. ImageFormat is " << string_VkFormat(imageFormat) << " ImageViewFormat is "
551 << string_VkFormat(ivciFormat);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700552 skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT,
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700553 (uint64_t)pCreateInfo->image, __LINE__, IMAGE_INVALID_FORMAT, "IMAGE", "%s", ss.str().c_str());
Mark Lobodzinskidc86b852015-10-23 14:20:31 -0600554 }
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700555 // TODO: Uncompressed formats are compatible if they occupy they same number of bits per pixel.
556 // Compressed formats are compatible if the only difference between them is the numerical type of
557 // the uncompressed pixels (e.g. signed vs. unsigned, or sRGB vs. UNORM encoding).
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700558 } else if (vk_format_is_depth_and_stencil(imageFormat)) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700559 if ((aspectMask & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) == 0) {
Mark Lobodzinskidc86b852015-10-23 14:20:31 -0600560 std::stringstream ss;
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700561 ss << "vkCreateImageView: Depth/stencil image formats must have at least one of VK_IMAGE_ASPECT_DEPTH_BIT and "
562 "VK_IMAGE_ASPECT_STENCIL_BIT set";
563 skipCall |=
564 log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT,
565 (uint64_t)pCreateInfo->image, __LINE__, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", "%s", ss.str().c_str());
Mark Lobodzinskidc86b852015-10-23 14:20:31 -0600566 }
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700567 if ((aspectMask & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) != aspectMask) {
Mark Lobodzinskidc86b852015-10-23 14:20:31 -0600568 std::stringstream ss;
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700569 ss << "vkCreateImageView: Combination depth/stencil image formats can have only the VK_IMAGE_ASPECT_DEPTH_BIT and "
570 "VK_IMAGE_ASPECT_STENCIL_BIT set";
571 skipCall |=
572 log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT,
573 (uint64_t)pCreateInfo->image, __LINE__, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", "%s", ss.str().c_str());
Mark Lobodzinskidc86b852015-10-23 14:20:31 -0600574 }
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700575 } else if (vk_format_is_depth_only(imageFormat)) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700576 if ((aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT) != VK_IMAGE_ASPECT_DEPTH_BIT) {
Mark Lobodzinskidc86b852015-10-23 14:20:31 -0600577 std::stringstream ss;
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700578 ss << "vkCreateImageView: Depth-only image formats must have the VK_IMAGE_ASPECT_DEPTH_BIT set";
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700579 skipCall |=
580 log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT,
581 (uint64_t)pCreateInfo->image, __LINE__, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", "%s", ss.str().c_str());
Mark Lobodzinskidc86b852015-10-23 14:20:31 -0600582 }
583 if ((aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT) != aspectMask) {
584 std::stringstream ss;
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700585 ss << "vkCreateImageView: Depth-only image formats can have only the VK_IMAGE_ASPECT_DEPTH_BIT set";
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700586 skipCall |=
587 log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT,
588 (uint64_t)pCreateInfo->image, __LINE__, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", "%s", ss.str().c_str());
Mark Lobodzinskidc86b852015-10-23 14:20:31 -0600589 }
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700590 } else if (vk_format_is_stencil_only(imageFormat)) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700591 if ((aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT) != VK_IMAGE_ASPECT_STENCIL_BIT) {
Mark Lobodzinskidc86b852015-10-23 14:20:31 -0600592 std::stringstream ss;
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700593 ss << "vkCreateImageView: Stencil-only image formats must have the VK_IMAGE_ASPECT_STENCIL_BIT set";
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700594 skipCall |=
595 log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT,
596 (uint64_t)pCreateInfo->image, __LINE__, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", "%s", ss.str().c_str());
Mark Lobodzinskidc86b852015-10-23 14:20:31 -0600597 }
598 if ((aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT) != aspectMask) {
599 std::stringstream ss;
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700600 ss << "vkCreateImageView: Stencil-only image formats can have only the VK_IMAGE_ASPECT_STENCIL_BIT set";
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700601 skipCall |=
602 log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT,
603 (uint64_t)pCreateInfo->image, __LINE__, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", "%s", ss.str().c_str());
Mark Lobodzinskidc86b852015-10-23 14:20:31 -0600604 }
605 }
606 }
Mark Lobodzinskia5eabe72015-10-05 17:16:05 -0600607
Mark Lobodzinskiadaac9d2016-01-08 11:07:56 -0700608 if (skipCall) {
Courtney Goeltzenleuchter52fee652015-12-10 16:41:22 -0700609 return VK_ERROR_VALIDATION_FAILED_EXT;
Mark Lobodzinskiadaac9d2016-01-08 11:07:56 -0700610 }
Tobin Ehlisdea00952015-09-22 08:40:52 -0600611
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700612 VkResult result = device_data->device_dispatch_table->CreateImageView(device, pCreateInfo, pAllocator, pView);
Tobin Ehlisad8c4462015-09-21 15:20:28 -0600613 return result;
614}
615
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700616VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdClearColorImage(VkCommandBuffer commandBuffer, VkImage image,
617 VkImageLayout imageLayout, const VkClearColorValue *pColor,
618 uint32_t rangeCount, const VkImageSubresourceRange *pRanges) {
Dustin Graves080069b2016-04-05 13:48:15 -0600619 bool skipCall = false;
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700620 layer_data *device_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
Jeremy Hayesa4dc0ac2016-03-01 16:51:02 -0700621
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700622 if (imageLayout != VK_IMAGE_LAYOUT_GENERAL && imageLayout != VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL) {
Jeremy Hayesa4dc0ac2016-03-01 16:51:02 -0700623 skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
624 (uint64_t)commandBuffer, __LINE__, IMAGE_INVALID_LAYOUT, "IMAGE",
625 "vkCmdClearColorImage parameter, imageLayout, must be VK_IMAGE_LAYOUT_GENERAL or "
626 "VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL");
627 }
628
Mark Lobodzinskia5eabe72015-10-05 17:16:05 -0600629 // For each range, image aspect must be color only
630 for (uint32_t i = 0; i < rangeCount; i++) {
631 if (pRanges[i].aspectMask != VK_IMAGE_ASPECT_COLOR_BIT) {
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700632 char const str[] =
633 "vkCmdClearColorImage aspectMasks for all subresource ranges must be set to VK_IMAGE_ASPECT_COLOR_BIT";
634 skipCall |=
635 log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
636 (uint64_t)commandBuffer, __LINE__, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", str);
Mark Lobodzinskia5eabe72015-10-05 17:16:05 -0600637 }
638 }
639
Dustin Graves080069b2016-04-05 13:48:15 -0600640 if (!skipCall) {
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700641 device_data->device_dispatch_table->CmdClearColorImage(commandBuffer, image, imageLayout, pColor, rangeCount, pRanges);
Mark Lobodzinskia5eabe72015-10-05 17:16:05 -0600642 }
643}
644
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700645VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL
646vkCmdClearDepthStencilImage(VkCommandBuffer commandBuffer, VkImage image, VkImageLayout imageLayout,
647 const VkClearDepthStencilValue *pDepthStencil, uint32_t rangeCount,
648 const VkImageSubresourceRange *pRanges) {
Dustin Graves080069b2016-04-05 13:48:15 -0600649 bool skipCall = false;
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700650 layer_data *device_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
Mark Lobodzinskia5eabe72015-10-05 17:16:05 -0600651 // For each range, Image aspect must be depth or stencil or both
652 for (uint32_t i = 0; i < rangeCount; i++) {
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700653 if (((pRanges[i].aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT) != VK_IMAGE_ASPECT_DEPTH_BIT) &&
654 ((pRanges[i].aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT) != VK_IMAGE_ASPECT_STENCIL_BIT)) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700655 char const str[] = "vkCmdClearDepthStencilImage aspectMasks for all subresource ranges must be "
656 "set to VK_IMAGE_ASPECT_DEPTH_BIT and/or VK_IMAGE_ASPECT_STENCIL_BIT";
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700657 skipCall |=
658 log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
659 (uint64_t)commandBuffer, __LINE__, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", str);
Mark Lobodzinskia5eabe72015-10-05 17:16:05 -0600660 }
661 }
662
Dustin Graves080069b2016-04-05 13:48:15 -0600663 if (!skipCall) {
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700664 device_data->device_dispatch_table->CmdClearDepthStencilImage(commandBuffer, image, imageLayout, pDepthStencil, rangeCount,
665 pRanges);
Mark Lobodzinskia5eabe72015-10-05 17:16:05 -0600666 }
667}
668
Mark Lobodzinskib2ad7022016-03-29 17:10:14 -0600669// Returns true if [x, xoffset] and [y, yoffset] overlap
670static bool ranges_intersect(int32_t start, uint32_t start_offset, int32_t end, uint32_t end_offset) {
671 bool result = false;
672 uint32_t intersection_min = std::max(static_cast<uint32_t>(start), static_cast<uint32_t>(end));
673 uint32_t intersection_max = std::min(static_cast<uint32_t>(start) + start_offset, static_cast<uint32_t>(end) + end_offset);
674
675 if (intersection_max > intersection_min) {
676 result = true;
677 }
678 return result;
679}
680
681// Returns true if two VkImageCopy structures overlap
682static bool region_intersects(const VkImageCopy *src, const VkImageCopy *dst, VkImageType type) {
683 bool result = true;
684 if ((src->srcSubresource.mipLevel == dst->dstSubresource.mipLevel) &&
685 (ranges_intersect(src->srcSubresource.baseArrayLayer, src->srcSubresource.layerCount, dst->dstSubresource.baseArrayLayer,
686 dst->dstSubresource.layerCount))) {
687
688 switch (type) {
689 case VK_IMAGE_TYPE_3D:
690 result &= ranges_intersect(src->srcOffset.z, src->extent.depth, dst->dstOffset.z, dst->extent.depth);
691 // Intentionally fall through to 2D case
692 case VK_IMAGE_TYPE_2D:
693 result &= ranges_intersect(src->srcOffset.y, src->extent.height, dst->dstOffset.y, dst->extent.height);
694 // Intentionally fall through to 1D case
695 case VK_IMAGE_TYPE_1D:
696 result &= ranges_intersect(src->srcOffset.x, src->extent.width, dst->dstOffset.x, dst->extent.width);
697 break;
698 default:
699 // Unrecognized or new IMAGE_TYPE enums will be caught in parameter_validation
700 assert(false);
701 }
702 }
703 return result;
704}
705
706// Returns true if offset and extent exceed image extents
707static bool exceeds_bounds(const VkOffset3D *offset, const VkExtent3D *extent, IMAGE_STATE *image) {
708 bool result = false;
709 // Extents/depths cannot be negative but checks left in for clarity
710
711 return result;
712}
713
Dustin Graves080069b2016-04-05 13:48:15 -0600714bool cmd_copy_image_valid_usage(VkCommandBuffer commandBuffer, VkImage srcImage, VkImage dstImage, uint32_t regionCount,
715 const VkImageCopy *pRegions) {
Mark Lobodzinskib2ad7022016-03-29 17:10:14 -0600716
Dustin Graves080069b2016-04-05 13:48:15 -0600717 bool skipCall = false;
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700718 layer_data *device_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
Chia-I Wue2fc5522015-10-26 20:04:44 +0800719 auto srcImageEntry = device_data->imageMap.find(srcImage);
Chia-I Wu3432a0c2015-10-27 18:04:07 +0800720 auto dstImageEntry = device_data->imageMap.find(dstImage);
Mark Lobodzinskia5eabe72015-10-05 17:16:05 -0600721
Mark Lobodzinskib2ad7022016-03-29 17:10:14 -0600722 // TODO: This does not cover swapchain-created images. This should fall out when this layer is moved
723 // into the core_validation layer
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700724 if ((srcImageEntry != device_data->imageMap.end()) && (dstImageEntry != device_data->imageMap.end())) {
Mark Lobodzinskib2ad7022016-03-29 17:10:14 -0600725
726 for (uint32_t i = 0; i < regionCount; i++) {
727
728 if (pRegions[i].srcSubresource.layerCount == 0) {
729 std::stringstream ss;
730 ss << "vkCmdCopyImage: number of layers in pRegions[" << i << "] srcSubresource is zero";
731 skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT,
732 VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, reinterpret_cast<uint64_t &>(commandBuffer),
733 __LINE__, IMAGE_MISMATCHED_IMAGE_ASPECT, "IMAGE", "%s", ss.str().c_str());
734 }
735
736 if (pRegions[i].dstSubresource.layerCount == 0) {
737 std::stringstream ss;
738 ss << "vkCmdCopyImage: number of layers in pRegions[" << i << "] dstSubresource is zero";
739 skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT,
740 VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, reinterpret_cast<uint64_t &>(commandBuffer),
741 __LINE__, IMAGE_MISMATCHED_IMAGE_ASPECT, "IMAGE", "%s", ss.str().c_str());
742 }
743
744 // For each region the layerCount member of srcSubresource and dstSubresource must match
745 if (pRegions[i].srcSubresource.layerCount != pRegions[i].dstSubresource.layerCount) {
746 std::stringstream ss;
747 ss << "vkCmdCopyImage: number of layers in source and destination subresources for pRegions[" << i
748 << "] do not match";
749 skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
750 VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, reinterpret_cast<uint64_t &>(commandBuffer),
751 __LINE__, IMAGE_INVALID_EXTENTS, "IMAGE", "%s", ss.str().c_str());
752 }
753
754 // For each region, the aspectMask member of srcSubresource and dstSubresource must match
755 if (pRegions[i].srcSubresource.aspectMask != pRegions[i].dstSubresource.aspectMask) {
756 char const str[] = "vkCmdCopyImage: Src and dest aspectMasks for each region must match";
757 skipCall |=
758 log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
759 reinterpret_cast<uint64_t &>(commandBuffer), __LINE__, IMAGE_MISMATCHED_IMAGE_ASPECT, "IMAGE", str);
760 }
761
762 // AspectMask must not contain VK_IMAGE_ASPECT_METADATA_BIT
763 if ((pRegions[i].srcSubresource.aspectMask & VK_IMAGE_ASPECT_METADATA_BIT) ||
764 (pRegions[i].dstSubresource.aspectMask & VK_IMAGE_ASPECT_METADATA_BIT)) {
765 std::stringstream ss;
766 ss << "vkCmdCopyImage: pRegions[" << i << "] may not specify aspectMask containing VK_IMAGE_ASPECT_METADATA_BIT";
767 skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
768 VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, reinterpret_cast<uint64_t &>(commandBuffer),
769 __LINE__, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", "%s", ss.str().c_str());
770 }
771
772 // For each region, if aspectMask contains VK_IMAGE_ASPECT_COLOR_BIT, it must not contain either of
773 // VK_IMAGE_ASPECT_DEPTH_BIT or VK_IMAGE_ASPECT_STENCIL_BIT
774 if ((pRegions[i].srcSubresource.aspectMask & VK_IMAGE_ASPECT_COLOR_BIT) &&
775 (pRegions[i].srcSubresource.aspectMask & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT))) {
776 char const str[] = "vkCmdCopyImage aspectMask cannot specify both COLOR and DEPTH/STENCIL aspects";
777 skipCall |=
778 log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
779 reinterpret_cast<uint64_t &>(commandBuffer), __LINE__, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", str);
780 }
781
782 // If either of the calling command's srcImage or dstImage parameters are of VkImageType VK_IMAGE_TYPE_3D,
783 // the baseArrayLayer and layerCount members of both srcSubresource and dstSubresource must be 0 and 1, respectively
784 if (((srcImageEntry->second.imageType == VK_IMAGE_TYPE_3D) || (dstImageEntry->second.imageType == VK_IMAGE_TYPE_3D)) &&
785 ((pRegions[i].srcSubresource.baseArrayLayer != 0) || (pRegions[i].srcSubresource.layerCount != 1) ||
786 (pRegions[i].dstSubresource.baseArrayLayer != 0) || (pRegions[i].dstSubresource.layerCount != 1))) {
787 std::stringstream ss;
788 ss << "vkCmdCopyImage: src or dstImage type was IMAGE_TYPE_3D, but in subRegion[" << i
789 << "] baseArrayLayer was not zero or layerCount was not 1.";
790 skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
791 VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, reinterpret_cast<uint64_t &>(commandBuffer),
792 __LINE__, IMAGE_INVALID_EXTENTS, "IMAGE", "%s", ss.str().c_str());
793 }
794
795 // MipLevel must be less than the mipLevels specified in VkImageCreateInfo when the image was created
796 if (pRegions[i].srcSubresource.mipLevel >= srcImageEntry->second.mipLevels) {
797 std::stringstream ss;
798 ss << "vkCmdCopyImage: pRegions[" << i
799 << "] specifies a src mipLevel greater than the number specified when the srcImage was created.";
800 skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
801 VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, reinterpret_cast<uint64_t &>(commandBuffer),
802 __LINE__, IMAGE_INVALID_EXTENTS, "IMAGE", "%s", ss.str().c_str());
803 }
804 if (pRegions[i].dstSubresource.mipLevel >= dstImageEntry->second.mipLevels) {
805 std::stringstream ss;
806 ss << "vkCmdCopyImage: pRegions[" << i
807 << "] specifies a dst mipLevel greater than the number specified when the dstImage was created.";
808 skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
809 VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, reinterpret_cast<uint64_t &>(commandBuffer),
810 __LINE__, IMAGE_INVALID_EXTENTS, "IMAGE", "%s", ss.str().c_str());
811 }
812
813 // (baseArrayLayer + layerCount) must be less than or equal to the arrayLayers specified in VkImageCreateInfo when the
814 // image was created
815 if ((pRegions[i].srcSubresource.baseArrayLayer + pRegions[i].srcSubresource.layerCount) >
816 srcImageEntry->second.arraySize) {
817 std::stringstream ss;
818 ss << "vkCmdCopyImage: srcImage arrayLayers was " << srcImageEntry->second.arraySize << " but subRegion[" << i
819 << "] baseArrayLayer + layerCount is "
820 << (pRegions[i].srcSubresource.baseArrayLayer + pRegions[i].srcSubresource.layerCount);
821 skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
822 VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, reinterpret_cast<uint64_t &>(commandBuffer),
823 __LINE__, IMAGE_INVALID_EXTENTS, "IMAGE", "%s", ss.str().c_str());
824 }
825 if ((pRegions[i].dstSubresource.baseArrayLayer + pRegions[i].dstSubresource.layerCount) >
826 dstImageEntry->second.arraySize) {
827 std::stringstream ss;
828 ss << "vkCmdCopyImage: dstImage arrayLayers was " << dstImageEntry->second.arraySize << " but subRegion[" << i
829 << "] baseArrayLayer + layerCount is "
830 << (pRegions[i].dstSubresource.baseArrayLayer + pRegions[i].dstSubresource.layerCount);
831 skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
832 VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, reinterpret_cast<uint64_t &>(commandBuffer),
833 __LINE__, IMAGE_INVALID_EXTENTS, "IMAGE", "%s", ss.str().c_str());
834 }
835
836 // The source region specified by a given element of pRegions must be a region that is contained within srcImage
837 if (exceeds_bounds(&pRegions[i].srcOffset, &pRegions[i].extent, &srcImageEntry->second)) {
838 std::stringstream ss;
839 ss << "vkCmdCopyImage: srcSubResource in pRegions[" << i << "] exceeds extents srcImage was created with";
840 skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
841 VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, reinterpret_cast<uint64_t &>(commandBuffer),
842 __LINE__, IMAGE_INVALID_EXTENTS, "IMAGE", "%s", ss.str().c_str());
843 }
844
845 // The destination region specified by a given element of pRegions must be a region that is contained within dstImage
846 if (exceeds_bounds(&pRegions[i].dstOffset, &pRegions[i].extent, &dstImageEntry->second)) {
847 std::stringstream ss;
848 ss << "vkCmdCopyImage: dstSubResource in pRegions[" << i << "] exceeds extents dstImage was created with";
849 skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
850 VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, reinterpret_cast<uint64_t &>(commandBuffer),
851 __LINE__, IMAGE_INVALID_EXTENTS, "IMAGE", "%s", ss.str().c_str());
852 }
853
854 // The union of all source regions, and the union of all destination regions, specified by the elements of pRegions,
855 // must not overlap in memory
856 if (srcImage == dstImage) {
857 for (uint32_t j = 0; j < regionCount; j++) {
858 if (region_intersects(&pRegions[i], &pRegions[j], srcImageEntry->second.imageType)) {
859 std::stringstream ss;
860 ss << "vkCmdCopyImage: pRegions[" << i << "] src overlaps with pRegions[" << j << "].";
861 skipCall |=
862 log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
863 VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, reinterpret_cast<uint64_t &>(commandBuffer),
864 __LINE__, IMAGE_INVALID_EXTENTS, "IMAGE", "%s", ss.str().c_str());
865 }
866 }
867 }
Mike Stroyana3082432015-09-25 13:39:21 -0600868 }
Mark Lobodzinskib2ad7022016-03-29 17:10:14 -0600869
870 // The formats of srcImage and dstImage must be compatible. Formats are considered compatible if their texel size in bytes
871 // is the same between both formats. For example, VK_FORMAT_R8G8B8A8_UNORM is compatible with VK_FORMAT_R32_UINT because
872 // because both texels are 4 bytes in size. Depth/stencil formats must match exactly.
873 if (is_depth_format(srcImageEntry->second.format) || is_depth_format(dstImageEntry->second.format)) {
Chia-I Wu3432a0c2015-10-27 18:04:07 +0800874 if (srcImageEntry->second.format != dstImageEntry->second.format) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700875 char const str[] = "vkCmdCopyImage called with unmatched source and dest image depth/stencil formats.";
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700876 skipCall |=
877 log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
Mark Lobodzinskib2ad7022016-03-29 17:10:14 -0600878 reinterpret_cast<uint64_t &>(commandBuffer), __LINE__, IMAGE_MISMATCHED_IMAGE_FORMAT, "IMAGE", str);
Mike Stroyana3082432015-09-25 13:39:21 -0600879 }
880 } else {
Tobin Ehlisd923d152015-09-25 14:49:43 -0600881 size_t srcSize = vk_format_get_size(srcImageEntry->second.format);
Chia-I Wu3432a0c2015-10-27 18:04:07 +0800882 size_t destSize = vk_format_get_size(dstImageEntry->second.format);
Mike Stroyana3082432015-09-25 13:39:21 -0600883 if (srcSize != destSize) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700884 char const str[] = "vkCmdCopyImage called with unmatched source and dest image format sizes.";
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700885 skipCall |=
886 log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
Mark Lobodzinskib2ad7022016-03-29 17:10:14 -0600887 reinterpret_cast<uint64_t &>(commandBuffer), __LINE__, IMAGE_MISMATCHED_IMAGE_FORMAT, "IMAGE", str);
Mike Stroyana3082432015-09-25 13:39:21 -0600888 }
889 }
890 }
Mark Lobodzinskib2ad7022016-03-29 17:10:14 -0600891 return skipCall;
892}
893
894VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdCopyImage(VkCommandBuffer commandBuffer, VkImage srcImage,
895 VkImageLayout srcImageLayout, VkImage dstImage,
896 VkImageLayout dstImageLayout, uint32_t regionCount,
897 const VkImageCopy *pRegions) {
898
Dustin Graves080069b2016-04-05 13:48:15 -0600899 bool skipCall = false;
Mark Lobodzinskib2ad7022016-03-29 17:10:14 -0600900 layer_data *device_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
901
902 skipCall = cmd_copy_image_valid_usage(commandBuffer, srcImage, dstImage, regionCount, pRegions);
Mike Stroyana3082432015-09-25 13:39:21 -0600903
Dustin Graves080069b2016-04-05 13:48:15 -0600904 if (!skipCall) {
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700905 device_data->device_dispatch_table->CmdCopyImage(commandBuffer, srcImage, srcImageLayout, dstImage, dstImageLayout,
906 regionCount, pRegions);
Mark Lobodzinskia5eabe72015-10-05 17:16:05 -0600907 }
908}
909
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700910VKAPI_ATTR void VKAPI_CALL vkCmdClearAttachments(VkCommandBuffer commandBuffer, uint32_t attachmentCount,
911 const VkClearAttachment *pAttachments, uint32_t rectCount,
912 const VkClearRect *pRects) {
Dustin Graves080069b2016-04-05 13:48:15 -0600913 bool skipCall = false;
Courtney Goeltzenleuchterc9323e02015-10-15 16:51:05 -0600914 VkImageAspectFlags aspectMask;
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700915 layer_data *device_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
Courtney Goeltzenleuchterc9323e02015-10-15 16:51:05 -0600916 for (uint32_t i = 0; i < attachmentCount; i++) {
917 aspectMask = pAttachments[i].aspectMask;
918 if (aspectMask & VK_IMAGE_ASPECT_COLOR_BIT) {
919 if (aspectMask != VK_IMAGE_ASPECT_COLOR_BIT) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700920 // VK_IMAGE_ASPECT_COLOR_BIT is not the only bit set for this attachment
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700921 char const str[] =
922 "vkCmdClearAttachments aspectMask [%d] must set only VK_IMAGE_ASPECT_COLOR_BIT of a color attachment.";
923 skipCall |=
924 log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
925 (uint64_t)commandBuffer, __LINE__, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", str, i);
Courtney Goeltzenleuchterc9323e02015-10-15 16:51:05 -0600926 }
927 } else {
928 // Image aspect must be depth or stencil or both
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700929 if (((aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT) != VK_IMAGE_ASPECT_DEPTH_BIT) &&
930 ((aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT) != VK_IMAGE_ASPECT_STENCIL_BIT)) {
931 char const str[] = "vkCmdClearAttachments aspectMask [%d] must be set to VK_IMAGE_ASPECT_DEPTH_BIT and/or "
932 "VK_IMAGE_ASPECT_STENCIL_BIT";
933 skipCall |=
934 log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
935 (uint64_t)commandBuffer, __LINE__, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", str, i);
Courtney Goeltzenleuchterc9323e02015-10-15 16:51:05 -0600936 }
937 }
938 }
939
Dustin Graves080069b2016-04-05 13:48:15 -0600940 if (!skipCall) {
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700941 device_data->device_dispatch_table->CmdClearAttachments(commandBuffer, attachmentCount, pAttachments, rectCount, pRects);
Courtney Goeltzenleuchterc9323e02015-10-15 16:51:05 -0600942 }
943}
944
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700945VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdCopyImageToBuffer(VkCommandBuffer commandBuffer, VkImage srcImage,
946 VkImageLayout srcImageLayout, VkBuffer dstBuffer,
947 uint32_t regionCount, const VkBufferImageCopy *pRegions) {
Dustin Graves080069b2016-04-05 13:48:15 -0600948 bool skipCall = false;
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700949 layer_data *device_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
950 // For each region, the number of layers in the image subresource should not be zero
Mark Lobodzinskia5eabe72015-10-05 17:16:05 -0600951 // Image aspect must be ONE OF color, depth, stencil
952 for (uint32_t i = 0; i < regionCount; i++) {
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700953 if (pRegions[i].imageSubresource.layerCount == 0) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700954 char const str[] = "vkCmdCopyImageToBuffer: number of layers in image subresource is zero";
955 // TODO: Verify against Valid Use section of spec, if this case yields undefined results, then it's an error
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700956 skipCall |=
957 log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
958 (uint64_t)commandBuffer, __LINE__, IMAGE_MISMATCHED_IMAGE_ASPECT, "IMAGE", str);
Jeremy Hayes148bab22015-10-28 13:01:39 -0600959 }
960
Chia-I Wuab83a0e2015-10-27 19:00:15 +0800961 VkImageAspectFlags aspectMask = pRegions[i].imageSubresource.aspectMask;
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700962 if ((aspectMask != VK_IMAGE_ASPECT_COLOR_BIT) && (aspectMask != VK_IMAGE_ASPECT_DEPTH_BIT) &&
Chia-I Wuab83a0e2015-10-27 19:00:15 +0800963 (aspectMask != VK_IMAGE_ASPECT_STENCIL_BIT)) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700964 char const str[] = "vkCmdCopyImageToBuffer: aspectMasks for each region must specify only COLOR or DEPTH or STENCIL";
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700965 skipCall |=
966 log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
967 (uint64_t)commandBuffer, __LINE__, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", str);
Mark Lobodzinskia5eabe72015-10-05 17:16:05 -0600968 }
969 }
970
Dustin Graves080069b2016-04-05 13:48:15 -0600971 if (!skipCall) {
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700972 device_data->device_dispatch_table->CmdCopyImageToBuffer(commandBuffer, srcImage, srcImageLayout, dstBuffer, regionCount,
973 pRegions);
Mark Lobodzinskia5eabe72015-10-05 17:16:05 -0600974 }
975}
976
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700977VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdCopyBufferToImage(VkCommandBuffer commandBuffer, VkBuffer srcBuffer,
978 VkImage dstImage, VkImageLayout dstImageLayout,
979 uint32_t regionCount, const VkBufferImageCopy *pRegions) {
Dustin Graves080069b2016-04-05 13:48:15 -0600980 bool skipCall = false;
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700981 layer_data *device_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
982 // For each region, the number of layers in the image subresource should not be zero
Mark Lobodzinskia5eabe72015-10-05 17:16:05 -0600983 // Image aspect must be ONE OF color, depth, stencil
984 for (uint32_t i = 0; i < regionCount; i++) {
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700985 if (pRegions[i].imageSubresource.layerCount == 0) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700986 char const str[] = "vkCmdCopyBufferToImage: number of layers in image subresource is zero";
987 // TODO: Verify against Valid Use section of spec, if this case yields undefined results, then it's an error
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700988 skipCall |=
989 log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
990 (uint64_t)commandBuffer, __LINE__, IMAGE_MISMATCHED_IMAGE_ASPECT, "IMAGE", str);
Jeremy Hayes148bab22015-10-28 13:01:39 -0600991 }
992
Chia-I Wuab83a0e2015-10-27 19:00:15 +0800993 VkImageAspectFlags aspectMask = pRegions[i].imageSubresource.aspectMask;
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700994 if ((aspectMask != VK_IMAGE_ASPECT_COLOR_BIT) && (aspectMask != VK_IMAGE_ASPECT_DEPTH_BIT) &&
Chia-I Wuab83a0e2015-10-27 19:00:15 +0800995 (aspectMask != VK_IMAGE_ASPECT_STENCIL_BIT)) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700996 char const str[] = "vkCmdCopyBufferToImage: aspectMasks for each region must specify only COLOR or DEPTH or STENCIL";
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700997 skipCall |=
998 log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
999 (uint64_t)commandBuffer, __LINE__, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", str);
Mark Lobodzinskia5eabe72015-10-05 17:16:05 -06001000 }
1001 }
1002
Dustin Graves080069b2016-04-05 13:48:15 -06001003 if (!skipCall) {
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001004 device_data->device_dispatch_table->CmdCopyBufferToImage(commandBuffer, srcBuffer, dstImage, dstImageLayout, regionCount,
1005 pRegions);
Mark Lobodzinskia5eabe72015-10-05 17:16:05 -06001006 }
1007}
1008
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001009VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL
1010vkCmdBlitImage(VkCommandBuffer commandBuffer, VkImage srcImage, VkImageLayout srcImageLayout, VkImage dstImage,
1011 VkImageLayout dstImageLayout, uint32_t regionCount, const VkImageBlit *pRegions, VkFilter filter) {
Dustin Graves080069b2016-04-05 13:48:15 -06001012 bool skipCall = false;
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001013 layer_data *device_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
Mark Lobodzinskidc86b852015-10-23 14:20:31 -06001014
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001015 auto srcImageEntry = device_data->imageMap.find(srcImage);
Chia-I Wu3432a0c2015-10-27 18:04:07 +08001016 auto dstImageEntry = device_data->imageMap.find(dstImage);
Mark Lobodzinskidc86b852015-10-23 14:20:31 -06001017
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001018 if ((srcImageEntry != device_data->imageMap.end()) && (dstImageEntry != device_data->imageMap.end())) {
Mark Lobodzinskidc86b852015-10-23 14:20:31 -06001019
Tobin Ehlisd923d152015-09-25 14:49:43 -06001020 VkFormat srcFormat = srcImageEntry->second.format;
Chia-I Wu3432a0c2015-10-27 18:04:07 +08001021 VkFormat dstFormat = dstImageEntry->second.format;
Mark Lobodzinskidc86b852015-10-23 14:20:31 -06001022
1023 // Validate consistency for signed and unsigned formats
1024 if ((vk_format_is_sint(srcFormat) && !vk_format_is_sint(dstFormat)) ||
1025 (vk_format_is_uint(srcFormat) && !vk_format_is_uint(dstFormat))) {
1026 std::stringstream ss;
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001027 ss << "vkCmdBlitImage: If one of srcImage and dstImage images has signed/unsigned integer format, "
1028 << "the other one must also have signed/unsigned integer format. "
1029 << "Source format is " << string_VkFormat(srcFormat) << " Destination format is " << string_VkFormat(dstFormat);
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001030 skipCall |=
1031 log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
1032 (uint64_t)commandBuffer, __LINE__, IMAGE_INVALID_FORMAT, "IMAGE", "%s", ss.str().c_str());
Mark Lobodzinskidc86b852015-10-23 14:20:31 -06001033 }
1034
1035 // Validate aspect bits and formats for depth/stencil images
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001036 if (vk_format_is_depth_or_stencil(srcFormat) || vk_format_is_depth_or_stencil(dstFormat)) {
Mark Lobodzinskidc86b852015-10-23 14:20:31 -06001037 if (srcFormat != dstFormat) {
1038 std::stringstream ss;
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001039 ss << "vkCmdBlitImage: If one of srcImage and dstImage images has a format of depth, stencil or depth "
1040 << "stencil, the other one must have exactly the same format. "
1041 << "Source format is " << string_VkFormat(srcFormat) << " Destination format is " << string_VkFormat(dstFormat);
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001042 skipCall |=
1043 log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
1044 (uint64_t)commandBuffer, __LINE__, IMAGE_INVALID_FORMAT, "IMAGE", "%s", ss.str().c_str());
Mark Lobodzinskidc86b852015-10-23 14:20:31 -06001045 }
1046
1047 for (uint32_t i = 0; i < regionCount; i++) {
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001048 if (pRegions[i].srcSubresource.layerCount == 0) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001049 char const str[] = "vkCmdBlitImage: number of layers in source subresource is zero";
1050 // TODO: Verify against Valid Use section of spec, if this case yields undefined results, then it's an error
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001051 skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
1052 VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, (uint64_t)commandBuffer, __LINE__,
1053 IMAGE_MISMATCHED_IMAGE_ASPECT, "IMAGE", str);
Jeremy Hayes148bab22015-10-28 13:01:39 -06001054 }
1055
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001056 if (pRegions[i].dstSubresource.layerCount == 0) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001057 char const str[] = "vkCmdBlitImage: number of layers in destination subresource is zero";
1058 // TODO: Verify against Valid Use section of spec, if this case yields undefined results, then it's an error
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001059 skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
1060 VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, (uint64_t)commandBuffer, __LINE__,
1061 IMAGE_MISMATCHED_IMAGE_ASPECT, "IMAGE", str);
Jeremy Hayes148bab22015-10-28 13:01:39 -06001062 }
1063
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001064 if (pRegions[i].srcSubresource.layerCount != pRegions[i].dstSubresource.layerCount) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001065 char const str[] = "vkCmdBlitImage: number of layers in source and destination subresources must match";
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001066 skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
1067 VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, (uint64_t)commandBuffer, __LINE__,
1068 IMAGE_MISMATCHED_IMAGE_ASPECT, "IMAGE", str);
Jeremy Hayes148bab22015-10-28 13:01:39 -06001069 }
1070
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001071 VkImageAspectFlags srcAspect = pRegions[i].srcSubresource.aspectMask;
1072 VkImageAspectFlags dstAspect = pRegions[i].dstSubresource.aspectMask;
Mark Lobodzinskidc86b852015-10-23 14:20:31 -06001073
1074 if (srcAspect != dstAspect) {
1075 std::stringstream ss;
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001076 ss << "vkCmdBlitImage: Image aspects of depth/stencil images should match";
1077 // TODO: Verify against Valid Use section of spec, if this case yields undefined results, then it's an error
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001078 skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
1079 VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, (uint64_t)commandBuffer, __LINE__,
1080 IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", "%s", ss.str().c_str());
Mark Lobodzinskidc86b852015-10-23 14:20:31 -06001081 }
1082 if (vk_format_is_depth_and_stencil(srcFormat)) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001083 if ((srcAspect != VK_IMAGE_ASPECT_DEPTH_BIT) && (srcAspect != VK_IMAGE_ASPECT_STENCIL_BIT)) {
Mark Lobodzinskidc86b852015-10-23 14:20:31 -06001084 std::stringstream ss;
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001085 ss << "vkCmdBlitImage: Combination depth/stencil image formats must have only one of "
1086 "VK_IMAGE_ASPECT_DEPTH_BIT "
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001087 << "and VK_IMAGE_ASPECT_STENCIL_BIT set in srcImage and dstImage";
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001088 skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
1089 VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, (uint64_t)commandBuffer, __LINE__,
1090 IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", "%s", ss.str().c_str());
Mark Lobodzinskidc86b852015-10-23 14:20:31 -06001091 }
1092 } else if (vk_format_is_stencil_only(srcFormat)) {
1093 if (srcAspect != VK_IMAGE_ASPECT_STENCIL_BIT) {
1094 std::stringstream ss;
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001095 ss << "vkCmdBlitImage: Stencil-only image formats must have only the VK_IMAGE_ASPECT_STENCIL_BIT "
Chia-I Wu3432a0c2015-10-27 18:04:07 +08001096 << "set in both the srcImage and dstImage";
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001097 skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
1098 VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, (uint64_t)commandBuffer, __LINE__,
1099 IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", "%s", ss.str().c_str());
Mark Lobodzinskidc86b852015-10-23 14:20:31 -06001100 }
1101 } else if (vk_format_is_depth_only(srcFormat)) {
1102 if (srcAspect != VK_IMAGE_ASPECT_DEPTH_BIT) {
1103 std::stringstream ss;
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001104 ss << "vkCmdBlitImage: Depth-only image formats must have only the VK_IMAGE_ASPECT_DEPTH "
Chia-I Wu3432a0c2015-10-27 18:04:07 +08001105 << "set in both the srcImage and dstImage";
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001106 skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
1107 VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, (uint64_t)commandBuffer, __LINE__,
1108 IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", "%s", ss.str().c_str());
Mark Lobodzinskidc86b852015-10-23 14:20:31 -06001109 }
1110 }
1111 }
1112 }
1113
1114 // Validate filter
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001115 if (vk_format_is_depth_or_stencil(srcFormat) || vk_format_is_int(srcFormat)) {
Chia-I Wub99df442015-10-26 16:49:32 +08001116 if (filter != VK_FILTER_NEAREST) {
Mark Lobodzinskidc86b852015-10-23 14:20:31 -06001117 std::stringstream ss;
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001118 ss << "vkCmdBlitImage: If the format of srcImage is a depth, stencil, depth stencil or integer-based format "
Chia-I Wub99df442015-10-26 16:49:32 +08001119 << "then filter must be VK_FILTER_NEAREST.";
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001120 skipCall |=
1121 log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
1122 (uint64_t)commandBuffer, __LINE__, IMAGE_INVALID_FILTER, "IMAGE", "%s", ss.str().c_str());
Mark Lobodzinskidc86b852015-10-23 14:20:31 -06001123 }
1124 }
1125 }
Mark Lobodzinskia5eabe72015-10-05 17:16:05 -06001126
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001127 device_data->device_dispatch_table->CmdBlitImage(commandBuffer, srcImage, srcImageLayout, dstImage, dstImageLayout, regionCount,
1128 pRegions, filter);
Mark Lobodzinskia5eabe72015-10-05 17:16:05 -06001129}
1130
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001131VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL
1132vkCmdPipelineBarrier(VkCommandBuffer commandBuffer, VkPipelineStageFlags srcStageMask, VkPipelineStageFlags dstStageMask,
1133 VkDependencyFlags dependencyFlags, uint32_t memoryBarrierCount, const VkMemoryBarrier *pMemoryBarriers,
1134 uint32_t bufferMemoryBarrierCount, const VkBufferMemoryBarrier *pBufferMemoryBarriers,
1135 uint32_t imageMemoryBarrierCount, const VkImageMemoryBarrier *pImageMemoryBarriers) {
Dustin Graves080069b2016-04-05 13:48:15 -06001136 bool skipCall = false;
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001137 layer_data *device_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
Jeremy Hayes01b38892015-11-17 18:19:55 -07001138
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001139 for (uint32_t i = 0; i < imageMemoryBarrierCount; ++i) {
1140 VkImageMemoryBarrier const *const barrier = (VkImageMemoryBarrier const *const) & pImageMemoryBarriers[i];
1141 if (barrier->sType == VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER) {
1142 if (barrier->subresourceRange.layerCount == 0) {
Jeremy Hayes01b38892015-11-17 18:19:55 -07001143 std::stringstream ss;
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001144 ss << "vkCmdPipelineBarrier called with 0 in ppMemoryBarriers[" << i << "]->subresourceRange.layerCount.";
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001145 skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0,
1146 __LINE__, IMAGE_INVALID_IMAGE_RESOURCE, "IMAGE", "%s", ss.str().c_str());
Jeremy Hayes01b38892015-11-17 18:19:55 -07001147 }
1148 }
1149 }
1150
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001151 if (skipCall) {
Jeremy Hayes01b38892015-11-17 18:19:55 -07001152 return;
1153 }
1154
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001155 device_data->device_dispatch_table->CmdPipelineBarrier(commandBuffer, srcStageMask, dstStageMask, dependencyFlags,
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001156 memoryBarrierCount, pMemoryBarriers, bufferMemoryBarrierCount,
1157 pBufferMemoryBarriers, imageMemoryBarrierCount, pImageMemoryBarriers);
Jeremy Hayes01b38892015-11-17 18:19:55 -07001158}
1159
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001160VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL
1161vkCmdResolveImage(VkCommandBuffer commandBuffer, VkImage srcImage, VkImageLayout srcImageLayout, VkImage dstImage,
1162 VkImageLayout dstImageLayout, uint32_t regionCount, const VkImageResolve *pRegions) {
Dustin Graves080069b2016-04-05 13:48:15 -06001163 bool skipCall = false;
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001164 layer_data *device_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
Chia-I Wue2fc5522015-10-26 20:04:44 +08001165 auto srcImageEntry = device_data->imageMap.find(srcImage);
Chia-I Wu3432a0c2015-10-27 18:04:07 +08001166 auto dstImageEntry = device_data->imageMap.find(dstImage);
Mark Lobodzinskia5eabe72015-10-05 17:16:05 -06001167
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001168 // For each region, the number of layers in the image subresource should not be zero
Mark Lobodzinskia5eabe72015-10-05 17:16:05 -06001169 // For each region, src and dest image aspect must be color only
1170 for (uint32_t i = 0; i < regionCount; i++) {
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001171 if (pRegions[i].srcSubresource.layerCount == 0) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001172 char const str[] = "vkCmdResolveImage: number of layers in source subresource is zero";
1173 // TODO: Verify against Valid Use section of spec. Generally if something yield an undefined result, it's invalid/error
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001174 skipCall |=
1175 log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
1176 (uint64_t)commandBuffer, __LINE__, IMAGE_MISMATCHED_IMAGE_ASPECT, "IMAGE", str);
Jeremy Hayes148bab22015-10-28 13:01:39 -06001177 }
1178
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001179 if (pRegions[i].dstSubresource.layerCount == 0) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001180 char const str[] = "vkCmdResolveImage: number of layers in destination subresource is zero";
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -07001181
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001182 // TODO: Verify against Valid Use section of spec. Generally if something yield an undefined result, it's invalid/error
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001183 skipCall |=
1184 log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
1185 (uint64_t)commandBuffer, __LINE__, IMAGE_MISMATCHED_IMAGE_ASPECT, "IMAGE", str);
Jeremy Hayes148bab22015-10-28 13:01:39 -06001186 }
1187
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001188 if ((pRegions[i].srcSubresource.aspectMask != VK_IMAGE_ASPECT_COLOR_BIT) ||
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001189 (pRegions[i].dstSubresource.aspectMask != VK_IMAGE_ASPECT_COLOR_BIT)) {
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001190 char const str[] =
1191 "vkCmdResolveImage: src and dest aspectMasks for each region must specify only VK_IMAGE_ASPECT_COLOR_BIT";
1192 skipCall |=
1193 log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
1194 (uint64_t)commandBuffer, __LINE__, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", str);
Mark Lobodzinskia5eabe72015-10-05 17:16:05 -06001195 }
1196 }
1197
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001198 if ((srcImageEntry != device_data->imageMap.end()) && (dstImageEntry != device_data->imageMap.end())) {
Chia-I Wu3432a0c2015-10-27 18:04:07 +08001199 if (srcImageEntry->second.format != dstImageEntry->second.format) {
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001200 char const str[] = "vkCmdResolveImage called with unmatched source and dest formats.";
1201 skipCall |=
1202 log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
1203 (uint64_t)commandBuffer, __LINE__, IMAGE_MISMATCHED_IMAGE_FORMAT, "IMAGE", str);
Mike Stroyana3082432015-09-25 13:39:21 -06001204 }
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001205 if (srcImageEntry->second.imageType != dstImageEntry->second.imageType) {
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001206 char const str[] = "vkCmdResolveImage called with unmatched source and dest image types.";
1207 skipCall |=
1208 log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
1209 (uint64_t)commandBuffer, __LINE__, IMAGE_MISMATCHED_IMAGE_TYPE, "IMAGE", str);
Mike Stroyana3082432015-09-25 13:39:21 -06001210 }
Chia-I Wu5c17c962015-10-31 00:31:16 +08001211 if (srcImageEntry->second.samples == VK_SAMPLE_COUNT_1_BIT) {
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001212 char const str[] = "vkCmdResolveImage called with source sample count less than 2.";
1213 skipCall |=
1214 log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
1215 (uint64_t)commandBuffer, __LINE__, IMAGE_INVALID_RESOLVE_SAMPLES, "IMAGE", str);
Mike Stroyana3082432015-09-25 13:39:21 -06001216 }
Chia-I Wu5c17c962015-10-31 00:31:16 +08001217 if (dstImageEntry->second.samples != VK_SAMPLE_COUNT_1_BIT) {
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001218 char const str[] = "vkCmdResolveImage called with dest sample count greater than 1.";
1219 skipCall |=
1220 log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
1221 (uint64_t)commandBuffer, __LINE__, IMAGE_INVALID_RESOLVE_SAMPLES, "IMAGE", str);
Mike Stroyana3082432015-09-25 13:39:21 -06001222 }
1223 }
1224
Dustin Graves080069b2016-04-05 13:48:15 -06001225 if (!skipCall) {
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001226 device_data->device_dispatch_table->CmdResolveImage(commandBuffer, srcImage, srcImageLayout, dstImage, dstImageLayout,
1227 regionCount, pRegions);
Mark Lobodzinskia5eabe72015-10-05 17:16:05 -06001228 }
1229}
1230
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001231VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL
1232vkGetImageSubresourceLayout(VkDevice device, VkImage image, const VkImageSubresource *pSubresource, VkSubresourceLayout *pLayout) {
Dustin Graves080069b2016-04-05 13:48:15 -06001233 bool skipCall = false;
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001234 layer_data *device_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001235 VkFormat format;
Mark Lobodzinskia5eabe72015-10-05 17:16:05 -06001236
Chia-I Wue2fc5522015-10-26 20:04:44 +08001237 auto imageEntry = device_data->imageMap.find(image);
Mark Lobodzinskidc86b852015-10-23 14:20:31 -06001238
1239 // Validate that image aspects match formats
1240 if (imageEntry != device_data->imageMap.end()) {
Tobin Ehlisd923d152015-09-25 14:49:43 -06001241 format = imageEntry->second.format;
Mark Lobodzinskidc86b852015-10-23 14:20:31 -06001242 if (vk_format_is_color(format)) {
Chia-I Wu52b07e72015-10-27 19:55:05 +08001243 if (pSubresource->aspectMask != VK_IMAGE_ASPECT_COLOR_BIT) {
Mark Lobodzinskidc86b852015-10-23 14:20:31 -06001244 std::stringstream ss;
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001245 ss << "vkGetImageSubresourceLayout: For color formats, the aspectMask field of VkImageSubresource must be "
1246 "VK_IMAGE_ASPECT_COLOR.";
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001247 skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT,
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001248 (uint64_t)image, __LINE__, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", "%s", ss.str().c_str());
Mark Lobodzinskidc86b852015-10-23 14:20:31 -06001249 }
1250 } else if (vk_format_is_depth_or_stencil(format)) {
Chia-I Wu52b07e72015-10-27 19:55:05 +08001251 if ((pSubresource->aspectMask != VK_IMAGE_ASPECT_DEPTH_BIT) &&
1252 (pSubresource->aspectMask != VK_IMAGE_ASPECT_STENCIL_BIT)) {
Mark Lobodzinskidc86b852015-10-23 14:20:31 -06001253 std::stringstream ss;
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001254 ss << "vkGetImageSubresourceLayout: For depth/stencil formats, the aspectMask selects either the depth or stencil "
1255 "image aspectMask.";
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001256 skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT,
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001257 (uint64_t)image, __LINE__, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", "%s", ss.str().c_str());
Mark Lobodzinskidc86b852015-10-23 14:20:31 -06001258 }
1259 }
1260 }
1261
Dustin Graves080069b2016-04-05 13:48:15 -06001262 if (!skipCall) {
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001263 device_data->device_dispatch_table->GetImageSubresourceLayout(device, image, pSubresource, pLayout);
Mark Lobodzinskidc86b852015-10-23 14:20:31 -06001264 }
Mark Lobodzinskia5eabe72015-10-05 17:16:05 -06001265}
1266
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001267VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL
1268vkGetPhysicalDeviceProperties(VkPhysicalDevice physicalDevice, VkPhysicalDeviceProperties *pProperties) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001269 layer_data *phy_dev_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);
1270 phy_dev_data->instance_dispatch_table->GetPhysicalDeviceProperties(physicalDevice, pProperties);
Mark Lobodzinskid5a23822015-11-12 15:14:35 -07001271}
1272
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001273VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetDeviceProcAddr(VkDevice device, const char *funcName) {
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -07001274 if (!strcmp(funcName, "vkGetDeviceProcAddr"))
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001275 return (PFN_vkVoidFunction)vkGetDeviceProcAddr;
Jeremy Hayes9cc31582015-06-18 10:12:39 -06001276 if (!strcmp(funcName, "vkDestroyDevice"))
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001277 return (PFN_vkVoidFunction)vkDestroyDevice;
Jeremy Hayes9cc31582015-06-18 10:12:39 -06001278 if (!strcmp(funcName, "vkCreateImage"))
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001279 return (PFN_vkVoidFunction)vkCreateImage;
Mark Lobodzinski46fc3dd2015-10-29 12:58:33 -06001280 if (!strcmp(funcName, "vkDestroyImage"))
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001281 return (PFN_vkVoidFunction)vkDestroyImage;
Tobin Ehliscde08892015-09-22 10:11:37 -06001282 if (!strcmp(funcName, "vkCreateImageView"))
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001283 return (PFN_vkVoidFunction)vkCreateImageView;
Jeremy Hayes9cc31582015-06-18 10:12:39 -06001284 if (!strcmp(funcName, "vkCreateRenderPass"))
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001285 return (PFN_vkVoidFunction)vkCreateRenderPass;
Mark Lobodzinskia5eabe72015-10-05 17:16:05 -06001286 if (!strcmp(funcName, "vkCmdClearColorImage"))
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001287 return (PFN_vkVoidFunction)vkCmdClearColorImage;
Mark Lobodzinskia5eabe72015-10-05 17:16:05 -06001288 if (!strcmp(funcName, "vkCmdClearDepthStencilImage"))
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001289 return (PFN_vkVoidFunction)vkCmdClearDepthStencilImage;
Courtney Goeltzenleuchterc9323e02015-10-15 16:51:05 -06001290 if (!strcmp(funcName, "vkCmdClearAttachments"))
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001291 return (PFN_vkVoidFunction)vkCmdClearAttachments;
Mark Lobodzinskia5eabe72015-10-05 17:16:05 -06001292 if (!strcmp(funcName, "vkCmdCopyImage"))
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001293 return (PFN_vkVoidFunction)vkCmdCopyImage;
Mark Lobodzinskia5eabe72015-10-05 17:16:05 -06001294 if (!strcmp(funcName, "vkCmdCopyImageToBuffer"))
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001295 return (PFN_vkVoidFunction)vkCmdCopyImageToBuffer;
Mark Lobodzinskia5eabe72015-10-05 17:16:05 -06001296 if (!strcmp(funcName, "vkCmdCopyBufferToImage"))
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001297 return (PFN_vkVoidFunction)vkCmdCopyBufferToImage;
Mark Lobodzinskia5eabe72015-10-05 17:16:05 -06001298 if (!strcmp(funcName, "vkCmdBlitImage"))
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001299 return (PFN_vkVoidFunction)vkCmdBlitImage;
Jeremy Hayes01b38892015-11-17 18:19:55 -07001300 if (!strcmp(funcName, "vkCmdPipelineBarrier"))
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001301 return (PFN_vkVoidFunction)vkCmdPipelineBarrier;
Mark Lobodzinskia5eabe72015-10-05 17:16:05 -06001302 if (!strcmp(funcName, "vkCmdResolveImage"))
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001303 return (PFN_vkVoidFunction)vkCmdResolveImage;
Mark Lobodzinskia5eabe72015-10-05 17:16:05 -06001304 if (!strcmp(funcName, "vkGetImageSubresourceLayout"))
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001305 return (PFN_vkVoidFunction)vkGetImageSubresourceLayout;
Tobin Ehlisb74f6ab2015-10-29 14:19:18 -06001306
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -07001307 if (device == NULL) {
1308 return NULL;
1309 }
1310
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001311 layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -07001312
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001313 VkLayerDispatchTable *pTable = my_data->device_dispatch_table;
Jeremy Hayes9cc31582015-06-18 10:12:39 -06001314 {
Tobin Ehlisb74f6ab2015-10-29 14:19:18 -06001315 if (pTable->GetDeviceProcAddr == NULL)
Jeremy Hayes9cc31582015-06-18 10:12:39 -06001316 return NULL;
Tobin Ehlisb74f6ab2015-10-29 14:19:18 -06001317 return pTable->GetDeviceProcAddr(device, funcName);
Jeremy Hayes9cc31582015-06-18 10:12:39 -06001318 }
1319}
1320
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001321VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetInstanceProcAddr(VkInstance instance, const char *funcName) {
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -07001322 if (!strcmp(funcName, "vkGetInstanceProcAddr"))
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001323 return (PFN_vkVoidFunction)vkGetInstanceProcAddr;
Jeremy Hayes9cc31582015-06-18 10:12:39 -06001324 if (!strcmp(funcName, "vkCreateInstance"))
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001325 return (PFN_vkVoidFunction)vkCreateInstance;
Jeremy Hayes9cc31582015-06-18 10:12:39 -06001326 if (!strcmp(funcName, "vkDestroyInstance"))
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001327 return (PFN_vkVoidFunction)vkDestroyInstance;
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -07001328 if (!strcmp(funcName, "vkCreateDevice"))
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001329 return (PFN_vkVoidFunction)vkCreateDevice;
Courtney Goeltzenleuchter35985f62015-09-14 17:22:16 -06001330 if (!strcmp(funcName, "vkEnumerateInstanceLayerProperties"))
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001331 return (PFN_vkVoidFunction)vkEnumerateInstanceLayerProperties;
Courtney Goeltzenleuchter35985f62015-09-14 17:22:16 -06001332 if (!strcmp(funcName, "vkEnumerateInstanceExtensionProperties"))
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001333 return (PFN_vkVoidFunction)vkEnumerateInstanceExtensionProperties;
Courtney Goeltzenleuchter35985f62015-09-14 17:22:16 -06001334 if (!strcmp(funcName, "vkEnumerateDeviceLayerProperties"))
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001335 return (PFN_vkVoidFunction)vkEnumerateDeviceLayerProperties;
Courtney Goeltzenleuchter35985f62015-09-14 17:22:16 -06001336 if (!strcmp(funcName, "vkEnumerateDeviceExtensionProperties"))
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001337 return (PFN_vkVoidFunction)vkEnumerateDeviceExtensionProperties;
Mark Lobodzinskid5a23822015-11-12 15:14:35 -07001338 if (!strcmp(funcName, "vkGetPhysicalDeviceProperties"))
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001339 return (PFN_vkVoidFunction)vkGetPhysicalDeviceProperties;
Jeremy Hayes9cc31582015-06-18 10:12:39 -06001340
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -07001341 if (instance == NULL) {
1342 return NULL;
1343 }
1344
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001345 layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -07001346
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001347 PFN_vkVoidFunction fptr = debug_report_get_instance_proc_addr(my_data->report_data, funcName);
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001348 if (fptr)
Jeremy Hayes9cc31582015-06-18 10:12:39 -06001349 return fptr;
1350
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001351 VkLayerInstanceDispatchTable *pTable = my_data->instance_dispatch_table;
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -07001352 if (pTable->GetInstanceProcAddr == NULL)
1353 return NULL;
1354 return pTable->GetInstanceProcAddr(instance, funcName);
Jeremy Hayes9cc31582015-06-18 10:12:39 -06001355}