blob: 93579c720d2637f7d5bfefb169ad5a02ba0d6b12 [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"
Mike Stroyan43909d82015-09-25 13:39:21 -060046#include "vk_layer_utils.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;
52 VkDbgMsgCallback logging_callback;
Chris Forbesd7576302015-06-21 22:55:02 +120053 VkPhysicalDevice physicalDevice;
Tobin Ehlis342b9bf2015-09-22 10:11:37 -060054 unordered_map<uint64_t, unique_ptr<IMAGE_STATE>> imageMap;
Cody Northrop73bb6572015-09-28 15:09:32 -060055
56 layer_data() :
57 report_data(nullptr),
58 logging_callback(nullptr),
59 physicalDevice(0)
60 {};
61};
Jeremy Hayesb707aa52015-06-18 10:12:39 -060062
Tobin Ehlis65380532015-09-21 15:20:28 -060063static unordered_map<void*, layer_data*> layer_data_map;
Jeremy Hayesb707aa52015-06-18 10:12:39 -060064static device_table_map image_device_table_map;
65static instance_table_map image_instance_table_map;
66
67// "my device data"
Tony Barbour2a199c12015-07-09 17:31:46 -060068debug_report_data *mdd(const void* object)
Jeremy Hayesb707aa52015-06-18 10:12:39 -060069{
70 dispatch_key key = get_dispatch_key(object);
71 layer_data *data = get_my_data_ptr(key, layer_data_map);
72#if DISPATCH_MAP_DEBUG
73 fprintf(stderr, "MDD: map: %p, object: %p, key: %p, data: %p\n", &layer_data_map, object, key, data);
74#endif
Jeremy Hayesb707aa52015-06-18 10:12:39 -060075 return data->report_data;
76}
77
78// "my instance data"
79debug_report_data *mid(VkInstance object)
80{
81 dispatch_key key = get_dispatch_key(object);
Courtney Goeltzenleuchter07199212015-06-22 16:19:14 -060082 layer_data *data = get_my_data_ptr(key, layer_data_map);
Jeremy Hayesb707aa52015-06-18 10:12:39 -060083#if DISPATCH_MAP_DEBUG
84 fprintf(stderr, "MID: map: %p, object: %p, key: %p, data: %p\n", &layer_data_map, object, key, data);
85#endif
Jeremy Hayesb707aa52015-06-18 10:12:39 -060086 return data->report_data;
87}
88
89static void InitImage(layer_data *data)
90{
91 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");
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600100 layer_create_msg_callback(data->report_data, report_flags, log_callback, (void*)log_output, &data->logging_callback);
101 }
102}
103
104VK_LAYER_EXPORT VkResult VKAPI vkDbgCreateMsgCallback(
105 VkInstance instance,
106 VkFlags msgFlags,
107 const PFN_vkDbgMsgCallback pfnMsgCallback,
108 void* pUserData,
109 VkDbgMsgCallback* pMsgCallback)
110{
111 VkLayerInstanceDispatchTable *pTable = get_dispatch_table(image_instance_table_map, instance);
112 VkResult res = pTable->DbgCreateMsgCallback(instance, msgFlags, pfnMsgCallback, pUserData, pMsgCallback);
113 if (res == VK_SUCCESS) {
114 layer_data *data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
115
116 res = layer_create_msg_callback(data->report_data, msgFlags, pfnMsgCallback, pUserData, pMsgCallback);
117 }
118 return res;
119}
120
121VK_LAYER_EXPORT VkResult VKAPI vkDbgDestroyMsgCallback(
122 VkInstance instance,
123 VkDbgMsgCallback msgCallback)
124{
125 VkLayerInstanceDispatchTable *pTable = get_dispatch_table(image_instance_table_map, instance);
126 VkResult res = pTable->DbgDestroyMsgCallback(instance, msgCallback);
127
128 layer_data *data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
129 layer_destroy_msg_callback(data->report_data, msgCallback);
130
131 return res;
132}
133
134VK_LAYER_EXPORT VkResult VKAPI vkCreateInstance(const VkInstanceCreateInfo* pCreateInfo, VkInstance* pInstance)
135{
136 VkLayerInstanceDispatchTable *pTable = get_dispatch_table(image_instance_table_map, *pInstance);
137 VkResult result = pTable->CreateInstance(pCreateInfo, pInstance);
138
139 if (result == VK_SUCCESS) {
140 layer_data *data = get_my_data_ptr(get_dispatch_key(*pInstance), layer_data_map);
141 data->report_data = debug_report_create_instance(pTable, *pInstance, pCreateInfo->extensionCount,
Courtney Goeltzenleuchtereb1ddb02015-07-07 11:18:30 -0600142 pCreateInfo->ppEnabledExtensionNames);
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600143
144 InitImage(data);
145 }
146
147 return result;
148}
149
Mark Lobodzinski67b42b72015-09-07 13:59:43 -0600150VK_LAYER_EXPORT void VKAPI vkDestroyInstance(VkInstance instance)
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600151{
152 // Grab the key before the instance is destroyed.
153 dispatch_key key = get_dispatch_key(instance);
154 VkLayerInstanceDispatchTable *pTable = get_dispatch_table(image_instance_table_map, instance);
Mark Lobodzinski67b42b72015-09-07 13:59:43 -0600155 pTable->DestroyInstance(instance);
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600156
157 // Clean up logging callback, if any
158 layer_data *data = get_my_data_ptr(key, layer_data_map);
159 if(data->logging_callback)
160 {
161 layer_destroy_msg_callback(data->report_data, data->logging_callback);
162 }
163
164 layer_debug_report_destroy_instance(mid(instance));
165 layer_data_map.erase(pTable);
166
167 image_instance_table_map.erase(key);
168 assert(image_instance_table_map.size() == 0 && "Should not have any instance mappings hanging around");
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600169}
170
171VK_LAYER_EXPORT VkResult VKAPI vkCreateDevice(VkPhysicalDevice physicalDevice, const VkDeviceCreateInfo* pCreateInfo, VkDevice* pDevice)
172{
Courtney Goeltzenleuchterbe637992015-06-25 18:01:43 -0600173 VkLayerDispatchTable *pTable = get_dispatch_table(image_device_table_map, *pDevice);
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600174 VkResult result = pTable->CreateDevice(physicalDevice, pCreateInfo, pDevice);
175 if(result == VK_SUCCESS)
176 {
177 layer_data *instance_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);
178 layer_data *device_data = get_my_data_ptr(get_dispatch_key(*pDevice), layer_data_map);
179 device_data->report_data = layer_debug_report_create_device(instance_data->report_data, *pDevice);
Chris Forbesd7576302015-06-21 22:55:02 +1200180 device_data->physicalDevice = physicalDevice;
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600181 }
182
183 return result;
184}
185
Mark Lobodzinski67b42b72015-09-07 13:59:43 -0600186VK_LAYER_EXPORT void VKAPI vkDestroyDevice(VkDevice device)
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600187{
188 layer_debug_report_destroy_device(device);
189
190 dispatch_key key = get_dispatch_key(device);
191#if DISPATCH_MAP_DEBUG
192 fprintf(stderr, "Device: %p, key: %p\n", device, key);
193#endif
194
Mark Lobodzinski67b42b72015-09-07 13:59:43 -0600195 get_dispatch_table(image_device_table_map, device)->DestroyDevice(device);
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600196 image_device_table_map.erase(key);
197 assert(image_device_table_map.size() == 0 && "Should not have any instance mappings hanging around");
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600198}
199
Courtney Goeltzenleuchtereb1ddb02015-07-07 11:18:30 -0600200static const VkLayerProperties pc_global_layers[] = {
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600201 {
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600202 "Image",
Courtney Goeltzenleuchtereb1ddb02015-07-07 11:18:30 -0600203 VK_API_VERSION,
204 VK_MAKE_VERSION(0, 1, 0),
205 "Validation layer: Image ParamChecker",
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600206 }
207};
208
Courtney Goeltzenleuchter74c4ce92015-09-14 17:22:16 -0600209VK_LAYER_EXPORT VkResult VKAPI vkEnumerateInstanceExtensionProperties(
Courtney Goeltzenleuchtereb1ddb02015-07-07 11:18:30 -0600210 const char *pLayerName,
211 uint32_t *pCount,
212 VkExtensionProperties* pProperties)
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600213{
Courtney Goeltzenleuchtereb1ddb02015-07-07 11:18:30 -0600214 /* ParamChecker does not have any global extensions */
215 return util_GetExtensionProperties(0, NULL, pCount, pProperties);
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600216}
217
Courtney Goeltzenleuchter74c4ce92015-09-14 17:22:16 -0600218VK_LAYER_EXPORT VkResult VKAPI vkEnumerateInstanceLayerProperties(
Courtney Goeltzenleuchtereb1ddb02015-07-07 11:18:30 -0600219 uint32_t *pCount,
220 VkLayerProperties* pProperties)
Tony Barbour426b9052015-06-24 16:06:58 -0600221{
Courtney Goeltzenleuchtereb1ddb02015-07-07 11:18:30 -0600222 return util_GetLayerProperties(ARRAY_SIZE(pc_global_layers),
223 pc_global_layers,
224 pCount, pProperties);
Tony Barbour426b9052015-06-24 16:06:58 -0600225}
226
Courtney Goeltzenleuchter74c4ce92015-09-14 17:22:16 -0600227VK_LAYER_EXPORT VkResult VKAPI vkEnumerateDeviceExtensionProperties(
Courtney Goeltzenleuchtereb1ddb02015-07-07 11:18:30 -0600228 VkPhysicalDevice physicalDevice,
229 const char* pLayerName,
230 uint32_t* pCount,
231 VkExtensionProperties* pProperties)
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600232{
Courtney Goeltzenleuchtereb1ddb02015-07-07 11:18:30 -0600233 /* ParamChecker does not have any physical device extensions */
234 return util_GetExtensionProperties(0, NULL, pCount, pProperties);
235}
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600236
Courtney Goeltzenleuchter74c4ce92015-09-14 17:22:16 -0600237VK_LAYER_EXPORT VkResult VKAPI vkEnumerateDeviceLayerProperties(
Courtney Goeltzenleuchtereb1ddb02015-07-07 11:18:30 -0600238 VkPhysicalDevice physicalDevice,
239 uint32_t* pCount,
240 VkLayerProperties* pProperties)
241{
242 /* ParamChecker's physical device layers are the same as global */
243 return util_GetLayerProperties(ARRAY_SIZE(pc_global_layers), pc_global_layers,
244 pCount, pProperties);
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600245}
246
Mark Lobodzinski9cce7832015-07-29 09:21:22 -0600247// Start of the Image layer proper
248
249// Returns TRUE if a format is a depth-compatible format
250bool is_depth_format(VkFormat format)
251{
252 bool result = VK_FALSE;
253 switch (format) {
254 case VK_FORMAT_D16_UNORM:
Courtney Goeltzenleuchter7ed10592015-09-10 17:17:43 -0600255 case VK_FORMAT_D24_UNORM_X8:
Mark Lobodzinski9cce7832015-07-29 09:21:22 -0600256 case VK_FORMAT_D32_SFLOAT:
257 case VK_FORMAT_S8_UINT:
258 case VK_FORMAT_D16_UNORM_S8_UINT:
259 case VK_FORMAT_D24_UNORM_S8_UINT:
260 case VK_FORMAT_D32_SFLOAT_S8_UINT:
261 result = VK_TRUE;
262 break;
263 default:
264 break;
265 }
266 return result;
267}
268
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600269VK_LAYER_EXPORT VkResult VKAPI vkCreateImage(VkDevice device, const VkImageCreateInfo* pCreateInfo, VkImage* pImage)
270{
Tobin Ehlis35613802015-09-22 08:40:52 -0600271 VkBool32 skipCall = VK_FALSE;
Tobin Ehlis65380532015-09-21 15:20:28 -0600272 layer_data *device_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600273 if(pCreateInfo->format != VK_FORMAT_UNDEFINED)
274 {
275 VkFormatProperties properties;
Courtney Goeltzenleuchterab36aa62015-07-12 12:40:29 -0600276 VkResult result = get_dispatch_table(image_instance_table_map, device_data->physicalDevice)->GetPhysicalDeviceFormatProperties(
Chris Forbesd7576302015-06-21 22:55:02 +1200277 device_data->physicalDevice, pCreateInfo->format, &properties);
Tobin Ehlis65380532015-09-21 15:20:28 -0600278 if(result != VK_SUCCESS) {
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600279 char const str[] = "vkCreateImage parameter, VkFormat pCreateInfo->format, cannot be validated";
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
283 if((properties.linearTilingFeatures) == 0 && (properties.optimalTilingFeatures == 0))
284 {
285 char const str[] = "vkCreateImage parameter, VkFormat pCreateInfo->format, contains unsupported format";
Tobin Ehlis35613802015-09-22 08:40:52 -0600286 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 -0600287 }
288 }
Tobin Ehlis35613802015-09-22 08:40:52 -0600289 if (skipCall)
290 return VK_ERROR_VALIDATION_FAILED;
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600291
292 VkResult result = get_dispatch_table(image_device_table_map, device)->CreateImage(device, pCreateInfo, pImage);
293
Tobin Ehlis65380532015-09-21 15:20:28 -0600294 if(result == VK_SUCCESS) {
Tobin Ehlis342b9bf2015-09-22 10:11:37 -0600295 device_data->imageMap[pImage->handle] = unique_ptr<IMAGE_STATE>(new IMAGE_STATE(pCreateInfo));
Tobin Ehlis65380532015-09-21 15:20:28 -0600296 }
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600297 return result;
298}
299
Tobin Ehlis65380532015-09-21 15:20:28 -0600300VK_LAYER_EXPORT void VKAPI vkDestroyImage(VkDevice device, VkImage image)
301{
302 layer_data *device_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
303 device_data->imageMap.erase(image.handle);
304 get_dispatch_table(image_device_table_map, device)->DestroyImage(device, image);
305}
306
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600307VK_LAYER_EXPORT VkResult VKAPI vkCreateRenderPass(VkDevice device, const VkRenderPassCreateInfo* pCreateInfo, VkRenderPass* pRenderPass)
308{
Tobin Ehlis35613802015-09-22 08:40:52 -0600309 VkBool32 skipCall = VK_FALSE;
Chia-I Wuc278df82015-07-07 11:50:03 +0800310 for(uint32_t i = 0; i < pCreateInfo->attachmentCount; ++i)
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600311 {
Chia-I Wuc278df82015-07-07 11:50:03 +0800312 if(pCreateInfo->pAttachments[i].format != VK_FORMAT_UNDEFINED)
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600313 {
Courtney Goeltzenleuchter07199212015-06-22 16:19:14 -0600314 layer_data *device_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600315 VkFormatProperties properties;
Courtney Goeltzenleuchterab36aa62015-07-12 12:40:29 -0600316 VkResult result = get_dispatch_table(image_instance_table_map, device_data->physicalDevice)->GetPhysicalDeviceFormatProperties(
Chia-I Wuc278df82015-07-07 11:50:03 +0800317 device_data->physicalDevice, pCreateInfo->pAttachments[i].format, &properties);
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600318 if(result != VK_SUCCESS)
319 {
320 std::stringstream ss;
Chia-I Wuc278df82015-07-07 11:50:03 +0800321 ss << "vkCreateRenderPass parameter, VkFormat in pCreateInfo->pAttachments[" << i << "], cannot be validated";
Tobin Ehlis35613802015-09-22 08:40:52 -0600322 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 -0600323 continue;
324 }
325
326 if((properties.linearTilingFeatures) == 0 && (properties.optimalTilingFeatures == 0))
327 {
328 std::stringstream ss;
Chia-I Wuc278df82015-07-07 11:50:03 +0800329 ss << "vkCreateRenderPass parameter, VkFormat in pCreateInfo->pAttachments[" << i << "], contains unsupported format";
Tobin Ehlis35613802015-09-22 08:40:52 -0600330 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 -0600331 }
332 }
333 }
334
Chia-I Wuc278df82015-07-07 11:50:03 +0800335 for(uint32_t i = 0; i < pCreateInfo->attachmentCount; ++i)
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600336 {
Chia-I Wuc278df82015-07-07 11:50:03 +0800337 if(!validate_VkImageLayout(pCreateInfo->pAttachments[i].initialLayout) ||
338 !validate_VkImageLayout(pCreateInfo->pAttachments[i].finalLayout))
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600339 {
340 std::stringstream ss;
Chia-I Wuc278df82015-07-07 11:50:03 +0800341 ss << "vkCreateRenderPass parameter, VkImageLayout in pCreateInfo->pAttachments[" << i << "], is unrecognized";
Tobin Ehlis35613802015-09-22 08:40:52 -0600342 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 -0600343 }
344 }
345
Chia-I Wuc278df82015-07-07 11:50:03 +0800346 for(uint32_t i = 0; i < pCreateInfo->attachmentCount; ++i)
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600347 {
Chia-I Wuc278df82015-07-07 11:50:03 +0800348 if(!validate_VkAttachmentLoadOp(pCreateInfo->pAttachments[i].loadOp))
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600349 {
350 std::stringstream ss;
Chia-I Wuc278df82015-07-07 11:50:03 +0800351 ss << "vkCreateRenderPass parameter, VkAttachmentLoadOp in pCreateInfo->pAttachments[" << i << "], is unrecognized";
Tobin Ehlis35613802015-09-22 08:40:52 -0600352 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 -0600353 }
354 }
355
Chia-I Wuc278df82015-07-07 11:50:03 +0800356 for(uint32_t i = 0; i < pCreateInfo->attachmentCount; ++i)
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600357 {
Chia-I Wuc278df82015-07-07 11:50:03 +0800358 if(!validate_VkAttachmentStoreOp(pCreateInfo->pAttachments[i].storeOp))
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600359 {
360 std::stringstream ss;
Chia-I Wuc278df82015-07-07 11:50:03 +0800361 ss << "vkCreateRenderPass parameter, VkAttachmentStoreOp in pCreateInfo->pAttachments[" << i << "], is unrecognized";
Tobin Ehlis35613802015-09-22 08:40:52 -0600362 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 -0600363 }
364 }
365
Mark Lobodzinski9cce7832015-07-29 09:21:22 -0600366 // Any depth buffers specified as attachments?
367 bool depthFormatPresent = VK_FALSE;
368 for (uint32_t i = 0; i < pCreateInfo->attachmentCount; ++i)
369 {
370 depthFormatPresent |= is_depth_format(pCreateInfo->pAttachments[i].format);
371 }
372
373 if (depthFormatPresent == VK_FALSE) {
374 // No depth attachment is present, validate that subpasses set depthStencilAttachment to VK_ATTACHMENT_UNUSED;
375 for (uint32_t i = 0; i < pCreateInfo->subpassCount; i++) {
376 if (pCreateInfo->pSubpasses[i].depthStencilAttachment.attachment != VK_ATTACHMENT_UNUSED) {
377 std::stringstream ss;
378 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 -0600379 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 -0600380 }
381 }
382 }
Tobin Ehlis35613802015-09-22 08:40:52 -0600383 if (skipCall)
384 return VK_ERROR_VALIDATION_FAILED;
Mark Lobodzinski9cce7832015-07-29 09:21:22 -0600385
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600386 VkResult result = get_dispatch_table(image_device_table_map, device)->CreateRenderPass(device, pCreateInfo, pRenderPass);
387
388 return result;
389}
390
Tobin Ehlis65380532015-09-21 15:20:28 -0600391VK_LAYER_EXPORT VkResult VKAPI vkCreateImageView(VkDevice device, const VkImageViewCreateInfo* pCreateInfo, VkImageView* pView)
392{
393 VkBool32 skipCall = VK_FALSE;
394 layer_data *device_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
395 auto imageEntry = device_data->imageMap.find(pCreateInfo->image.handle);
396 if (imageEntry != device_data->imageMap.end()) {
397 if (pCreateInfo->subresourceRange.baseMipLevel >= imageEntry->second->mipLevels) {
398 std::stringstream ss;
399 ss << "vkCreateImageView called with baseMipLevel " << pCreateInfo->subresourceRange.baseMipLevel << " for image " << pCreateInfo->image.handle << " that only has " << imageEntry->second->mipLevels << " mip levels.";
400 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());
401 }
402 if (pCreateInfo->subresourceRange.baseArrayLayer >= imageEntry->second->arraySize) {
403 std::stringstream ss;
404 ss << "vkCreateImageView called with baseArrayLayer " << pCreateInfo->subresourceRange.baseArrayLayer << " for image " << pCreateInfo->image.handle << " that only has " << imageEntry->second->arraySize << " mip levels.";
405 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());
406 }
407 if (!pCreateInfo->subresourceRange.mipLevels) {
408 std::stringstream ss;
409 ss << "vkCreateImageView called with 0 in pCreateInfo->subresourceRange.mipLevels.";
410 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());
411 }
412 if (!pCreateInfo->subresourceRange.arraySize) {
413 std::stringstream ss;
414 ss << "vkCreateImageView called with 0 in pCreateInfo->subresourceRange.arraySize.";
415 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());
416 }
417 }
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600418
419 // TODO: Image aspect mask must be only VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_ASPECT_DEPTH_BIT or VK_IMAGE_ASPECT_STENCIL_BIT
420 // if the format is a color, depth-only or stencil-only format respectively. If using a depth/stencil format,
421 // aspectMask must include at least one of VK_IMAGE_ASPECT_DEPTH_BIT and VK_IMAGE_ASPECT_STENCIL_BIT, and may include both.
422 // Add after image/buffer state tracking is implemented.
423
Tobin Ehlis65380532015-09-21 15:20:28 -0600424 if (skipCall)
425 return VK_ERROR_VALIDATION_FAILED;
Tobin Ehlis35613802015-09-22 08:40:52 -0600426
Tobin Ehlis65380532015-09-21 15:20:28 -0600427 VkResult result = get_dispatch_table(image_device_table_map, device)->CreateImageView(device, pCreateInfo, pView);
428 return result;
429}
430
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600431VK_LAYER_EXPORT void VKAPI vkCmdClearColorImage(
432 VkCmdBuffer cmdBuffer,
433 VkImage image,
434 VkImageLayout imageLayout,
435 const VkClearColorValue *pColor,
436 uint32_t rangeCount,
437 const VkImageSubresourceRange *pRanges)
438{
439 VkBool32 skipCall = VK_FALSE;
440
441 // For each range, image aspect must be color only
442 for (uint32_t i = 0; i < rangeCount; i++) {
443 if (pRanges[i].aspectMask != VK_IMAGE_ASPECT_COLOR_BIT) {
444 layer_data *device_data = get_my_data_ptr(get_dispatch_key(cmdBuffer), layer_data_map);
445 char const str[] = "vkCmdClearColorImage aspectMasks for all subresource ranges must be set to VK_IMAGE_ASPECT_COLOR_BIT";
446 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
447 (uint64_t)cmdBuffer, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", str);
448 }
449 }
450
451 if (VK_FALSE == skipCall) {
452 get_dispatch_table(image_device_table_map, cmdBuffer)->CmdClearColorImage(cmdBuffer, image, imageLayout,
453 pColor, rangeCount, pRanges);
454 }
455}
456
457VK_LAYER_EXPORT void VKAPI vkCmdClearDepthStencilImage(
458 VkCmdBuffer cmdBuffer,
459 VkImage image,
460 VkImageLayout imageLayout,
461 const VkClearDepthStencilValue *pDepthStencil,
462 uint32_t rangeCount,
463 const VkImageSubresourceRange *pRanges)
464{
465 VkBool32 skipCall = VK_FALSE;
466
467 // For each range, Image aspect must be depth or stencil or both
468 for (uint32_t i = 0; i < rangeCount; i++) {
469 if (((pRanges[i].aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT) != VK_IMAGE_ASPECT_DEPTH_BIT) &&
470 ((pRanges[i].aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT) != VK_IMAGE_ASPECT_STENCIL_BIT))
471 {
472 layer_data *device_data = get_my_data_ptr(get_dispatch_key(cmdBuffer), layer_data_map);
473 char const str[] = "vkCmdClearDepthStencilImage aspectMasks for all subresource ranges must be "
474 "set to VK_IMAGE_ASPECT_DEPTH_BIT and/or VK_IMAGE_ASPECT_STENCIL_BIT";
475 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
476 (uint64_t)cmdBuffer, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", str);
477 }
478 }
479
480 if (VK_FALSE == skipCall) {
481 get_dispatch_table(image_device_table_map, cmdBuffer)->CmdClearDepthStencilImage(cmdBuffer,
482 image, imageLayout, pDepthStencil, rangeCount, pRanges);
483 }
484}
485
486VK_LAYER_EXPORT void VKAPI vkCmdClearDepthStencilAttachment(
487 VkCmdBuffer cmdBuffer,
488 VkImageAspectFlags imageAspectMask,
489 VkImageLayout imageLayout,
490 const VkClearDepthStencilValue *pDepthStencil,
491 uint32_t rectCount,
492 const VkRect3D *pRects)
493{
494 VkBool32 skipCall = VK_FALSE;
495
496 // Image aspect must be depth or stencil or both
497 if (((imageAspectMask & VK_IMAGE_ASPECT_DEPTH_BIT) != VK_IMAGE_ASPECT_DEPTH_BIT) &&
498 ((imageAspectMask & VK_IMAGE_ASPECT_STENCIL_BIT) != VK_IMAGE_ASPECT_STENCIL_BIT))
499 {
500 layer_data *device_data = get_my_data_ptr(get_dispatch_key(cmdBuffer), layer_data_map);
501 char const str[] = "vkCmdClearDepthStencilAttachment aspectMask must be set to VK_IMAGE_ASPECT_DEPTH_BIT and/or VK_IMAGE_ASPECT_STENCIL_BIT";
502 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
503 (uint64_t)cmdBuffer, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", str);
504 }
505
506 if (VK_FALSE == skipCall) {
507 get_dispatch_table(image_device_table_map, cmdBuffer)->CmdClearDepthStencilAttachment(cmdBuffer,
508 imageAspectMask, imageLayout, pDepthStencil, rectCount, pRects);
509 }
510}
511
512VK_LAYER_EXPORT void VKAPI vkCmdCopyImage(
513 VkCmdBuffer cmdBuffer,
514 VkImage srcImage,
515 VkImageLayout srcImageLayout,
516 VkImage destImage,
517 VkImageLayout destImageLayout,
518 uint32_t regionCount,
519 const VkImageCopy *pRegions)
520{
521 VkBool32 skipCall = VK_FALSE;
Mike Stroyan43909d82015-09-25 13:39:21 -0600522 layer_data *device_data = get_my_data_ptr(get_dispatch_key(cmdBuffer), layer_data_map);
523 auto srcImageEntry = device_data->imageMap.find(srcImage.handle);
524 auto destImageEntry = device_data->imageMap.find(destImage.handle);
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600525
526 // For each region, src aspect mask must match dest aspect mask
527 // For each region, color aspects cannot be mixed with depth/stencil aspects
528 for (uint32_t i = 0; i < regionCount; i++) {
529 if (pRegions[i].srcSubresource.aspect != pRegions[i].destSubresource.aspect) {
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600530 char const str[] = "vkCmdCopyImage: Src and dest aspectMasks for each region must match";
531 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
532 (uint64_t)cmdBuffer, 0, IMAGE_MISMATCHED_IMAGE_ASPECT, "IMAGE", str);
533 }
534 if ((pRegions[i].srcSubresource.aspect & VK_IMAGE_ASPECT_COLOR) &&
535 (pRegions[i].srcSubresource.aspect & (VK_IMAGE_ASPECT_DEPTH | VK_IMAGE_ASPECT_STENCIL))) {
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600536 char const str[] = "vkCmdCopyImage aspectMask cannot specify both COLOR and DEPTH/STENCIL aspects";
537 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
538 (uint64_t)cmdBuffer, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", str);
539 }
540 }
541
Mike Stroyan43909d82015-09-25 13:39:21 -0600542 if ((srcImageEntry != device_data->imageMap.end())
543 && (destImageEntry != device_data->imageMap.end())) {
544 if (srcImageEntry->second->imageType != destImageEntry->second->imageType) {
545 char const str[] = "vkCmdCopyImage called with unmatched source and dest image types.";
546 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
547 (uint64_t)cmdBuffer, 0, IMAGE_MISMATCHED_IMAGE_TYPE, "IMAGE", str);
548 }
549 // Check that format is same size or exact stencil/depth
550 if (is_depth_format(srcImageEntry->second->format)) {
551 if (srcImageEntry->second->format != destImageEntry->second->format) {
552 char const str[] = "vkCmdCopyImage called with unmatched source and dest image depth/stencil formats.";
553 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
554 (uint64_t)cmdBuffer, 0, IMAGE_MISMATCHED_IMAGE_FORMAT, "IMAGE", str);
555 }
556 } else {
557 size_t srcSize = vk_format_get_size(srcImageEntry->second->format);
558 size_t destSize = vk_format_get_size(destImageEntry->second->format);
559 if (srcSize != destSize) {
560 char const str[] = "vkCmdCopyImage called with unmatched source and dest image format sizes.";
561 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
562 (uint64_t)cmdBuffer, 0, IMAGE_MISMATCHED_IMAGE_FORMAT, "IMAGE", str);
563 }
564 }
565 }
566
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600567 if (VK_FALSE == skipCall) {
568 get_dispatch_table(image_device_table_map, cmdBuffer)->CmdCopyImage(cmdBuffer, srcImage,
569 srcImageLayout, destImage, destImageLayout, regionCount, pRegions);
570 }
571}
572
573VK_LAYER_EXPORT void VKAPI vkCmdCopyImageToBuffer(
574 VkCmdBuffer cmdBuffer,
575 VkImage srcImage,
576 VkImageLayout srcImageLayout,
577 VkBuffer destBuffer,
578 uint32_t regionCount,
579 const VkBufferImageCopy *pRegions)
580{
581 VkBool32 skipCall = VK_FALSE;
582
583 // Image aspect must be ONE OF color, depth, stencil
584 for (uint32_t i = 0; i < regionCount; i++) {
585 VkImageAspect aspect = pRegions[i].imageSubresource.aspect;
586 if ((aspect != VK_IMAGE_ASPECT_COLOR) &&
587 (aspect != VK_IMAGE_ASPECT_DEPTH) &&
588 (aspect != VK_IMAGE_ASPECT_STENCIL)) {
589 layer_data *device_data = get_my_data_ptr(get_dispatch_key(cmdBuffer), layer_data_map);
590 char const str[] = "vkCmdCopyImageToBuffer: aspectMasks for each region must specify only COLOR or DEPTH or STENCIL";
591 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
592 (uint64_t)cmdBuffer, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", str);
593 }
594 }
595
596 if (VK_FALSE == skipCall) {
597 get_dispatch_table(image_device_table_map, cmdBuffer)->CmdCopyImageToBuffer(cmdBuffer,
598 srcImage, srcImageLayout, destBuffer, regionCount, pRegions);
599 }
600}
601
602
603VK_LAYER_EXPORT void VKAPI vkCmdCopyBufferToImage(
604 VkCmdBuffer cmdBuffer,
605 VkBuffer srcBuffer,
606 VkImage destImage,
607 VkImageLayout destImageLayout,
608 uint32_t regionCount,
609 const VkBufferImageCopy *pRegions)
610{
611 VkBool32 skipCall = VK_FALSE;
612
613 // Image aspect must be ONE OF color, depth, stencil
614 for (uint32_t i = 0; i < regionCount; i++) {
615 VkImageAspect aspect = pRegions[i].imageSubresource.aspect;
616 if ((aspect != VK_IMAGE_ASPECT_COLOR) &&
617 (aspect != VK_IMAGE_ASPECT_DEPTH) &&
618 (aspect != VK_IMAGE_ASPECT_STENCIL)) {
619 layer_data *device_data = get_my_data_ptr(get_dispatch_key(cmdBuffer), layer_data_map);
620 char const str[] = "vkCmdCopyBufferToImage: aspectMasks for each region must specify only COLOR or DEPTH or STENCIL";
621 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
622 (uint64_t)cmdBuffer, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", str);
623 }
624 }
625
626 if (VK_FALSE == skipCall) {
627 get_dispatch_table(image_device_table_map, cmdBuffer)->CmdCopyBufferToImage(cmdBuffer,
628 srcBuffer, destImage, destImageLayout, regionCount, pRegions);
629 }
630}
631
632VK_LAYER_EXPORT void VKAPI vkCmdBlitImage(
633 VkCmdBuffer cmdBuffer,
634 VkImage srcImage,
635 VkImageLayout srcImageLayout,
636 VkImage destImage,
637 VkImageLayout destImageLayout,
638 uint32_t regionCount,
639 const VkImageBlit *pRegions,
640 VkTexFilter filter)
641{
642 // TODO: From the spec -- these validation items will require the image layer to maintain image/buffer state.
643 // If one of srcImage and destImage images has signed integer format, the other one must also have be signed integer format.
644 // If one of srcImage and destImage images has unsigned integer format, the other one must also have be an unsigned integer format.
645 // If the format of srcImage is a depth, stencil, depth stencil or integer-based format then filter must be VK_TEX_FILTER_NEAREST.
646 // 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.
647 // Additionally the allowed aspect bits in srcSubresource and destSubresource are only VK_IMAGE_ASPECT_DEPTH_BIT and
648 // VK_IMAGE_ASPECT_STENCIL_BIT and the given aspect must exist in the format of both srcImage and destImage images.
649
650 get_dispatch_table(image_device_table_map, cmdBuffer)->CmdBlitImage(cmdBuffer, srcImage,
651 srcImageLayout, destImage, destImageLayout, regionCount, pRegions, filter);
652}
653
654VK_LAYER_EXPORT void VKAPI vkCmdResolveImage(
655 VkCmdBuffer cmdBuffer,
656 VkImage srcImage,
657 VkImageLayout srcImageLayout,
658 VkImage destImage,
659 VkImageLayout destImageLayout,
660 uint32_t regionCount,
661 const VkImageResolve *pRegions)
662{
663 VkBool32 skipCall = VK_FALSE;
Mike Stroyan43909d82015-09-25 13:39:21 -0600664 layer_data *device_data = get_my_data_ptr(get_dispatch_key(cmdBuffer), layer_data_map);
665 auto srcImageEntry = device_data->imageMap.find(srcImage.handle);
666 auto destImageEntry = device_data->imageMap.find(destImage.handle);
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600667
668 // For each region, src and dest image aspect must be color only
669 for (uint32_t i = 0; i < regionCount; i++) {
670 if ((pRegions[i].srcSubresource.aspect != VK_IMAGE_ASPECT_COLOR) ||
671 (pRegions[i].destSubresource.aspect != VK_IMAGE_ASPECT_COLOR)) {
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600672 char const str[] = "vkCmdResolveImage: src and dest aspectMasks for each region must specify only VK_IMAGE_ASPECT_COLOR_BIT";
673 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
674 (uint64_t)cmdBuffer, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", str);
675 }
676 }
677
Mike Stroyan43909d82015-09-25 13:39:21 -0600678 if ((srcImageEntry != device_data->imageMap.end())
679 && (destImageEntry != device_data->imageMap.end())) {
680 if (srcImageEntry->second->format != destImageEntry->second->format) {
681 char const str[] = "vkCmdResolveImage called with unmatched source and dest formats.";
682 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
683 (uint64_t)cmdBuffer, 0, IMAGE_MISMATCHED_IMAGE_FORMAT, "IMAGE", str);
684 }
685 if (srcImageEntry->second->imageType != destImageEntry->second->imageType) {
686 char const str[] = "vkCmdResolveImage called with unmatched source and dest image types.";
687 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
688 (uint64_t)cmdBuffer, 0, IMAGE_MISMATCHED_IMAGE_TYPE, "IMAGE", str);
689 }
690 if (srcImageEntry->second->samples <= 1) {
691 char const str[] = "vkCmdResolveImage called with source sample count less than 2.";
692 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
693 (uint64_t)cmdBuffer, 0, IMAGE_INVALID_RESOLVE_SAMPLES, "IMAGE", str);
694 }
695 if (destImageEntry->second->samples > 1) {
696 char const str[] = "vkCmdResolveImage called with dest sample count greater than 1.";
697 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
698 (uint64_t)cmdBuffer, 0, IMAGE_INVALID_RESOLVE_SAMPLES, "IMAGE", str);
699 }
700 }
701
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600702 if (VK_FALSE == skipCall) {
703 get_dispatch_table(image_device_table_map, cmdBuffer)->CmdResolveImage(cmdBuffer, srcImage,
704 srcImageLayout, destImage, destImageLayout, regionCount, pRegions);
705 }
706}
707
708VK_LAYER_EXPORT VkResult VKAPI vkGetImageSubresourceLayout(
709 VkDevice device,
710 VkImage image,
711 const VkImageSubresource *pSubresource,
712 VkSubresourceLayout *pLayout)
713{
714 VkResult result = get_dispatch_table(image_device_table_map, device)->GetImageSubresourceLayout(device,
715 image, pSubresource, pLayout);
716
717 // TODO: After state tracking for images/buffers is implemented, validate that returned aspects match
718 // the created formats -- color for color formats, depth|stencil for ds formats
719
720 return result;
721}
722
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -0600723VK_LAYER_EXPORT PFN_vkVoidFunction VKAPI vkGetDeviceProcAddr(VkDevice device, const char* funcName)
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600724{
725 if (device == NULL) {
726 return NULL;
727 }
728
729 /* loader uses this to force layer initialization; device object is wrapped */
730 if (!strcmp(funcName, "vkGetDeviceProcAddr")) {
731 initDeviceTable(image_device_table_map, (const VkBaseLayerObject *) device);
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -0600732 return (PFN_vkVoidFunction) vkGetDeviceProcAddr;
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600733 }
734
Courtney Goeltzenleuchterbe637992015-06-25 18:01:43 -0600735 if (!strcmp(funcName, "vkCreateDevice"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -0600736 return (PFN_vkVoidFunction) vkCreateDevice;
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600737 if (!strcmp(funcName, "vkDestroyDevice"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -0600738 return (PFN_vkVoidFunction) vkDestroyDevice;
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600739 if (!strcmp(funcName, "vkCreateImage"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -0600740 return (PFN_vkVoidFunction) vkCreateImage;
Tobin Ehlis342b9bf2015-09-22 10:11:37 -0600741 if (!strcmp(funcName, "vkCreateImageView"))
742 return (PFN_vkVoidFunction) vkCreateImageView;
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600743 if (!strcmp(funcName, "vkCreateRenderPass"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -0600744 return (PFN_vkVoidFunction) vkCreateRenderPass;
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600745 if (!strcmp(funcName, "vkCmdClearColorImage"))
746 return (PFN_vkVoidFunction) vkCmdClearColorImage;
747 if (!strcmp(funcName, "vkCmdClearDepthStencilImage"))
748 return (PFN_vkVoidFunction) vkCmdClearDepthStencilImage;
749 if (!strcmp(funcName, "vkCmdClearDepthStencilAttachment"))
750 return (PFN_vkVoidFunction) vkCmdClearDepthStencilAttachment;
751 if (!strcmp(funcName, "vkCmdCopyImage"))
752 return (PFN_vkVoidFunction) vkCmdCopyImage;
753 if (!strcmp(funcName, "vkCmdCopyImageToBuffer"))
754 return (PFN_vkVoidFunction) vkCmdCopyImageToBuffer;
755 if (!strcmp(funcName, "vkCmdCopyBufferToImage"))
756 return (PFN_vkVoidFunction) vkCmdCopyBufferToImage;
757 if (!strcmp(funcName, "vkCmdBlitImage"))
758 return (PFN_vkVoidFunction) vkCmdBlitImage;
759 if (!strcmp(funcName, "vkCmdResolveImage"))
760 return (PFN_vkVoidFunction) vkCmdResolveImage;
761 if (!strcmp(funcName, "vkGetImageSubresourceLayout"))
762 return (PFN_vkVoidFunction) vkGetImageSubresourceLayout;
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600763 {
764 if (get_dispatch_table(image_device_table_map, device)->GetDeviceProcAddr == NULL)
765 return NULL;
766 return get_dispatch_table(image_device_table_map, device)->GetDeviceProcAddr(device, funcName);
767 }
768}
769
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -0600770VK_LAYER_EXPORT PFN_vkVoidFunction VKAPI vkGetInstanceProcAddr(VkInstance instance, const char* funcName)
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600771{
772 if (instance == NULL) {
773 return NULL;
774 }
775
776 /* loader uses this to force layer initialization; instance object is wrapped */
777 if (!strcmp(funcName, "vkGetInstanceProcAddr")) {
778 initInstanceTable(image_instance_table_map, (const VkBaseLayerObject *) instance);
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -0600779 return (PFN_vkVoidFunction) vkGetInstanceProcAddr;
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600780 }
781
782 if (!strcmp(funcName, "vkCreateInstance"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -0600783 return (PFN_vkVoidFunction) vkCreateInstance;
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600784 if (!strcmp(funcName, "vkDestroyInstance"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -0600785 return (PFN_vkVoidFunction) vkDestroyInstance;
Courtney Goeltzenleuchter74c4ce92015-09-14 17:22:16 -0600786 if (!strcmp(funcName, "vkEnumerateInstanceLayerProperties"))
787 return (PFN_vkVoidFunction) vkEnumerateInstanceLayerProperties;
788 if (!strcmp(funcName, "vkEnumerateInstanceExtensionProperties"))
789 return (PFN_vkVoidFunction) vkEnumerateInstanceExtensionProperties;
790 if (!strcmp(funcName, "vkEnumerateDeviceLayerProperties"))
791 return (PFN_vkVoidFunction) vkEnumerateDeviceLayerProperties;
792 if (!strcmp(funcName, "vkEnumerateDeviceExtensionProperties"))
793 return (PFN_vkVoidFunction) vkEnumerateDeviceExtensionProperties;
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600794
795 layer_data *data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -0600796 PFN_vkVoidFunction fptr = debug_report_get_instance_proc_addr(data->report_data, funcName);
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600797 if(fptr)
798 return fptr;
799
800 {
801 if (get_dispatch_table(image_instance_table_map, instance)->GetInstanceProcAddr == NULL)
802 return NULL;
803 return get_dispatch_table(image_instance_table_map, instance)->GetInstanceProcAddr(instance, funcName);
804 }
805}