blob: d822b2eba362c699bcb892a06c1aa27ae87400a6 [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
Jeremy Hayesb707aa52015-06-18 10:12:39 -060049typedef struct _layer_data {
50 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;
Jeremy Hayesb707aa52015-06-18 10:12:39 -060054} layer_data;
55
Tobin Ehlis65380532015-09-21 15:20:28 -060056static unordered_map<void*, layer_data*> layer_data_map;
Jeremy Hayesb707aa52015-06-18 10:12:39 -060057static device_table_map image_device_table_map;
58static instance_table_map image_instance_table_map;
59
60// "my device data"
Tony Barbour2a199c12015-07-09 17:31:46 -060061debug_report_data *mdd(const void* object)
Jeremy Hayesb707aa52015-06-18 10:12:39 -060062{
63 dispatch_key key = get_dispatch_key(object);
64 layer_data *data = get_my_data_ptr(key, layer_data_map);
65#if DISPATCH_MAP_DEBUG
66 fprintf(stderr, "MDD: map: %p, object: %p, key: %p, data: %p\n", &layer_data_map, object, key, data);
67#endif
Jeremy Hayesb707aa52015-06-18 10:12:39 -060068 return data->report_data;
69}
70
71// "my instance data"
72debug_report_data *mid(VkInstance object)
73{
74 dispatch_key key = get_dispatch_key(object);
Courtney Goeltzenleuchter07199212015-06-22 16:19:14 -060075 layer_data *data = get_my_data_ptr(key, layer_data_map);
Jeremy Hayesb707aa52015-06-18 10:12:39 -060076#if DISPATCH_MAP_DEBUG
77 fprintf(stderr, "MID: map: %p, object: %p, key: %p, data: %p\n", &layer_data_map, object, key, data);
78#endif
Jeremy Hayesb707aa52015-06-18 10:12:39 -060079 return data->report_data;
80}
81
82static void InitImage(layer_data *data)
83{
84 uint32_t report_flags = getLayerOptionFlags("ImageReportFlags", 0);
85
86 uint32_t debug_action = 0;
87 getLayerOptionEnum("ImageDebugAction", (uint32_t *) &debug_action);
88 if(debug_action & VK_DBG_LAYER_ACTION_LOG_MSG)
89 {
90 FILE *log_output = NULL;
91 const char* option_str = getLayerOption("ImageLogFilename");
Tobin Ehlisb4b6e7c2015-09-15 09:55:54 -060092 log_output = getLayerLogOutput(option_str, "Image");
Jeremy Hayesb707aa52015-06-18 10:12:39 -060093 layer_create_msg_callback(data->report_data, report_flags, log_callback, (void*)log_output, &data->logging_callback);
94 }
95}
96
97VK_LAYER_EXPORT VkResult VKAPI vkDbgCreateMsgCallback(
98 VkInstance instance,
99 VkFlags msgFlags,
100 const PFN_vkDbgMsgCallback pfnMsgCallback,
101 void* pUserData,
102 VkDbgMsgCallback* pMsgCallback)
103{
104 VkLayerInstanceDispatchTable *pTable = get_dispatch_table(image_instance_table_map, instance);
105 VkResult res = pTable->DbgCreateMsgCallback(instance, msgFlags, pfnMsgCallback, pUserData, pMsgCallback);
106 if (res == VK_SUCCESS) {
107 layer_data *data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
108
109 res = layer_create_msg_callback(data->report_data, msgFlags, pfnMsgCallback, pUserData, pMsgCallback);
110 }
111 return res;
112}
113
114VK_LAYER_EXPORT VkResult VKAPI vkDbgDestroyMsgCallback(
115 VkInstance instance,
116 VkDbgMsgCallback msgCallback)
117{
118 VkLayerInstanceDispatchTable *pTable = get_dispatch_table(image_instance_table_map, instance);
119 VkResult res = pTable->DbgDestroyMsgCallback(instance, msgCallback);
120
121 layer_data *data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
122 layer_destroy_msg_callback(data->report_data, msgCallback);
123
124 return res;
125}
126
127VK_LAYER_EXPORT VkResult VKAPI vkCreateInstance(const VkInstanceCreateInfo* pCreateInfo, VkInstance* pInstance)
128{
129 VkLayerInstanceDispatchTable *pTable = get_dispatch_table(image_instance_table_map, *pInstance);
130 VkResult result = pTable->CreateInstance(pCreateInfo, pInstance);
131
132 if (result == VK_SUCCESS) {
133 layer_data *data = get_my_data_ptr(get_dispatch_key(*pInstance), layer_data_map);
134 data->report_data = debug_report_create_instance(pTable, *pInstance, pCreateInfo->extensionCount,
Courtney Goeltzenleuchtereb1ddb02015-07-07 11:18:30 -0600135 pCreateInfo->ppEnabledExtensionNames);
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600136
137 InitImage(data);
138 }
139
140 return result;
141}
142
Mark Lobodzinski67b42b72015-09-07 13:59:43 -0600143VK_LAYER_EXPORT void VKAPI vkDestroyInstance(VkInstance instance)
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600144{
145 // Grab the key before the instance is destroyed.
146 dispatch_key key = get_dispatch_key(instance);
147 VkLayerInstanceDispatchTable *pTable = get_dispatch_table(image_instance_table_map, instance);
Mark Lobodzinski67b42b72015-09-07 13:59:43 -0600148 pTable->DestroyInstance(instance);
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600149
150 // Clean up logging callback, if any
151 layer_data *data = get_my_data_ptr(key, layer_data_map);
152 if(data->logging_callback)
153 {
154 layer_destroy_msg_callback(data->report_data, data->logging_callback);
155 }
156
157 layer_debug_report_destroy_instance(mid(instance));
158 layer_data_map.erase(pTable);
159
160 image_instance_table_map.erase(key);
161 assert(image_instance_table_map.size() == 0 && "Should not have any instance mappings hanging around");
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600162}
163
164VK_LAYER_EXPORT VkResult VKAPI vkCreateDevice(VkPhysicalDevice physicalDevice, const VkDeviceCreateInfo* pCreateInfo, VkDevice* pDevice)
165{
Courtney Goeltzenleuchterbe637992015-06-25 18:01:43 -0600166 VkLayerDispatchTable *pTable = get_dispatch_table(image_device_table_map, *pDevice);
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600167 VkResult result = pTable->CreateDevice(physicalDevice, pCreateInfo, pDevice);
168 if(result == VK_SUCCESS)
169 {
170 layer_data *instance_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);
171 layer_data *device_data = get_my_data_ptr(get_dispatch_key(*pDevice), layer_data_map);
172 device_data->report_data = layer_debug_report_create_device(instance_data->report_data, *pDevice);
Chris Forbesd7576302015-06-21 22:55:02 +1200173 device_data->physicalDevice = physicalDevice;
Tobin Ehlis342b9bf2015-09-22 10:11:37 -0600174 device_data->imageMap.reserve(10);
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600175 }
176
177 return result;
178}
179
Mark Lobodzinski67b42b72015-09-07 13:59:43 -0600180VK_LAYER_EXPORT void VKAPI vkDestroyDevice(VkDevice device)
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600181{
182 layer_debug_report_destroy_device(device);
183
184 dispatch_key key = get_dispatch_key(device);
185#if DISPATCH_MAP_DEBUG
186 fprintf(stderr, "Device: %p, key: %p\n", device, key);
187#endif
188
Mark Lobodzinski67b42b72015-09-07 13:59:43 -0600189 get_dispatch_table(image_device_table_map, device)->DestroyDevice(device);
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600190 image_device_table_map.erase(key);
191 assert(image_device_table_map.size() == 0 && "Should not have any instance mappings hanging around");
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600192}
193
Courtney Goeltzenleuchtereb1ddb02015-07-07 11:18:30 -0600194static const VkLayerProperties pc_global_layers[] = {
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600195 {
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600196 "Image",
Courtney Goeltzenleuchtereb1ddb02015-07-07 11:18:30 -0600197 VK_API_VERSION,
198 VK_MAKE_VERSION(0, 1, 0),
199 "Validation layer: Image ParamChecker",
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600200 }
201};
202
Courtney Goeltzenleuchter74c4ce92015-09-14 17:22:16 -0600203VK_LAYER_EXPORT VkResult VKAPI vkEnumerateInstanceExtensionProperties(
Courtney Goeltzenleuchtereb1ddb02015-07-07 11:18:30 -0600204 const char *pLayerName,
205 uint32_t *pCount,
206 VkExtensionProperties* pProperties)
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600207{
Courtney Goeltzenleuchtereb1ddb02015-07-07 11:18:30 -0600208 /* ParamChecker does not have any global extensions */
209 return util_GetExtensionProperties(0, NULL, pCount, pProperties);
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600210}
211
Courtney Goeltzenleuchter74c4ce92015-09-14 17:22:16 -0600212VK_LAYER_EXPORT VkResult VKAPI vkEnumerateInstanceLayerProperties(
Courtney Goeltzenleuchtereb1ddb02015-07-07 11:18:30 -0600213 uint32_t *pCount,
214 VkLayerProperties* pProperties)
Tony Barbour426b9052015-06-24 16:06:58 -0600215{
Courtney Goeltzenleuchtereb1ddb02015-07-07 11:18:30 -0600216 return util_GetLayerProperties(ARRAY_SIZE(pc_global_layers),
217 pc_global_layers,
218 pCount, pProperties);
Tony Barbour426b9052015-06-24 16:06:58 -0600219}
220
Courtney Goeltzenleuchter74c4ce92015-09-14 17:22:16 -0600221VK_LAYER_EXPORT VkResult VKAPI vkEnumerateDeviceExtensionProperties(
Courtney Goeltzenleuchtereb1ddb02015-07-07 11:18:30 -0600222 VkPhysicalDevice physicalDevice,
223 const char* pLayerName,
224 uint32_t* pCount,
225 VkExtensionProperties* pProperties)
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600226{
Courtney Goeltzenleuchtereb1ddb02015-07-07 11:18:30 -0600227 /* ParamChecker does not have any physical device extensions */
228 return util_GetExtensionProperties(0, NULL, pCount, pProperties);
229}
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600230
Courtney Goeltzenleuchter74c4ce92015-09-14 17:22:16 -0600231VK_LAYER_EXPORT VkResult VKAPI vkEnumerateDeviceLayerProperties(
Courtney Goeltzenleuchtereb1ddb02015-07-07 11:18:30 -0600232 VkPhysicalDevice physicalDevice,
233 uint32_t* pCount,
234 VkLayerProperties* pProperties)
235{
236 /* ParamChecker's physical device layers are the same as global */
237 return util_GetLayerProperties(ARRAY_SIZE(pc_global_layers), pc_global_layers,
238 pCount, pProperties);
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600239}
240
Mark Lobodzinski9cce7832015-07-29 09:21:22 -0600241// Start of the Image layer proper
242
243// Returns TRUE if a format is a depth-compatible format
244bool is_depth_format(VkFormat format)
245{
246 bool result = VK_FALSE;
247 switch (format) {
248 case VK_FORMAT_D16_UNORM:
Courtney Goeltzenleuchter7ed10592015-09-10 17:17:43 -0600249 case VK_FORMAT_D24_UNORM_X8:
Mark Lobodzinski9cce7832015-07-29 09:21:22 -0600250 case VK_FORMAT_D32_SFLOAT:
251 case VK_FORMAT_S8_UINT:
252 case VK_FORMAT_D16_UNORM_S8_UINT:
253 case VK_FORMAT_D24_UNORM_S8_UINT:
254 case VK_FORMAT_D32_SFLOAT_S8_UINT:
255 result = VK_TRUE;
256 break;
257 default:
258 break;
259 }
260 return result;
261}
262
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600263VK_LAYER_EXPORT VkResult VKAPI vkCreateImage(VkDevice device, const VkImageCreateInfo* pCreateInfo, VkImage* pImage)
264{
Tobin Ehlis35613802015-09-22 08:40:52 -0600265 VkBool32 skipCall = VK_FALSE;
Tobin Ehlis65380532015-09-21 15:20:28 -0600266 layer_data *device_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600267 if(pCreateInfo->format != VK_FORMAT_UNDEFINED)
268 {
269 VkFormatProperties properties;
Courtney Goeltzenleuchterab36aa62015-07-12 12:40:29 -0600270 VkResult result = get_dispatch_table(image_instance_table_map, device_data->physicalDevice)->GetPhysicalDeviceFormatProperties(
Chris Forbesd7576302015-06-21 22:55:02 +1200271 device_data->physicalDevice, pCreateInfo->format, &properties);
Tobin Ehlis65380532015-09-21 15:20:28 -0600272 if(result != VK_SUCCESS) {
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600273 char const str[] = "vkCreateImage parameter, VkFormat pCreateInfo->format, cannot be validated";
Tobin Ehlis35613802015-09-22 08:40:52 -0600274 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 -0600275 }
276
277 if((properties.linearTilingFeatures) == 0 && (properties.optimalTilingFeatures == 0))
278 {
279 char const str[] = "vkCreateImage parameter, VkFormat pCreateInfo->format, contains unsupported format";
Tobin Ehlis35613802015-09-22 08:40:52 -0600280 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 -0600281 }
282 }
Tobin Ehlis35613802015-09-22 08:40:52 -0600283 if (skipCall)
284 return VK_ERROR_VALIDATION_FAILED;
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600285
286 VkResult result = get_dispatch_table(image_device_table_map, device)->CreateImage(device, pCreateInfo, pImage);
287
Tobin Ehlis65380532015-09-21 15:20:28 -0600288 if(result == VK_SUCCESS) {
Tobin Ehlis342b9bf2015-09-22 10:11:37 -0600289 device_data->imageMap[pImage->handle] = unique_ptr<IMAGE_STATE>(new IMAGE_STATE(pCreateInfo));
Tobin Ehlis65380532015-09-21 15:20:28 -0600290 }
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600291 return result;
292}
293
Tobin Ehlis65380532015-09-21 15:20:28 -0600294VK_LAYER_EXPORT void VKAPI vkDestroyImage(VkDevice device, VkImage image)
295{
296 layer_data *device_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
297 device_data->imageMap.erase(image.handle);
298 get_dispatch_table(image_device_table_map, device)->DestroyImage(device, image);
299}
300
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600301VK_LAYER_EXPORT VkResult VKAPI vkCreateRenderPass(VkDevice device, const VkRenderPassCreateInfo* pCreateInfo, VkRenderPass* pRenderPass)
302{
Tobin Ehlis35613802015-09-22 08:40:52 -0600303 VkBool32 skipCall = VK_FALSE;
Chia-I Wuc278df82015-07-07 11:50:03 +0800304 for(uint32_t i = 0; i < pCreateInfo->attachmentCount; ++i)
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600305 {
Chia-I Wuc278df82015-07-07 11:50:03 +0800306 if(pCreateInfo->pAttachments[i].format != VK_FORMAT_UNDEFINED)
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600307 {
Courtney Goeltzenleuchter07199212015-06-22 16:19:14 -0600308 layer_data *device_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600309 VkFormatProperties properties;
Courtney Goeltzenleuchterab36aa62015-07-12 12:40:29 -0600310 VkResult result = get_dispatch_table(image_instance_table_map, device_data->physicalDevice)->GetPhysicalDeviceFormatProperties(
Chia-I Wuc278df82015-07-07 11:50:03 +0800311 device_data->physicalDevice, pCreateInfo->pAttachments[i].format, &properties);
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600312 if(result != VK_SUCCESS)
313 {
314 std::stringstream ss;
Chia-I Wuc278df82015-07-07 11:50:03 +0800315 ss << "vkCreateRenderPass parameter, VkFormat in pCreateInfo->pAttachments[" << i << "], cannot be validated";
Tobin Ehlis35613802015-09-22 08:40:52 -0600316 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 -0600317 continue;
318 }
319
320 if((properties.linearTilingFeatures) == 0 && (properties.optimalTilingFeatures == 0))
321 {
322 std::stringstream ss;
Chia-I Wuc278df82015-07-07 11:50:03 +0800323 ss << "vkCreateRenderPass parameter, VkFormat in pCreateInfo->pAttachments[" << i << "], contains unsupported format";
Tobin Ehlis35613802015-09-22 08:40:52 -0600324 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 -0600325 }
326 }
327 }
328
Chia-I Wuc278df82015-07-07 11:50:03 +0800329 for(uint32_t i = 0; i < pCreateInfo->attachmentCount; ++i)
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600330 {
Chia-I Wuc278df82015-07-07 11:50:03 +0800331 if(!validate_VkImageLayout(pCreateInfo->pAttachments[i].initialLayout) ||
332 !validate_VkImageLayout(pCreateInfo->pAttachments[i].finalLayout))
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600333 {
334 std::stringstream ss;
Chia-I Wuc278df82015-07-07 11:50:03 +0800335 ss << "vkCreateRenderPass parameter, VkImageLayout in pCreateInfo->pAttachments[" << i << "], is unrecognized";
Tobin Ehlis35613802015-09-22 08:40:52 -0600336 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 -0600337 }
338 }
339
Chia-I Wuc278df82015-07-07 11:50:03 +0800340 for(uint32_t i = 0; i < pCreateInfo->attachmentCount; ++i)
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600341 {
Chia-I Wuc278df82015-07-07 11:50:03 +0800342 if(!validate_VkAttachmentLoadOp(pCreateInfo->pAttachments[i].loadOp))
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600343 {
344 std::stringstream ss;
Chia-I Wuc278df82015-07-07 11:50:03 +0800345 ss << "vkCreateRenderPass parameter, VkAttachmentLoadOp in pCreateInfo->pAttachments[" << i << "], is unrecognized";
Tobin Ehlis35613802015-09-22 08:40:52 -0600346 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 -0600347 }
348 }
349
Chia-I Wuc278df82015-07-07 11:50:03 +0800350 for(uint32_t i = 0; i < pCreateInfo->attachmentCount; ++i)
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600351 {
Chia-I Wuc278df82015-07-07 11:50:03 +0800352 if(!validate_VkAttachmentStoreOp(pCreateInfo->pAttachments[i].storeOp))
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600353 {
354 std::stringstream ss;
Chia-I Wuc278df82015-07-07 11:50:03 +0800355 ss << "vkCreateRenderPass parameter, VkAttachmentStoreOp in pCreateInfo->pAttachments[" << i << "], is unrecognized";
Tobin Ehlis35613802015-09-22 08:40:52 -0600356 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 -0600357 }
358 }
359
Mark Lobodzinski9cce7832015-07-29 09:21:22 -0600360 // Any depth buffers specified as attachments?
361 bool depthFormatPresent = VK_FALSE;
362 for (uint32_t i = 0; i < pCreateInfo->attachmentCount; ++i)
363 {
364 depthFormatPresent |= is_depth_format(pCreateInfo->pAttachments[i].format);
365 }
366
367 if (depthFormatPresent == VK_FALSE) {
368 // No depth attachment is present, validate that subpasses set depthStencilAttachment to VK_ATTACHMENT_UNUSED;
369 for (uint32_t i = 0; i < pCreateInfo->subpassCount; i++) {
370 if (pCreateInfo->pSubpasses[i].depthStencilAttachment.attachment != VK_ATTACHMENT_UNUSED) {
371 std::stringstream ss;
372 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 -0600373 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 -0600374 }
375 }
376 }
Tobin Ehlis35613802015-09-22 08:40:52 -0600377 if (skipCall)
378 return VK_ERROR_VALIDATION_FAILED;
Mark Lobodzinski9cce7832015-07-29 09:21:22 -0600379
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600380 VkResult result = get_dispatch_table(image_device_table_map, device)->CreateRenderPass(device, pCreateInfo, pRenderPass);
381
382 return result;
383}
384
Tobin Ehlis65380532015-09-21 15:20:28 -0600385VK_LAYER_EXPORT VkResult VKAPI vkCreateImageView(VkDevice device, const VkImageViewCreateInfo* pCreateInfo, VkImageView* pView)
386{
387 VkBool32 skipCall = VK_FALSE;
388 layer_data *device_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
389 auto imageEntry = device_data->imageMap.find(pCreateInfo->image.handle);
390 if (imageEntry != device_data->imageMap.end()) {
391 if (pCreateInfo->subresourceRange.baseMipLevel >= imageEntry->second->mipLevels) {
392 std::stringstream ss;
393 ss << "vkCreateImageView called with baseMipLevel " << pCreateInfo->subresourceRange.baseMipLevel << " for image " << pCreateInfo->image.handle << " that only has " << imageEntry->second->mipLevels << " mip levels.";
394 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());
395 }
396 if (pCreateInfo->subresourceRange.baseArrayLayer >= imageEntry->second->arraySize) {
397 std::stringstream ss;
398 ss << "vkCreateImageView called with baseArrayLayer " << pCreateInfo->subresourceRange.baseArrayLayer << " for image " << pCreateInfo->image.handle << " that only has " << imageEntry->second->arraySize << " 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.mipLevels) {
402 std::stringstream ss;
403 ss << "vkCreateImageView called with 0 in pCreateInfo->subresourceRange.mipLevels.";
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.arraySize) {
407 std::stringstream ss;
408 ss << "vkCreateImageView called with 0 in pCreateInfo->subresourceRange.arraySize.";
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 }
412 if (skipCall)
413 return VK_ERROR_VALIDATION_FAILED;
Tobin Ehlis35613802015-09-22 08:40:52 -0600414
Tobin Ehlis65380532015-09-21 15:20:28 -0600415 VkResult result = get_dispatch_table(image_device_table_map, device)->CreateImageView(device, pCreateInfo, pView);
416 return result;
417}
418
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -0600419VK_LAYER_EXPORT PFN_vkVoidFunction VKAPI vkGetDeviceProcAddr(VkDevice device, const char* funcName)
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600420{
421 if (device == NULL) {
422 return NULL;
423 }
424
425 /* loader uses this to force layer initialization; device object is wrapped */
426 if (!strcmp(funcName, "vkGetDeviceProcAddr")) {
427 initDeviceTable(image_device_table_map, (const VkBaseLayerObject *) device);
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -0600428 return (PFN_vkVoidFunction) vkGetDeviceProcAddr;
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600429 }
430
Courtney Goeltzenleuchterbe637992015-06-25 18:01:43 -0600431 if (!strcmp(funcName, "vkCreateDevice"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -0600432 return (PFN_vkVoidFunction) vkCreateDevice;
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600433 if (!strcmp(funcName, "vkDestroyDevice"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -0600434 return (PFN_vkVoidFunction) vkDestroyDevice;
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600435 if (!strcmp(funcName, "vkCreateImage"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -0600436 return (PFN_vkVoidFunction) vkCreateImage;
Tobin Ehlis342b9bf2015-09-22 10:11:37 -0600437 if (!strcmp(funcName, "vkCreateImageView"))
438 return (PFN_vkVoidFunction) vkCreateImageView;
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600439 if (!strcmp(funcName, "vkCreateRenderPass"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -0600440 return (PFN_vkVoidFunction) vkCreateRenderPass;
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600441
442 {
443 if (get_dispatch_table(image_device_table_map, device)->GetDeviceProcAddr == NULL)
444 return NULL;
445 return get_dispatch_table(image_device_table_map, device)->GetDeviceProcAddr(device, funcName);
446 }
447}
448
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -0600449VK_LAYER_EXPORT PFN_vkVoidFunction VKAPI vkGetInstanceProcAddr(VkInstance instance, const char* funcName)
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600450{
451 if (instance == NULL) {
452 return NULL;
453 }
454
455 /* loader uses this to force layer initialization; instance object is wrapped */
456 if (!strcmp(funcName, "vkGetInstanceProcAddr")) {
457 initInstanceTable(image_instance_table_map, (const VkBaseLayerObject *) instance);
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -0600458 return (PFN_vkVoidFunction) vkGetInstanceProcAddr;
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600459 }
460
461 if (!strcmp(funcName, "vkCreateInstance"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -0600462 return (PFN_vkVoidFunction) vkCreateInstance;
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600463 if (!strcmp(funcName, "vkDestroyInstance"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -0600464 return (PFN_vkVoidFunction) vkDestroyInstance;
Courtney Goeltzenleuchter74c4ce92015-09-14 17:22:16 -0600465 if (!strcmp(funcName, "vkEnumerateInstanceLayerProperties"))
466 return (PFN_vkVoidFunction) vkEnumerateInstanceLayerProperties;
467 if (!strcmp(funcName, "vkEnumerateInstanceExtensionProperties"))
468 return (PFN_vkVoidFunction) vkEnumerateInstanceExtensionProperties;
469 if (!strcmp(funcName, "vkEnumerateDeviceLayerProperties"))
470 return (PFN_vkVoidFunction) vkEnumerateDeviceLayerProperties;
471 if (!strcmp(funcName, "vkEnumerateDeviceExtensionProperties"))
472 return (PFN_vkVoidFunction) vkEnumerateDeviceExtensionProperties;
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600473
474 layer_data *data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -0600475 PFN_vkVoidFunction fptr = debug_report_get_instance_proc_addr(data->report_data, funcName);
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600476 if(fptr)
477 return fptr;
478
479 {
480 if (get_dispatch_table(image_instance_table_map, instance)->GetInstanceProcAddr == NULL)
481 return NULL;
482 return get_dispatch_table(image_instance_table_map, instance)->GetInstanceProcAddr(instance, funcName);
483 }
484}