blob: 0e75dfcac9e97020f82ecb20bf92b4f39b248e94 [file] [log] [blame]
Jeremy Hayesb707aa52015-06-18 10:12:39 -06001/*
2 * Vulkan
3 *
4 * Copyright (C) 2014 LunarG, Inc.
5 *
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.
23 */
24
Courtney Goeltzenleuchter6ff93732015-10-07 08:38:30 -060025#include <inttypes.h>
Jeremy Hayesb707aa52015-06-18 10:12:39 -060026#include <stdio.h>
27#include <stdlib.h>
28#include <string.h>
Courtney Goeltzenleuchter6ff93732015-10-07 08:38:30 -060029#include <assert.h>
30#include <vector>
Jeremy Hayesb707aa52015-06-18 10:12:39 -060031#include <unordered_map>
Tobin Ehlis65380532015-09-21 15:20:28 -060032#include <memory>
Courtney Goeltzenleuchter6ff93732015-10-07 08:38:30 -060033using namespace std;
Jeremy Hayesb707aa52015-06-18 10:12:39 -060034
Tobin Ehlis7a51d902015-07-03 10:34:49 -060035#include "vk_loader_platform.h"
Courtney Goeltzenleuchter6ff93732015-10-07 08:38:30 -060036#include "vk_dispatch_table_helper.h"
37#include "vk_struct_string_helper_cpp.h"
Jeremy Hayesb707aa52015-06-18 10:12:39 -060038#include "vk_enum_validate_helper.h"
Courtney Goeltzenleuchter6ff93732015-10-07 08:38:30 -060039#include "image.h"
40#include "vk_layer_config.h"
41#include "vk_layer_extension_utils.h"
Tobin Ehlis56d204a2015-07-03 10:15:26 -060042#include "vk_layer_table.h"
43#include "vk_layer_data.h"
Courtney Goeltzenleuchtereb1ddb02015-07-07 11:18:30 -060044#include "vk_layer_extension_utils.h"
Mike Stroyan43909d82015-09-25 13:39:21 -060045#include "vk_layer_utils.h"
Courtney Goeltzenleuchter6ff93732015-10-07 08:38:30 -060046#include "vk_layer_logging.h"
Jeremy Hayesb707aa52015-06-18 10:12:39 -060047
Tobin Ehlis65380532015-09-21 15:20:28 -060048using namespace std;
49
Cody Northrop73bb6572015-09-28 15:09:32 -060050struct layer_data {
Jeremy Hayesb707aa52015-06-18 10:12:39 -060051 debug_report_data *report_data;
Courtney Goeltzenleuchter9fac1572015-10-05 15:59:11 -060052 std::vector<VkDbgMsgCallback> logging_callback;
Chris Forbesd7576302015-06-21 22:55:02 +120053 VkPhysicalDevice physicalDevice;
Tobin Ehlis6fa437d2015-09-25 14:49:43 -060054 unordered_map<uint64_t, IMAGE_STATE> imageMap;
Cody Northrop73bb6572015-09-28 15:09:32 -060055
56 layer_data() :
57 report_data(nullptr),
Cody Northrop73bb6572015-09-28 15:09:32 -060058 physicalDevice(0)
59 {};
60};
Jeremy Hayesb707aa52015-06-18 10:12:39 -060061
Tobin Ehlis65380532015-09-21 15:20:28 -060062static unordered_map<void*, layer_data*> layer_data_map;
Mark Lobodzinskib4092de2015-10-23 14:20:31 -060063static device_table_map image_device_table_map;
Jeremy Hayesb707aa52015-06-18 10:12:39 -060064static instance_table_map image_instance_table_map;
65
66// "my device data"
Tony Barbour2a199c12015-07-09 17:31:46 -060067debug_report_data *mdd(const void* object)
Jeremy Hayesb707aa52015-06-18 10:12:39 -060068{
69 dispatch_key key = get_dispatch_key(object);
70 layer_data *data = get_my_data_ptr(key, layer_data_map);
71#if DISPATCH_MAP_DEBUG
72 fprintf(stderr, "MDD: map: %p, object: %p, key: %p, data: %p\n", &layer_data_map, object, key, data);
73#endif
Jeremy Hayesb707aa52015-06-18 10:12:39 -060074 return data->report_data;
75}
76
77// "my instance data"
78debug_report_data *mid(VkInstance object)
79{
80 dispatch_key key = get_dispatch_key(object);
Courtney Goeltzenleuchter07199212015-06-22 16:19:14 -060081 layer_data *data = get_my_data_ptr(key, layer_data_map);
Jeremy Hayesb707aa52015-06-18 10:12:39 -060082#if DISPATCH_MAP_DEBUG
83 fprintf(stderr, "MID: map: %p, object: %p, key: %p, data: %p\n", &layer_data_map, object, key, data);
84#endif
Jeremy Hayesb707aa52015-06-18 10:12:39 -060085 return data->report_data;
86}
87
88static void InitImage(layer_data *data)
89{
Courtney Goeltzenleuchter9fac1572015-10-05 15:59:11 -060090 VkDbgMsgCallback callback;
Jeremy Hayesb707aa52015-06-18 10:12:39 -060091 uint32_t report_flags = getLayerOptionFlags("ImageReportFlags", 0);
92
93 uint32_t debug_action = 0;
94 getLayerOptionEnum("ImageDebugAction", (uint32_t *) &debug_action);
95 if(debug_action & VK_DBG_LAYER_ACTION_LOG_MSG)
96 {
97 FILE *log_output = NULL;
98 const char* option_str = getLayerOption("ImageLogFilename");
Tobin Ehlisb4b6e7c2015-09-15 09:55:54 -060099 log_output = getLayerLogOutput(option_str, "Image");
Courtney Goeltzenleuchter9fac1572015-10-05 15:59:11 -0600100 layer_create_msg_callback(data->report_data, report_flags, log_callback, (void *) log_output, &callback);
101 data->logging_callback.push_back(callback);
102 }
103
104 if (debug_action & VK_DBG_LAYER_ACTION_DEBUG_OUTPUT) {
105 layer_create_msg_callback(data->report_data, report_flags, win32_debug_output_msg, NULL, &callback);
106 data->logging_callback.push_back(callback);
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600107 }
108}
109
110VK_LAYER_EXPORT VkResult VKAPI vkDbgCreateMsgCallback(
111 VkInstance instance,
112 VkFlags msgFlags,
113 const PFN_vkDbgMsgCallback pfnMsgCallback,
114 void* pUserData,
115 VkDbgMsgCallback* pMsgCallback)
116{
117 VkLayerInstanceDispatchTable *pTable = get_dispatch_table(image_instance_table_map, instance);
118 VkResult res = pTable->DbgCreateMsgCallback(instance, msgFlags, pfnMsgCallback, pUserData, pMsgCallback);
119 if (res == VK_SUCCESS) {
120 layer_data *data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
121
122 res = layer_create_msg_callback(data->report_data, msgFlags, pfnMsgCallback, pUserData, pMsgCallback);
123 }
124 return res;
125}
126
127VK_LAYER_EXPORT VkResult VKAPI vkDbgDestroyMsgCallback(
128 VkInstance instance,
129 VkDbgMsgCallback msgCallback)
130{
131 VkLayerInstanceDispatchTable *pTable = get_dispatch_table(image_instance_table_map, instance);
132 VkResult res = pTable->DbgDestroyMsgCallback(instance, msgCallback);
133
134 layer_data *data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
135 layer_destroy_msg_callback(data->report_data, msgCallback);
136
137 return res;
138}
139
140VK_LAYER_EXPORT VkResult VKAPI vkCreateInstance(const VkInstanceCreateInfo* pCreateInfo, VkInstance* pInstance)
141{
142 VkLayerInstanceDispatchTable *pTable = get_dispatch_table(image_instance_table_map, *pInstance);
143 VkResult result = pTable->CreateInstance(pCreateInfo, pInstance);
144
145 if (result == VK_SUCCESS) {
146 layer_data *data = get_my_data_ptr(get_dispatch_key(*pInstance), layer_data_map);
147 data->report_data = debug_report_create_instance(pTable, *pInstance, pCreateInfo->extensionCount,
Courtney Goeltzenleuchtereb1ddb02015-07-07 11:18:30 -0600148 pCreateInfo->ppEnabledExtensionNames);
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600149
150 InitImage(data);
151 }
152
153 return result;
154}
155
Mark Lobodzinski67b42b72015-09-07 13:59:43 -0600156VK_LAYER_EXPORT void VKAPI vkDestroyInstance(VkInstance instance)
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600157{
158 // Grab the key before the instance is destroyed.
159 dispatch_key key = get_dispatch_key(instance);
160 VkLayerInstanceDispatchTable *pTable = get_dispatch_table(image_instance_table_map, instance);
Mark Lobodzinski67b42b72015-09-07 13:59:43 -0600161 pTable->DestroyInstance(instance);
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600162
163 // Clean up logging callback, if any
Courtney Goeltzenleuchter9fac1572015-10-05 15:59:11 -0600164 layer_data *my_data = get_my_data_ptr(key, layer_data_map);
165 while (my_data->logging_callback.size() > 0) {
166 VkDbgMsgCallback callback = my_data->logging_callback.back();
167 layer_destroy_msg_callback(my_data->report_data, callback);
168 my_data->logging_callback.pop_back();
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600169 }
170
171 layer_debug_report_destroy_instance(mid(instance));
172 layer_data_map.erase(pTable);
173
174 image_instance_table_map.erase(key);
175 assert(image_instance_table_map.size() == 0 && "Should not have any instance mappings hanging around");
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600176}
177
178VK_LAYER_EXPORT VkResult VKAPI vkCreateDevice(VkPhysicalDevice physicalDevice, const VkDeviceCreateInfo* pCreateInfo, VkDevice* pDevice)
179{
Courtney Goeltzenleuchterbe637992015-06-25 18:01:43 -0600180 VkLayerDispatchTable *pTable = get_dispatch_table(image_device_table_map, *pDevice);
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600181 VkResult result = pTable->CreateDevice(physicalDevice, pCreateInfo, pDevice);
182 if(result == VK_SUCCESS)
183 {
184 layer_data *instance_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);
185 layer_data *device_data = get_my_data_ptr(get_dispatch_key(*pDevice), layer_data_map);
186 device_data->report_data = layer_debug_report_create_device(instance_data->report_data, *pDevice);
Chris Forbesd7576302015-06-21 22:55:02 +1200187 device_data->physicalDevice = physicalDevice;
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600188 }
189
190 return result;
191}
192
Mark Lobodzinski67b42b72015-09-07 13:59:43 -0600193VK_LAYER_EXPORT void VKAPI vkDestroyDevice(VkDevice device)
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600194{
195 layer_debug_report_destroy_device(device);
196
197 dispatch_key key = get_dispatch_key(device);
198#if DISPATCH_MAP_DEBUG
199 fprintf(stderr, "Device: %p, key: %p\n", device, key);
200#endif
201
Mark Lobodzinski67b42b72015-09-07 13:59:43 -0600202 get_dispatch_table(image_device_table_map, device)->DestroyDevice(device);
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600203 image_device_table_map.erase(key);
204 assert(image_device_table_map.size() == 0 && "Should not have any instance mappings hanging around");
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600205}
206
Courtney Goeltzenleuchtereb1ddb02015-07-07 11:18:30 -0600207static const VkLayerProperties pc_global_layers[] = {
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600208 {
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600209 "Image",
Courtney Goeltzenleuchtereb1ddb02015-07-07 11:18:30 -0600210 VK_API_VERSION,
211 VK_MAKE_VERSION(0, 1, 0),
212 "Validation layer: Image ParamChecker",
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600213 }
214};
215
Courtney Goeltzenleuchter74c4ce92015-09-14 17:22:16 -0600216VK_LAYER_EXPORT VkResult VKAPI vkEnumerateInstanceExtensionProperties(
Courtney Goeltzenleuchtereb1ddb02015-07-07 11:18:30 -0600217 const char *pLayerName,
218 uint32_t *pCount,
219 VkExtensionProperties* pProperties)
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600220{
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600221 // ParamChecker does not have any global extensions
Courtney Goeltzenleuchtereb1ddb02015-07-07 11:18:30 -0600222 return util_GetExtensionProperties(0, NULL, pCount, pProperties);
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600223}
224
Courtney Goeltzenleuchter74c4ce92015-09-14 17:22:16 -0600225VK_LAYER_EXPORT VkResult VKAPI vkEnumerateInstanceLayerProperties(
Courtney Goeltzenleuchtereb1ddb02015-07-07 11:18:30 -0600226 uint32_t *pCount,
227 VkLayerProperties* pProperties)
Tony Barbour426b9052015-06-24 16:06:58 -0600228{
Courtney Goeltzenleuchtereb1ddb02015-07-07 11:18:30 -0600229 return util_GetLayerProperties(ARRAY_SIZE(pc_global_layers),
230 pc_global_layers,
231 pCount, pProperties);
Tony Barbour426b9052015-06-24 16:06:58 -0600232}
233
Courtney Goeltzenleuchter74c4ce92015-09-14 17:22:16 -0600234VK_LAYER_EXPORT VkResult VKAPI vkEnumerateDeviceExtensionProperties(
Courtney Goeltzenleuchtereb1ddb02015-07-07 11:18:30 -0600235 VkPhysicalDevice physicalDevice,
236 const char* pLayerName,
237 uint32_t* pCount,
238 VkExtensionProperties* pProperties)
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600239{
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600240 // ParamChecker does not have any physical device extensions
Courtney Goeltzenleuchtereb1ddb02015-07-07 11:18:30 -0600241 return util_GetExtensionProperties(0, NULL, pCount, pProperties);
242}
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600243
Courtney Goeltzenleuchter74c4ce92015-09-14 17:22:16 -0600244VK_LAYER_EXPORT VkResult VKAPI vkEnumerateDeviceLayerProperties(
Courtney Goeltzenleuchtereb1ddb02015-07-07 11:18:30 -0600245 VkPhysicalDevice physicalDevice,
246 uint32_t* pCount,
247 VkLayerProperties* pProperties)
248{
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600249 // ParamChecker's physical device layers are the same as global
Courtney Goeltzenleuchtereb1ddb02015-07-07 11:18:30 -0600250 return util_GetLayerProperties(ARRAY_SIZE(pc_global_layers), pc_global_layers,
251 pCount, pProperties);
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600252}
253
Mark Lobodzinski9cce7832015-07-29 09:21:22 -0600254// Start of the Image layer proper
255
256// Returns TRUE if a format is a depth-compatible format
257bool is_depth_format(VkFormat format)
258{
259 bool result = VK_FALSE;
260 switch (format) {
261 case VK_FORMAT_D16_UNORM:
Courtney Goeltzenleuchter7ed10592015-09-10 17:17:43 -0600262 case VK_FORMAT_D24_UNORM_X8:
Mark Lobodzinski9cce7832015-07-29 09:21:22 -0600263 case VK_FORMAT_D32_SFLOAT:
264 case VK_FORMAT_S8_UINT:
265 case VK_FORMAT_D16_UNORM_S8_UINT:
266 case VK_FORMAT_D24_UNORM_S8_UINT:
267 case VK_FORMAT_D32_SFLOAT_S8_UINT:
268 result = VK_TRUE;
269 break;
270 default:
271 break;
272 }
273 return result;
274}
275
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600276VK_LAYER_EXPORT VkResult VKAPI vkCreateImage(VkDevice device, const VkImageCreateInfo* pCreateInfo, VkImage* pImage)
277{
Tobin Ehlis35613802015-09-22 08:40:52 -0600278 VkBool32 skipCall = VK_FALSE;
Tobin Ehlis65380532015-09-21 15:20:28 -0600279 layer_data *device_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600280 if(pCreateInfo->format != VK_FORMAT_UNDEFINED)
281 {
282 VkFormatProperties properties;
Courtney Goeltzenleuchter01d2ae12015-10-20 16:40:38 -0600283 get_dispatch_table(image_instance_table_map, device_data->physicalDevice)->GetPhysicalDeviceFormatProperties(
Chris Forbesd7576302015-06-21 22:55:02 +1200284 device_data->physicalDevice, pCreateInfo->format, &properties);
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600285
286 if((properties.linearTilingFeatures) == 0 && (properties.optimalTilingFeatures == 0))
287 {
288 char const str[] = "vkCreateImage parameter, VkFormat pCreateInfo->format, contains unsupported format";
Tobin Ehlis35613802015-09-22 08:40:52 -0600289 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_WARN_BIT, (VkDbgObjectType)0, 0, 0, IMAGE_FORMAT_UNSUPPORTED, "IMAGE", str);
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600290 }
291 }
Tobin Ehlis35613802015-09-22 08:40:52 -0600292 if (skipCall)
293 return VK_ERROR_VALIDATION_FAILED;
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600294
295 VkResult result = get_dispatch_table(image_device_table_map, device)->CreateImage(device, pCreateInfo, pImage);
296
Tobin Ehlis65380532015-09-21 15:20:28 -0600297 if(result == VK_SUCCESS) {
Tobin Ehlis6fa437d2015-09-25 14:49:43 -0600298 device_data->imageMap[pImage->handle] = IMAGE_STATE(pCreateInfo);
Tobin Ehlis65380532015-09-21 15:20:28 -0600299 }
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600300 return result;
301}
302
Tobin Ehlis65380532015-09-21 15:20:28 -0600303VK_LAYER_EXPORT void VKAPI vkDestroyImage(VkDevice device, VkImage image)
304{
305 layer_data *device_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
306 device_data->imageMap.erase(image.handle);
307 get_dispatch_table(image_device_table_map, device)->DestroyImage(device, image);
308}
309
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600310VK_LAYER_EXPORT VkResult VKAPI vkCreateRenderPass(VkDevice device, const VkRenderPassCreateInfo* pCreateInfo, VkRenderPass* pRenderPass)
311{
Tobin Ehlis35613802015-09-22 08:40:52 -0600312 VkBool32 skipCall = VK_FALSE;
Chia-I Wuc278df82015-07-07 11:50:03 +0800313 for(uint32_t i = 0; i < pCreateInfo->attachmentCount; ++i)
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600314 {
Chia-I Wuc278df82015-07-07 11:50:03 +0800315 if(pCreateInfo->pAttachments[i].format != VK_FORMAT_UNDEFINED)
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600316 {
Courtney Goeltzenleuchter07199212015-06-22 16:19:14 -0600317 layer_data *device_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600318 VkFormatProperties properties;
Courtney Goeltzenleuchter01d2ae12015-10-20 16:40:38 -0600319 get_dispatch_table(image_instance_table_map, device_data->physicalDevice)->GetPhysicalDeviceFormatProperties(
Chia-I Wuc278df82015-07-07 11:50:03 +0800320 device_data->physicalDevice, pCreateInfo->pAttachments[i].format, &properties);
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600321
322 if((properties.linearTilingFeatures) == 0 && (properties.optimalTilingFeatures == 0))
323 {
324 std::stringstream ss;
Chia-I Wuc278df82015-07-07 11:50:03 +0800325 ss << "vkCreateRenderPass parameter, VkFormat in pCreateInfo->pAttachments[" << i << "], contains unsupported format";
Tobin Ehlis35613802015-09-22 08:40:52 -0600326 skipCall |= log_msg(mdd(device), VK_DBG_REPORT_WARN_BIT, (VkDbgObjectType)0, 0, 0, IMAGE_FORMAT_UNSUPPORTED, "IMAGE", ss.str().c_str());
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600327 }
328 }
329 }
330
Chia-I Wuc278df82015-07-07 11:50:03 +0800331 for(uint32_t i = 0; i < pCreateInfo->attachmentCount; ++i)
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600332 {
Chia-I Wuc278df82015-07-07 11:50:03 +0800333 if(!validate_VkImageLayout(pCreateInfo->pAttachments[i].initialLayout) ||
334 !validate_VkImageLayout(pCreateInfo->pAttachments[i].finalLayout))
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600335 {
336 std::stringstream ss;
Chia-I Wuc278df82015-07-07 11:50:03 +0800337 ss << "vkCreateRenderPass parameter, VkImageLayout in pCreateInfo->pAttachments[" << i << "], is unrecognized";
Tobin Ehlis35613802015-09-22 08:40:52 -0600338 skipCall |= log_msg(mdd(device), VK_DBG_REPORT_WARN_BIT, (VkDbgObjectType)0, 0, 0, IMAGE_RENDERPASS_INVALID_ATTACHMENT, "IMAGE", ss.str().c_str());
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600339 }
340 }
341
Chia-I Wuc278df82015-07-07 11:50:03 +0800342 for(uint32_t i = 0; i < pCreateInfo->attachmentCount; ++i)
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600343 {
Chia-I Wuc278df82015-07-07 11:50:03 +0800344 if(!validate_VkAttachmentLoadOp(pCreateInfo->pAttachments[i].loadOp))
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600345 {
346 std::stringstream ss;
Chia-I Wuc278df82015-07-07 11:50:03 +0800347 ss << "vkCreateRenderPass parameter, VkAttachmentLoadOp in pCreateInfo->pAttachments[" << i << "], is unrecognized";
Tobin Ehlis35613802015-09-22 08:40:52 -0600348 skipCall |= log_msg(mdd(device), VK_DBG_REPORT_WARN_BIT, (VkDbgObjectType)0, 0, 0, IMAGE_RENDERPASS_INVALID_ATTACHMENT, "IMAGE", ss.str().c_str());
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600349 }
350 }
351
Chia-I Wuc278df82015-07-07 11:50:03 +0800352 for(uint32_t i = 0; i < pCreateInfo->attachmentCount; ++i)
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600353 {
Chia-I Wuc278df82015-07-07 11:50:03 +0800354 if(!validate_VkAttachmentStoreOp(pCreateInfo->pAttachments[i].storeOp))
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600355 {
356 std::stringstream ss;
Chia-I Wuc278df82015-07-07 11:50:03 +0800357 ss << "vkCreateRenderPass parameter, VkAttachmentStoreOp in pCreateInfo->pAttachments[" << i << "], is unrecognized";
Tobin Ehlis35613802015-09-22 08:40:52 -0600358 skipCall |= log_msg(mdd(device), VK_DBG_REPORT_WARN_BIT, (VkDbgObjectType)0, 0, 0, IMAGE_RENDERPASS_INVALID_ATTACHMENT, "IMAGE", ss.str().c_str());
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600359 }
360 }
361
Mark Lobodzinski9cce7832015-07-29 09:21:22 -0600362 // Any depth buffers specified as attachments?
363 bool depthFormatPresent = VK_FALSE;
364 for (uint32_t i = 0; i < pCreateInfo->attachmentCount; ++i)
365 {
366 depthFormatPresent |= is_depth_format(pCreateInfo->pAttachments[i].format);
367 }
368
369 if (depthFormatPresent == VK_FALSE) {
370 // No depth attachment is present, validate that subpasses set depthStencilAttachment to VK_ATTACHMENT_UNUSED;
371 for (uint32_t i = 0; i < pCreateInfo->subpassCount; i++) {
372 if (pCreateInfo->pSubpasses[i].depthStencilAttachment.attachment != VK_ATTACHMENT_UNUSED) {
373 std::stringstream ss;
374 ss << "vkCreateRenderPass has no depth/stencil attachment, yet subpass[" << i << "] has VkSubpassDescription::depthStencilAttachment value that is not VK_ATTACHMENT_UNUSED";
Tobin Ehlis35613802015-09-22 08:40:52 -0600375 skipCall |= log_msg(mdd(device), VK_DBG_REPORT_ERROR_BIT, (VkDbgObjectType)0, 0, 0, IMAGE_RENDERPASS_INVALID_DS_ATTACHMENT, "IMAGE", ss.str().c_str());
Mark Lobodzinski9cce7832015-07-29 09:21:22 -0600376 }
377 }
378 }
Tobin Ehlis35613802015-09-22 08:40:52 -0600379 if (skipCall)
380 return VK_ERROR_VALIDATION_FAILED;
Mark Lobodzinski9cce7832015-07-29 09:21:22 -0600381
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600382 VkResult result = get_dispatch_table(image_device_table_map, device)->CreateRenderPass(device, pCreateInfo, pRenderPass);
383
384 return result;
385}
386
Tobin Ehlis65380532015-09-21 15:20:28 -0600387VK_LAYER_EXPORT VkResult VKAPI vkCreateImageView(VkDevice device, const VkImageViewCreateInfo* pCreateInfo, VkImageView* pView)
388{
389 VkBool32 skipCall = VK_FALSE;
390 layer_data *device_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
391 auto imageEntry = device_data->imageMap.find(pCreateInfo->image.handle);
392 if (imageEntry != device_data->imageMap.end()) {
Tobin Ehlis6fa437d2015-09-25 14:49:43 -0600393 if (pCreateInfo->subresourceRange.baseMipLevel >= imageEntry->second.mipLevels) {
Tobin Ehlis65380532015-09-21 15:20:28 -0600394 std::stringstream ss;
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600395 ss << "vkCreateImageView called with baseMipLevel " << pCreateInfo->subresourceRange.baseMipLevel
Tobin Ehlis6fa437d2015-09-25 14:49:43 -0600396 << " for image " << pCreateInfo->image.handle << " that only has " << imageEntry->second.mipLevels << " mip levels.";
Tobin Ehlis65380532015-09-21 15:20:28 -0600397 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, (VkDbgObjectType)0, 0, 0, IMAGE_VIEW_CREATE_ERROR, "IMAGE", ss.str().c_str());
398 }
Tobin Ehlis6fa437d2015-09-25 14:49:43 -0600399 if (pCreateInfo->subresourceRange.baseArrayLayer >= imageEntry->second.arraySize) {
Tobin Ehlis65380532015-09-21 15:20:28 -0600400 std::stringstream ss;
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600401 ss << "vkCreateImageView called with baseArrayLayer " << pCreateInfo->subresourceRange.baseArrayLayer << " for image "
Tobin Ehlis6fa437d2015-09-25 14:49:43 -0600402 << pCreateInfo->image.handle << " that only has " << imageEntry->second.arraySize << " mip levels.";
Tobin Ehlis65380532015-09-21 15:20:28 -0600403 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, (VkDbgObjectType)0, 0, 0, IMAGE_VIEW_CREATE_ERROR, "IMAGE", ss.str().c_str());
404 }
Courtney Goeltzenleuchter63f0ead2015-10-16 09:46:00 -0600405 if (!pCreateInfo->subresourceRange.numLevels) {
Tobin Ehlis65380532015-09-21 15:20:28 -0600406 std::stringstream ss;
407 ss << "vkCreateImageView called with 0 in pCreateInfo->subresourceRange.mipLevels.";
408 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, (VkDbgObjectType)0, 0, 0, IMAGE_VIEW_CREATE_ERROR, "IMAGE", ss.str().c_str());
409 }
Courtney Goeltzenleuchter63f0ead2015-10-16 09:46:00 -0600410 if (!pCreateInfo->subresourceRange.numLayers) {
Tobin Ehlis65380532015-09-21 15:20:28 -0600411 std::stringstream ss;
412 ss << "vkCreateImageView called with 0 in pCreateInfo->subresourceRange.arraySize.";
413 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, (VkDbgObjectType)0, 0, 0, IMAGE_VIEW_CREATE_ERROR, "IMAGE", ss.str().c_str());
414 }
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600415
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600416 // Validate correct image aspect bits for desired formats and format consistency
Tobin Ehlis6fa437d2015-09-25 14:49:43 -0600417 VkFormat imageFormat = imageEntry->second.format;
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600418 VkFormat ivciFormat = pCreateInfo->format;
419 VkImageAspectFlags aspectMask = pCreateInfo->subresourceRange.aspectMask;
420
421 if (vk_format_is_color(imageFormat)) {
422 if ((aspectMask & VK_IMAGE_ASPECT_COLOR_BIT) != VK_IMAGE_ASPECT_COLOR_BIT) {
423 std::stringstream ss;
424 ss << "vkCreateImageView: Color image formats must have the VK_IMAGE_ASPECT_COLOR_BIT set";
425 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_IMAGE,
426 (uint64_t)pCreateInfo->image.handle, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", ss.str().c_str());
427 }
428 if ((aspectMask & VK_IMAGE_ASPECT_COLOR_BIT) != aspectMask) {
429 std::stringstream ss;
430 ss << "vkCreateImageView: Color image formats must have ONLY the VK_IMAGE_ASPECT_COLOR_BIT set";
431 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_IMAGE,
432 (uint64_t)pCreateInfo->image.handle, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", ss.str().c_str());
433 }
434 if (VK_FALSE == vk_format_is_color(ivciFormat)) {
435 std::stringstream ss;
436 ss << "vkCreateImageView: The image view's format can differ from the parent image's format, but both must be "
437 << "color formats. ImageFormat is " << string_VkFormat(imageFormat) << " ImageViewFormat is " << string_VkFormat(ivciFormat);
438 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_IMAGE,
439 (uint64_t)pCreateInfo->image.handle, 0, IMAGE_INVALID_FORMAT, "IMAGE", ss.str().c_str());
440 }
441 // TODO: Uncompressed formats are compatible if they occupy they same number of bits per pixel.
442 // Compressed formats are compatible if the only difference between them is the numerical type of
443 // the uncompressed pixels (e.g. signed vs. unsigned, or sRGB vs. UNORM encoding).
444 } else if (vk_format_is_depth_and_stencil(imageFormat)) {
445 if ((aspectMask & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) !=
446 (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) {
447 std::stringstream ss;
448 ss << "vkCreateImageView: Combination depth/stencil image formats must have both VK_IMAGE_ASPECT_DEPTH_BIT and VK_IMAGE_ASPECT_STENCIL_BIT set";
449 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_IMAGE,
450 (uint64_t)pCreateInfo->image.handle, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", ss.str().c_str());
451 }
452 if ((aspectMask & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) != aspectMask) {
453 std::stringstream ss;
454 ss << "vkCreateImageView: Combination depth/stencil image formats can have only the VK_IMAGE_ASPECT_DEPTH_BIT and VK_IMAGE_ASPECT_STENCIL_BIT set";
455 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_IMAGE,
456 (uint64_t)pCreateInfo->image.handle, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", ss.str().c_str());
457 }
458 } else if (vk_format_is_depth_only(imageFormat)) {
459 if ((aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT) != VK_IMAGE_ASPECT_DEPTH_BIT) {
460 std::stringstream ss;
461 ss << "vkCreateImageView: Depth-only image formats must have the VK_IMAGE_ASPECT_DEPTH_BIT set";
462 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_IMAGE,
463 (uint64_t)pCreateInfo->image.handle, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", ss.str().c_str());
464 }
465 if ((aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT) != aspectMask) {
466 std::stringstream ss;
467 ss << "vkCreateImageView: Depth-only image formats can have only the VK_IMAGE_ASPECT_DEPTH_BIT set";
468 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_IMAGE,
469 (uint64_t)pCreateInfo->image.handle, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", ss.str().c_str());
470 }
471 } else if (vk_format_is_stencil_only(imageFormat)) {
472 if ((aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT) != VK_IMAGE_ASPECT_STENCIL_BIT) {
473 std::stringstream ss;
474 ss << "vkCreateImageView: Stencil-only image formats must have the VK_IMAGE_ASPECT_STENCIL_BIT set";
475 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_IMAGE,
476 (uint64_t)pCreateInfo->image.handle, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", ss.str().c_str());
477 }
478 if ((aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT) != aspectMask) {
479 std::stringstream ss;
480 ss << "vkCreateImageView: Stencil-only image formats can have only the VK_IMAGE_ASPECT_STENCIL_BIT set";
481 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_IMAGE,
482 (uint64_t)pCreateInfo->image.handle, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", ss.str().c_str());
483 }
484 }
485 }
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600486
Tobin Ehlis65380532015-09-21 15:20:28 -0600487 if (skipCall)
488 return VK_ERROR_VALIDATION_FAILED;
Tobin Ehlis35613802015-09-22 08:40:52 -0600489
Tobin Ehlis65380532015-09-21 15:20:28 -0600490 VkResult result = get_dispatch_table(image_device_table_map, device)->CreateImageView(device, pCreateInfo, pView);
491 return result;
492}
493
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600494VK_LAYER_EXPORT void VKAPI vkCmdClearColorImage(
495 VkCmdBuffer cmdBuffer,
496 VkImage image,
497 VkImageLayout imageLayout,
498 const VkClearColorValue *pColor,
499 uint32_t rangeCount,
500 const VkImageSubresourceRange *pRanges)
501{
502 VkBool32 skipCall = VK_FALSE;
503
504 // For each range, image aspect must be color only
505 for (uint32_t i = 0; i < rangeCount; i++) {
506 if (pRanges[i].aspectMask != VK_IMAGE_ASPECT_COLOR_BIT) {
507 layer_data *device_data = get_my_data_ptr(get_dispatch_key(cmdBuffer), layer_data_map);
508 char const str[] = "vkCmdClearColorImage aspectMasks for all subresource ranges must be set to VK_IMAGE_ASPECT_COLOR_BIT";
509 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
510 (uint64_t)cmdBuffer, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", str);
511 }
512 }
513
514 if (VK_FALSE == skipCall) {
515 get_dispatch_table(image_device_table_map, cmdBuffer)->CmdClearColorImage(cmdBuffer, image, imageLayout,
516 pColor, rangeCount, pRanges);
517 }
518}
519
520VK_LAYER_EXPORT void VKAPI vkCmdClearDepthStencilImage(
521 VkCmdBuffer cmdBuffer,
522 VkImage image,
523 VkImageLayout imageLayout,
524 const VkClearDepthStencilValue *pDepthStencil,
525 uint32_t rangeCount,
526 const VkImageSubresourceRange *pRanges)
527{
528 VkBool32 skipCall = VK_FALSE;
529
530 // For each range, Image aspect must be depth or stencil or both
531 for (uint32_t i = 0; i < rangeCount; i++) {
532 if (((pRanges[i].aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT) != VK_IMAGE_ASPECT_DEPTH_BIT) &&
533 ((pRanges[i].aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT) != VK_IMAGE_ASPECT_STENCIL_BIT))
534 {
535 layer_data *device_data = get_my_data_ptr(get_dispatch_key(cmdBuffer), layer_data_map);
536 char const str[] = "vkCmdClearDepthStencilImage aspectMasks for all subresource ranges must be "
537 "set to VK_IMAGE_ASPECT_DEPTH_BIT and/or VK_IMAGE_ASPECT_STENCIL_BIT";
538 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
539 (uint64_t)cmdBuffer, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", str);
540 }
541 }
542
543 if (VK_FALSE == skipCall) {
544 get_dispatch_table(image_device_table_map, cmdBuffer)->CmdClearDepthStencilImage(cmdBuffer,
545 image, imageLayout, pDepthStencil, rangeCount, pRanges);
546 }
547}
548
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600549VK_LAYER_EXPORT void VKAPI vkCmdCopyImage(
550 VkCmdBuffer cmdBuffer,
551 VkImage srcImage,
552 VkImageLayout srcImageLayout,
553 VkImage destImage,
554 VkImageLayout destImageLayout,
555 uint32_t regionCount,
556 const VkImageCopy *pRegions)
557{
558 VkBool32 skipCall = VK_FALSE;
Mike Stroyan43909d82015-09-25 13:39:21 -0600559 layer_data *device_data = get_my_data_ptr(get_dispatch_key(cmdBuffer), layer_data_map);
560 auto srcImageEntry = device_data->imageMap.find(srcImage.handle);
561 auto destImageEntry = device_data->imageMap.find(destImage.handle);
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600562
563 // For each region, src aspect mask must match dest aspect mask
564 // For each region, color aspects cannot be mixed with depth/stencil aspects
565 for (uint32_t i = 0; i < regionCount; i++) {
566 if (pRegions[i].srcSubresource.aspect != pRegions[i].destSubresource.aspect) {
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600567 char const str[] = "vkCmdCopyImage: Src and dest aspectMasks for each region must match";
568 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
569 (uint64_t)cmdBuffer, 0, IMAGE_MISMATCHED_IMAGE_ASPECT, "IMAGE", str);
570 }
Courtney Goeltzenleuchterba11ebe2015-10-21 17:00:51 -0600571 if ((pRegions[i].srcSubresource.aspect & VK_IMAGE_ASPECT_COLOR_BIT) &&
572 (pRegions[i].srcSubresource.aspect & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT))) {
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600573 char const str[] = "vkCmdCopyImage aspectMask cannot specify both COLOR and DEPTH/STENCIL aspects";
574 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
575 (uint64_t)cmdBuffer, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", str);
576 }
577 }
578
Mike Stroyan43909d82015-09-25 13:39:21 -0600579 if ((srcImageEntry != device_data->imageMap.end())
580 && (destImageEntry != device_data->imageMap.end())) {
Tobin Ehlis6fa437d2015-09-25 14:49:43 -0600581 if (srcImageEntry->second.imageType != destImageEntry->second.imageType) {
Mike Stroyan43909d82015-09-25 13:39:21 -0600582 char const str[] = "vkCmdCopyImage called with unmatched source and dest image types.";
583 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
584 (uint64_t)cmdBuffer, 0, IMAGE_MISMATCHED_IMAGE_TYPE, "IMAGE", str);
585 }
586 // Check that format is same size or exact stencil/depth
Tobin Ehlis6fa437d2015-09-25 14:49:43 -0600587 if (is_depth_format(srcImageEntry->second.format)) {
588 if (srcImageEntry->second.format != destImageEntry->second.format) {
Mike Stroyan43909d82015-09-25 13:39:21 -0600589 char const str[] = "vkCmdCopyImage called with unmatched source and dest image depth/stencil formats.";
590 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
591 (uint64_t)cmdBuffer, 0, IMAGE_MISMATCHED_IMAGE_FORMAT, "IMAGE", str);
592 }
593 } else {
Tobin Ehlis6fa437d2015-09-25 14:49:43 -0600594 size_t srcSize = vk_format_get_size(srcImageEntry->second.format);
595 size_t destSize = vk_format_get_size(destImageEntry->second.format);
Mike Stroyan43909d82015-09-25 13:39:21 -0600596 if (srcSize != destSize) {
597 char const str[] = "vkCmdCopyImage called with unmatched source and dest image format sizes.";
598 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
599 (uint64_t)cmdBuffer, 0, IMAGE_MISMATCHED_IMAGE_FORMAT, "IMAGE", str);
600 }
601 }
602 }
603
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600604 if (VK_FALSE == skipCall) {
605 get_dispatch_table(image_device_table_map, cmdBuffer)->CmdCopyImage(cmdBuffer, srcImage,
606 srcImageLayout, destImage, destImageLayout, regionCount, pRegions);
607 }
608}
609
Courtney Goeltzenleuchter9feb0732015-10-15 16:51:05 -0600610void VKAPI vkCmdClearAttachments(
611 VkCmdBuffer cmdBuffer,
612 uint32_t attachmentCount,
613 const VkClearAttachment* pAttachments,
614 uint32_t rectCount,
Courtney Goeltzenleuchtera12e2912015-10-15 18:22:08 -0600615 const VkClearRect* pRects)
Courtney Goeltzenleuchter9feb0732015-10-15 16:51:05 -0600616{
617 VkBool32 skipCall = VK_FALSE;
618 VkImageAspectFlags aspectMask;
619
620 for (uint32_t i = 0; i < attachmentCount; i++) {
621 aspectMask = pAttachments[i].aspectMask;
622 if (aspectMask & VK_IMAGE_ASPECT_COLOR_BIT) {
623 if (aspectMask != VK_IMAGE_ASPECT_COLOR_BIT) {
624 // VK_IMAGE_ASPECT_COLOR_BIT is not the only bit set for this attachment
625 layer_data *device_data = get_my_data_ptr(get_dispatch_key(cmdBuffer), layer_data_map);
626 char const str[] = "vkCmdClearAttachments aspectMask [%d] must set only VK_IMAGE_ASPECT_COLOR_BIT of a color attachment.";
627 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
628 (uint64_t)cmdBuffer, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", str, i);
629 }
630 } else {
631 // Image aspect must be depth or stencil or both
632 if (((aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT) != VK_IMAGE_ASPECT_DEPTH_BIT) &&
633 ((aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT) != VK_IMAGE_ASPECT_STENCIL_BIT))
634 {
635 layer_data *device_data = get_my_data_ptr(get_dispatch_key(cmdBuffer), layer_data_map);
636 char const str[] = "vkCmdClearAttachments aspectMask [%d] must be set to VK_IMAGE_ASPECT_DEPTH_BIT and/or VK_IMAGE_ASPECT_STENCIL_BIT";
637 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
638 (uint64_t)cmdBuffer, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", str, i);
639 }
640 }
641 }
642
643 if (VK_FALSE == skipCall) {
644 get_dispatch_table(image_device_table_map, cmdBuffer)->CmdClearAttachments(cmdBuffer,
645 attachmentCount, pAttachments, rectCount, pRects);
646 }
647}
648
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600649VK_LAYER_EXPORT void VKAPI vkCmdCopyImageToBuffer(
650 VkCmdBuffer cmdBuffer,
651 VkImage srcImage,
652 VkImageLayout srcImageLayout,
653 VkBuffer destBuffer,
654 uint32_t regionCount,
655 const VkBufferImageCopy *pRegions)
656{
657 VkBool32 skipCall = VK_FALSE;
658
659 // Image aspect must be ONE OF color, depth, stencil
660 for (uint32_t i = 0; i < regionCount; i++) {
Courtney Goeltzenleuchterba11ebe2015-10-21 17:00:51 -0600661 VkImageAspectFlags aspect = pRegions[i].imageSubresource.aspect;
662 if ((aspect != VK_IMAGE_ASPECT_COLOR_BIT) &&
663 (aspect != VK_IMAGE_ASPECT_DEPTH_BIT) &&
664 (aspect != VK_IMAGE_ASPECT_STENCIL_BIT)) {
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600665 layer_data *device_data = get_my_data_ptr(get_dispatch_key(cmdBuffer), layer_data_map);
666 char const str[] = "vkCmdCopyImageToBuffer: aspectMasks for each region must specify only COLOR or DEPTH or STENCIL";
667 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
668 (uint64_t)cmdBuffer, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", str);
669 }
670 }
671
672 if (VK_FALSE == skipCall) {
673 get_dispatch_table(image_device_table_map, cmdBuffer)->CmdCopyImageToBuffer(cmdBuffer,
674 srcImage, srcImageLayout, destBuffer, regionCount, pRegions);
675 }
676}
677
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600678VK_LAYER_EXPORT void VKAPI vkCmdCopyBufferToImage(
679 VkCmdBuffer cmdBuffer,
680 VkBuffer srcBuffer,
681 VkImage destImage,
682 VkImageLayout destImageLayout,
683 uint32_t regionCount,
684 const VkBufferImageCopy *pRegions)
685{
686 VkBool32 skipCall = VK_FALSE;
687
688 // Image aspect must be ONE OF color, depth, stencil
689 for (uint32_t i = 0; i < regionCount; i++) {
Courtney Goeltzenleuchterba11ebe2015-10-21 17:00:51 -0600690 VkImageAspectFlags aspect = pRegions[i].imageSubresource.aspect;
691 if ((aspect != VK_IMAGE_ASPECT_COLOR_BIT) &&
692 (aspect != VK_IMAGE_ASPECT_DEPTH_BIT) &&
693 (aspect != VK_IMAGE_ASPECT_STENCIL_BIT)) {
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600694 layer_data *device_data = get_my_data_ptr(get_dispatch_key(cmdBuffer), layer_data_map);
695 char const str[] = "vkCmdCopyBufferToImage: aspectMasks for each region must specify only COLOR or DEPTH or STENCIL";
696 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
697 (uint64_t)cmdBuffer, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", str);
698 }
699 }
700
701 if (VK_FALSE == skipCall) {
702 get_dispatch_table(image_device_table_map, cmdBuffer)->CmdCopyBufferToImage(cmdBuffer,
703 srcBuffer, destImage, destImageLayout, regionCount, pRegions);
704 }
705}
706
707VK_LAYER_EXPORT void VKAPI vkCmdBlitImage(
708 VkCmdBuffer cmdBuffer,
709 VkImage srcImage,
710 VkImageLayout srcImageLayout,
711 VkImage destImage,
712 VkImageLayout destImageLayout,
713 uint32_t regionCount,
714 const VkImageBlit *pRegions,
715 VkTexFilter filter)
716{
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600717 VkBool32 skipCall = VK_FALSE;
718 layer_data *device_data = get_my_data_ptr(get_dispatch_key(cmdBuffer), layer_data_map);
719
720 auto srcImageEntry = device_data->imageMap.find(srcImage.handle);
721 auto destImageEntry = device_data->imageMap.find(destImage.handle);
722
723 if ((srcImageEntry != device_data->imageMap.end()) &&
724 (destImageEntry != device_data->imageMap.end())) {
725
Tobin Ehlis6fa437d2015-09-25 14:49:43 -0600726 VkFormat srcFormat = srcImageEntry->second.format;
727 VkFormat dstFormat = destImageEntry->second.format;
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600728
729 // Validate consistency for signed and unsigned formats
730 if ((vk_format_is_sint(srcFormat) && !vk_format_is_sint(dstFormat)) ||
731 (vk_format_is_uint(srcFormat) && !vk_format_is_uint(dstFormat))) {
732 std::stringstream ss;
733 ss << "vkCmdBlitImage: If one of srcImage and destImage images has signed/unsigned integer format, "
734 << "the other one must also have signed/unsigned integer format. "
735 << "Source format is " << string_VkFormat(srcFormat) << " Destinatino format is " << string_VkFormat(dstFormat);
736 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
737 (uint64_t)cmdBuffer, 0, IMAGE_INVALID_FORMAT, "IMAGE", ss.str().c_str());
738 }
739
740 // Validate aspect bits and formats for depth/stencil images
741 if (vk_format_is_depth_or_stencil(srcFormat) ||
742 vk_format_is_depth_or_stencil(dstFormat)) {
743 if (srcFormat != dstFormat) {
744 std::stringstream ss;
745 ss << "vkCmdBlitImage: If one of srcImage and destImage images has a format of depth, stencil or depth "
746 << "stencil, the other one must have exactly the same format. "
747 << "Source format is " << string_VkFormat(srcFormat) << " Destinatino format is " << string_VkFormat(dstFormat);
748 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
749 (uint64_t)cmdBuffer, 0, IMAGE_INVALID_FORMAT, "IMAGE", ss.str().c_str());
750 }
751
752 for (uint32_t i = 0; i < regionCount; i++) {
753 VkImageAspectFlags srcAspect = pRegions[i].srcSubresource.aspect;
754 VkImageAspectFlags dstAspect = pRegions[i].destSubresource.aspect;
755
756 if (srcAspect != dstAspect) {
757 std::stringstream ss;
758 ss << "vkCmdBlitImage: Image aspects of depth/stencil images should match";
759 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_WARN_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
760 (uint64_t)cmdBuffer, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", ss.str().c_str());
761 }
762 if (vk_format_is_depth_and_stencil(srcFormat)) {
763 if (srcAspect != (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) {
764 std::stringstream ss;
765 ss << "vkCmdBlitImage: Combination depth/stencil image formats must have both VK_IMAGE_ASPECT_DEPTH_BIT "
766 << "and VK_IMAGE_ASPECT_STENCIL_BIT set in both the srcImage and destImage";
767 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
768 (uint64_t)cmdBuffer, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", ss.str().c_str());
769 }
770 } else if (vk_format_is_stencil_only(srcFormat)) {
771 if (srcAspect != VK_IMAGE_ASPECT_STENCIL_BIT) {
772 std::stringstream ss;
773 ss << "vkCmdBlitImage: Stencil-only image formats must have only the VK_IMAGE_ASPECT_STENCIL_BIT "
774 << "set in both the srcImage and destImage";
775 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
776 (uint64_t)cmdBuffer, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", ss.str().c_str());
777 }
778 } else if (vk_format_is_depth_only(srcFormat)) {
779 if (srcAspect != VK_IMAGE_ASPECT_DEPTH_BIT) {
780 std::stringstream ss;
781 ss << "vkCmdBlitImage: Depth-only image formats must have only the VK_IMAGE_ASPECT_DEPTH "
782 << "set in both the srcImage and destImage";
783 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
784 (uint64_t)cmdBuffer, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", ss.str().c_str());
785 }
786 }
787 }
788 }
789
790 // Validate filter
791 if (vk_format_is_depth_or_stencil(srcFormat) ||
792 vk_format_is_int(srcFormat)) {
793 if (filter != VK_TEX_FILTER_NEAREST) {
794 std::stringstream ss;
795 ss << "vkCmdBlitImage: If the format of srcImage is a depth, stencil, depth stencil or integer-based format "
796 << "then filter must be VK_TEX_FILTER_NEAREST.";
797 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
798 (uint64_t)cmdBuffer, 0, IMAGE_INVALID_FILTER, "IMAGE", ss.str().c_str());
799 }
800 }
801 }
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600802
803 get_dispatch_table(image_device_table_map, cmdBuffer)->CmdBlitImage(cmdBuffer, srcImage,
804 srcImageLayout, destImage, destImageLayout, regionCount, pRegions, filter);
805}
806
807VK_LAYER_EXPORT void VKAPI vkCmdResolveImage(
808 VkCmdBuffer cmdBuffer,
809 VkImage srcImage,
810 VkImageLayout srcImageLayout,
811 VkImage destImage,
812 VkImageLayout destImageLayout,
813 uint32_t regionCount,
814 const VkImageResolve *pRegions)
815{
816 VkBool32 skipCall = VK_FALSE;
Mike Stroyan43909d82015-09-25 13:39:21 -0600817 layer_data *device_data = get_my_data_ptr(get_dispatch_key(cmdBuffer), layer_data_map);
818 auto srcImageEntry = device_data->imageMap.find(srcImage.handle);
819 auto destImageEntry = device_data->imageMap.find(destImage.handle);
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600820
821 // For each region, src and dest image aspect must be color only
822 for (uint32_t i = 0; i < regionCount; i++) {
Courtney Goeltzenleuchterba11ebe2015-10-21 17:00:51 -0600823 if ((pRegions[i].srcSubresource.aspect != VK_IMAGE_ASPECT_COLOR_BIT) ||
824 (pRegions[i].destSubresource.aspect != VK_IMAGE_ASPECT_COLOR_BIT)) {
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600825 char const str[] = "vkCmdResolveImage: src and dest aspectMasks for each region must specify only VK_IMAGE_ASPECT_COLOR_BIT";
826 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
827 (uint64_t)cmdBuffer, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", str);
828 }
829 }
830
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600831 if ((srcImageEntry != device_data->imageMap.end()) &&
832 (destImageEntry != device_data->imageMap.end())) {
Tobin Ehlis6fa437d2015-09-25 14:49:43 -0600833 if (srcImageEntry->second.format != destImageEntry->second.format) {
Mike Stroyan43909d82015-09-25 13:39:21 -0600834 char const str[] = "vkCmdResolveImage called with unmatched source and dest formats.";
835 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
836 (uint64_t)cmdBuffer, 0, IMAGE_MISMATCHED_IMAGE_FORMAT, "IMAGE", str);
837 }
Tobin Ehlis6fa437d2015-09-25 14:49:43 -0600838 if (srcImageEntry->second.imageType != destImageEntry->second.imageType) {
Mike Stroyan43909d82015-09-25 13:39:21 -0600839 char const str[] = "vkCmdResolveImage called with unmatched source and dest image types.";
840 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
841 (uint64_t)cmdBuffer, 0, IMAGE_MISMATCHED_IMAGE_TYPE, "IMAGE", str);
842 }
Tobin Ehlis6fa437d2015-09-25 14:49:43 -0600843 if (srcImageEntry->second.samples <= 1) {
Mike Stroyan43909d82015-09-25 13:39:21 -0600844 char const str[] = "vkCmdResolveImage called with source sample count less than 2.";
845 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
846 (uint64_t)cmdBuffer, 0, IMAGE_INVALID_RESOLVE_SAMPLES, "IMAGE", str);
847 }
Tobin Ehlis6fa437d2015-09-25 14:49:43 -0600848 if (destImageEntry->second.samples > 1) {
Mike Stroyan43909d82015-09-25 13:39:21 -0600849 char const str[] = "vkCmdResolveImage called with dest sample count greater than 1.";
850 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
851 (uint64_t)cmdBuffer, 0, IMAGE_INVALID_RESOLVE_SAMPLES, "IMAGE", str);
852 }
853 }
854
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600855 if (VK_FALSE == skipCall) {
856 get_dispatch_table(image_device_table_map, cmdBuffer)->CmdResolveImage(cmdBuffer, srcImage,
857 srcImageLayout, destImage, destImageLayout, regionCount, pRegions);
858 }
859}
860
Courtney Goeltzenleuchter01d2ae12015-10-20 16:40:38 -0600861VK_LAYER_EXPORT void VKAPI vkGetImageSubresourceLayout(
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600862 VkDevice device,
863 VkImage image,
864 const VkImageSubresource *pSubresource,
865 VkSubresourceLayout *pLayout)
866{
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600867 VkBool32 skipCall = VK_FALSE;
868 layer_data *device_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
869 VkFormat format;
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600870
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600871 auto imageEntry = device_data->imageMap.find(image.handle);
872
873 // Validate that image aspects match formats
874 if (imageEntry != device_data->imageMap.end()) {
Tobin Ehlis6fa437d2015-09-25 14:49:43 -0600875 format = imageEntry->second.format;
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600876 if (vk_format_is_color(format)) {
877 if (pSubresource->aspect != VK_IMAGE_ASPECT_COLOR_BIT) {
878 std::stringstream ss;
879 ss << "vkGetImageSubresourceLayout: For color formats, the aspect field of VkImageSubresource must be VK_IMAGE_ASPECT_COLOR.";
880 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_IMAGE,
881 (uint64_t)image.handle, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", ss.str().c_str());
882 }
883 } else if (vk_format_is_depth_or_stencil(format)) {
884 if ((pSubresource->aspect != VK_IMAGE_ASPECT_DEPTH_BIT) &&
885 (pSubresource->aspect != VK_IMAGE_ASPECT_STENCIL_BIT)) {
886 std::stringstream ss;
887 ss << "vkGetImageSubresourceLayout: For depth/stencil formats, the aspect selects either the depth or stencil image aspect.";
888 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_IMAGE,
889 (uint64_t)image.handle, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", ss.str().c_str());
890 }
891 }
892 }
893
894 if (VK_FALSE == skipCall) {
895 get_dispatch_table(image_device_table_map, device)->GetImageSubresourceLayout(device,
896 image, pSubresource, pLayout);
897 }
898
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600899}
900
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -0600901VK_LAYER_EXPORT PFN_vkVoidFunction VKAPI vkGetDeviceProcAddr(VkDevice device, const char* funcName)
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600902{
903 if (device == NULL) {
904 return NULL;
905 }
906
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600907 // loader uses this to force layer initialization; device object is wrapped
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600908 if (!strcmp(funcName, "vkGetDeviceProcAddr")) {
909 initDeviceTable(image_device_table_map, (const VkBaseLayerObject *) device);
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -0600910 return (PFN_vkVoidFunction) vkGetDeviceProcAddr;
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600911 }
912
Courtney Goeltzenleuchterbe637992015-06-25 18:01:43 -0600913 if (!strcmp(funcName, "vkCreateDevice"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -0600914 return (PFN_vkVoidFunction) vkCreateDevice;
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600915 if (!strcmp(funcName, "vkDestroyDevice"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -0600916 return (PFN_vkVoidFunction) vkDestroyDevice;
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600917 if (!strcmp(funcName, "vkCreateImage"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -0600918 return (PFN_vkVoidFunction) vkCreateImage;
Tobin Ehlis342b9bf2015-09-22 10:11:37 -0600919 if (!strcmp(funcName, "vkCreateImageView"))
920 return (PFN_vkVoidFunction) vkCreateImageView;
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600921 if (!strcmp(funcName, "vkCreateRenderPass"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -0600922 return (PFN_vkVoidFunction) vkCreateRenderPass;
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600923 if (!strcmp(funcName, "vkCmdClearColorImage"))
924 return (PFN_vkVoidFunction) vkCmdClearColorImage;
925 if (!strcmp(funcName, "vkCmdClearDepthStencilImage"))
926 return (PFN_vkVoidFunction) vkCmdClearDepthStencilImage;
Courtney Goeltzenleuchter9feb0732015-10-15 16:51:05 -0600927 if (!strcmp(funcName, "vkCmdClearAttachments"))
928 return (PFN_vkVoidFunction) vkCmdClearAttachments;
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600929 if (!strcmp(funcName, "vkCmdCopyImage"))
930 return (PFN_vkVoidFunction) vkCmdCopyImage;
931 if (!strcmp(funcName, "vkCmdCopyImageToBuffer"))
932 return (PFN_vkVoidFunction) vkCmdCopyImageToBuffer;
933 if (!strcmp(funcName, "vkCmdCopyBufferToImage"))
934 return (PFN_vkVoidFunction) vkCmdCopyBufferToImage;
935 if (!strcmp(funcName, "vkCmdBlitImage"))
936 return (PFN_vkVoidFunction) vkCmdBlitImage;
937 if (!strcmp(funcName, "vkCmdResolveImage"))
938 return (PFN_vkVoidFunction) vkCmdResolveImage;
939 if (!strcmp(funcName, "vkGetImageSubresourceLayout"))
940 return (PFN_vkVoidFunction) vkGetImageSubresourceLayout;
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600941 {
942 if (get_dispatch_table(image_device_table_map, device)->GetDeviceProcAddr == NULL)
943 return NULL;
944 return get_dispatch_table(image_device_table_map, device)->GetDeviceProcAddr(device, funcName);
945 }
946}
947
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -0600948VK_LAYER_EXPORT PFN_vkVoidFunction VKAPI vkGetInstanceProcAddr(VkInstance instance, const char* funcName)
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600949{
950 if (instance == NULL) {
951 return NULL;
952 }
953
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600954 // loader uses this to force layer initialization; instance object is wrapped
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600955 if (!strcmp(funcName, "vkGetInstanceProcAddr")) {
956 initInstanceTable(image_instance_table_map, (const VkBaseLayerObject *) instance);
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -0600957 return (PFN_vkVoidFunction) vkGetInstanceProcAddr;
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600958 }
959
960 if (!strcmp(funcName, "vkCreateInstance"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -0600961 return (PFN_vkVoidFunction) vkCreateInstance;
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600962 if (!strcmp(funcName, "vkDestroyInstance"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -0600963 return (PFN_vkVoidFunction) vkDestroyInstance;
Courtney Goeltzenleuchter74c4ce92015-09-14 17:22:16 -0600964 if (!strcmp(funcName, "vkEnumerateInstanceLayerProperties"))
965 return (PFN_vkVoidFunction) vkEnumerateInstanceLayerProperties;
966 if (!strcmp(funcName, "vkEnumerateInstanceExtensionProperties"))
967 return (PFN_vkVoidFunction) vkEnumerateInstanceExtensionProperties;
968 if (!strcmp(funcName, "vkEnumerateDeviceLayerProperties"))
969 return (PFN_vkVoidFunction) vkEnumerateDeviceLayerProperties;
970 if (!strcmp(funcName, "vkEnumerateDeviceExtensionProperties"))
971 return (PFN_vkVoidFunction) vkEnumerateDeviceExtensionProperties;
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600972
973 layer_data *data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -0600974 PFN_vkVoidFunction fptr = debug_report_get_instance_proc_addr(data->report_data, funcName);
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600975 if(fptr)
976 return fptr;
977
978 {
979 if (get_dispatch_table(image_instance_table_map, instance)->GetInstanceProcAddr == NULL)
980 return NULL;
981 return get_dispatch_table(image_instance_table_map, instance)->GetInstanceProcAddr(instance, funcName);
982 }
983}