blob: 912c23f407b7390d914f3846f61914e58125dfaf [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
25#include <stdio.h>
26#include <stdlib.h>
27#include <string.h>
28
29#include <iostream>
30#include <string>
31#include <sstream>
32#include <unordered_map>
Tobin Ehlis65380532015-09-21 15:20:28 -060033#include <memory>
Jeremy Hayesb707aa52015-06-18 10:12:39 -060034
Tobin Ehlis65380532015-09-21 15:20:28 -060035#include "image.h"
Tobin Ehlis7a51d902015-07-03 10:34:49 -060036#include "vk_loader_platform.h"
Tobin Ehlis2d1d9702015-07-03 09:42:57 -060037#include "vk_layer.h"
Jeremy Hayesb707aa52015-06-18 10:12:39 -060038#include "vk_enum_validate_helper.h"
39#include "vk_struct_validate_helper.h"
40//The following is #included again to catch certain OS-specific functions being used:
Tobin Ehlis7a51d902015-07-03 10:34:49 -060041#include "vk_loader_platform.h"
Jeremy Hayesb707aa52015-06-18 10:12:39 -060042
Tobin Ehlis56d204a2015-07-03 10:15:26 -060043#include "vk_layer_table.h"
44#include "vk_layer_data.h"
Courtney Goeltzenleuchtereb1ddb02015-07-07 11:18:30 -060045#include "vk_layer_extension_utils.h"
Jeremy Hayesb707aa52015-06-18 10:12:39 -060046
Tobin Ehlis65380532015-09-21 15:20:28 -060047using namespace std;
48
Cody Northrop73bb6572015-09-28 15:09:32 -060049struct layer_data {
Jeremy Hayesb707aa52015-06-18 10:12:39 -060050 debug_report_data *report_data;
51 VkDbgMsgCallback logging_callback;
Chris Forbesd7576302015-06-21 22:55:02 +120052 VkPhysicalDevice physicalDevice;
Tobin Ehlis342b9bf2015-09-22 10:11:37 -060053 unordered_map<uint64_t, unique_ptr<IMAGE_STATE>> imageMap;
Cody Northrop73bb6572015-09-28 15:09:32 -060054
55 layer_data() :
56 report_data(nullptr),
57 logging_callback(nullptr),
58 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;
Jeremy Hayesb707aa52015-06-18 10:12:39 -060063static device_table_map image_device_table_map;
64static 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{
90 uint32_t report_flags = getLayerOptionFlags("ImageReportFlags", 0);
91
92 uint32_t debug_action = 0;
93 getLayerOptionEnum("ImageDebugAction", (uint32_t *) &debug_action);
94 if(debug_action & VK_DBG_LAYER_ACTION_LOG_MSG)
95 {
96 FILE *log_output = NULL;
97 const char* option_str = getLayerOption("ImageLogFilename");
Tobin Ehlisb4b6e7c2015-09-15 09:55:54 -060098 log_output = getLayerLogOutput(option_str, "Image");
Jeremy Hayesb707aa52015-06-18 10:12:39 -060099 layer_create_msg_callback(data->report_data, report_flags, log_callback, (void*)log_output, &data->logging_callback);
100 }
101}
102
103VK_LAYER_EXPORT VkResult VKAPI vkDbgCreateMsgCallback(
104 VkInstance instance,
105 VkFlags msgFlags,
106 const PFN_vkDbgMsgCallback pfnMsgCallback,
107 void* pUserData,
108 VkDbgMsgCallback* pMsgCallback)
109{
110 VkLayerInstanceDispatchTable *pTable = get_dispatch_table(image_instance_table_map, instance);
111 VkResult res = pTable->DbgCreateMsgCallback(instance, msgFlags, pfnMsgCallback, pUserData, pMsgCallback);
112 if (res == VK_SUCCESS) {
113 layer_data *data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
114
115 res = layer_create_msg_callback(data->report_data, msgFlags, pfnMsgCallback, pUserData, pMsgCallback);
116 }
117 return res;
118}
119
120VK_LAYER_EXPORT VkResult VKAPI vkDbgDestroyMsgCallback(
121 VkInstance instance,
122 VkDbgMsgCallback msgCallback)
123{
124 VkLayerInstanceDispatchTable *pTable = get_dispatch_table(image_instance_table_map, instance);
125 VkResult res = pTable->DbgDestroyMsgCallback(instance, msgCallback);
126
127 layer_data *data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
128 layer_destroy_msg_callback(data->report_data, msgCallback);
129
130 return res;
131}
132
133VK_LAYER_EXPORT VkResult VKAPI vkCreateInstance(const VkInstanceCreateInfo* pCreateInfo, VkInstance* pInstance)
134{
135 VkLayerInstanceDispatchTable *pTable = get_dispatch_table(image_instance_table_map, *pInstance);
136 VkResult result = pTable->CreateInstance(pCreateInfo, pInstance);
137
138 if (result == VK_SUCCESS) {
139 layer_data *data = get_my_data_ptr(get_dispatch_key(*pInstance), layer_data_map);
140 data->report_data = debug_report_create_instance(pTable, *pInstance, pCreateInfo->extensionCount,
Courtney Goeltzenleuchtereb1ddb02015-07-07 11:18:30 -0600141 pCreateInfo->ppEnabledExtensionNames);
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600142
143 InitImage(data);
144 }
145
146 return result;
147}
148
Mark Lobodzinski67b42b72015-09-07 13:59:43 -0600149VK_LAYER_EXPORT void VKAPI vkDestroyInstance(VkInstance instance)
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600150{
151 // Grab the key before the instance is destroyed.
152 dispatch_key key = get_dispatch_key(instance);
153 VkLayerInstanceDispatchTable *pTable = get_dispatch_table(image_instance_table_map, instance);
Mark Lobodzinski67b42b72015-09-07 13:59:43 -0600154 pTable->DestroyInstance(instance);
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600155
156 // Clean up logging callback, if any
157 layer_data *data = get_my_data_ptr(key, layer_data_map);
158 if(data->logging_callback)
159 {
160 layer_destroy_msg_callback(data->report_data, data->logging_callback);
161 }
162
163 layer_debug_report_destroy_instance(mid(instance));
164 layer_data_map.erase(pTable);
165
166 image_instance_table_map.erase(key);
167 assert(image_instance_table_map.size() == 0 && "Should not have any instance mappings hanging around");
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600168}
169
170VK_LAYER_EXPORT VkResult VKAPI vkCreateDevice(VkPhysicalDevice physicalDevice, const VkDeviceCreateInfo* pCreateInfo, VkDevice* pDevice)
171{
Courtney Goeltzenleuchterbe637992015-06-25 18:01:43 -0600172 VkLayerDispatchTable *pTable = get_dispatch_table(image_device_table_map, *pDevice);
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600173 VkResult result = pTable->CreateDevice(physicalDevice, pCreateInfo, pDevice);
174 if(result == VK_SUCCESS)
175 {
176 layer_data *instance_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);
177 layer_data *device_data = get_my_data_ptr(get_dispatch_key(*pDevice), layer_data_map);
178 device_data->report_data = layer_debug_report_create_device(instance_data->report_data, *pDevice);
Chris Forbesd7576302015-06-21 22:55:02 +1200179 device_data->physicalDevice = physicalDevice;
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600180 }
181
182 return result;
183}
184
Mark Lobodzinski67b42b72015-09-07 13:59:43 -0600185VK_LAYER_EXPORT void VKAPI vkDestroyDevice(VkDevice device)
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600186{
187 layer_debug_report_destroy_device(device);
188
189 dispatch_key key = get_dispatch_key(device);
190#if DISPATCH_MAP_DEBUG
191 fprintf(stderr, "Device: %p, key: %p\n", device, key);
192#endif
193
Mark Lobodzinski67b42b72015-09-07 13:59:43 -0600194 get_dispatch_table(image_device_table_map, device)->DestroyDevice(device);
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600195 image_device_table_map.erase(key);
196 assert(image_device_table_map.size() == 0 && "Should not have any instance mappings hanging around");
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600197}
198
Courtney Goeltzenleuchtereb1ddb02015-07-07 11:18:30 -0600199static const VkLayerProperties pc_global_layers[] = {
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600200 {
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600201 "Image",
Courtney Goeltzenleuchtereb1ddb02015-07-07 11:18:30 -0600202 VK_API_VERSION,
203 VK_MAKE_VERSION(0, 1, 0),
204 "Validation layer: Image ParamChecker",
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600205 }
206};
207
Courtney Goeltzenleuchter74c4ce92015-09-14 17:22:16 -0600208VK_LAYER_EXPORT VkResult VKAPI vkEnumerateInstanceExtensionProperties(
Courtney Goeltzenleuchtereb1ddb02015-07-07 11:18:30 -0600209 const char *pLayerName,
210 uint32_t *pCount,
211 VkExtensionProperties* pProperties)
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600212{
Courtney Goeltzenleuchtereb1ddb02015-07-07 11:18:30 -0600213 /* ParamChecker does not have any global extensions */
214 return util_GetExtensionProperties(0, NULL, pCount, pProperties);
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600215}
216
Courtney Goeltzenleuchter74c4ce92015-09-14 17:22:16 -0600217VK_LAYER_EXPORT VkResult VKAPI vkEnumerateInstanceLayerProperties(
Courtney Goeltzenleuchtereb1ddb02015-07-07 11:18:30 -0600218 uint32_t *pCount,
219 VkLayerProperties* pProperties)
Tony Barbour426b9052015-06-24 16:06:58 -0600220{
Courtney Goeltzenleuchtereb1ddb02015-07-07 11:18:30 -0600221 return util_GetLayerProperties(ARRAY_SIZE(pc_global_layers),
222 pc_global_layers,
223 pCount, pProperties);
Tony Barbour426b9052015-06-24 16:06:58 -0600224}
225
Courtney Goeltzenleuchter74c4ce92015-09-14 17:22:16 -0600226VK_LAYER_EXPORT VkResult VKAPI vkEnumerateDeviceExtensionProperties(
Courtney Goeltzenleuchtereb1ddb02015-07-07 11:18:30 -0600227 VkPhysicalDevice physicalDevice,
228 const char* pLayerName,
229 uint32_t* pCount,
230 VkExtensionProperties* pProperties)
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600231{
Courtney Goeltzenleuchtereb1ddb02015-07-07 11:18:30 -0600232 /* ParamChecker does not have any physical device extensions */
233 return util_GetExtensionProperties(0, NULL, pCount, pProperties);
234}
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600235
Courtney Goeltzenleuchter74c4ce92015-09-14 17:22:16 -0600236VK_LAYER_EXPORT VkResult VKAPI vkEnumerateDeviceLayerProperties(
Courtney Goeltzenleuchtereb1ddb02015-07-07 11:18:30 -0600237 VkPhysicalDevice physicalDevice,
238 uint32_t* pCount,
239 VkLayerProperties* pProperties)
240{
241 /* ParamChecker's physical device layers are the same as global */
242 return util_GetLayerProperties(ARRAY_SIZE(pc_global_layers), pc_global_layers,
243 pCount, pProperties);
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600244}
245
Mark Lobodzinski9cce7832015-07-29 09:21:22 -0600246// Start of the Image layer proper
247
248// Returns TRUE if a format is a depth-compatible format
249bool is_depth_format(VkFormat format)
250{
251 bool result = VK_FALSE;
252 switch (format) {
253 case VK_FORMAT_D16_UNORM:
Courtney Goeltzenleuchter7ed10592015-09-10 17:17:43 -0600254 case VK_FORMAT_D24_UNORM_X8:
Mark Lobodzinski9cce7832015-07-29 09:21:22 -0600255 case VK_FORMAT_D32_SFLOAT:
256 case VK_FORMAT_S8_UINT:
257 case VK_FORMAT_D16_UNORM_S8_UINT:
258 case VK_FORMAT_D24_UNORM_S8_UINT:
259 case VK_FORMAT_D32_SFLOAT_S8_UINT:
260 result = VK_TRUE;
261 break;
262 default:
263 break;
264 }
265 return result;
266}
267
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600268VK_LAYER_EXPORT VkResult VKAPI vkCreateImage(VkDevice device, const VkImageCreateInfo* pCreateInfo, VkImage* pImage)
269{
Tobin Ehlis35613802015-09-22 08:40:52 -0600270 VkBool32 skipCall = VK_FALSE;
Tobin Ehlis65380532015-09-21 15:20:28 -0600271 layer_data *device_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600272 if(pCreateInfo->format != VK_FORMAT_UNDEFINED)
273 {
274 VkFormatProperties properties;
Courtney Goeltzenleuchterab36aa62015-07-12 12:40:29 -0600275 VkResult result = get_dispatch_table(image_instance_table_map, device_data->physicalDevice)->GetPhysicalDeviceFormatProperties(
Chris Forbesd7576302015-06-21 22:55:02 +1200276 device_data->physicalDevice, pCreateInfo->format, &properties);
Tobin Ehlis65380532015-09-21 15:20:28 -0600277 if(result != VK_SUCCESS) {
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600278 char const str[] = "vkCreateImage parameter, VkFormat pCreateInfo->format, cannot be validated";
Tobin Ehlis35613802015-09-22 08:40:52 -0600279 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 -0600280 }
281
282 if((properties.linearTilingFeatures) == 0 && (properties.optimalTilingFeatures == 0))
283 {
284 char const str[] = "vkCreateImage parameter, VkFormat pCreateInfo->format, contains unsupported format";
Tobin Ehlis35613802015-09-22 08:40:52 -0600285 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 -0600286 }
287 }
Tobin Ehlis35613802015-09-22 08:40:52 -0600288 if (skipCall)
289 return VK_ERROR_VALIDATION_FAILED;
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600290
291 VkResult result = get_dispatch_table(image_device_table_map, device)->CreateImage(device, pCreateInfo, pImage);
292
Tobin Ehlis65380532015-09-21 15:20:28 -0600293 if(result == VK_SUCCESS) {
Tobin Ehlis342b9bf2015-09-22 10:11:37 -0600294 device_data->imageMap[pImage->handle] = unique_ptr<IMAGE_STATE>(new IMAGE_STATE(pCreateInfo));
Tobin Ehlis65380532015-09-21 15:20:28 -0600295 }
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600296 return result;
297}
298
Tobin Ehlis65380532015-09-21 15:20:28 -0600299VK_LAYER_EXPORT void VKAPI vkDestroyImage(VkDevice device, VkImage image)
300{
301 layer_data *device_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
302 device_data->imageMap.erase(image.handle);
303 get_dispatch_table(image_device_table_map, device)->DestroyImage(device, image);
304}
305
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600306VK_LAYER_EXPORT VkResult VKAPI vkCreateRenderPass(VkDevice device, const VkRenderPassCreateInfo* pCreateInfo, VkRenderPass* pRenderPass)
307{
Tobin Ehlis35613802015-09-22 08:40:52 -0600308 VkBool32 skipCall = VK_FALSE;
Chia-I Wuc278df82015-07-07 11:50:03 +0800309 for(uint32_t i = 0; i < pCreateInfo->attachmentCount; ++i)
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600310 {
Chia-I Wuc278df82015-07-07 11:50:03 +0800311 if(pCreateInfo->pAttachments[i].format != VK_FORMAT_UNDEFINED)
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600312 {
Courtney Goeltzenleuchter07199212015-06-22 16:19:14 -0600313 layer_data *device_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600314 VkFormatProperties properties;
Courtney Goeltzenleuchterab36aa62015-07-12 12:40:29 -0600315 VkResult result = get_dispatch_table(image_instance_table_map, device_data->physicalDevice)->GetPhysicalDeviceFormatProperties(
Chia-I Wuc278df82015-07-07 11:50:03 +0800316 device_data->physicalDevice, pCreateInfo->pAttachments[i].format, &properties);
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600317 if(result != VK_SUCCESS)
318 {
319 std::stringstream ss;
Chia-I Wuc278df82015-07-07 11:50:03 +0800320 ss << "vkCreateRenderPass parameter, VkFormat in pCreateInfo->pAttachments[" << i << "], cannot be validated";
Tobin Ehlis35613802015-09-22 08:40:52 -0600321 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 -0600322 continue;
323 }
324
325 if((properties.linearTilingFeatures) == 0 && (properties.optimalTilingFeatures == 0))
326 {
327 std::stringstream ss;
Chia-I Wuc278df82015-07-07 11:50:03 +0800328 ss << "vkCreateRenderPass parameter, VkFormat in pCreateInfo->pAttachments[" << i << "], contains unsupported format";
Tobin Ehlis35613802015-09-22 08:40:52 -0600329 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 -0600330 }
331 }
332 }
333
Chia-I Wuc278df82015-07-07 11:50:03 +0800334 for(uint32_t i = 0; i < pCreateInfo->attachmentCount; ++i)
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600335 {
Chia-I Wuc278df82015-07-07 11:50:03 +0800336 if(!validate_VkImageLayout(pCreateInfo->pAttachments[i].initialLayout) ||
337 !validate_VkImageLayout(pCreateInfo->pAttachments[i].finalLayout))
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600338 {
339 std::stringstream ss;
Chia-I Wuc278df82015-07-07 11:50:03 +0800340 ss << "vkCreateRenderPass parameter, VkImageLayout in pCreateInfo->pAttachments[" << i << "], is unrecognized";
Tobin Ehlis35613802015-09-22 08:40:52 -0600341 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 -0600342 }
343 }
344
Chia-I Wuc278df82015-07-07 11:50:03 +0800345 for(uint32_t i = 0; i < pCreateInfo->attachmentCount; ++i)
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600346 {
Chia-I Wuc278df82015-07-07 11:50:03 +0800347 if(!validate_VkAttachmentLoadOp(pCreateInfo->pAttachments[i].loadOp))
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600348 {
349 std::stringstream ss;
Chia-I Wuc278df82015-07-07 11:50:03 +0800350 ss << "vkCreateRenderPass parameter, VkAttachmentLoadOp in pCreateInfo->pAttachments[" << i << "], is unrecognized";
Tobin Ehlis35613802015-09-22 08:40:52 -0600351 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 -0600352 }
353 }
354
Chia-I Wuc278df82015-07-07 11:50:03 +0800355 for(uint32_t i = 0; i < pCreateInfo->attachmentCount; ++i)
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600356 {
Chia-I Wuc278df82015-07-07 11:50:03 +0800357 if(!validate_VkAttachmentStoreOp(pCreateInfo->pAttachments[i].storeOp))
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600358 {
359 std::stringstream ss;
Chia-I Wuc278df82015-07-07 11:50:03 +0800360 ss << "vkCreateRenderPass parameter, VkAttachmentStoreOp in pCreateInfo->pAttachments[" << i << "], is unrecognized";
Tobin Ehlis35613802015-09-22 08:40:52 -0600361 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 -0600362 }
363 }
364
Mark Lobodzinski9cce7832015-07-29 09:21:22 -0600365 // Any depth buffers specified as attachments?
366 bool depthFormatPresent = VK_FALSE;
367 for (uint32_t i = 0; i < pCreateInfo->attachmentCount; ++i)
368 {
369 depthFormatPresent |= is_depth_format(pCreateInfo->pAttachments[i].format);
370 }
371
372 if (depthFormatPresent == VK_FALSE) {
373 // No depth attachment is present, validate that subpasses set depthStencilAttachment to VK_ATTACHMENT_UNUSED;
374 for (uint32_t i = 0; i < pCreateInfo->subpassCount; i++) {
375 if (pCreateInfo->pSubpasses[i].depthStencilAttachment.attachment != VK_ATTACHMENT_UNUSED) {
376 std::stringstream ss;
377 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 -0600378 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 -0600379 }
380 }
381 }
Tobin Ehlis35613802015-09-22 08:40:52 -0600382 if (skipCall)
383 return VK_ERROR_VALIDATION_FAILED;
Mark Lobodzinski9cce7832015-07-29 09:21:22 -0600384
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600385 VkResult result = get_dispatch_table(image_device_table_map, device)->CreateRenderPass(device, pCreateInfo, pRenderPass);
386
387 return result;
388}
389
Tobin Ehlis65380532015-09-21 15:20:28 -0600390VK_LAYER_EXPORT VkResult VKAPI vkCreateImageView(VkDevice device, const VkImageViewCreateInfo* pCreateInfo, VkImageView* pView)
391{
392 VkBool32 skipCall = VK_FALSE;
393 layer_data *device_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
394 auto imageEntry = device_data->imageMap.find(pCreateInfo->image.handle);
395 if (imageEntry != device_data->imageMap.end()) {
396 if (pCreateInfo->subresourceRange.baseMipLevel >= imageEntry->second->mipLevels) {
397 std::stringstream ss;
398 ss << "vkCreateImageView called with baseMipLevel " << pCreateInfo->subresourceRange.baseMipLevel << " for image " << pCreateInfo->image.handle << " that only has " << imageEntry->second->mipLevels << " mip levels.";
399 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());
400 }
401 if (pCreateInfo->subresourceRange.baseArrayLayer >= imageEntry->second->arraySize) {
402 std::stringstream ss;
403 ss << "vkCreateImageView called with baseArrayLayer " << pCreateInfo->subresourceRange.baseArrayLayer << " for image " << pCreateInfo->image.handle << " that only has " << imageEntry->second->arraySize << " mip levels.";
404 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());
405 }
406 if (!pCreateInfo->subresourceRange.mipLevels) {
407 std::stringstream ss;
408 ss << "vkCreateImageView called with 0 in pCreateInfo->subresourceRange.mipLevels.";
409 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());
410 }
411 if (!pCreateInfo->subresourceRange.arraySize) {
412 std::stringstream ss;
413 ss << "vkCreateImageView called with 0 in pCreateInfo->subresourceRange.arraySize.";
414 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());
415 }
416 }
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600417
418 // TODO: Image aspect mask must be only VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_ASPECT_DEPTH_BIT or VK_IMAGE_ASPECT_STENCIL_BIT
419 // if the format is a color, depth-only or stencil-only format respectively. If using a depth/stencil format,
420 // aspectMask must include at least one of VK_IMAGE_ASPECT_DEPTH_BIT and VK_IMAGE_ASPECT_STENCIL_BIT, and may include both.
421 // Add after image/buffer state tracking is implemented.
422
Tobin Ehlis65380532015-09-21 15:20:28 -0600423 if (skipCall)
424 return VK_ERROR_VALIDATION_FAILED;
Tobin Ehlis35613802015-09-22 08:40:52 -0600425
Tobin Ehlis65380532015-09-21 15:20:28 -0600426 VkResult result = get_dispatch_table(image_device_table_map, device)->CreateImageView(device, pCreateInfo, pView);
427 return result;
428}
429
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600430VK_LAYER_EXPORT void VKAPI vkCmdClearColorImage(
431 VkCmdBuffer cmdBuffer,
432 VkImage image,
433 VkImageLayout imageLayout,
434 const VkClearColorValue *pColor,
435 uint32_t rangeCount,
436 const VkImageSubresourceRange *pRanges)
437{
438 VkBool32 skipCall = VK_FALSE;
439
440 // For each range, image aspect must be color only
441 for (uint32_t i = 0; i < rangeCount; i++) {
442 if (pRanges[i].aspectMask != VK_IMAGE_ASPECT_COLOR_BIT) {
443 layer_data *device_data = get_my_data_ptr(get_dispatch_key(cmdBuffer), layer_data_map);
444 char const str[] = "vkCmdClearColorImage aspectMasks for all subresource ranges must be set to VK_IMAGE_ASPECT_COLOR_BIT";
445 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
446 (uint64_t)cmdBuffer, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", str);
447 }
448 }
449
450 if (VK_FALSE == skipCall) {
451 get_dispatch_table(image_device_table_map, cmdBuffer)->CmdClearColorImage(cmdBuffer, image, imageLayout,
452 pColor, rangeCount, pRanges);
453 }
454}
455
456VK_LAYER_EXPORT void VKAPI vkCmdClearDepthStencilImage(
457 VkCmdBuffer cmdBuffer,
458 VkImage image,
459 VkImageLayout imageLayout,
460 const VkClearDepthStencilValue *pDepthStencil,
461 uint32_t rangeCount,
462 const VkImageSubresourceRange *pRanges)
463{
464 VkBool32 skipCall = VK_FALSE;
465
466 // For each range, Image aspect must be depth or stencil or both
467 for (uint32_t i = 0; i < rangeCount; i++) {
468 if (((pRanges[i].aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT) != VK_IMAGE_ASPECT_DEPTH_BIT) &&
469 ((pRanges[i].aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT) != VK_IMAGE_ASPECT_STENCIL_BIT))
470 {
471 layer_data *device_data = get_my_data_ptr(get_dispatch_key(cmdBuffer), layer_data_map);
472 char const str[] = "vkCmdClearDepthStencilImage aspectMasks for all subresource ranges must be "
473 "set to VK_IMAGE_ASPECT_DEPTH_BIT and/or VK_IMAGE_ASPECT_STENCIL_BIT";
474 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
475 (uint64_t)cmdBuffer, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", str);
476 }
477 }
478
479 if (VK_FALSE == skipCall) {
480 get_dispatch_table(image_device_table_map, cmdBuffer)->CmdClearDepthStencilImage(cmdBuffer,
481 image, imageLayout, pDepthStencil, rangeCount, pRanges);
482 }
483}
484
485VK_LAYER_EXPORT void VKAPI vkCmdClearDepthStencilAttachment(
486 VkCmdBuffer cmdBuffer,
487 VkImageAspectFlags imageAspectMask,
488 VkImageLayout imageLayout,
489 const VkClearDepthStencilValue *pDepthStencil,
490 uint32_t rectCount,
491 const VkRect3D *pRects)
492{
493 VkBool32 skipCall = VK_FALSE;
494
495 // Image aspect must be depth or stencil or both
496 if (((imageAspectMask & VK_IMAGE_ASPECT_DEPTH_BIT) != VK_IMAGE_ASPECT_DEPTH_BIT) &&
497 ((imageAspectMask & VK_IMAGE_ASPECT_STENCIL_BIT) != VK_IMAGE_ASPECT_STENCIL_BIT))
498 {
499 layer_data *device_data = get_my_data_ptr(get_dispatch_key(cmdBuffer), layer_data_map);
500 char const str[] = "vkCmdClearDepthStencilAttachment aspectMask must be set to VK_IMAGE_ASPECT_DEPTH_BIT and/or VK_IMAGE_ASPECT_STENCIL_BIT";
501 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
502 (uint64_t)cmdBuffer, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", str);
503 }
504
505 if (VK_FALSE == skipCall) {
506 get_dispatch_table(image_device_table_map, cmdBuffer)->CmdClearDepthStencilAttachment(cmdBuffer,
507 imageAspectMask, imageLayout, pDepthStencil, rectCount, pRects);
508 }
509}
510
511VK_LAYER_EXPORT void VKAPI vkCmdCopyImage(
512 VkCmdBuffer cmdBuffer,
513 VkImage srcImage,
514 VkImageLayout srcImageLayout,
515 VkImage destImage,
516 VkImageLayout destImageLayout,
517 uint32_t regionCount,
518 const VkImageCopy *pRegions)
519{
520 VkBool32 skipCall = VK_FALSE;
521
522 // For each region, src aspect mask must match dest aspect mask
523 // For each region, color aspects cannot be mixed with depth/stencil aspects
524 for (uint32_t i = 0; i < regionCount; i++) {
525 if (pRegions[i].srcSubresource.aspect != pRegions[i].destSubresource.aspect) {
526 layer_data *device_data = get_my_data_ptr(get_dispatch_key(cmdBuffer), layer_data_map);
527 char const str[] = "vkCmdCopyImage: Src and dest aspectMasks for each region must match";
528 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
529 (uint64_t)cmdBuffer, 0, IMAGE_MISMATCHED_IMAGE_ASPECT, "IMAGE", str);
530 }
531 if ((pRegions[i].srcSubresource.aspect & VK_IMAGE_ASPECT_COLOR) &&
532 (pRegions[i].srcSubresource.aspect & (VK_IMAGE_ASPECT_DEPTH | VK_IMAGE_ASPECT_STENCIL))) {
533 layer_data *device_data = get_my_data_ptr(get_dispatch_key(cmdBuffer), layer_data_map);
534 char const str[] = "vkCmdCopyImage aspectMask cannot specify both COLOR and DEPTH/STENCIL aspects";
535 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
536 (uint64_t)cmdBuffer, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", str);
537 }
538 }
539
540 if (VK_FALSE == skipCall) {
541 get_dispatch_table(image_device_table_map, cmdBuffer)->CmdCopyImage(cmdBuffer, srcImage,
542 srcImageLayout, destImage, destImageLayout, regionCount, pRegions);
543 }
544}
545
546VK_LAYER_EXPORT void VKAPI vkCmdCopyImageToBuffer(
547 VkCmdBuffer cmdBuffer,
548 VkImage srcImage,
549 VkImageLayout srcImageLayout,
550 VkBuffer destBuffer,
551 uint32_t regionCount,
552 const VkBufferImageCopy *pRegions)
553{
554 VkBool32 skipCall = VK_FALSE;
555
556 // Image aspect must be ONE OF color, depth, stencil
557 for (uint32_t i = 0; i < regionCount; i++) {
558 VkImageAspect aspect = pRegions[i].imageSubresource.aspect;
559 if ((aspect != VK_IMAGE_ASPECT_COLOR) &&
560 (aspect != VK_IMAGE_ASPECT_DEPTH) &&
561 (aspect != VK_IMAGE_ASPECT_STENCIL)) {
562 layer_data *device_data = get_my_data_ptr(get_dispatch_key(cmdBuffer), layer_data_map);
563 char const str[] = "vkCmdCopyImageToBuffer: aspectMasks for each region must specify only COLOR or DEPTH or STENCIL";
564 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
565 (uint64_t)cmdBuffer, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", str);
566 }
567 }
568
569 if (VK_FALSE == skipCall) {
570 get_dispatch_table(image_device_table_map, cmdBuffer)->CmdCopyImageToBuffer(cmdBuffer,
571 srcImage, srcImageLayout, destBuffer, regionCount, pRegions);
572 }
573}
574
575
576VK_LAYER_EXPORT void VKAPI vkCmdCopyBufferToImage(
577 VkCmdBuffer cmdBuffer,
578 VkBuffer srcBuffer,
579 VkImage destImage,
580 VkImageLayout destImageLayout,
581 uint32_t regionCount,
582 const VkBufferImageCopy *pRegions)
583{
584 VkBool32 skipCall = VK_FALSE;
585
586 // Image aspect must be ONE OF color, depth, stencil
587 for (uint32_t i = 0; i < regionCount; i++) {
588 VkImageAspect aspect = pRegions[i].imageSubresource.aspect;
589 if ((aspect != VK_IMAGE_ASPECT_COLOR) &&
590 (aspect != VK_IMAGE_ASPECT_DEPTH) &&
591 (aspect != VK_IMAGE_ASPECT_STENCIL)) {
592 layer_data *device_data = get_my_data_ptr(get_dispatch_key(cmdBuffer), layer_data_map);
593 char const str[] = "vkCmdCopyBufferToImage: aspectMasks for each region must specify only COLOR or DEPTH or STENCIL";
594 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
595 (uint64_t)cmdBuffer, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", str);
596 }
597 }
598
599 if (VK_FALSE == skipCall) {
600 get_dispatch_table(image_device_table_map, cmdBuffer)->CmdCopyBufferToImage(cmdBuffer,
601 srcBuffer, destImage, destImageLayout, regionCount, pRegions);
602 }
603}
604
605VK_LAYER_EXPORT void VKAPI vkCmdBlitImage(
606 VkCmdBuffer cmdBuffer,
607 VkImage srcImage,
608 VkImageLayout srcImageLayout,
609 VkImage destImage,
610 VkImageLayout destImageLayout,
611 uint32_t regionCount,
612 const VkImageBlit *pRegions,
613 VkTexFilter filter)
614{
615 // TODO: From the spec -- these validation items will require the image layer to maintain image/buffer state.
616 // If one of srcImage and destImage images has signed integer format, the other one must also have be signed integer format.
617 // If one of srcImage and destImage images has unsigned integer format, the other one must also have be an unsigned integer format.
618 // If the format of srcImage is a depth, stencil, depth stencil or integer-based format then filter must be VK_TEX_FILTER_NEAREST.
619 // If one of srcImage and destImage images has a format of depth, stencil or depth stencil, the other one must have exactly the same format.
620 // Additionally the allowed aspect bits in srcSubresource and destSubresource are only VK_IMAGE_ASPECT_DEPTH_BIT and
621 // VK_IMAGE_ASPECT_STENCIL_BIT and the given aspect must exist in the format of both srcImage and destImage images.
622
623 get_dispatch_table(image_device_table_map, cmdBuffer)->CmdBlitImage(cmdBuffer, srcImage,
624 srcImageLayout, destImage, destImageLayout, regionCount, pRegions, filter);
625}
626
627VK_LAYER_EXPORT void VKAPI vkCmdResolveImage(
628 VkCmdBuffer cmdBuffer,
629 VkImage srcImage,
630 VkImageLayout srcImageLayout,
631 VkImage destImage,
632 VkImageLayout destImageLayout,
633 uint32_t regionCount,
634 const VkImageResolve *pRegions)
635{
636 VkBool32 skipCall = VK_FALSE;
637
638 // For each region, src and dest image aspect must be color only
639 for (uint32_t i = 0; i < regionCount; i++) {
640 if ((pRegions[i].srcSubresource.aspect != VK_IMAGE_ASPECT_COLOR) ||
641 (pRegions[i].destSubresource.aspect != VK_IMAGE_ASPECT_COLOR)) {
642 layer_data *device_data = get_my_data_ptr(get_dispatch_key(cmdBuffer), layer_data_map);
643 char const str[] = "vkCmdResolveImage: src and dest aspectMasks for each region must specify only VK_IMAGE_ASPECT_COLOR_BIT";
644 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
645 (uint64_t)cmdBuffer, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", str);
646 }
647 }
648
649 if (VK_FALSE == skipCall) {
650 get_dispatch_table(image_device_table_map, cmdBuffer)->CmdResolveImage(cmdBuffer, srcImage,
651 srcImageLayout, destImage, destImageLayout, regionCount, pRegions);
652 }
653}
654
655VK_LAYER_EXPORT VkResult VKAPI vkGetImageSubresourceLayout(
656 VkDevice device,
657 VkImage image,
658 const VkImageSubresource *pSubresource,
659 VkSubresourceLayout *pLayout)
660{
661 VkResult result = get_dispatch_table(image_device_table_map, device)->GetImageSubresourceLayout(device,
662 image, pSubresource, pLayout);
663
664 // TODO: After state tracking for images/buffers is implemented, validate that returned aspects match
665 // the created formats -- color for color formats, depth|stencil for ds formats
666
667 return result;
668}
669
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -0600670VK_LAYER_EXPORT PFN_vkVoidFunction VKAPI vkGetDeviceProcAddr(VkDevice device, const char* funcName)
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600671{
672 if (device == NULL) {
673 return NULL;
674 }
675
676 /* loader uses this to force layer initialization; device object is wrapped */
677 if (!strcmp(funcName, "vkGetDeviceProcAddr")) {
678 initDeviceTable(image_device_table_map, (const VkBaseLayerObject *) device);
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -0600679 return (PFN_vkVoidFunction) vkGetDeviceProcAddr;
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600680 }
681
Courtney Goeltzenleuchterbe637992015-06-25 18:01:43 -0600682 if (!strcmp(funcName, "vkCreateDevice"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -0600683 return (PFN_vkVoidFunction) vkCreateDevice;
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600684 if (!strcmp(funcName, "vkDestroyDevice"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -0600685 return (PFN_vkVoidFunction) vkDestroyDevice;
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600686 if (!strcmp(funcName, "vkCreateImage"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -0600687 return (PFN_vkVoidFunction) vkCreateImage;
Tobin Ehlis342b9bf2015-09-22 10:11:37 -0600688 if (!strcmp(funcName, "vkCreateImageView"))
689 return (PFN_vkVoidFunction) vkCreateImageView;
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600690 if (!strcmp(funcName, "vkCreateRenderPass"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -0600691 return (PFN_vkVoidFunction) vkCreateRenderPass;
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600692 if (!strcmp(funcName, "vkCmdClearColorImage"))
693 return (PFN_vkVoidFunction) vkCmdClearColorImage;
694 if (!strcmp(funcName, "vkCmdClearDepthStencilImage"))
695 return (PFN_vkVoidFunction) vkCmdClearDepthStencilImage;
696 if (!strcmp(funcName, "vkCmdClearDepthStencilAttachment"))
697 return (PFN_vkVoidFunction) vkCmdClearDepthStencilAttachment;
698 if (!strcmp(funcName, "vkCmdCopyImage"))
699 return (PFN_vkVoidFunction) vkCmdCopyImage;
700 if (!strcmp(funcName, "vkCmdCopyImageToBuffer"))
701 return (PFN_vkVoidFunction) vkCmdCopyImageToBuffer;
702 if (!strcmp(funcName, "vkCmdCopyBufferToImage"))
703 return (PFN_vkVoidFunction) vkCmdCopyBufferToImage;
704 if (!strcmp(funcName, "vkCmdBlitImage"))
705 return (PFN_vkVoidFunction) vkCmdBlitImage;
706 if (!strcmp(funcName, "vkCmdResolveImage"))
707 return (PFN_vkVoidFunction) vkCmdResolveImage;
708 if (!strcmp(funcName, "vkGetImageSubresourceLayout"))
709 return (PFN_vkVoidFunction) vkGetImageSubresourceLayout;
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600710 {
711 if (get_dispatch_table(image_device_table_map, device)->GetDeviceProcAddr == NULL)
712 return NULL;
713 return get_dispatch_table(image_device_table_map, device)->GetDeviceProcAddr(device, funcName);
714 }
715}
716
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -0600717VK_LAYER_EXPORT PFN_vkVoidFunction VKAPI vkGetInstanceProcAddr(VkInstance instance, const char* funcName)
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600718{
719 if (instance == NULL) {
720 return NULL;
721 }
722
723 /* loader uses this to force layer initialization; instance object is wrapped */
724 if (!strcmp(funcName, "vkGetInstanceProcAddr")) {
725 initInstanceTable(image_instance_table_map, (const VkBaseLayerObject *) instance);
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -0600726 return (PFN_vkVoidFunction) vkGetInstanceProcAddr;
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600727 }
728
729 if (!strcmp(funcName, "vkCreateInstance"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -0600730 return (PFN_vkVoidFunction) vkCreateInstance;
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600731 if (!strcmp(funcName, "vkDestroyInstance"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -0600732 return (PFN_vkVoidFunction) vkDestroyInstance;
Courtney Goeltzenleuchter74c4ce92015-09-14 17:22:16 -0600733 if (!strcmp(funcName, "vkEnumerateInstanceLayerProperties"))
734 return (PFN_vkVoidFunction) vkEnumerateInstanceLayerProperties;
735 if (!strcmp(funcName, "vkEnumerateInstanceExtensionProperties"))
736 return (PFN_vkVoidFunction) vkEnumerateInstanceExtensionProperties;
737 if (!strcmp(funcName, "vkEnumerateDeviceLayerProperties"))
738 return (PFN_vkVoidFunction) vkEnumerateDeviceLayerProperties;
739 if (!strcmp(funcName, "vkEnumerateDeviceExtensionProperties"))
740 return (PFN_vkVoidFunction) vkEnumerateDeviceExtensionProperties;
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600741
742 layer_data *data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -0600743 PFN_vkVoidFunction fptr = debug_report_get_instance_proc_addr(data->report_data, funcName);
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600744 if(fptr)
745 return fptr;
746
747 {
748 if (get_dispatch_table(image_instance_table_map, instance)->GetInstanceProcAddr == NULL)
749 return NULL;
750 return get_dispatch_table(image_instance_table_map, instance)->GetInstanceProcAddr(instance, funcName);
751 }
752}