blob: a821712b3704af3113b386b7a7d065a0ae3d5cbd [file] [log] [blame]
Jeremy Hayes9cc31582015-06-18 10:12:39 -06001/*
Jeremy Hayes9cc31582015-06-18 10:12:39 -06002 *
Courtney Goeltzenleuchterfcbe16f2015-10-29 13:50:34 -06003 * Copyright (C) 2015 Valve Corporation
Michael Lentine03107b42015-12-11 10:49:51 -08004 * Copyright (C) 2015 Google Inc.
Jeremy Hayes9cc31582015-06-18 10:12:39 -06005 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included
14 * in all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
Courtney Goeltzenleuchter05559522015-10-30 11:14:30 -060023 *
24 * Author: Jeremy Hayes <jeremy@lunarg.com>
25 * Author: Mark Lobodzinski <mark@lunarg.com>
26 * Author: Mike Stroyan <mike@LunarG.com>
27 * Author: Tobin Ehlis <tobin@lunarg.com>
Jeremy Hayes9cc31582015-06-18 10:12:39 -060028 */
29
Courtney Goeltzenleuchter8f8367e2015-10-07 08:38:30 -060030#include <inttypes.h>
Jeremy Hayes9cc31582015-06-18 10:12:39 -060031#include <stdio.h>
32#include <stdlib.h>
33#include <string.h>
Courtney Goeltzenleuchter8f8367e2015-10-07 08:38:30 -060034#include <assert.h>
35#include <vector>
Jeremy Hayes9cc31582015-06-18 10:12:39 -060036#include <unordered_map>
Tobin Ehlisad8c4462015-09-21 15:20:28 -060037#include <memory>
Courtney Goeltzenleuchter8f8367e2015-10-07 08:38:30 -060038using namespace std;
Jeremy Hayes9cc31582015-06-18 10:12:39 -060039
Tobin Ehlisb835d1b2015-07-03 10:34:49 -060040#include "vk_loader_platform.h"
Courtney Goeltzenleuchter8f8367e2015-10-07 08:38:30 -060041#include "vk_dispatch_table_helper.h"
42#include "vk_struct_string_helper_cpp.h"
Jeremy Hayes9cc31582015-06-18 10:12:39 -060043#include "vk_enum_validate_helper.h"
Courtney Goeltzenleuchter8f8367e2015-10-07 08:38:30 -060044#include "image.h"
45#include "vk_layer_config.h"
46#include "vk_layer_extension_utils.h"
Tobin Ehlisa0cb02e2015-07-03 10:15:26 -060047#include "vk_layer_table.h"
48#include "vk_layer_data.h"
Courtney Goeltzenleuchter426e1872015-07-07 11:18:30 -060049#include "vk_layer_extension_utils.h"
Mike Stroyana3082432015-09-25 13:39:21 -060050#include "vk_layer_utils.h"
Courtney Goeltzenleuchter8f8367e2015-10-07 08:38:30 -060051#include "vk_layer_logging.h"
Jeremy Hayes9cc31582015-06-18 10:12:39 -060052
Tobin Ehlisad8c4462015-09-21 15:20:28 -060053using namespace std;
54
Cody Northrop55443ef2015-09-28 15:09:32 -060055struct layer_data {
Mark Lobodzinskid5a23822015-11-12 15:14:35 -070056 debug_report_data *report_data;
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -070057 vector<VkDebugReportCallbackEXT> logging_callback;
Mark Lobodzinskid5a23822015-11-12 15:14:35 -070058 VkLayerDispatchTable* device_dispatch_table;
59 VkLayerInstanceDispatchTable *instance_dispatch_table;
60 VkPhysicalDevice physicalDevice;
61 VkPhysicalDeviceProperties physicalDeviceProperties;
62
Chia-I Wue2fc5522015-10-26 20:04:44 +080063 unordered_map<VkImage, IMAGE_STATE> imageMap;
Cody Northrop55443ef2015-09-28 15:09:32 -060064
65 layer_data() :
66 report_data(nullptr),
Tobin Ehlisb74f6ab2015-10-29 14:19:18 -060067 device_dispatch_table(nullptr),
68 instance_dispatch_table(nullptr),
Mark Lobodzinskid5a23822015-11-12 15:14:35 -070069 physicalDevice(0),
70 physicalDeviceProperties()
Cody Northrop55443ef2015-09-28 15:09:32 -060071 {};
72};
Jeremy Hayes9cc31582015-06-18 10:12:39 -060073
Tobin Ehlisad8c4462015-09-21 15:20:28 -060074static unordered_map<void*, layer_data*> layer_data_map;
Jeremy Hayes9cc31582015-06-18 10:12:39 -060075
Courtney Goeltzenleuchter6d8e8182015-11-25 14:31:49 -070076static void InitImage(layer_data *data, const VkAllocationCallbacks *pAllocator)
Jeremy Hayes9cc31582015-06-18 10:12:39 -060077{
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -070078 VkDebugReportCallbackEXT callback;
Jeremy Hayes9cc31582015-06-18 10:12:39 -060079 uint32_t report_flags = getLayerOptionFlags("ImageReportFlags", 0);
80
81 uint32_t debug_action = 0;
82 getLayerOptionEnum("ImageDebugAction", (uint32_t *) &debug_action);
83 if(debug_action & VK_DBG_LAYER_ACTION_LOG_MSG)
84 {
85 FILE *log_output = NULL;
86 const char* option_str = getLayerOption("ImageLogFilename");
Tobin Ehlisb1df55e2015-09-15 09:55:54 -060087 log_output = getLayerLogOutput(option_str, "Image");
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -070088 VkDebugReportCallbackCreateInfoEXT dbgInfo;
Courtney Goeltzenleuchter05854bf2015-11-30 12:13:14 -070089 memset(&dbgInfo, 0, sizeof(dbgInfo));
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -070090 dbgInfo.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT;
Courtney Goeltzenleuchter05854bf2015-11-30 12:13:14 -070091 dbgInfo.pfnCallback = log_callback;
92 dbgInfo.pUserData = log_output;
93 dbgInfo.flags = report_flags;
94 layer_create_msg_callback(data->report_data, &dbgInfo, pAllocator, &callback);
Courtney Goeltzenleuchterffcdd8b2015-10-05 15:59:11 -060095 data->logging_callback.push_back(callback);
96 }
97
98 if (debug_action & VK_DBG_LAYER_ACTION_DEBUG_OUTPUT) {
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -070099 VkDebugReportCallbackCreateInfoEXT dbgInfo;
Courtney Goeltzenleuchter05854bf2015-11-30 12:13:14 -0700100 memset(&dbgInfo, 0, sizeof(dbgInfo));
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -0700101 dbgInfo.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT;
Courtney Goeltzenleuchter05854bf2015-11-30 12:13:14 -0700102 dbgInfo.pfnCallback = win32_debug_output_msg;
103 dbgInfo.flags = report_flags;
104 layer_create_msg_callback(data->report_data, &dbgInfo, pAllocator, &callback);
Courtney Goeltzenleuchterffcdd8b2015-10-05 15:59:11 -0600105 data->logging_callback.push_back(callback);
Jeremy Hayes9cc31582015-06-18 10:12:39 -0600106 }
107}
108
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -0700109VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateDebugReportCallbackEXT(
Courtney Goeltzenleuchter05854bf2015-11-30 12:13:14 -0700110 VkInstance instance,
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -0700111 const VkDebugReportCallbackCreateInfoEXT* pCreateInfo,
Courtney Goeltzenleuchter05854bf2015-11-30 12:13:14 -0700112 const VkAllocationCallbacks* pAllocator,
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -0700113 VkDebugReportCallbackEXT* pMsgCallback)
Jeremy Hayes9cc31582015-06-18 10:12:39 -0600114{
Tobin Ehlisb74f6ab2015-10-29 14:19:18 -0600115 layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -0700116 VkResult res = my_data->instance_dispatch_table->CreateDebugReportCallbackEXT(instance, pCreateInfo, pAllocator, pMsgCallback);
Jeremy Hayes9cc31582015-06-18 10:12:39 -0600117 if (res == VK_SUCCESS) {
Courtney Goeltzenleuchter05854bf2015-11-30 12:13:14 -0700118 res = layer_create_msg_callback(my_data->report_data, pCreateInfo, pAllocator, pMsgCallback);
Jeremy Hayes9cc31582015-06-18 10:12:39 -0600119 }
120 return res;
121}
122
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -0700123VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL vkDestroyDebugReportCallbackEXT(
Courtney Goeltzenleuchter05854bf2015-11-30 12:13:14 -0700124 VkInstance instance,
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -0700125 VkDebugReportCallbackEXT msgCallback,
Courtney Goeltzenleuchter05854bf2015-11-30 12:13:14 -0700126 const VkAllocationCallbacks* pAllocator)
Jeremy Hayes9cc31582015-06-18 10:12:39 -0600127{
Tobin Ehlisb74f6ab2015-10-29 14:19:18 -0600128 layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -0700129 my_data->instance_dispatch_table->DestroyDebugReportCallbackEXT(instance, msgCallback, pAllocator);
Courtney Goeltzenleuchter05854bf2015-11-30 12:13:14 -0700130 layer_destroy_msg_callback(my_data->report_data, msgCallback, pAllocator);
Jeremy Hayes9cc31582015-06-18 10:12:39 -0600131}
132
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -0700133VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL vkDebugReportMessageEXT(
Courtney Goeltzenleuchterf0de7242015-12-01 14:10:55 -0700134 VkInstance instance,
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -0700135 VkDebugReportFlagsEXT flags,
136 VkDebugReportObjectTypeEXT objType,
Courtney Goeltzenleuchterf0de7242015-12-01 14:10:55 -0700137 uint64_t object,
138 size_t location,
139 int32_t msgCode,
140 const char* pLayerPrefix,
141 const char* pMsg)
142{
143 layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -0700144 my_data->instance_dispatch_table->DebugReportMessageEXT(instance, flags, objType, object, location, msgCode, pLayerPrefix, pMsg);
Courtney Goeltzenleuchterf0de7242015-12-01 14:10:55 -0700145}
146
Chia-I Wu9ab61502015-11-06 06:42:02 +0800147VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateInstance(const VkInstanceCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkInstance* pInstance)
Jeremy Hayes9cc31582015-06-18 10:12:39 -0600148{
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -0700149 VkLayerInstanceCreateInfo *chain_info = get_chain_info(pCreateInfo, VK_LAYER_LINK_INFO);
Jeremy Hayes9cc31582015-06-18 10:12:39 -0600150
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -0700151 assert(chain_info->u.pLayerInfo);
152 PFN_vkGetInstanceProcAddr fpGetInstanceProcAddr = chain_info->u.pLayerInfo->pfnNextGetInstanceProcAddr;
153 PFN_vkCreateInstance fpCreateInstance = (PFN_vkCreateInstance) fpGetInstanceProcAddr(NULL, "vkCreateInstance");
154 if (fpCreateInstance == NULL) {
155 return VK_ERROR_INITIALIZATION_FAILED;
Jeremy Hayes9cc31582015-06-18 10:12:39 -0600156 }
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -0700157
158 // Advance the link info for the next element on the chain
159 chain_info->u.pLayerInfo = chain_info->u.pLayerInfo->pNext;
160
161 VkResult result = fpCreateInstance(pCreateInfo, pAllocator, pInstance);
162 if (result != VK_SUCCESS)
163 return result;
164
165 layer_data *my_data = get_my_data_ptr(get_dispatch_key(*pInstance), layer_data_map);
166 my_data->instance_dispatch_table = new VkLayerInstanceDispatchTable;
167 layer_init_instance_dispatch_table(*pInstance, my_data->instance_dispatch_table, fpGetInstanceProcAddr);
168
169 my_data->report_data = debug_report_create_instance(
170 my_data->instance_dispatch_table,
171 *pInstance,
172 pCreateInfo->enabledExtensionCount,
173 pCreateInfo->ppEnabledExtensionNames);
174
175 InitImage(my_data, pAllocator);
176
Jeremy Hayes9cc31582015-06-18 10:12:39 -0600177 return result;
178}
179
Chia-I Wu9ab61502015-11-06 06:42:02 +0800180VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL vkDestroyInstance(VkInstance instance, const VkAllocationCallbacks* pAllocator)
Jeremy Hayes9cc31582015-06-18 10:12:39 -0600181{
182 // Grab the key before the instance is destroyed.
183 dispatch_key key = get_dispatch_key(instance);
Tobin Ehlisb74f6ab2015-10-29 14:19:18 -0600184 layer_data *my_data = get_my_data_ptr(key, layer_data_map);
185 VkLayerInstanceDispatchTable *pTable = my_data->instance_dispatch_table;
Chia-I Wuf7458c52015-10-26 21:10:41 +0800186 pTable->DestroyInstance(instance, pAllocator);
Jeremy Hayes9cc31582015-06-18 10:12:39 -0600187
188 // Clean up logging callback, if any
Courtney Goeltzenleuchterffcdd8b2015-10-05 15:59:11 -0600189 while (my_data->logging_callback.size() > 0) {
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -0700190 VkDebugReportCallbackEXT callback = my_data->logging_callback.back();
Courtney Goeltzenleuchter05854bf2015-11-30 12:13:14 -0700191 layer_destroy_msg_callback(my_data->report_data, callback, pAllocator);
Courtney Goeltzenleuchterffcdd8b2015-10-05 15:59:11 -0600192 my_data->logging_callback.pop_back();
Jeremy Hayes9cc31582015-06-18 10:12:39 -0600193 }
194
Tobin Ehlisb74f6ab2015-10-29 14:19:18 -0600195 layer_debug_report_destroy_instance(my_data->report_data);
196 delete my_data->instance_dispatch_table;
197 layer_data_map.erase(key);
Jeremy Hayes9cc31582015-06-18 10:12:39 -0600198
Jeremy Hayes9cc31582015-06-18 10:12:39 -0600199}
200
Chia-I Wu9ab61502015-11-06 06:42:02 +0800201VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateDevice(VkPhysicalDevice physicalDevice, const VkDeviceCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDevice* pDevice)
Jeremy Hayes9cc31582015-06-18 10:12:39 -0600202{
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -0700203 VkLayerDeviceCreateInfo *chain_info = get_chain_info(pCreateInfo, VK_LAYER_LINK_INFO);
204
205 assert(chain_info->u.pLayerInfo);
206 PFN_vkGetInstanceProcAddr fpGetInstanceProcAddr = chain_info->u.pLayerInfo->pfnNextGetInstanceProcAddr;
207 PFN_vkGetDeviceProcAddr fpGetDeviceProcAddr = chain_info->u.pLayerInfo->pfnNextGetDeviceProcAddr;
208 PFN_vkCreateDevice fpCreateDevice = (PFN_vkCreateDevice) fpGetInstanceProcAddr(NULL, "vkCreateDevice");
209 if (fpCreateDevice == NULL) {
210 return VK_ERROR_INITIALIZATION_FAILED;
Jeremy Hayes9cc31582015-06-18 10:12:39 -0600211 }
212
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -0700213 // Advance the link info for the next element on the chain
214 chain_info->u.pLayerInfo = chain_info->u.pLayerInfo->pNext;
215
216 VkResult result = fpCreateDevice(physicalDevice, pCreateInfo, pAllocator, pDevice);
217 if (result != VK_SUCCESS) {
218 return result;
219 }
220
221 layer_data *my_instance_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);
222 layer_data *my_device_data = get_my_data_ptr(get_dispatch_key(*pDevice), layer_data_map);
223
224 // Setup device dispatch table
225 my_device_data->device_dispatch_table = new VkLayerDispatchTable;
226 layer_init_device_dispatch_table(*pDevice, my_device_data->device_dispatch_table, fpGetDeviceProcAddr);
227
228 my_device_data->report_data = layer_debug_report_create_device(my_instance_data->report_data, *pDevice);
229 my_device_data->physicalDevice = physicalDevice;
230
231 my_instance_data->instance_dispatch_table->GetPhysicalDeviceProperties(physicalDevice, &(my_device_data->physicalDeviceProperties));
Mark Lobodzinskid5a23822015-11-12 15:14:35 -0700232
Jeremy Hayes9cc31582015-06-18 10:12:39 -0600233 return result;
234}
235
Chia-I Wu9ab61502015-11-06 06:42:02 +0800236VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL vkDestroyDevice(VkDevice device, const VkAllocationCallbacks* pAllocator)
Jeremy Hayes9cc31582015-06-18 10:12:39 -0600237{
Jeremy Hayes9cc31582015-06-18 10:12:39 -0600238 dispatch_key key = get_dispatch_key(device);
Tobin Ehlisb74f6ab2015-10-29 14:19:18 -0600239 layer_data *my_data = get_my_data_ptr(key, layer_data_map);
Chia-I Wuf7458c52015-10-26 21:10:41 +0800240 my_data->device_dispatch_table->DestroyDevice(device, pAllocator);
Tobin Ehlisb74f6ab2015-10-29 14:19:18 -0600241 delete my_data->device_dispatch_table;
242 layer_data_map.erase(key);
Jeremy Hayes9cc31582015-06-18 10:12:39 -0600243}
244
Courtney Goeltzenleuchter52857662015-12-01 14:08:28 -0700245static const VkExtensionProperties instance_extensions[] = {
Jeremy Hayes9cc31582015-06-18 10:12:39 -0600246 {
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -0700247 VK_EXT_DEBUG_REPORT_EXTENSION_NAME,
Courtney Goeltzenleuchterb69cd592016-01-19 16:08:39 -0700248 VK_EXT_DEBUG_REPORT_SPEC_VERSION
Jeremy Hayes9cc31582015-06-18 10:12:39 -0600249 }
250};
251
Chia-I Wu9ab61502015-11-06 06:42:02 +0800252VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateInstanceExtensionProperties(
Courtney Goeltzenleuchter426e1872015-07-07 11:18:30 -0600253 const char *pLayerName,
254 uint32_t *pCount,
255 VkExtensionProperties* pProperties)
Jeremy Hayes9cc31582015-06-18 10:12:39 -0600256{
Courtney Goeltzenleuchter52857662015-12-01 14:08:28 -0700257 return util_GetExtensionProperties(1, instance_extensions, pCount, pProperties);
Jeremy Hayes9cc31582015-06-18 10:12:39 -0600258}
259
Courtney Goeltzenleuchter52857662015-12-01 14:08:28 -0700260static const VkLayerProperties pc_global_layers[] = {
261 {
Michael Lentine03107b42015-12-11 10:49:51 -0800262 "VK_LAYER_LUNARG_image",
Courtney Goeltzenleuchter52857662015-12-01 14:08:28 -0700263 VK_API_VERSION,
264 VK_MAKE_VERSION(0, 1, 0),
Mark Lobodzinski0d054fe2015-12-30 08:16:12 -0700265 "Validation layer: image",
Courtney Goeltzenleuchter52857662015-12-01 14:08:28 -0700266 }
267};
268
Chia-I Wu9ab61502015-11-06 06:42:02 +0800269VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateInstanceLayerProperties(
Courtney Goeltzenleuchter426e1872015-07-07 11:18:30 -0600270 uint32_t *pCount,
271 VkLayerProperties* pProperties)
Tony Barbour59a47322015-06-24 16:06:58 -0600272{
Courtney Goeltzenleuchter426e1872015-07-07 11:18:30 -0600273 return util_GetLayerProperties(ARRAY_SIZE(pc_global_layers),
274 pc_global_layers,
275 pCount, pProperties);
Tony Barbour59a47322015-06-24 16:06:58 -0600276}
277
Chia-I Wu9ab61502015-11-06 06:42:02 +0800278VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateDeviceExtensionProperties(
Courtney Goeltzenleuchter426e1872015-07-07 11:18:30 -0600279 VkPhysicalDevice physicalDevice,
280 const char* pLayerName,
281 uint32_t* pCount,
282 VkExtensionProperties* pProperties)
Jeremy Hayes9cc31582015-06-18 10:12:39 -0600283{
Jon Ashburn751c4842015-11-02 17:37:20 -0700284 // Image does not have any physical device extensions
285 if (pLayerName == NULL) {
286 dispatch_key key = get_dispatch_key(physicalDevice);
287 layer_data *my_data = get_my_data_ptr(key, layer_data_map);
288 VkLayerInstanceDispatchTable *pTable = my_data->instance_dispatch_table;
289 return pTable->EnumerateDeviceExtensionProperties(
290 physicalDevice,
291 NULL,
292 pCount,
293 pProperties);
294 } else {
295 return util_GetExtensionProperties(0, NULL, pCount, pProperties);
296 }
Courtney Goeltzenleuchter426e1872015-07-07 11:18:30 -0600297}
Jeremy Hayes9cc31582015-06-18 10:12:39 -0600298
Chia-I Wu9ab61502015-11-06 06:42:02 +0800299VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateDeviceLayerProperties(
Courtney Goeltzenleuchter426e1872015-07-07 11:18:30 -0600300 VkPhysicalDevice physicalDevice,
301 uint32_t* pCount,
302 VkLayerProperties* pProperties)
303{
Mark Lobodzinskidc86b852015-10-23 14:20:31 -0600304 // ParamChecker's physical device layers are the same as global
Courtney Goeltzenleuchter426e1872015-07-07 11:18:30 -0600305 return util_GetLayerProperties(ARRAY_SIZE(pc_global_layers), pc_global_layers,
306 pCount, pProperties);
Jeremy Hayes9cc31582015-06-18 10:12:39 -0600307}
308
Mark Lobodzinski2fd634c2015-07-29 09:21:22 -0600309// Start of the Image layer proper
310
311// Returns TRUE if a format is a depth-compatible format
312bool is_depth_format(VkFormat format)
313{
314 bool result = VK_FALSE;
315 switch (format) {
316 case VK_FORMAT_D16_UNORM:
Chia-I Wu935f2ed2015-11-10 17:01:22 +0800317 case VK_FORMAT_X8_D24_UNORM_PACK32:
Mark Lobodzinski2fd634c2015-07-29 09:21:22 -0600318 case VK_FORMAT_D32_SFLOAT:
319 case VK_FORMAT_S8_UINT:
320 case VK_FORMAT_D16_UNORM_S8_UINT:
321 case VK_FORMAT_D24_UNORM_S8_UINT:
322 case VK_FORMAT_D32_SFLOAT_S8_UINT:
323 result = VK_TRUE;
324 break;
325 default:
326 break;
327 }
328 return result;
329}
330
Mark Lobodzinski601ed152015-11-10 11:01:32 -0700331static inline uint32_t validate_VkImageLayoutKHR(VkImageLayout input_value)
332{
333 return ((validate_VkImageLayout(input_value) == 1) ||
Ian Elliott05846062015-11-20 14:13:17 -0700334 (input_value == VK_IMAGE_LAYOUT_PRESENT_SRC_KHR));
Mark Lobodzinski601ed152015-11-10 11:01:32 -0700335}
336
Chia-I Wu9ab61502015-11-06 06:42:02 +0800337VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateImage(VkDevice device, const VkImageCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkImage* pImage)
Jeremy Hayes9cc31582015-06-18 10:12:39 -0600338{
Mark Lobodzinskid5a23822015-11-12 15:14:35 -0700339 VkBool32 skipCall = VK_FALSE;
Courtney Goeltzenleuchter52fee652015-12-10 16:41:22 -0700340 VkResult result = VK_ERROR_VALIDATION_FAILED_EXT;
Mark Lobodzinskid5a23822015-11-12 15:14:35 -0700341 VkImageFormatProperties ImageFormatProperties = {0};
342
343 layer_data *device_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
344 VkPhysicalDevice physicalDevice = device_data->physicalDevice;
345 layer_data *phy_dev_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);
346
347 if (pCreateInfo->format != VK_FORMAT_UNDEFINED)
Jeremy Hayes9cc31582015-06-18 10:12:39 -0600348 {
349 VkFormatProperties properties;
Mark Lobodzinskid5a23822015-11-12 15:14:35 -0700350 phy_dev_data->instance_dispatch_table->GetPhysicalDeviceFormatProperties(
Chris Forbesbc0bb772015-06-21 22:55:02 +1200351 device_data->physicalDevice, pCreateInfo->format, &properties);
Jeremy Hayes9cc31582015-06-18 10:12:39 -0600352
Mark Lobodzinskid5a23822015-11-12 15:14:35 -0700353 if ((properties.linearTilingFeatures) == 0 && (properties.optimalTilingFeatures == 0))
Jeremy Hayes9cc31582015-06-18 10:12:39 -0600354 {
355 char const str[] = "vkCreateImage parameter, VkFormat pCreateInfo->format, contains unsupported format";
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -0700356 // TODO: Verify against Valid Use section of spec. Generally if something yield an undefined result, it's invalid
Mark Lobodzinski37a38b12016-01-04 13:32:45 -0700357 skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_WARN_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__, IMAGE_FORMAT_UNSUPPORTED, "IMAGE", str);
Jeremy Hayes9cc31582015-06-18 10:12:39 -0600358 }
359 }
360
Mark Lobodzinskid5a23822015-11-12 15:14:35 -0700361 // Internal call to get format info. Still goes through layers, could potentially go directly to ICD.
362 phy_dev_data->instance_dispatch_table->GetPhysicalDeviceImageFormatProperties(
363 physicalDevice, pCreateInfo->format, pCreateInfo->imageType, pCreateInfo->tiling,
364 pCreateInfo->usage, pCreateInfo->flags, &ImageFormatProperties);
Jeremy Hayes9cc31582015-06-18 10:12:39 -0600365
Mark Lobodzinskid5a23822015-11-12 15:14:35 -0700366 VkDeviceSize imageGranularity = device_data->physicalDeviceProperties.limits.bufferImageGranularity;
367 imageGranularity = imageGranularity == 1 ? 0 : imageGranularity;
368
369 if ((pCreateInfo->extent.depth > ImageFormatProperties.maxExtent.depth) ||
370 (pCreateInfo->extent.width > ImageFormatProperties.maxExtent.width) ||
371 (pCreateInfo->extent.height > ImageFormatProperties.maxExtent.height)) {
Mark Lobodzinski37a38b12016-01-04 13:32:45 -0700372 skipCall |= log_msg(phy_dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, (uint64_t)pImage, __LINE__,
Mark Lobodzinskid5a23822015-11-12 15:14:35 -0700373 IMAGE_INVALID_FORMAT_LIMITS_VIOLATION, "Image",
374 "CreateImage extents exceed allowable limits for format: "
375 "Width = %d Height = %d Depth = %d: Limits for Width = %d Height = %d Depth = %d for format %s.",
376 pCreateInfo->extent.width, pCreateInfo->extent.height, pCreateInfo->extent.depth,
377 ImageFormatProperties.maxExtent.width, ImageFormatProperties.maxExtent.height, ImageFormatProperties.maxExtent.depth,
378 string_VkFormat(pCreateInfo->format));
379
380 }
381
382 uint64_t totalSize = ((uint64_t)pCreateInfo->extent.width *
383 (uint64_t)pCreateInfo->extent.height *
384 (uint64_t)pCreateInfo->extent.depth *
385 (uint64_t)pCreateInfo->arrayLayers *
386 (uint64_t)pCreateInfo->samples *
387 (uint64_t)vk_format_get_size(pCreateInfo->format) +
388 (uint64_t)imageGranularity ) & ~(uint64_t)imageGranularity;
389
390 if (totalSize > ImageFormatProperties.maxResourceSize) {
Mark Lobodzinski37a38b12016-01-04 13:32:45 -0700391 skipCall |= log_msg(phy_dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, (uint64_t)pImage, __LINE__,
Mark Lobodzinskid5a23822015-11-12 15:14:35 -0700392 IMAGE_INVALID_FORMAT_LIMITS_VIOLATION, "Image",
393 "CreateImage resource size exceeds allowable maximum "
394 "Image resource size = %#" PRIxLEAST64 ", maximum resource size = %#" PRIxLEAST64 " ",
395 totalSize, ImageFormatProperties.maxResourceSize);
396 }
397
398 if (pCreateInfo->mipLevels > ImageFormatProperties.maxMipLevels) {
Mark Lobodzinski37a38b12016-01-04 13:32:45 -0700399 skipCall |= log_msg(phy_dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, (uint64_t)pImage, __LINE__,
Mark Lobodzinskid5a23822015-11-12 15:14:35 -0700400 IMAGE_INVALID_FORMAT_LIMITS_VIOLATION, "Image",
401 "CreateImage mipLevels=%d exceeds allowable maximum supported by format of %d",
402 pCreateInfo->mipLevels, ImageFormatProperties.maxMipLevels);
403 }
404
405 if (pCreateInfo->arrayLayers > ImageFormatProperties.maxArrayLayers) {
Mark Lobodzinski37a38b12016-01-04 13:32:45 -0700406 skipCall |= log_msg(phy_dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, (uint64_t)pImage, __LINE__,
Mark Lobodzinskid5a23822015-11-12 15:14:35 -0700407 IMAGE_INVALID_FORMAT_LIMITS_VIOLATION, "Image",
408 "CreateImage arrayLayers=%d exceeds allowable maximum supported by format of %d",
409 pCreateInfo->arrayLayers, ImageFormatProperties.maxArrayLayers);
410 }
411
412 if ((pCreateInfo->samples & ImageFormatProperties.sampleCounts) == 0) {
Mark Lobodzinski37a38b12016-01-04 13:32:45 -0700413 skipCall |= log_msg(phy_dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, (uint64_t)pImage, __LINE__,
Mark Lobodzinskid5a23822015-11-12 15:14:35 -0700414 IMAGE_INVALID_FORMAT_LIMITS_VIOLATION, "Image",
415 "CreateImage samples %s is not supported by format 0x%.8X",
416 string_VkSampleCountFlagBits(pCreateInfo->samples), ImageFormatProperties.sampleCounts);
417 }
418
419 if (VK_FALSE == skipCall) {
420 result = device_data->device_dispatch_table->CreateImage(device, pCreateInfo, pAllocator, pImage);
421 }
422 if (result == VK_SUCCESS) {
Chia-I Wue2fc5522015-10-26 20:04:44 +0800423 device_data->imageMap[*pImage] = IMAGE_STATE(pCreateInfo);
Tobin Ehlisad8c4462015-09-21 15:20:28 -0600424 }
Jeremy Hayes9cc31582015-06-18 10:12:39 -0600425 return result;
426}
427
Chia-I Wu9ab61502015-11-06 06:42:02 +0800428VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL vkDestroyImage(VkDevice device, VkImage image, const VkAllocationCallbacks* pAllocator)
Tobin Ehlisad8c4462015-09-21 15:20:28 -0600429{
430 layer_data *device_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
Chia-I Wue2fc5522015-10-26 20:04:44 +0800431 device_data->imageMap.erase(image);
Chia-I Wuf7458c52015-10-26 21:10:41 +0800432 device_data->device_dispatch_table->DestroyImage(device, image, pAllocator);
Tobin Ehlisad8c4462015-09-21 15:20:28 -0600433}
434
Chia-I Wu9ab61502015-11-06 06:42:02 +0800435VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateRenderPass(VkDevice device, const VkRenderPassCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkRenderPass* pRenderPass)
Jeremy Hayes9cc31582015-06-18 10:12:39 -0600436{
Tobin Ehlisb74f6ab2015-10-29 14:19:18 -0600437 layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
Tobin Ehlisdea00952015-09-22 08:40:52 -0600438 VkBool32 skipCall = VK_FALSE;
Chia-I Wu08accc62015-07-07 11:50:03 +0800439 for(uint32_t i = 0; i < pCreateInfo->attachmentCount; ++i)
Jeremy Hayes9cc31582015-06-18 10:12:39 -0600440 {
Chia-I Wu08accc62015-07-07 11:50:03 +0800441 if(pCreateInfo->pAttachments[i].format != VK_FORMAT_UNDEFINED)
Jeremy Hayes9cc31582015-06-18 10:12:39 -0600442 {
443 VkFormatProperties properties;
Tobin Ehlisb74f6ab2015-10-29 14:19:18 -0600444 get_my_data_ptr(get_dispatch_key(my_data->physicalDevice), layer_data_map)->instance_dispatch_table->GetPhysicalDeviceFormatProperties(
445 my_data->physicalDevice, pCreateInfo->pAttachments[i].format, &properties);
Jeremy Hayes9cc31582015-06-18 10:12:39 -0600446
447 if((properties.linearTilingFeatures) == 0 && (properties.optimalTilingFeatures == 0))
448 {
449 std::stringstream ss;
Chia-I Wu08accc62015-07-07 11:50:03 +0800450 ss << "vkCreateRenderPass parameter, VkFormat in pCreateInfo->pAttachments[" << i << "], contains unsupported format";
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -0700451 // TODO: Verify against Valid Use section of spec. Generally if something yield an undefined result, it's invalid
Mark Lobodzinski37a38b12016-01-04 13:32:45 -0700452 skipCall |= log_msg(my_data->report_data, VK_DEBUG_REPORT_WARN_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__, IMAGE_FORMAT_UNSUPPORTED, "IMAGE", "%s", ss.str().c_str());
Jeremy Hayes9cc31582015-06-18 10:12:39 -0600453 }
454 }
455 }
456
Chia-I Wu08accc62015-07-07 11:50:03 +0800457 for(uint32_t i = 0; i < pCreateInfo->attachmentCount; ++i)
Jeremy Hayes9cc31582015-06-18 10:12:39 -0600458 {
Mark Lobodzinski601ed152015-11-10 11:01:32 -0700459 if(!validate_VkImageLayoutKHR(pCreateInfo->pAttachments[i].initialLayout) ||
460 !validate_VkImageLayoutKHR(pCreateInfo->pAttachments[i].finalLayout))
Jeremy Hayes9cc31582015-06-18 10:12:39 -0600461 {
462 std::stringstream ss;
Chia-I Wu08accc62015-07-07 11:50:03 +0800463 ss << "vkCreateRenderPass parameter, VkImageLayout in pCreateInfo->pAttachments[" << i << "], is unrecognized";
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -0700464 // TODO: Verify against Valid Use section of spec. Generally if something yield an undefined result, it's invalid
Mark Lobodzinski37a38b12016-01-04 13:32:45 -0700465 skipCall |= log_msg(my_data->report_data, VK_DEBUG_REPORT_WARN_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__, IMAGE_RENDERPASS_INVALID_ATTACHMENT, "IMAGE", "%s", ss.str().c_str());
Jeremy Hayes9cc31582015-06-18 10:12:39 -0600466 }
467 }
468
Chia-I Wu08accc62015-07-07 11:50:03 +0800469 for(uint32_t i = 0; i < pCreateInfo->attachmentCount; ++i)
Jeremy Hayes9cc31582015-06-18 10:12:39 -0600470 {
Chia-I Wu08accc62015-07-07 11:50:03 +0800471 if(!validate_VkAttachmentLoadOp(pCreateInfo->pAttachments[i].loadOp))
Jeremy Hayes9cc31582015-06-18 10:12:39 -0600472 {
473 std::stringstream ss;
Chia-I Wu08accc62015-07-07 11:50:03 +0800474 ss << "vkCreateRenderPass parameter, VkAttachmentLoadOp in pCreateInfo->pAttachments[" << i << "], is unrecognized";
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -0700475 // TODO: Verify against Valid Use section of spec. Generally if something yield an undefined result, it's invalid
Mark Lobodzinski37a38b12016-01-04 13:32:45 -0700476 skipCall |= log_msg(my_data->report_data, VK_DEBUG_REPORT_WARN_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__, IMAGE_RENDERPASS_INVALID_ATTACHMENT, "IMAGE", "%s", ss.str().c_str());
Jeremy Hayes9cc31582015-06-18 10:12:39 -0600477 }
478 }
479
Chia-I Wu08accc62015-07-07 11:50:03 +0800480 for(uint32_t i = 0; i < pCreateInfo->attachmentCount; ++i)
Jeremy Hayes9cc31582015-06-18 10:12:39 -0600481 {
Chia-I Wu08accc62015-07-07 11:50:03 +0800482 if(!validate_VkAttachmentStoreOp(pCreateInfo->pAttachments[i].storeOp))
Jeremy Hayes9cc31582015-06-18 10:12:39 -0600483 {
484 std::stringstream ss;
Chia-I Wu08accc62015-07-07 11:50:03 +0800485 ss << "vkCreateRenderPass parameter, VkAttachmentStoreOp in pCreateInfo->pAttachments[" << i << "], is unrecognized";
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -0700486 // TODO: Verify against Valid Use section of spec. Generally if something yield an undefined result, it's invalid
Mark Lobodzinski37a38b12016-01-04 13:32:45 -0700487 skipCall |= log_msg(my_data->report_data, VK_DEBUG_REPORT_WARN_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__, IMAGE_RENDERPASS_INVALID_ATTACHMENT, "IMAGE", "%s", ss.str().c_str());
Jeremy Hayes9cc31582015-06-18 10:12:39 -0600488 }
489 }
490
Mark Lobodzinski2fd634c2015-07-29 09:21:22 -0600491 // Any depth buffers specified as attachments?
492 bool depthFormatPresent = VK_FALSE;
493 for (uint32_t i = 0; i < pCreateInfo->attachmentCount; ++i)
494 {
495 depthFormatPresent |= is_depth_format(pCreateInfo->pAttachments[i].format);
496 }
497
498 if (depthFormatPresent == VK_FALSE) {
499 // No depth attachment is present, validate that subpasses set depthStencilAttachment to VK_ATTACHMENT_UNUSED;
500 for (uint32_t i = 0; i < pCreateInfo->subpassCount; i++) {
Chia-I Wu1efb7e52015-10-26 17:32:47 +0800501 if (pCreateInfo->pSubpasses[i].pDepthStencilAttachment &&
502 pCreateInfo->pSubpasses[i].pDepthStencilAttachment->attachment != VK_ATTACHMENT_UNUSED) {
Mark Lobodzinski2fd634c2015-07-29 09:21:22 -0600503 std::stringstream ss;
504 ss << "vkCreateRenderPass has no depth/stencil attachment, yet subpass[" << i << "] has VkSubpassDescription::depthStencilAttachment value that is not VK_ATTACHMENT_UNUSED";
Mark Lobodzinski37a38b12016-01-04 13:32:45 -0700505 skipCall |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__, IMAGE_RENDERPASS_INVALID_DS_ATTACHMENT, "IMAGE", "%s", ss.str().c_str());
Mark Lobodzinski2fd634c2015-07-29 09:21:22 -0600506 }
507 }
508 }
Tobin Ehlisdea00952015-09-22 08:40:52 -0600509 if (skipCall)
Courtney Goeltzenleuchter52fee652015-12-10 16:41:22 -0700510 return VK_ERROR_VALIDATION_FAILED_EXT;
Mark Lobodzinski2fd634c2015-07-29 09:21:22 -0600511
Chia-I Wuf7458c52015-10-26 21:10:41 +0800512 VkResult result = my_data->device_dispatch_table->CreateRenderPass(device, pCreateInfo, pAllocator, pRenderPass);
Jeremy Hayes9cc31582015-06-18 10:12:39 -0600513
514 return result;
515}
516
Chia-I Wu9ab61502015-11-06 06:42:02 +0800517VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateImageView(VkDevice device, const VkImageViewCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkImageView* pView)
Tobin Ehlisad8c4462015-09-21 15:20:28 -0600518{
519 VkBool32 skipCall = VK_FALSE;
520 layer_data *device_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
Chia-I Wue2fc5522015-10-26 20:04:44 +0800521 auto imageEntry = device_data->imageMap.find(pCreateInfo->image);
Tobin Ehlisad8c4462015-09-21 15:20:28 -0600522 if (imageEntry != device_data->imageMap.end()) {
Tobin Ehlisd923d152015-09-25 14:49:43 -0600523 if (pCreateInfo->subresourceRange.baseMipLevel >= imageEntry->second.mipLevels) {
Tobin Ehlisad8c4462015-09-21 15:20:28 -0600524 std::stringstream ss;
Mark Lobodzinskidc86b852015-10-23 14:20:31 -0600525 ss << "vkCreateImageView called with baseMipLevel " << pCreateInfo->subresourceRange.baseMipLevel
Chia-I Wue2fc5522015-10-26 20:04:44 +0800526 << " for image " << pCreateInfo->image << " that only has " << imageEntry->second.mipLevels << " mip levels.";
Mark Lobodzinski37a38b12016-01-04 13:32:45 -0700527 skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__, IMAGE_VIEW_CREATE_ERROR, "IMAGE", "%s", ss.str().c_str());
Tobin Ehlisad8c4462015-09-21 15:20:28 -0600528 }
Tobin Ehlisd923d152015-09-25 14:49:43 -0600529 if (pCreateInfo->subresourceRange.baseArrayLayer >= imageEntry->second.arraySize) {
Tobin Ehlisad8c4462015-09-21 15:20:28 -0600530 std::stringstream ss;
Mark Lobodzinskidc86b852015-10-23 14:20:31 -0600531 ss << "vkCreateImageView called with baseArrayLayer " << pCreateInfo->subresourceRange.baseArrayLayer << " for image "
Chia-I Wue2fc5522015-10-26 20:04:44 +0800532 << pCreateInfo->image << " that only has " << imageEntry->second.arraySize << " mip levels.";
Mark Lobodzinski37a38b12016-01-04 13:32:45 -0700533 skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__, IMAGE_VIEW_CREATE_ERROR, "IMAGE", "%s", ss.str().c_str());
Tobin Ehlisad8c4462015-09-21 15:20:28 -0600534 }
Chia-I Wu3432a0c2015-10-27 18:04:07 +0800535 if (!pCreateInfo->subresourceRange.levelCount) {
Tobin Ehlisad8c4462015-09-21 15:20:28 -0600536 std::stringstream ss;
Jeremy Hayes5097da02015-11-17 18:24:56 -0700537 ss << "vkCreateImageView called with 0 in pCreateInfo->subresourceRange.levelCount.";
Mark Lobodzinski37a38b12016-01-04 13:32:45 -0700538 skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__, IMAGE_VIEW_CREATE_ERROR, "IMAGE", "%s", ss.str().c_str());
Tobin Ehlisad8c4462015-09-21 15:20:28 -0600539 }
Chia-I Wu3432a0c2015-10-27 18:04:07 +0800540 if (!pCreateInfo->subresourceRange.layerCount) {
Tobin Ehlisad8c4462015-09-21 15:20:28 -0600541 std::stringstream ss;
Jeremy Hayes5097da02015-11-17 18:24:56 -0700542 ss << "vkCreateImageView called with 0 in pCreateInfo->subresourceRange.layerCount.";
Mark Lobodzinski37a38b12016-01-04 13:32:45 -0700543 skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__, IMAGE_VIEW_CREATE_ERROR, "IMAGE", "%s", ss.str().c_str());
Tobin Ehlisad8c4462015-09-21 15:20:28 -0600544 }
Mark Lobodzinskia5eabe72015-10-05 17:16:05 -0600545
Mark Lobodzinski1e638c62016-01-11 16:50:30 -0700546 VkImageCreateFlags imageFlags = imageEntry->second.flags;
Tobin Ehlisd923d152015-09-25 14:49:43 -0600547 VkFormat imageFormat = imageEntry->second.format;
Mark Lobodzinskidc86b852015-10-23 14:20:31 -0600548 VkFormat ivciFormat = pCreateInfo->format;
549 VkImageAspectFlags aspectMask = pCreateInfo->subresourceRange.aspectMask;
550
Mark Lobodzinskiadaac9d2016-01-08 11:07:56 -0700551 // Validate VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT state
Mark Lobodzinski1e638c62016-01-11 16:50:30 -0700552 if (imageFlags & VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT) {
Mark Lobodzinskiadaac9d2016-01-08 11:07:56 -0700553 // Format MUST be compatible (in the same format compatibility class) as the format the image was created with
554 if (vk_format_get_compatibility_class(imageFormat) != vk_format_get_compatibility_class(ivciFormat)) {
555 std::stringstream ss;
556 ss << "vkCreateImageView(): ImageView format " << string_VkFormat(ivciFormat) << " is not in the same format compatibility class as image (" <<
557 (uint64_t)pCreateInfo->image << ") format " << string_VkFormat(imageFormat) << ". Images created with the VK_IMAGE_CREATE_MUTABLE_FORMAT BIT " <<
558 "can support ImageViews with differing formats but they must be in the same compatibility class.";
559 skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
560 IMAGE_VIEW_CREATE_ERROR, "IMAGE", "%s", ss.str().c_str());
561 }
562 } else {
563 // Format MUST be IDENTICAL to the format the image was created with
564 if (imageFormat != ivciFormat) {
565 std::stringstream ss;
566 ss << "vkCreateImageView() format " << string_VkFormat(ivciFormat) << " differs from image " << (uint64_t)pCreateInfo->image << " format " <<
567 string_VkFormat(imageFormat) << ". Formats MUST be IDENTICAL unless VK_IMAGE_CREATE_MUTABLE_FORMAT BIT was set on image creation.";
568 skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
569 IMAGE_VIEW_CREATE_ERROR, "IMAGE", "%s", ss.str().c_str());
570 }
571 }
572
573 // Validate correct image aspect bits for desired formats and format consistency
Mark Lobodzinskidc86b852015-10-23 14:20:31 -0600574 if (vk_format_is_color(imageFormat)) {
575 if ((aspectMask & VK_IMAGE_ASPECT_COLOR_BIT) != VK_IMAGE_ASPECT_COLOR_BIT) {
576 std::stringstream ss;
577 ss << "vkCreateImageView: Color image formats must have the VK_IMAGE_ASPECT_COLOR_BIT set";
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -0700578 skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT,
Mark Lobodzinski37a38b12016-01-04 13:32:45 -0700579 (uint64_t)pCreateInfo->image, __LINE__, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", "%s", ss.str().c_str());
Mark Lobodzinskidc86b852015-10-23 14:20:31 -0600580 }
581 if ((aspectMask & VK_IMAGE_ASPECT_COLOR_BIT) != aspectMask) {
582 std::stringstream ss;
583 ss << "vkCreateImageView: Color image formats must have ONLY the VK_IMAGE_ASPECT_COLOR_BIT set";
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -0700584 skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT,
Mark Lobodzinski37a38b12016-01-04 13:32:45 -0700585 (uint64_t)pCreateInfo->image, __LINE__, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", "%s", ss.str().c_str());
Mark Lobodzinskidc86b852015-10-23 14:20:31 -0600586 }
587 if (VK_FALSE == vk_format_is_color(ivciFormat)) {
588 std::stringstream ss;
589 ss << "vkCreateImageView: The image view's format can differ from the parent image's format, but both must be "
590 << "color formats. ImageFormat is " << string_VkFormat(imageFormat) << " ImageViewFormat is " << string_VkFormat(ivciFormat);
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -0700591 skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT,
Mark Lobodzinski37a38b12016-01-04 13:32:45 -0700592 (uint64_t)pCreateInfo->image, __LINE__, IMAGE_INVALID_FORMAT, "IMAGE", "%s", ss.str().c_str());
Mark Lobodzinskidc86b852015-10-23 14:20:31 -0600593 }
594 // TODO: Uncompressed formats are compatible if they occupy they same number of bits per pixel.
595 // Compressed formats are compatible if the only difference between them is the numerical type of
596 // the uncompressed pixels (e.g. signed vs. unsigned, or sRGB vs. UNORM encoding).
597 } else if (vk_format_is_depth_and_stencil(imageFormat)) {
Mark Lobodzinskid21bbff2015-11-23 09:07:20 -0700598 if ((aspectMask & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) == 0) {
Mark Lobodzinskidc86b852015-10-23 14:20:31 -0600599 std::stringstream ss;
Mark Lobodzinski26d58042015-11-18 09:14:04 -0700600 ss << "vkCreateImageView: Depth/stencil image formats must have at least one of VK_IMAGE_ASPECT_DEPTH_BIT and VK_IMAGE_ASPECT_STENCIL_BIT set";
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -0700601 skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT,
Mark Lobodzinski37a38b12016-01-04 13:32:45 -0700602 (uint64_t)pCreateInfo->image, __LINE__, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", "%s", ss.str().c_str());
Mark Lobodzinskidc86b852015-10-23 14:20:31 -0600603 }
604 if ((aspectMask & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) != aspectMask) {
605 std::stringstream ss;
606 ss << "vkCreateImageView: Combination depth/stencil image formats can have only the VK_IMAGE_ASPECT_DEPTH_BIT and VK_IMAGE_ASPECT_STENCIL_BIT set";
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -0700607 skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT,
Mark Lobodzinski37a38b12016-01-04 13:32:45 -0700608 (uint64_t)pCreateInfo->image, __LINE__, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", "%s", ss.str().c_str());
Mark Lobodzinskidc86b852015-10-23 14:20:31 -0600609 }
610 } else if (vk_format_is_depth_only(imageFormat)) {
611 if ((aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT) != VK_IMAGE_ASPECT_DEPTH_BIT) {
612 std::stringstream ss;
613 ss << "vkCreateImageView: Depth-only image formats must have the VK_IMAGE_ASPECT_DEPTH_BIT set";
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -0700614 skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT,
Mark Lobodzinski37a38b12016-01-04 13:32:45 -0700615 (uint64_t)pCreateInfo->image, __LINE__, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", "%s", ss.str().c_str());
Mark Lobodzinskidc86b852015-10-23 14:20:31 -0600616 }
617 if ((aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT) != aspectMask) {
618 std::stringstream ss;
619 ss << "vkCreateImageView: Depth-only image formats can have only the VK_IMAGE_ASPECT_DEPTH_BIT set";
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -0700620 skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT,
Mark Lobodzinski37a38b12016-01-04 13:32:45 -0700621 (uint64_t)pCreateInfo->image, __LINE__, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", "%s", ss.str().c_str());
Mark Lobodzinskidc86b852015-10-23 14:20:31 -0600622 }
623 } else if (vk_format_is_stencil_only(imageFormat)) {
624 if ((aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT) != VK_IMAGE_ASPECT_STENCIL_BIT) {
625 std::stringstream ss;
626 ss << "vkCreateImageView: Stencil-only image formats must have the VK_IMAGE_ASPECT_STENCIL_BIT set";
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -0700627 skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT,
Mark Lobodzinski37a38b12016-01-04 13:32:45 -0700628 (uint64_t)pCreateInfo->image, __LINE__, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", "%s", ss.str().c_str());
Mark Lobodzinskidc86b852015-10-23 14:20:31 -0600629 }
630 if ((aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT) != aspectMask) {
631 std::stringstream ss;
632 ss << "vkCreateImageView: Stencil-only image formats can have only the VK_IMAGE_ASPECT_STENCIL_BIT set";
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -0700633 skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT,
Mark Lobodzinski37a38b12016-01-04 13:32:45 -0700634 (uint64_t)pCreateInfo->image, __LINE__, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", "%s", ss.str().c_str());
Mark Lobodzinskidc86b852015-10-23 14:20:31 -0600635 }
636 }
637 }
Mark Lobodzinskia5eabe72015-10-05 17:16:05 -0600638
Mark Lobodzinskiadaac9d2016-01-08 11:07:56 -0700639 if (skipCall) {
Courtney Goeltzenleuchter52fee652015-12-10 16:41:22 -0700640 return VK_ERROR_VALIDATION_FAILED_EXT;
Mark Lobodzinskiadaac9d2016-01-08 11:07:56 -0700641 }
Tobin Ehlisdea00952015-09-22 08:40:52 -0600642
Chia-I Wuf7458c52015-10-26 21:10:41 +0800643 VkResult result = device_data->device_dispatch_table->CreateImageView(device, pCreateInfo, pAllocator, pView);
Tobin Ehlisad8c4462015-09-21 15:20:28 -0600644 return result;
645}
646
Chia-I Wu9ab61502015-11-06 06:42:02 +0800647VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdClearColorImage(
Chia-I Wu3432a0c2015-10-27 18:04:07 +0800648 VkCommandBuffer commandBuffer,
Mark Lobodzinskia5eabe72015-10-05 17:16:05 -0600649 VkImage image,
650 VkImageLayout imageLayout,
651 const VkClearColorValue *pColor,
652 uint32_t rangeCount,
653 const VkImageSubresourceRange *pRanges)
654{
655 VkBool32 skipCall = VK_FALSE;
Chia-I Wu3432a0c2015-10-27 18:04:07 +0800656 layer_data *device_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
Mark Lobodzinskia5eabe72015-10-05 17:16:05 -0600657 // For each range, image aspect must be color only
658 for (uint32_t i = 0; i < rangeCount; i++) {
659 if (pRanges[i].aspectMask != VK_IMAGE_ASPECT_COLOR_BIT) {
Mark Lobodzinskia5eabe72015-10-05 17:16:05 -0600660 char const str[] = "vkCmdClearColorImage aspectMasks for all subresource ranges must be set to VK_IMAGE_ASPECT_COLOR_BIT";
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -0700661 skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
Mark Lobodzinski37a38b12016-01-04 13:32:45 -0700662 (uint64_t)commandBuffer, __LINE__, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", str);
Mark Lobodzinskia5eabe72015-10-05 17:16:05 -0600663 }
664 }
665
666 if (VK_FALSE == skipCall) {
Chia-I Wu3432a0c2015-10-27 18:04:07 +0800667 device_data->device_dispatch_table->CmdClearColorImage(commandBuffer, image, imageLayout,
668 pColor, rangeCount, pRanges);
Mark Lobodzinskia5eabe72015-10-05 17:16:05 -0600669 }
670}
671
Chia-I Wu9ab61502015-11-06 06:42:02 +0800672VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdClearDepthStencilImage(
Chia-I Wu3432a0c2015-10-27 18:04:07 +0800673 VkCommandBuffer commandBuffer,
Mark Lobodzinskia5eabe72015-10-05 17:16:05 -0600674 VkImage image,
675 VkImageLayout imageLayout,
676 const VkClearDepthStencilValue *pDepthStencil,
677 uint32_t rangeCount,
678 const VkImageSubresourceRange *pRanges)
679{
680 VkBool32 skipCall = VK_FALSE;
Chia-I Wu3432a0c2015-10-27 18:04:07 +0800681 layer_data *device_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
Mark Lobodzinskia5eabe72015-10-05 17:16:05 -0600682 // For each range, Image aspect must be depth or stencil or both
683 for (uint32_t i = 0; i < rangeCount; i++) {
684 if (((pRanges[i].aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT) != VK_IMAGE_ASPECT_DEPTH_BIT) &&
685 ((pRanges[i].aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT) != VK_IMAGE_ASPECT_STENCIL_BIT))
686 {
Mark Lobodzinskia5eabe72015-10-05 17:16:05 -0600687 char const str[] = "vkCmdClearDepthStencilImage aspectMasks for all subresource ranges must be "
688 "set to VK_IMAGE_ASPECT_DEPTH_BIT and/or VK_IMAGE_ASPECT_STENCIL_BIT";
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -0700689 skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
Mark Lobodzinski37a38b12016-01-04 13:32:45 -0700690 (uint64_t)commandBuffer, __LINE__, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", str);
Mark Lobodzinskia5eabe72015-10-05 17:16:05 -0600691 }
692 }
693
694 if (VK_FALSE == skipCall) {
Chia-I Wu3432a0c2015-10-27 18:04:07 +0800695 device_data->device_dispatch_table->CmdClearDepthStencilImage(commandBuffer,
Mark Lobodzinskia5eabe72015-10-05 17:16:05 -0600696 image, imageLayout, pDepthStencil, rangeCount, pRanges);
697 }
698}
699
Chia-I Wu9ab61502015-11-06 06:42:02 +0800700VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdCopyImage(
Chia-I Wu3432a0c2015-10-27 18:04:07 +0800701 VkCommandBuffer commandBuffer,
Mark Lobodzinskia5eabe72015-10-05 17:16:05 -0600702 VkImage srcImage,
703 VkImageLayout srcImageLayout,
Chia-I Wu3432a0c2015-10-27 18:04:07 +0800704 VkImage dstImage,
705 VkImageLayout dstImageLayout,
Mark Lobodzinskia5eabe72015-10-05 17:16:05 -0600706 uint32_t regionCount,
707 const VkImageCopy *pRegions)
708{
709 VkBool32 skipCall = VK_FALSE;
Chia-I Wu3432a0c2015-10-27 18:04:07 +0800710 layer_data *device_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
Chia-I Wue2fc5522015-10-26 20:04:44 +0800711 auto srcImageEntry = device_data->imageMap.find(srcImage);
Chia-I Wu3432a0c2015-10-27 18:04:07 +0800712 auto dstImageEntry = device_data->imageMap.find(dstImage);
Mark Lobodzinskia5eabe72015-10-05 17:16:05 -0600713
Jeremy Hayes148bab22015-10-28 13:01:39 -0600714 // For each region, src and dst number of layers should not be zero
715 // For each region, src and dst number of layers must match
Mark Lobodzinskia5eabe72015-10-05 17:16:05 -0600716 // For each region, src aspect mask must match dest aspect mask
717 // For each region, color aspects cannot be mixed with depth/stencil aspects
718 for (uint32_t i = 0; i < regionCount; i++) {
Chia-I Wu3432a0c2015-10-27 18:04:07 +0800719 if(pRegions[i].srcSubresource.layerCount == 0)
Jeremy Hayes148bab22015-10-28 13:01:39 -0600720 {
721 char const str[] = "vkCmdCopyImage: number of layers in source subresource is zero";
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -0700722 // TODO: Verify against Valid Use section of spec
723 skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_WARN_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
Mark Lobodzinski37a38b12016-01-04 13:32:45 -0700724 (uint64_t)commandBuffer, __LINE__, IMAGE_MISMATCHED_IMAGE_ASPECT, "IMAGE", str);
Jeremy Hayes148bab22015-10-28 13:01:39 -0600725 }
726
Chia-I Wu3432a0c2015-10-27 18:04:07 +0800727 if(pRegions[i].dstSubresource.layerCount == 0)
Jeremy Hayes148bab22015-10-28 13:01:39 -0600728 {
729 char const str[] = "vkCmdCopyImage: number of layers in destination subresource is zero";
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -0700730 // TODO: Verify against Valid Use section of spec
731 skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_WARN_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
Mark Lobodzinski37a38b12016-01-04 13:32:45 -0700732 (uint64_t)commandBuffer, __LINE__, IMAGE_MISMATCHED_IMAGE_ASPECT, "IMAGE", str);
Jeremy Hayes148bab22015-10-28 13:01:39 -0600733 }
734
Chia-I Wu3432a0c2015-10-27 18:04:07 +0800735 if(pRegions[i].srcSubresource.layerCount != pRegions[i].dstSubresource.layerCount)
Jeremy Hayes148bab22015-10-28 13:01:39 -0600736 {
737 char const str[] = "vkCmdCopyImage: number of layers in source and destination subresources must match";
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -0700738 skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
Mark Lobodzinski37a38b12016-01-04 13:32:45 -0700739 (uint64_t)commandBuffer, __LINE__, IMAGE_MISMATCHED_IMAGE_ASPECT, "IMAGE", str);
Jeremy Hayes148bab22015-10-28 13:01:39 -0600740 }
741
Chia-I Wuab83a0e2015-10-27 19:00:15 +0800742 if (pRegions[i].srcSubresource.aspectMask != pRegions[i].dstSubresource.aspectMask) {
Mark Lobodzinskia5eabe72015-10-05 17:16:05 -0600743 char const str[] = "vkCmdCopyImage: Src and dest aspectMasks for each region must match";
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -0700744 skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
Mark Lobodzinski37a38b12016-01-04 13:32:45 -0700745 (uint64_t)commandBuffer, __LINE__, IMAGE_MISMATCHED_IMAGE_ASPECT, "IMAGE", str);
Mark Lobodzinskia5eabe72015-10-05 17:16:05 -0600746 }
Chia-I Wuab83a0e2015-10-27 19:00:15 +0800747 if ((pRegions[i].srcSubresource.aspectMask & VK_IMAGE_ASPECT_COLOR_BIT) &&
748 (pRegions[i].srcSubresource.aspectMask & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT))) {
Mark Lobodzinskia5eabe72015-10-05 17:16:05 -0600749 char const str[] = "vkCmdCopyImage aspectMask cannot specify both COLOR and DEPTH/STENCIL aspects";
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -0700750 skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
Mark Lobodzinski37a38b12016-01-04 13:32:45 -0700751 (uint64_t)commandBuffer, __LINE__, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", str);
Mark Lobodzinskia5eabe72015-10-05 17:16:05 -0600752 }
753 }
754
Mike Stroyana3082432015-09-25 13:39:21 -0600755 if ((srcImageEntry != device_data->imageMap.end())
Chia-I Wu3432a0c2015-10-27 18:04:07 +0800756 && (dstImageEntry != device_data->imageMap.end())) {
757 if (srcImageEntry->second.imageType != dstImageEntry->second.imageType) {
Mike Stroyana3082432015-09-25 13:39:21 -0600758 char const str[] = "vkCmdCopyImage called with unmatched source and dest image types.";
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -0700759 skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
Mark Lobodzinski37a38b12016-01-04 13:32:45 -0700760 (uint64_t)commandBuffer, __LINE__, IMAGE_MISMATCHED_IMAGE_TYPE, "IMAGE", str);
Mike Stroyana3082432015-09-25 13:39:21 -0600761 }
762 // Check that format is same size or exact stencil/depth
Tobin Ehlisd923d152015-09-25 14:49:43 -0600763 if (is_depth_format(srcImageEntry->second.format)) {
Chia-I Wu3432a0c2015-10-27 18:04:07 +0800764 if (srcImageEntry->second.format != dstImageEntry->second.format) {
Mike Stroyana3082432015-09-25 13:39:21 -0600765 char const str[] = "vkCmdCopyImage called with unmatched source and dest image depth/stencil formats.";
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -0700766 skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
Mark Lobodzinski37a38b12016-01-04 13:32:45 -0700767 (uint64_t)commandBuffer, __LINE__, IMAGE_MISMATCHED_IMAGE_FORMAT, "IMAGE", str);
Mike Stroyana3082432015-09-25 13:39:21 -0600768 }
769 } else {
Tobin Ehlisd923d152015-09-25 14:49:43 -0600770 size_t srcSize = vk_format_get_size(srcImageEntry->second.format);
Chia-I Wu3432a0c2015-10-27 18:04:07 +0800771 size_t destSize = vk_format_get_size(dstImageEntry->second.format);
Mike Stroyana3082432015-09-25 13:39:21 -0600772 if (srcSize != destSize) {
773 char const str[] = "vkCmdCopyImage called with unmatched source and dest image format sizes.";
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -0700774 skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
Mark Lobodzinski37a38b12016-01-04 13:32:45 -0700775 (uint64_t)commandBuffer, __LINE__, IMAGE_MISMATCHED_IMAGE_FORMAT, "IMAGE", str);
Mike Stroyana3082432015-09-25 13:39:21 -0600776 }
777 }
778 }
779
Mark Lobodzinskia5eabe72015-10-05 17:16:05 -0600780 if (VK_FALSE == skipCall) {
Chia-I Wu3432a0c2015-10-27 18:04:07 +0800781 device_data->device_dispatch_table->CmdCopyImage(commandBuffer, srcImage,
782 srcImageLayout, dstImage, dstImageLayout, regionCount, pRegions);
Mark Lobodzinskia5eabe72015-10-05 17:16:05 -0600783 }
784}
785
Chia-I Wu9ab61502015-11-06 06:42:02 +0800786VKAPI_ATTR void VKAPI_CALL vkCmdClearAttachments(
Chia-I Wu3432a0c2015-10-27 18:04:07 +0800787 VkCommandBuffer commandBuffer,
Courtney Goeltzenleuchterc9323e02015-10-15 16:51:05 -0600788 uint32_t attachmentCount,
789 const VkClearAttachment* pAttachments,
790 uint32_t rectCount,
Courtney Goeltzenleuchter4ca43f62015-10-15 18:22:08 -0600791 const VkClearRect* pRects)
Courtney Goeltzenleuchterc9323e02015-10-15 16:51:05 -0600792{
793 VkBool32 skipCall = VK_FALSE;
794 VkImageAspectFlags aspectMask;
Chia-I Wu3432a0c2015-10-27 18:04:07 +0800795 layer_data *device_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
Courtney Goeltzenleuchterc9323e02015-10-15 16:51:05 -0600796 for (uint32_t i = 0; i < attachmentCount; i++) {
797 aspectMask = pAttachments[i].aspectMask;
798 if (aspectMask & VK_IMAGE_ASPECT_COLOR_BIT) {
799 if (aspectMask != VK_IMAGE_ASPECT_COLOR_BIT) {
800 // VK_IMAGE_ASPECT_COLOR_BIT is not the only bit set for this attachment
Courtney Goeltzenleuchterc9323e02015-10-15 16:51:05 -0600801 char const str[] = "vkCmdClearAttachments aspectMask [%d] must set only VK_IMAGE_ASPECT_COLOR_BIT of a color attachment.";
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -0700802 skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
Mark Lobodzinski37a38b12016-01-04 13:32:45 -0700803 (uint64_t)commandBuffer, __LINE__, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", str, i);
Courtney Goeltzenleuchterc9323e02015-10-15 16:51:05 -0600804 }
805 } else {
806 // Image aspect must be depth or stencil or both
807 if (((aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT) != VK_IMAGE_ASPECT_DEPTH_BIT) &&
808 ((aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT) != VK_IMAGE_ASPECT_STENCIL_BIT))
809 {
Courtney Goeltzenleuchterc9323e02015-10-15 16:51:05 -0600810 char const str[] = "vkCmdClearAttachments aspectMask [%d] must be set to VK_IMAGE_ASPECT_DEPTH_BIT and/or VK_IMAGE_ASPECT_STENCIL_BIT";
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -0700811 skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
Mark Lobodzinski37a38b12016-01-04 13:32:45 -0700812 (uint64_t)commandBuffer, __LINE__, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", str, i);
Courtney Goeltzenleuchterc9323e02015-10-15 16:51:05 -0600813 }
814 }
815 }
816
817 if (VK_FALSE == skipCall) {
Chia-I Wu3432a0c2015-10-27 18:04:07 +0800818 device_data->device_dispatch_table->CmdClearAttachments(commandBuffer,
Courtney Goeltzenleuchterc9323e02015-10-15 16:51:05 -0600819 attachmentCount, pAttachments, rectCount, pRects);
820 }
821}
822
Chia-I Wu9ab61502015-11-06 06:42:02 +0800823VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdCopyImageToBuffer(
Chia-I Wu3432a0c2015-10-27 18:04:07 +0800824 VkCommandBuffer commandBuffer,
Mark Lobodzinskia5eabe72015-10-05 17:16:05 -0600825 VkImage srcImage,
826 VkImageLayout srcImageLayout,
Chia-I Wu3432a0c2015-10-27 18:04:07 +0800827 VkBuffer dstBuffer,
Mark Lobodzinskia5eabe72015-10-05 17:16:05 -0600828 uint32_t regionCount,
829 const VkBufferImageCopy *pRegions)
830{
831 VkBool32 skipCall = VK_FALSE;
Chia-I Wu3432a0c2015-10-27 18:04:07 +0800832 layer_data *device_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
Jeremy Hayes148bab22015-10-28 13:01:39 -0600833 // For each region, the number of layers in the image subresource should not be zero
Mark Lobodzinskia5eabe72015-10-05 17:16:05 -0600834 // Image aspect must be ONE OF color, depth, stencil
835 for (uint32_t i = 0; i < regionCount; i++) {
Chia-I Wu3432a0c2015-10-27 18:04:07 +0800836 if(pRegions[i].imageSubresource.layerCount == 0)
Jeremy Hayes148bab22015-10-28 13:01:39 -0600837 {
Jeremy Hayes148bab22015-10-28 13:01:39 -0600838 char const str[] = "vkCmdCopyImageToBuffer: number of layers in image subresource is zero";
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -0700839 // TODO: Verify against Valid Use section of spec, if this case yields undefined results, then it's an error
840 skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_WARN_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
Mark Lobodzinski37a38b12016-01-04 13:32:45 -0700841 (uint64_t)commandBuffer, __LINE__, IMAGE_MISMATCHED_IMAGE_ASPECT, "IMAGE", str);
Jeremy Hayes148bab22015-10-28 13:01:39 -0600842 }
843
Chia-I Wuab83a0e2015-10-27 19:00:15 +0800844 VkImageAspectFlags aspectMask = pRegions[i].imageSubresource.aspectMask;
845 if ((aspectMask != VK_IMAGE_ASPECT_COLOR_BIT) &&
846 (aspectMask != VK_IMAGE_ASPECT_DEPTH_BIT) &&
847 (aspectMask != VK_IMAGE_ASPECT_STENCIL_BIT)) {
Mark Lobodzinskia5eabe72015-10-05 17:16:05 -0600848 char const str[] = "vkCmdCopyImageToBuffer: aspectMasks for each region must specify only COLOR or DEPTH or STENCIL";
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -0700849 skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
Mark Lobodzinski37a38b12016-01-04 13:32:45 -0700850 (uint64_t)commandBuffer, __LINE__, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", str);
Mark Lobodzinskia5eabe72015-10-05 17:16:05 -0600851 }
852 }
853
854 if (VK_FALSE == skipCall) {
Chia-I Wu3432a0c2015-10-27 18:04:07 +0800855 device_data->device_dispatch_table->CmdCopyImageToBuffer(commandBuffer,
856 srcImage, srcImageLayout, dstBuffer, regionCount, pRegions);
Mark Lobodzinskia5eabe72015-10-05 17:16:05 -0600857 }
858}
859
Chia-I Wu9ab61502015-11-06 06:42:02 +0800860VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdCopyBufferToImage(
Chia-I Wu3432a0c2015-10-27 18:04:07 +0800861 VkCommandBuffer commandBuffer,
Mark Lobodzinskia5eabe72015-10-05 17:16:05 -0600862 VkBuffer srcBuffer,
Chia-I Wu3432a0c2015-10-27 18:04:07 +0800863 VkImage dstImage,
864 VkImageLayout dstImageLayout,
Mark Lobodzinskia5eabe72015-10-05 17:16:05 -0600865 uint32_t regionCount,
866 const VkBufferImageCopy *pRegions)
867{
868 VkBool32 skipCall = VK_FALSE;
Chia-I Wu3432a0c2015-10-27 18:04:07 +0800869 layer_data *device_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
Jeremy Hayes148bab22015-10-28 13:01:39 -0600870 // For each region, the number of layers in the image subresource should not be zero
Mark Lobodzinskia5eabe72015-10-05 17:16:05 -0600871 // Image aspect must be ONE OF color, depth, stencil
872 for (uint32_t i = 0; i < regionCount; i++) {
Chia-I Wu3432a0c2015-10-27 18:04:07 +0800873 if(pRegions[i].imageSubresource.layerCount == 0)
Jeremy Hayes148bab22015-10-28 13:01:39 -0600874 {
Jeremy Hayes148bab22015-10-28 13:01:39 -0600875 char const str[] = "vkCmdCopyBufferToImage: number of layers in image subresource is zero";
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -0700876 // TODO: Verify against Valid Use section of spec, if this case yields undefined results, then it's an error
877 skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_WARN_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
Mark Lobodzinski37a38b12016-01-04 13:32:45 -0700878 (uint64_t)commandBuffer, __LINE__, IMAGE_MISMATCHED_IMAGE_ASPECT, "IMAGE", str);
Jeremy Hayes148bab22015-10-28 13:01:39 -0600879 }
880
Chia-I Wuab83a0e2015-10-27 19:00:15 +0800881 VkImageAspectFlags aspectMask = pRegions[i].imageSubresource.aspectMask;
882 if ((aspectMask != VK_IMAGE_ASPECT_COLOR_BIT) &&
883 (aspectMask != VK_IMAGE_ASPECT_DEPTH_BIT) &&
884 (aspectMask != VK_IMAGE_ASPECT_STENCIL_BIT)) {
Mark Lobodzinskia5eabe72015-10-05 17:16:05 -0600885 char const str[] = "vkCmdCopyBufferToImage: aspectMasks for each region must specify only COLOR or DEPTH or STENCIL";
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -0700886 skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
Mark Lobodzinski37a38b12016-01-04 13:32:45 -0700887 (uint64_t)commandBuffer, __LINE__, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", str);
Mark Lobodzinskia5eabe72015-10-05 17:16:05 -0600888 }
889 }
890
891 if (VK_FALSE == skipCall) {
Chia-I Wu3432a0c2015-10-27 18:04:07 +0800892 device_data->device_dispatch_table->CmdCopyBufferToImage(commandBuffer,
893 srcBuffer, dstImage, dstImageLayout, regionCount, pRegions);
Mark Lobodzinskia5eabe72015-10-05 17:16:05 -0600894 }
895}
896
Chia-I Wu9ab61502015-11-06 06:42:02 +0800897VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdBlitImage(
Chia-I Wu3432a0c2015-10-27 18:04:07 +0800898 VkCommandBuffer commandBuffer,
Mark Lobodzinskia5eabe72015-10-05 17:16:05 -0600899 VkImage srcImage,
900 VkImageLayout srcImageLayout,
Chia-I Wu3432a0c2015-10-27 18:04:07 +0800901 VkImage dstImage,
902 VkImageLayout dstImageLayout,
Mark Lobodzinskia5eabe72015-10-05 17:16:05 -0600903 uint32_t regionCount,
904 const VkImageBlit *pRegions,
Chia-I Wub99df442015-10-26 16:49:32 +0800905 VkFilter filter)
Mark Lobodzinskia5eabe72015-10-05 17:16:05 -0600906{
Mark Lobodzinskidc86b852015-10-23 14:20:31 -0600907 VkBool32 skipCall = VK_FALSE;
Chia-I Wu3432a0c2015-10-27 18:04:07 +0800908 layer_data *device_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
Mark Lobodzinskidc86b852015-10-23 14:20:31 -0600909
Chia-I Wue2fc5522015-10-26 20:04:44 +0800910 auto srcImageEntry = device_data->imageMap.find(srcImage);
Chia-I Wu3432a0c2015-10-27 18:04:07 +0800911 auto dstImageEntry = device_data->imageMap.find(dstImage);
Mark Lobodzinskidc86b852015-10-23 14:20:31 -0600912
913 if ((srcImageEntry != device_data->imageMap.end()) &&
Chia-I Wu3432a0c2015-10-27 18:04:07 +0800914 (dstImageEntry != device_data->imageMap.end())) {
Mark Lobodzinskidc86b852015-10-23 14:20:31 -0600915
Tobin Ehlisd923d152015-09-25 14:49:43 -0600916 VkFormat srcFormat = srcImageEntry->second.format;
Chia-I Wu3432a0c2015-10-27 18:04:07 +0800917 VkFormat dstFormat = dstImageEntry->second.format;
Mark Lobodzinskidc86b852015-10-23 14:20:31 -0600918
919 // Validate consistency for signed and unsigned formats
920 if ((vk_format_is_sint(srcFormat) && !vk_format_is_sint(dstFormat)) ||
921 (vk_format_is_uint(srcFormat) && !vk_format_is_uint(dstFormat))) {
922 std::stringstream ss;
Chia-I Wu3432a0c2015-10-27 18:04:07 +0800923 ss << "vkCmdBlitImage: If one of srcImage and dstImage images has signed/unsigned integer format, "
Mark Lobodzinskidc86b852015-10-23 14:20:31 -0600924 << "the other one must also have signed/unsigned integer format. "
Mark Lobodzinski2e8ccbb2015-12-31 09:49:50 -0700925 << "Source format is " << string_VkFormat(srcFormat) << " Destination format is " << string_VkFormat(dstFormat);
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -0700926 skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
Mark Lobodzinski37a38b12016-01-04 13:32:45 -0700927 (uint64_t)commandBuffer, __LINE__, IMAGE_INVALID_FORMAT, "IMAGE", "%s", ss.str().c_str());
Mark Lobodzinskidc86b852015-10-23 14:20:31 -0600928 }
929
930 // Validate aspect bits and formats for depth/stencil images
931 if (vk_format_is_depth_or_stencil(srcFormat) ||
932 vk_format_is_depth_or_stencil(dstFormat)) {
933 if (srcFormat != dstFormat) {
934 std::stringstream ss;
Chia-I Wu3432a0c2015-10-27 18:04:07 +0800935 ss << "vkCmdBlitImage: If one of srcImage and dstImage images has a format of depth, stencil or depth "
Mark Lobodzinskidc86b852015-10-23 14:20:31 -0600936 << "stencil, the other one must have exactly the same format. "
Mark Lobodzinski2e8ccbb2015-12-31 09:49:50 -0700937 << "Source format is " << string_VkFormat(srcFormat) << " Destination format is " << string_VkFormat(dstFormat);
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -0700938 skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
Mark Lobodzinski37a38b12016-01-04 13:32:45 -0700939 (uint64_t)commandBuffer, __LINE__, IMAGE_INVALID_FORMAT, "IMAGE", "%s", ss.str().c_str());
Mark Lobodzinskidc86b852015-10-23 14:20:31 -0600940 }
941
942 for (uint32_t i = 0; i < regionCount; i++) {
Chia-I Wu3432a0c2015-10-27 18:04:07 +0800943 if(pRegions[i].srcSubresource.layerCount == 0)
Jeremy Hayes148bab22015-10-28 13:01:39 -0600944 {
945 char const str[] = "vkCmdBlitImage: number of layers in source subresource is zero";
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -0700946 // TODO: Verify against Valid Use section of spec, if this case yields undefined results, then it's an error
947 skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_WARN_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
Mark Lobodzinski37a38b12016-01-04 13:32:45 -0700948 (uint64_t)commandBuffer, __LINE__, IMAGE_MISMATCHED_IMAGE_ASPECT, "IMAGE", str);
Jeremy Hayes148bab22015-10-28 13:01:39 -0600949 }
950
Chia-I Wu3432a0c2015-10-27 18:04:07 +0800951 if(pRegions[i].dstSubresource.layerCount == 0)
Jeremy Hayes148bab22015-10-28 13:01:39 -0600952 {
953 char const str[] = "vkCmdBlitImage: number of layers in destination subresource is zero";
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -0700954 // TODO: Verify against Valid Use section of spec, if this case yields undefined results, then it's an error
955 skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_WARN_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
Mark Lobodzinski37a38b12016-01-04 13:32:45 -0700956 (uint64_t)commandBuffer, __LINE__, IMAGE_MISMATCHED_IMAGE_ASPECT, "IMAGE", str);
Jeremy Hayes148bab22015-10-28 13:01:39 -0600957 }
958
Chia-I Wu3432a0c2015-10-27 18:04:07 +0800959 if(pRegions[i].srcSubresource.layerCount != pRegions[i].dstSubresource.layerCount)
Jeremy Hayes148bab22015-10-28 13:01:39 -0600960 {
961 char const str[] = "vkCmdBlitImage: number of layers in source and destination subresources must match";
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -0700962 skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
Mark Lobodzinski37a38b12016-01-04 13:32:45 -0700963 (uint64_t)commandBuffer, __LINE__, IMAGE_MISMATCHED_IMAGE_ASPECT, "IMAGE", str);
Jeremy Hayes148bab22015-10-28 13:01:39 -0600964 }
965
Chia-I Wuab83a0e2015-10-27 19:00:15 +0800966 VkImageAspectFlags srcAspect = pRegions[i].srcSubresource.aspectMask;
967 VkImageAspectFlags dstAspect = pRegions[i].dstSubresource.aspectMask;
Mark Lobodzinskidc86b852015-10-23 14:20:31 -0600968
969 if (srcAspect != dstAspect) {
970 std::stringstream ss;
971 ss << "vkCmdBlitImage: Image aspects of depth/stencil images should match";
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -0700972 // TODO: Verify against Valid Use section of spec, if this case yields undefined results, then it's an error
973 skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_WARN_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
Mark Lobodzinski37a38b12016-01-04 13:32:45 -0700974 (uint64_t)commandBuffer, __LINE__, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", "%s", ss.str().c_str());
Mark Lobodzinskidc86b852015-10-23 14:20:31 -0600975 }
976 if (vk_format_is_depth_and_stencil(srcFormat)) {
Mark Lobodzinskib0166852016-01-12 13:18:44 -0700977 if ((srcAspect != VK_IMAGE_ASPECT_DEPTH_BIT) && (srcAspect != VK_IMAGE_ASPECT_STENCIL_BIT)) {
Mark Lobodzinskidc86b852015-10-23 14:20:31 -0600978 std::stringstream ss;
Mark Lobodzinskib0166852016-01-12 13:18:44 -0700979 ss << "vkCmdBlitImage: Combination depth/stencil image formats must have only one of VK_IMAGE_ASPECT_DEPTH_BIT "
980 << "and VK_IMAGE_ASPECT_STENCIL_BIT set in srcImage and dstImage";
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -0700981 skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
Mark Lobodzinski37a38b12016-01-04 13:32:45 -0700982 (uint64_t)commandBuffer, __LINE__, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", "%s", ss.str().c_str());
Mark Lobodzinskidc86b852015-10-23 14:20:31 -0600983 }
984 } else if (vk_format_is_stencil_only(srcFormat)) {
985 if (srcAspect != VK_IMAGE_ASPECT_STENCIL_BIT) {
986 std::stringstream ss;
987 ss << "vkCmdBlitImage: Stencil-only image formats must have only the VK_IMAGE_ASPECT_STENCIL_BIT "
Chia-I Wu3432a0c2015-10-27 18:04:07 +0800988 << "set in both the srcImage and dstImage";
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -0700989 skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
Mark Lobodzinski37a38b12016-01-04 13:32:45 -0700990 (uint64_t)commandBuffer, __LINE__, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", "%s", ss.str().c_str());
Mark Lobodzinskidc86b852015-10-23 14:20:31 -0600991 }
992 } else if (vk_format_is_depth_only(srcFormat)) {
993 if (srcAspect != VK_IMAGE_ASPECT_DEPTH_BIT) {
994 std::stringstream ss;
995 ss << "vkCmdBlitImage: Depth-only image formats must have only the VK_IMAGE_ASPECT_DEPTH "
Chia-I Wu3432a0c2015-10-27 18:04:07 +0800996 << "set in both the srcImage and dstImage";
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -0700997 skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
Mark Lobodzinski37a38b12016-01-04 13:32:45 -0700998 (uint64_t)commandBuffer, __LINE__, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", "%s", ss.str().c_str());
Mark Lobodzinskidc86b852015-10-23 14:20:31 -0600999 }
1000 }
1001 }
1002 }
1003
1004 // Validate filter
1005 if (vk_format_is_depth_or_stencil(srcFormat) ||
1006 vk_format_is_int(srcFormat)) {
Chia-I Wub99df442015-10-26 16:49:32 +08001007 if (filter != VK_FILTER_NEAREST) {
Mark Lobodzinskidc86b852015-10-23 14:20:31 -06001008 std::stringstream ss;
1009 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 +08001010 << "then filter must be VK_FILTER_NEAREST.";
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -07001011 skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
Mark Lobodzinski37a38b12016-01-04 13:32:45 -07001012 (uint64_t)commandBuffer, __LINE__, IMAGE_INVALID_FILTER, "IMAGE", "%s", ss.str().c_str());
Mark Lobodzinskidc86b852015-10-23 14:20:31 -06001013 }
1014 }
1015 }
Mark Lobodzinskia5eabe72015-10-05 17:16:05 -06001016
Chia-I Wu3432a0c2015-10-27 18:04:07 +08001017 device_data->device_dispatch_table->CmdBlitImage(commandBuffer, srcImage,
1018 srcImageLayout, dstImage, dstImageLayout, regionCount, pRegions, filter);
Mark Lobodzinskia5eabe72015-10-05 17:16:05 -06001019}
1020
Jeremy Hayes01b38892015-11-17 18:19:55 -07001021VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdPipelineBarrier(
1022 VkCommandBuffer commandBuffer,
1023 VkPipelineStageFlags srcStageMask,
1024 VkPipelineStageFlags dstStageMask,
1025 VkDependencyFlags dependencyFlags,
1026 uint32_t memoryBarrierCount,
Jon Ashburnf19916e2016-01-11 13:12:43 -07001027 const VkMemoryBarrier *pMemoryBarriers,
1028 uint32_t bufferMemoryBarrierCount,
1029 const VkBufferMemoryBarrier *pBufferMemoryBarriers,
1030 uint32_t imageMemoryBarrierCount,
1031 const VkImageMemoryBarrier *pImageMemoryBarriers)
Jeremy Hayes01b38892015-11-17 18:19:55 -07001032{
1033 VkBool32 skipCall = VK_FALSE;
1034 layer_data *device_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
1035
Jon Ashburnf19916e2016-01-11 13:12:43 -07001036 for (uint32_t i = 0; i < imageMemoryBarrierCount; ++i)
Jeremy Hayes01b38892015-11-17 18:19:55 -07001037 {
Jon Ashburnf19916e2016-01-11 13:12:43 -07001038 VkImageMemoryBarrier const*const barrier = (VkImageMemoryBarrier const*const) &pImageMemoryBarriers[i];
Jeremy Hayes01b38892015-11-17 18:19:55 -07001039 if (barrier->sType == VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER)
1040 {
1041 if (barrier->subresourceRange.layerCount == 0)
1042 {
1043 std::stringstream ss;
1044 ss << "vkCmdPipelineBarrier called with 0 in ppMemoryBarriers[" << i << "]->subresourceRange.layerCount.";
Mark Lobodzinski37a38b12016-01-04 13:32:45 -07001045 skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0,
1046 0, __LINE__, IMAGE_INVALID_IMAGE_RESOURCE, "IMAGE", "%s", ss.str().c_str());
Jeremy Hayes01b38892015-11-17 18:19:55 -07001047 }
1048 }
1049 }
1050
1051 if (skipCall)
1052 {
1053 return;
1054 }
1055
1056 device_data->device_dispatch_table->CmdPipelineBarrier(commandBuffer, srcStageMask, dstStageMask, dependencyFlags,
Jon Ashburnf19916e2016-01-11 13:12:43 -07001057 memoryBarrierCount, pMemoryBarriers,
1058 bufferMemoryBarrierCount, pBufferMemoryBarriers,
1059 imageMemoryBarrierCount, pImageMemoryBarriers);
Jeremy Hayes01b38892015-11-17 18:19:55 -07001060}
1061
Chia-I Wu9ab61502015-11-06 06:42:02 +08001062VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdResolveImage(
Chia-I Wu3432a0c2015-10-27 18:04:07 +08001063 VkCommandBuffer commandBuffer,
Mark Lobodzinskia5eabe72015-10-05 17:16:05 -06001064 VkImage srcImage,
1065 VkImageLayout srcImageLayout,
Chia-I Wu3432a0c2015-10-27 18:04:07 +08001066 VkImage dstImage,
1067 VkImageLayout dstImageLayout,
Mark Lobodzinskia5eabe72015-10-05 17:16:05 -06001068 uint32_t regionCount,
1069 const VkImageResolve *pRegions)
1070{
1071 VkBool32 skipCall = VK_FALSE;
Chia-I Wu3432a0c2015-10-27 18:04:07 +08001072 layer_data *device_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
Chia-I Wue2fc5522015-10-26 20:04:44 +08001073 auto srcImageEntry = device_data->imageMap.find(srcImage);
Chia-I Wu3432a0c2015-10-27 18:04:07 +08001074 auto dstImageEntry = device_data->imageMap.find(dstImage);
Mark Lobodzinskia5eabe72015-10-05 17:16:05 -06001075
Jeremy Hayes148bab22015-10-28 13:01:39 -06001076 // For each region, the number of layers in the image subresource should not be zero
Mark Lobodzinskia5eabe72015-10-05 17:16:05 -06001077 // For each region, src and dest image aspect must be color only
1078 for (uint32_t i = 0; i < regionCount; i++) {
Chia-I Wu3432a0c2015-10-27 18:04:07 +08001079 if(pRegions[i].srcSubresource.layerCount == 0)
Jeremy Hayes148bab22015-10-28 13:01:39 -06001080 {
1081 char const str[] = "vkCmdResolveImage: number of layers in source subresource is zero";
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -07001082 // TODO: Verify against Valid Use section of spec. Generally if something yield an undefined result, it's invalid/error
1083 skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_WARN_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
Mark Lobodzinski37a38b12016-01-04 13:32:45 -07001084 (uint64_t)commandBuffer, __LINE__, IMAGE_MISMATCHED_IMAGE_ASPECT, "IMAGE", str);
Jeremy Hayes148bab22015-10-28 13:01:39 -06001085 }
1086
Chia-I Wu3432a0c2015-10-27 18:04:07 +08001087 if(pRegions[i].dstSubresource.layerCount == 0)
Jeremy Hayes148bab22015-10-28 13:01:39 -06001088 {
1089 char const str[] = "vkCmdResolveImage: number of layers in destination subresource is zero";
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -07001090
1091 // TODO: Verify against Valid Use section of spec. Generally if something yield an undefined result, it's invalid/error
1092 skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_WARN_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
Mark Lobodzinski37a38b12016-01-04 13:32:45 -07001093 (uint64_t)commandBuffer, __LINE__, IMAGE_MISMATCHED_IMAGE_ASPECT, "IMAGE", str);
Jeremy Hayes148bab22015-10-28 13:01:39 -06001094 }
1095
Chia-I Wuab83a0e2015-10-27 19:00:15 +08001096 if ((pRegions[i].srcSubresource.aspectMask != VK_IMAGE_ASPECT_COLOR_BIT) ||
1097 (pRegions[i].dstSubresource.aspectMask != VK_IMAGE_ASPECT_COLOR_BIT)) {
Mark Lobodzinskia5eabe72015-10-05 17:16:05 -06001098 char const str[] = "vkCmdResolveImage: src and dest aspectMasks for each region must specify only VK_IMAGE_ASPECT_COLOR_BIT";
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -07001099 skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
Mark Lobodzinski37a38b12016-01-04 13:32:45 -07001100 (uint64_t)commandBuffer, __LINE__, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", str);
Mark Lobodzinskia5eabe72015-10-05 17:16:05 -06001101 }
1102 }
1103
Mark Lobodzinskidc86b852015-10-23 14:20:31 -06001104 if ((srcImageEntry != device_data->imageMap.end()) &&
Chia-I Wu3432a0c2015-10-27 18:04:07 +08001105 (dstImageEntry != device_data->imageMap.end())) {
1106 if (srcImageEntry->second.format != dstImageEntry->second.format) {
Mike Stroyana3082432015-09-25 13:39:21 -06001107 char const str[] = "vkCmdResolveImage called with unmatched source and dest formats.";
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -07001108 skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
Mark Lobodzinski37a38b12016-01-04 13:32:45 -07001109 (uint64_t)commandBuffer, __LINE__, IMAGE_MISMATCHED_IMAGE_FORMAT, "IMAGE", str);
Mike Stroyana3082432015-09-25 13:39:21 -06001110 }
Chia-I Wu3432a0c2015-10-27 18:04:07 +08001111 if (srcImageEntry->second.imageType != dstImageEntry->second.imageType) {
Mike Stroyana3082432015-09-25 13:39:21 -06001112 char const str[] = "vkCmdResolveImage called with unmatched source and dest image types.";
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -07001113 skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
Mark Lobodzinski37a38b12016-01-04 13:32:45 -07001114 (uint64_t)commandBuffer, __LINE__, IMAGE_MISMATCHED_IMAGE_TYPE, "IMAGE", str);
Mike Stroyana3082432015-09-25 13:39:21 -06001115 }
Chia-I Wu5c17c962015-10-31 00:31:16 +08001116 if (srcImageEntry->second.samples == VK_SAMPLE_COUNT_1_BIT) {
Mike Stroyana3082432015-09-25 13:39:21 -06001117 char const str[] = "vkCmdResolveImage called with source sample count less than 2.";
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -07001118 skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
Mark Lobodzinski37a38b12016-01-04 13:32:45 -07001119 (uint64_t)commandBuffer, __LINE__, IMAGE_INVALID_RESOLVE_SAMPLES, "IMAGE", str);
Mike Stroyana3082432015-09-25 13:39:21 -06001120 }
Chia-I Wu5c17c962015-10-31 00:31:16 +08001121 if (dstImageEntry->second.samples != VK_SAMPLE_COUNT_1_BIT) {
Mike Stroyana3082432015-09-25 13:39:21 -06001122 char const str[] = "vkCmdResolveImage called with dest sample count greater than 1.";
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -07001123 skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
Mark Lobodzinski37a38b12016-01-04 13:32:45 -07001124 (uint64_t)commandBuffer, __LINE__, IMAGE_INVALID_RESOLVE_SAMPLES, "IMAGE", str);
Mike Stroyana3082432015-09-25 13:39:21 -06001125 }
1126 }
1127
Mark Lobodzinskia5eabe72015-10-05 17:16:05 -06001128 if (VK_FALSE == skipCall) {
Chia-I Wu3432a0c2015-10-27 18:04:07 +08001129 device_data->device_dispatch_table->CmdResolveImage(commandBuffer, srcImage,
1130 srcImageLayout, dstImage, dstImageLayout, regionCount, pRegions);
Mark Lobodzinskia5eabe72015-10-05 17:16:05 -06001131 }
1132}
1133
Chia-I Wu9ab61502015-11-06 06:42:02 +08001134VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL vkGetImageSubresourceLayout(
Mark Lobodzinskia5eabe72015-10-05 17:16:05 -06001135 VkDevice device,
1136 VkImage image,
1137 const VkImageSubresource *pSubresource,
1138 VkSubresourceLayout *pLayout)
1139{
Mark Lobodzinskidc86b852015-10-23 14:20:31 -06001140 VkBool32 skipCall = VK_FALSE;
1141 layer_data *device_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
1142 VkFormat format;
Mark Lobodzinskia5eabe72015-10-05 17:16:05 -06001143
Chia-I Wue2fc5522015-10-26 20:04:44 +08001144 auto imageEntry = device_data->imageMap.find(image);
Mark Lobodzinskidc86b852015-10-23 14:20:31 -06001145
1146 // Validate that image aspects match formats
1147 if (imageEntry != device_data->imageMap.end()) {
Tobin Ehlisd923d152015-09-25 14:49:43 -06001148 format = imageEntry->second.format;
Mark Lobodzinskidc86b852015-10-23 14:20:31 -06001149 if (vk_format_is_color(format)) {
Chia-I Wu52b07e72015-10-27 19:55:05 +08001150 if (pSubresource->aspectMask != VK_IMAGE_ASPECT_COLOR_BIT) {
Mark Lobodzinskidc86b852015-10-23 14:20:31 -06001151 std::stringstream ss;
Chia-I Wu52b07e72015-10-27 19:55:05 +08001152 ss << "vkGetImageSubresourceLayout: For color formats, the aspectMask field of VkImageSubresource must be VK_IMAGE_ASPECT_COLOR.";
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -07001153 skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT,
Mark Lobodzinski37a38b12016-01-04 13:32:45 -07001154 (uint64_t)image, __LINE__, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", "%s", ss.str().c_str());
Mark Lobodzinskidc86b852015-10-23 14:20:31 -06001155 }
1156 } else if (vk_format_is_depth_or_stencil(format)) {
Chia-I Wu52b07e72015-10-27 19:55:05 +08001157 if ((pSubresource->aspectMask != VK_IMAGE_ASPECT_DEPTH_BIT) &&
1158 (pSubresource->aspectMask != VK_IMAGE_ASPECT_STENCIL_BIT)) {
Mark Lobodzinskidc86b852015-10-23 14:20:31 -06001159 std::stringstream ss;
Chia-I Wu52b07e72015-10-27 19:55:05 +08001160 ss << "vkGetImageSubresourceLayout: For depth/stencil formats, the aspectMask selects either the depth or stencil image aspectMask.";
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -07001161 skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT,
Mark Lobodzinski37a38b12016-01-04 13:32:45 -07001162 (uint64_t)image, __LINE__, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", "%s", ss.str().c_str());
Mark Lobodzinskidc86b852015-10-23 14:20:31 -06001163 }
1164 }
1165 }
1166
1167 if (VK_FALSE == skipCall) {
Tobin Ehlisb74f6ab2015-10-29 14:19:18 -06001168 device_data->device_dispatch_table->GetImageSubresourceLayout(device,
Mark Lobodzinskidc86b852015-10-23 14:20:31 -06001169 image, pSubresource, pLayout);
1170 }
Mark Lobodzinskia5eabe72015-10-05 17:16:05 -06001171}
1172
Mark Lobodzinskid5a23822015-11-12 15:14:35 -07001173VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceProperties(VkPhysicalDevice physicalDevice, VkPhysicalDeviceProperties* pProperties)
1174{
1175 layer_data *phy_dev_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);
1176 phy_dev_data->instance_dispatch_table->GetPhysicalDeviceProperties(physicalDevice, pProperties);
1177}
1178
Chia-I Wu9ab61502015-11-06 06:42:02 +08001179VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetDeviceProcAddr(VkDevice device, const char* funcName)
Jeremy Hayes9cc31582015-06-18 10:12:39 -06001180{
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -07001181 if (!strcmp(funcName, "vkGetDeviceProcAddr"))
Courtney Goeltzenleuchter2d3ba632015-07-12 14:35:22 -06001182 return (PFN_vkVoidFunction) vkGetDeviceProcAddr;
Jeremy Hayes9cc31582015-06-18 10:12:39 -06001183 if (!strcmp(funcName, "vkDestroyDevice"))
Courtney Goeltzenleuchter2d3ba632015-07-12 14:35:22 -06001184 return (PFN_vkVoidFunction) vkDestroyDevice;
Jeremy Hayes9cc31582015-06-18 10:12:39 -06001185 if (!strcmp(funcName, "vkCreateImage"))
Courtney Goeltzenleuchter2d3ba632015-07-12 14:35:22 -06001186 return (PFN_vkVoidFunction) vkCreateImage;
Mark Lobodzinski46fc3dd2015-10-29 12:58:33 -06001187 if (!strcmp(funcName, "vkDestroyImage"))
1188 return (PFN_vkVoidFunction) vkDestroyImage;
Tobin Ehliscde08892015-09-22 10:11:37 -06001189 if (!strcmp(funcName, "vkCreateImageView"))
1190 return (PFN_vkVoidFunction) vkCreateImageView;
Jeremy Hayes9cc31582015-06-18 10:12:39 -06001191 if (!strcmp(funcName, "vkCreateRenderPass"))
Courtney Goeltzenleuchter2d3ba632015-07-12 14:35:22 -06001192 return (PFN_vkVoidFunction) vkCreateRenderPass;
Mark Lobodzinskia5eabe72015-10-05 17:16:05 -06001193 if (!strcmp(funcName, "vkCmdClearColorImage"))
1194 return (PFN_vkVoidFunction) vkCmdClearColorImage;
1195 if (!strcmp(funcName, "vkCmdClearDepthStencilImage"))
1196 return (PFN_vkVoidFunction) vkCmdClearDepthStencilImage;
Courtney Goeltzenleuchterc9323e02015-10-15 16:51:05 -06001197 if (!strcmp(funcName, "vkCmdClearAttachments"))
1198 return (PFN_vkVoidFunction) vkCmdClearAttachments;
Mark Lobodzinskia5eabe72015-10-05 17:16:05 -06001199 if (!strcmp(funcName, "vkCmdCopyImage"))
1200 return (PFN_vkVoidFunction) vkCmdCopyImage;
1201 if (!strcmp(funcName, "vkCmdCopyImageToBuffer"))
1202 return (PFN_vkVoidFunction) vkCmdCopyImageToBuffer;
1203 if (!strcmp(funcName, "vkCmdCopyBufferToImage"))
1204 return (PFN_vkVoidFunction) vkCmdCopyBufferToImage;
1205 if (!strcmp(funcName, "vkCmdBlitImage"))
1206 return (PFN_vkVoidFunction) vkCmdBlitImage;
Jeremy Hayes01b38892015-11-17 18:19:55 -07001207 if (!strcmp(funcName, "vkCmdPipelineBarrier"))
1208 return (PFN_vkVoidFunction) vkCmdPipelineBarrier;
Mark Lobodzinskia5eabe72015-10-05 17:16:05 -06001209 if (!strcmp(funcName, "vkCmdResolveImage"))
1210 return (PFN_vkVoidFunction) vkCmdResolveImage;
1211 if (!strcmp(funcName, "vkGetImageSubresourceLayout"))
1212 return (PFN_vkVoidFunction) vkGetImageSubresourceLayout;
Tobin Ehlisb74f6ab2015-10-29 14:19:18 -06001213
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -07001214 if (device == NULL) {
1215 return NULL;
1216 }
1217
1218 layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
1219
Tobin Ehlisb74f6ab2015-10-29 14:19:18 -06001220 VkLayerDispatchTable* pTable = my_data->device_dispatch_table;
Jeremy Hayes9cc31582015-06-18 10:12:39 -06001221 {
Tobin Ehlisb74f6ab2015-10-29 14:19:18 -06001222 if (pTable->GetDeviceProcAddr == NULL)
Jeremy Hayes9cc31582015-06-18 10:12:39 -06001223 return NULL;
Tobin Ehlisb74f6ab2015-10-29 14:19:18 -06001224 return pTable->GetDeviceProcAddr(device, funcName);
Jeremy Hayes9cc31582015-06-18 10:12:39 -06001225 }
1226}
1227
Chia-I Wu9ab61502015-11-06 06:42:02 +08001228VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetInstanceProcAddr(VkInstance instance, const char* funcName)
Jeremy Hayes9cc31582015-06-18 10:12:39 -06001229{
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -07001230 if (!strcmp(funcName, "vkGetInstanceProcAddr"))
Courtney Goeltzenleuchter2d3ba632015-07-12 14:35:22 -06001231 return (PFN_vkVoidFunction) vkGetInstanceProcAddr;
Jeremy Hayes9cc31582015-06-18 10:12:39 -06001232 if (!strcmp(funcName, "vkCreateInstance"))
Courtney Goeltzenleuchter2d3ba632015-07-12 14:35:22 -06001233 return (PFN_vkVoidFunction) vkCreateInstance;
Jeremy Hayes9cc31582015-06-18 10:12:39 -06001234 if (!strcmp(funcName, "vkDestroyInstance"))
Courtney Goeltzenleuchter2d3ba632015-07-12 14:35:22 -06001235 return (PFN_vkVoidFunction) vkDestroyInstance;
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -07001236 if (!strcmp(funcName, "vkCreateDevice"))
1237 return (PFN_vkVoidFunction) vkCreateDevice;
Courtney Goeltzenleuchter35985f62015-09-14 17:22:16 -06001238 if (!strcmp(funcName, "vkEnumerateInstanceLayerProperties"))
1239 return (PFN_vkVoidFunction) vkEnumerateInstanceLayerProperties;
1240 if (!strcmp(funcName, "vkEnumerateInstanceExtensionProperties"))
1241 return (PFN_vkVoidFunction) vkEnumerateInstanceExtensionProperties;
1242 if (!strcmp(funcName, "vkEnumerateDeviceLayerProperties"))
1243 return (PFN_vkVoidFunction) vkEnumerateDeviceLayerProperties;
1244 if (!strcmp(funcName, "vkEnumerateDeviceExtensionProperties"))
1245 return (PFN_vkVoidFunction) vkEnumerateDeviceExtensionProperties;
Mark Lobodzinskid5a23822015-11-12 15:14:35 -07001246 if (!strcmp(funcName, "vkGetPhysicalDeviceProperties"))
1247 return (PFN_vkVoidFunction) vkGetPhysicalDeviceProperties;
Jeremy Hayes9cc31582015-06-18 10:12:39 -06001248
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -07001249 if (instance == NULL) {
1250 return NULL;
1251 }
1252
1253 layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
1254
Tobin Ehlisb74f6ab2015-10-29 14:19:18 -06001255 PFN_vkVoidFunction fptr = debug_report_get_instance_proc_addr(my_data->report_data, funcName);
Jeremy Hayes9cc31582015-06-18 10:12:39 -06001256 if(fptr)
1257 return fptr;
1258
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -07001259 VkLayerInstanceDispatchTable* pTable = my_data->instance_dispatch_table;
1260 if (pTable->GetInstanceProcAddr == NULL)
1261 return NULL;
1262 return pTable->GetInstanceProcAddr(instance, funcName);
Jeremy Hayes9cc31582015-06-18 10:12:39 -06001263}