blob: b741a4c59cad1da3c16f3c0a7f7719e72cec5b28 [file] [log] [blame]
Jeremy Hayesb707aa52015-06-18 10:12:39 -06001/*
2 * Vulkan
3 *
4 * Copyright (C) 2014 LunarG, Inc.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included
14 * in all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
23 */
24
Courtney Goeltzenleuchter6ff93732015-10-07 08:38:30 -060025#include <inttypes.h>
Jeremy Hayesb707aa52015-06-18 10:12:39 -060026#include <stdio.h>
27#include <stdlib.h>
28#include <string.h>
Courtney Goeltzenleuchter6ff93732015-10-07 08:38:30 -060029#include <assert.h>
30#include <vector>
Jeremy Hayesb707aa52015-06-18 10:12:39 -060031#include <unordered_map>
Tobin Ehlis65380532015-09-21 15:20:28 -060032#include <memory>
Courtney Goeltzenleuchter6ff93732015-10-07 08:38:30 -060033using namespace std;
Jeremy Hayesb707aa52015-06-18 10:12:39 -060034
Tobin Ehlis7a51d902015-07-03 10:34:49 -060035#include "vk_loader_platform.h"
Courtney Goeltzenleuchter6ff93732015-10-07 08:38:30 -060036#include "vk_dispatch_table_helper.h"
37#include "vk_struct_string_helper_cpp.h"
Jeremy Hayesb707aa52015-06-18 10:12:39 -060038#include "vk_enum_validate_helper.h"
Courtney Goeltzenleuchter6ff93732015-10-07 08:38:30 -060039#include "image.h"
40#include "vk_layer_config.h"
41#include "vk_layer_extension_utils.h"
Tobin Ehlis56d204a2015-07-03 10:15:26 -060042#include "vk_layer_table.h"
43#include "vk_layer_data.h"
Courtney Goeltzenleuchtereb1ddb02015-07-07 11:18:30 -060044#include "vk_layer_extension_utils.h"
Mike Stroyan43909d82015-09-25 13:39:21 -060045#include "vk_layer_utils.h"
Courtney Goeltzenleuchter6ff93732015-10-07 08:38:30 -060046#include "vk_layer_logging.h"
Jeremy Hayesb707aa52015-06-18 10:12:39 -060047
Tobin Ehlis65380532015-09-21 15:20:28 -060048using namespace std;
49
Cody Northrop73bb6572015-09-28 15:09:32 -060050struct layer_data {
Jeremy Hayesb707aa52015-06-18 10:12:39 -060051 debug_report_data *report_data;
Courtney Goeltzenleuchter9fac1572015-10-05 15:59:11 -060052 std::vector<VkDbgMsgCallback> logging_callback;
Chris Forbesd7576302015-06-21 22:55:02 +120053 VkPhysicalDevice physicalDevice;
Chia-I Wue420a332015-10-26 20:04:44 +080054 unordered_map<VkImage, IMAGE_STATE> imageMap;
Cody Northrop73bb6572015-09-28 15:09:32 -060055
56 layer_data() :
57 report_data(nullptr),
Cody Northrop73bb6572015-09-28 15:09:32 -060058 physicalDevice(0)
59 {};
60};
Jeremy Hayesb707aa52015-06-18 10:12:39 -060061
Tobin Ehlis65380532015-09-21 15:20:28 -060062static unordered_map<void*, layer_data*> layer_data_map;
Mark Lobodzinskib4092de2015-10-23 14:20:31 -060063static device_table_map image_device_table_map;
Jeremy Hayesb707aa52015-06-18 10:12:39 -060064static instance_table_map image_instance_table_map;
65
66// "my device data"
Tony Barbour2a199c12015-07-09 17:31:46 -060067debug_report_data *mdd(const void* object)
Jeremy Hayesb707aa52015-06-18 10:12:39 -060068{
69 dispatch_key key = get_dispatch_key(object);
70 layer_data *data = get_my_data_ptr(key, layer_data_map);
71#if DISPATCH_MAP_DEBUG
72 fprintf(stderr, "MDD: map: %p, object: %p, key: %p, data: %p\n", &layer_data_map, object, key, data);
73#endif
Jeremy Hayesb707aa52015-06-18 10:12:39 -060074 return data->report_data;
75}
76
77// "my instance data"
78debug_report_data *mid(VkInstance object)
79{
80 dispatch_key key = get_dispatch_key(object);
Courtney Goeltzenleuchter07199212015-06-22 16:19:14 -060081 layer_data *data = get_my_data_ptr(key, layer_data_map);
Jeremy Hayesb707aa52015-06-18 10:12:39 -060082#if DISPATCH_MAP_DEBUG
83 fprintf(stderr, "MID: map: %p, object: %p, key: %p, data: %p\n", &layer_data_map, object, key, data);
84#endif
Jeremy Hayesb707aa52015-06-18 10:12:39 -060085 return data->report_data;
86}
87
88static void InitImage(layer_data *data)
89{
Courtney Goeltzenleuchter9fac1572015-10-05 15:59:11 -060090 VkDbgMsgCallback callback;
Jeremy Hayesb707aa52015-06-18 10:12:39 -060091 uint32_t report_flags = getLayerOptionFlags("ImageReportFlags", 0);
92
93 uint32_t debug_action = 0;
94 getLayerOptionEnum("ImageDebugAction", (uint32_t *) &debug_action);
95 if(debug_action & VK_DBG_LAYER_ACTION_LOG_MSG)
96 {
97 FILE *log_output = NULL;
98 const char* option_str = getLayerOption("ImageLogFilename");
Tobin Ehlisb4b6e7c2015-09-15 09:55:54 -060099 log_output = getLayerLogOutput(option_str, "Image");
Courtney Goeltzenleuchter9fac1572015-10-05 15:59:11 -0600100 layer_create_msg_callback(data->report_data, report_flags, log_callback, (void *) log_output, &callback);
101 data->logging_callback.push_back(callback);
102 }
103
104 if (debug_action & VK_DBG_LAYER_ACTION_DEBUG_OUTPUT) {
105 layer_create_msg_callback(data->report_data, report_flags, win32_debug_output_msg, NULL, &callback);
106 data->logging_callback.push_back(callback);
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600107 }
108}
109
110VK_LAYER_EXPORT VkResult VKAPI vkDbgCreateMsgCallback(
111 VkInstance instance,
112 VkFlags msgFlags,
113 const PFN_vkDbgMsgCallback pfnMsgCallback,
114 void* pUserData,
115 VkDbgMsgCallback* pMsgCallback)
116{
117 VkLayerInstanceDispatchTable *pTable = get_dispatch_table(image_instance_table_map, instance);
118 VkResult res = pTable->DbgCreateMsgCallback(instance, msgFlags, pfnMsgCallback, pUserData, pMsgCallback);
119 if (res == VK_SUCCESS) {
120 layer_data *data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
121
122 res = layer_create_msg_callback(data->report_data, msgFlags, pfnMsgCallback, pUserData, pMsgCallback);
123 }
124 return res;
125}
126
127VK_LAYER_EXPORT VkResult VKAPI vkDbgDestroyMsgCallback(
128 VkInstance instance,
129 VkDbgMsgCallback msgCallback)
130{
131 VkLayerInstanceDispatchTable *pTable = get_dispatch_table(image_instance_table_map, instance);
132 VkResult res = pTable->DbgDestroyMsgCallback(instance, msgCallback);
133
134 layer_data *data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
135 layer_destroy_msg_callback(data->report_data, msgCallback);
136
137 return res;
138}
139
140VK_LAYER_EXPORT VkResult VKAPI vkCreateInstance(const VkInstanceCreateInfo* pCreateInfo, VkInstance* pInstance)
141{
142 VkLayerInstanceDispatchTable *pTable = get_dispatch_table(image_instance_table_map, *pInstance);
143 VkResult result = pTable->CreateInstance(pCreateInfo, pInstance);
144
145 if (result == VK_SUCCESS) {
146 layer_data *data = get_my_data_ptr(get_dispatch_key(*pInstance), layer_data_map);
147 data->report_data = debug_report_create_instance(pTable, *pInstance, pCreateInfo->extensionCount,
Courtney Goeltzenleuchtereb1ddb02015-07-07 11:18:30 -0600148 pCreateInfo->ppEnabledExtensionNames);
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600149
150 InitImage(data);
151 }
152
153 return result;
154}
155
Mark Lobodzinski67b42b72015-09-07 13:59:43 -0600156VK_LAYER_EXPORT void VKAPI vkDestroyInstance(VkInstance instance)
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600157{
158 // Grab the key before the instance is destroyed.
159 dispatch_key key = get_dispatch_key(instance);
160 VkLayerInstanceDispatchTable *pTable = get_dispatch_table(image_instance_table_map, instance);
Mark Lobodzinski67b42b72015-09-07 13:59:43 -0600161 pTable->DestroyInstance(instance);
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600162
163 // Clean up logging callback, if any
Courtney Goeltzenleuchter9fac1572015-10-05 15:59:11 -0600164 layer_data *my_data = get_my_data_ptr(key, layer_data_map);
165 while (my_data->logging_callback.size() > 0) {
166 VkDbgMsgCallback callback = my_data->logging_callback.back();
167 layer_destroy_msg_callback(my_data->report_data, callback);
168 my_data->logging_callback.pop_back();
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600169 }
170
171 layer_debug_report_destroy_instance(mid(instance));
172 layer_data_map.erase(pTable);
173
174 image_instance_table_map.erase(key);
175 assert(image_instance_table_map.size() == 0 && "Should not have any instance mappings hanging around");
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600176}
177
178VK_LAYER_EXPORT VkResult VKAPI vkCreateDevice(VkPhysicalDevice physicalDevice, const VkDeviceCreateInfo* pCreateInfo, VkDevice* pDevice)
179{
Courtney Goeltzenleuchterbe637992015-06-25 18:01:43 -0600180 VkLayerDispatchTable *pTable = get_dispatch_table(image_device_table_map, *pDevice);
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600181 VkResult result = pTable->CreateDevice(physicalDevice, pCreateInfo, pDevice);
182 if(result == VK_SUCCESS)
183 {
184 layer_data *instance_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);
185 layer_data *device_data = get_my_data_ptr(get_dispatch_key(*pDevice), layer_data_map);
186 device_data->report_data = layer_debug_report_create_device(instance_data->report_data, *pDevice);
Chris Forbesd7576302015-06-21 22:55:02 +1200187 device_data->physicalDevice = physicalDevice;
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600188 }
189
190 return result;
191}
192
Mark Lobodzinski67b42b72015-09-07 13:59:43 -0600193VK_LAYER_EXPORT void VKAPI vkDestroyDevice(VkDevice device)
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600194{
195 layer_debug_report_destroy_device(device);
196
197 dispatch_key key = get_dispatch_key(device);
198#if DISPATCH_MAP_DEBUG
199 fprintf(stderr, "Device: %p, key: %p\n", device, key);
200#endif
201
Mark Lobodzinski67b42b72015-09-07 13:59:43 -0600202 get_dispatch_table(image_device_table_map, device)->DestroyDevice(device);
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600203 image_device_table_map.erase(key);
204 assert(image_device_table_map.size() == 0 && "Should not have any instance mappings hanging around");
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600205}
206
Courtney Goeltzenleuchtereb1ddb02015-07-07 11:18:30 -0600207static const VkLayerProperties pc_global_layers[] = {
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600208 {
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600209 "Image",
Courtney Goeltzenleuchtereb1ddb02015-07-07 11:18:30 -0600210 VK_API_VERSION,
211 VK_MAKE_VERSION(0, 1, 0),
212 "Validation layer: Image ParamChecker",
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600213 }
214};
215
Courtney Goeltzenleuchter74c4ce92015-09-14 17:22:16 -0600216VK_LAYER_EXPORT VkResult VKAPI vkEnumerateInstanceExtensionProperties(
Courtney Goeltzenleuchtereb1ddb02015-07-07 11:18:30 -0600217 const char *pLayerName,
218 uint32_t *pCount,
219 VkExtensionProperties* pProperties)
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600220{
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600221 // ParamChecker does not have any global extensions
Courtney Goeltzenleuchtereb1ddb02015-07-07 11:18:30 -0600222 return util_GetExtensionProperties(0, NULL, pCount, pProperties);
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600223}
224
Courtney Goeltzenleuchter74c4ce92015-09-14 17:22:16 -0600225VK_LAYER_EXPORT VkResult VKAPI vkEnumerateInstanceLayerProperties(
Courtney Goeltzenleuchtereb1ddb02015-07-07 11:18:30 -0600226 uint32_t *pCount,
227 VkLayerProperties* pProperties)
Tony Barbour426b9052015-06-24 16:06:58 -0600228{
Courtney Goeltzenleuchtereb1ddb02015-07-07 11:18:30 -0600229 return util_GetLayerProperties(ARRAY_SIZE(pc_global_layers),
230 pc_global_layers,
231 pCount, pProperties);
Tony Barbour426b9052015-06-24 16:06:58 -0600232}
233
Courtney Goeltzenleuchter74c4ce92015-09-14 17:22:16 -0600234VK_LAYER_EXPORT VkResult VKAPI vkEnumerateDeviceExtensionProperties(
Courtney Goeltzenleuchtereb1ddb02015-07-07 11:18:30 -0600235 VkPhysicalDevice physicalDevice,
236 const char* pLayerName,
237 uint32_t* pCount,
238 VkExtensionProperties* pProperties)
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600239{
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600240 // ParamChecker does not have any physical device extensions
Courtney Goeltzenleuchtereb1ddb02015-07-07 11:18:30 -0600241 return util_GetExtensionProperties(0, NULL, pCount, pProperties);
242}
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600243
Courtney Goeltzenleuchter74c4ce92015-09-14 17:22:16 -0600244VK_LAYER_EXPORT VkResult VKAPI vkEnumerateDeviceLayerProperties(
Courtney Goeltzenleuchtereb1ddb02015-07-07 11:18:30 -0600245 VkPhysicalDevice physicalDevice,
246 uint32_t* pCount,
247 VkLayerProperties* pProperties)
248{
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600249 // ParamChecker's physical device layers are the same as global
Courtney Goeltzenleuchtereb1ddb02015-07-07 11:18:30 -0600250 return util_GetLayerProperties(ARRAY_SIZE(pc_global_layers), pc_global_layers,
251 pCount, pProperties);
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600252}
253
Mark Lobodzinski9cce7832015-07-29 09:21:22 -0600254// Start of the Image layer proper
255
256// Returns TRUE if a format is a depth-compatible format
257bool is_depth_format(VkFormat format)
258{
259 bool result = VK_FALSE;
260 switch (format) {
261 case VK_FORMAT_D16_UNORM:
Courtney Goeltzenleuchter7ed10592015-09-10 17:17:43 -0600262 case VK_FORMAT_D24_UNORM_X8:
Mark Lobodzinski9cce7832015-07-29 09:21:22 -0600263 case VK_FORMAT_D32_SFLOAT:
264 case VK_FORMAT_S8_UINT:
265 case VK_FORMAT_D16_UNORM_S8_UINT:
266 case VK_FORMAT_D24_UNORM_S8_UINT:
267 case VK_FORMAT_D32_SFLOAT_S8_UINT:
268 result = VK_TRUE;
269 break;
270 default:
271 break;
272 }
273 return result;
274}
275
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600276VK_LAYER_EXPORT VkResult VKAPI vkCreateImage(VkDevice device, const VkImageCreateInfo* pCreateInfo, VkImage* pImage)
277{
Tobin Ehlis35613802015-09-22 08:40:52 -0600278 VkBool32 skipCall = VK_FALSE;
Tobin Ehlis65380532015-09-21 15:20:28 -0600279 layer_data *device_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600280 if(pCreateInfo->format != VK_FORMAT_UNDEFINED)
281 {
282 VkFormatProperties properties;
Courtney Goeltzenleuchter01d2ae12015-10-20 16:40:38 -0600283 get_dispatch_table(image_instance_table_map, device_data->physicalDevice)->GetPhysicalDeviceFormatProperties(
Chris Forbesd7576302015-06-21 22:55:02 +1200284 device_data->physicalDevice, pCreateInfo->format, &properties);
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600285
286 if((properties.linearTilingFeatures) == 0 && (properties.optimalTilingFeatures == 0))
287 {
288 char const str[] = "vkCreateImage parameter, VkFormat pCreateInfo->format, contains unsupported format";
Tobin Ehlis35613802015-09-22 08:40:52 -0600289 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_WARN_BIT, (VkDbgObjectType)0, 0, 0, IMAGE_FORMAT_UNSUPPORTED, "IMAGE", str);
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600290 }
291 }
Tobin Ehlis35613802015-09-22 08:40:52 -0600292 if (skipCall)
293 return VK_ERROR_VALIDATION_FAILED;
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600294
295 VkResult result = get_dispatch_table(image_device_table_map, device)->CreateImage(device, pCreateInfo, pImage);
296
Tobin Ehlis65380532015-09-21 15:20:28 -0600297 if(result == VK_SUCCESS) {
Chia-I Wue420a332015-10-26 20:04:44 +0800298 device_data->imageMap[*pImage] = IMAGE_STATE(pCreateInfo);
Tobin Ehlis65380532015-09-21 15:20:28 -0600299 }
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600300 return result;
301}
302
Tobin Ehlis65380532015-09-21 15:20:28 -0600303VK_LAYER_EXPORT void VKAPI vkDestroyImage(VkDevice device, VkImage image)
304{
305 layer_data *device_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
Chia-I Wue420a332015-10-26 20:04:44 +0800306 device_data->imageMap.erase(image);
Tobin Ehlis65380532015-09-21 15:20:28 -0600307 get_dispatch_table(image_device_table_map, device)->DestroyImage(device, image);
308}
309
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600310VK_LAYER_EXPORT VkResult VKAPI vkCreateRenderPass(VkDevice device, const VkRenderPassCreateInfo* pCreateInfo, VkRenderPass* pRenderPass)
311{
Tobin Ehlis35613802015-09-22 08:40:52 -0600312 VkBool32 skipCall = VK_FALSE;
Chia-I Wuc278df82015-07-07 11:50:03 +0800313 for(uint32_t i = 0; i < pCreateInfo->attachmentCount; ++i)
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600314 {
Chia-I Wuc278df82015-07-07 11:50:03 +0800315 if(pCreateInfo->pAttachments[i].format != VK_FORMAT_UNDEFINED)
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600316 {
Courtney Goeltzenleuchter07199212015-06-22 16:19:14 -0600317 layer_data *device_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600318 VkFormatProperties properties;
Courtney Goeltzenleuchter01d2ae12015-10-20 16:40:38 -0600319 get_dispatch_table(image_instance_table_map, device_data->physicalDevice)->GetPhysicalDeviceFormatProperties(
Chia-I Wuc278df82015-07-07 11:50:03 +0800320 device_data->physicalDevice, pCreateInfo->pAttachments[i].format, &properties);
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600321
322 if((properties.linearTilingFeatures) == 0 && (properties.optimalTilingFeatures == 0))
323 {
324 std::stringstream ss;
Chia-I Wuc278df82015-07-07 11:50:03 +0800325 ss << "vkCreateRenderPass parameter, VkFormat in pCreateInfo->pAttachments[" << i << "], contains unsupported format";
Tobin Ehlis35613802015-09-22 08:40:52 -0600326 skipCall |= log_msg(mdd(device), VK_DBG_REPORT_WARN_BIT, (VkDbgObjectType)0, 0, 0, IMAGE_FORMAT_UNSUPPORTED, "IMAGE", ss.str().c_str());
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600327 }
328 }
329 }
330
Chia-I Wuc278df82015-07-07 11:50:03 +0800331 for(uint32_t i = 0; i < pCreateInfo->attachmentCount; ++i)
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600332 {
Chia-I Wuc278df82015-07-07 11:50:03 +0800333 if(!validate_VkImageLayout(pCreateInfo->pAttachments[i].initialLayout) ||
334 !validate_VkImageLayout(pCreateInfo->pAttachments[i].finalLayout))
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600335 {
336 std::stringstream ss;
Chia-I Wuc278df82015-07-07 11:50:03 +0800337 ss << "vkCreateRenderPass parameter, VkImageLayout in pCreateInfo->pAttachments[" << i << "], is unrecognized";
Tobin Ehlis35613802015-09-22 08:40:52 -0600338 skipCall |= log_msg(mdd(device), VK_DBG_REPORT_WARN_BIT, (VkDbgObjectType)0, 0, 0, IMAGE_RENDERPASS_INVALID_ATTACHMENT, "IMAGE", ss.str().c_str());
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600339 }
340 }
341
Chia-I Wuc278df82015-07-07 11:50:03 +0800342 for(uint32_t i = 0; i < pCreateInfo->attachmentCount; ++i)
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600343 {
Chia-I Wuc278df82015-07-07 11:50:03 +0800344 if(!validate_VkAttachmentLoadOp(pCreateInfo->pAttachments[i].loadOp))
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600345 {
346 std::stringstream ss;
Chia-I Wuc278df82015-07-07 11:50:03 +0800347 ss << "vkCreateRenderPass parameter, VkAttachmentLoadOp in pCreateInfo->pAttachments[" << i << "], is unrecognized";
Tobin Ehlis35613802015-09-22 08:40:52 -0600348 skipCall |= log_msg(mdd(device), VK_DBG_REPORT_WARN_BIT, (VkDbgObjectType)0, 0, 0, IMAGE_RENDERPASS_INVALID_ATTACHMENT, "IMAGE", ss.str().c_str());
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600349 }
350 }
351
Chia-I Wuc278df82015-07-07 11:50:03 +0800352 for(uint32_t i = 0; i < pCreateInfo->attachmentCount; ++i)
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600353 {
Chia-I Wuc278df82015-07-07 11:50:03 +0800354 if(!validate_VkAttachmentStoreOp(pCreateInfo->pAttachments[i].storeOp))
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600355 {
356 std::stringstream ss;
Chia-I Wuc278df82015-07-07 11:50:03 +0800357 ss << "vkCreateRenderPass parameter, VkAttachmentStoreOp in pCreateInfo->pAttachments[" << i << "], is unrecognized";
Tobin Ehlis35613802015-09-22 08:40:52 -0600358 skipCall |= log_msg(mdd(device), VK_DBG_REPORT_WARN_BIT, (VkDbgObjectType)0, 0, 0, IMAGE_RENDERPASS_INVALID_ATTACHMENT, "IMAGE", ss.str().c_str());
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600359 }
360 }
361
Mark Lobodzinski9cce7832015-07-29 09:21:22 -0600362 // Any depth buffers specified as attachments?
363 bool depthFormatPresent = VK_FALSE;
364 for (uint32_t i = 0; i < pCreateInfo->attachmentCount; ++i)
365 {
366 depthFormatPresent |= is_depth_format(pCreateInfo->pAttachments[i].format);
367 }
368
369 if (depthFormatPresent == VK_FALSE) {
370 // No depth attachment is present, validate that subpasses set depthStencilAttachment to VK_ATTACHMENT_UNUSED;
371 for (uint32_t i = 0; i < pCreateInfo->subpassCount; i++) {
372 if (pCreateInfo->pSubpasses[i].depthStencilAttachment.attachment != VK_ATTACHMENT_UNUSED) {
373 std::stringstream ss;
374 ss << "vkCreateRenderPass has no depth/stencil attachment, yet subpass[" << i << "] has VkSubpassDescription::depthStencilAttachment value that is not VK_ATTACHMENT_UNUSED";
Tobin Ehlis35613802015-09-22 08:40:52 -0600375 skipCall |= log_msg(mdd(device), VK_DBG_REPORT_ERROR_BIT, (VkDbgObjectType)0, 0, 0, IMAGE_RENDERPASS_INVALID_DS_ATTACHMENT, "IMAGE", ss.str().c_str());
Mark Lobodzinski9cce7832015-07-29 09:21:22 -0600376 }
377 }
378 }
Tobin Ehlis35613802015-09-22 08:40:52 -0600379 if (skipCall)
380 return VK_ERROR_VALIDATION_FAILED;
Mark Lobodzinski9cce7832015-07-29 09:21:22 -0600381
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600382 VkResult result = get_dispatch_table(image_device_table_map, device)->CreateRenderPass(device, pCreateInfo, pRenderPass);
383
384 return result;
385}
386
Tobin Ehlis65380532015-09-21 15:20:28 -0600387VK_LAYER_EXPORT VkResult VKAPI vkCreateImageView(VkDevice device, const VkImageViewCreateInfo* pCreateInfo, VkImageView* pView)
388{
389 VkBool32 skipCall = VK_FALSE;
390 layer_data *device_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
Chia-I Wue420a332015-10-26 20:04:44 +0800391 auto imageEntry = device_data->imageMap.find(pCreateInfo->image);
Tobin Ehlis65380532015-09-21 15:20:28 -0600392 if (imageEntry != device_data->imageMap.end()) {
Tobin Ehlis6fa437d2015-09-25 14:49:43 -0600393 if (pCreateInfo->subresourceRange.baseMipLevel >= imageEntry->second.mipLevels) {
Tobin Ehlis65380532015-09-21 15:20:28 -0600394 std::stringstream ss;
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600395 ss << "vkCreateImageView called with baseMipLevel " << pCreateInfo->subresourceRange.baseMipLevel
Chia-I Wue420a332015-10-26 20:04:44 +0800396 << " for image " << pCreateInfo->image << " that only has " << imageEntry->second.mipLevels << " mip levels.";
Tobin Ehlis65380532015-09-21 15:20:28 -0600397 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, (VkDbgObjectType)0, 0, 0, IMAGE_VIEW_CREATE_ERROR, "IMAGE", ss.str().c_str());
398 }
Tobin Ehlis6fa437d2015-09-25 14:49:43 -0600399 if (pCreateInfo->subresourceRange.baseArrayLayer >= imageEntry->second.arraySize) {
Tobin Ehlis65380532015-09-21 15:20:28 -0600400 std::stringstream ss;
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600401 ss << "vkCreateImageView called with baseArrayLayer " << pCreateInfo->subresourceRange.baseArrayLayer << " for image "
Chia-I Wue420a332015-10-26 20:04:44 +0800402 << pCreateInfo->image << " that only has " << imageEntry->second.arraySize << " mip levels.";
Tobin Ehlis65380532015-09-21 15:20:28 -0600403 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, (VkDbgObjectType)0, 0, 0, IMAGE_VIEW_CREATE_ERROR, "IMAGE", ss.str().c_str());
404 }
Courtney Goeltzenleuchter63f0ead2015-10-16 09:46:00 -0600405 if (!pCreateInfo->subresourceRange.numLevels) {
Tobin Ehlis65380532015-09-21 15:20:28 -0600406 std::stringstream ss;
407 ss << "vkCreateImageView called with 0 in pCreateInfo->subresourceRange.mipLevels.";
408 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, (VkDbgObjectType)0, 0, 0, IMAGE_VIEW_CREATE_ERROR, "IMAGE", ss.str().c_str());
409 }
Courtney Goeltzenleuchter63f0ead2015-10-16 09:46:00 -0600410 if (!pCreateInfo->subresourceRange.numLayers) {
Tobin Ehlis65380532015-09-21 15:20:28 -0600411 std::stringstream ss;
412 ss << "vkCreateImageView called with 0 in pCreateInfo->subresourceRange.arraySize.";
413 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, (VkDbgObjectType)0, 0, 0, IMAGE_VIEW_CREATE_ERROR, "IMAGE", ss.str().c_str());
414 }
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600415
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600416 // Validate correct image aspect bits for desired formats and format consistency
Tobin Ehlis6fa437d2015-09-25 14:49:43 -0600417 VkFormat imageFormat = imageEntry->second.format;
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600418 VkFormat ivciFormat = pCreateInfo->format;
419 VkImageAspectFlags aspectMask = pCreateInfo->subresourceRange.aspectMask;
420
421 if (vk_format_is_color(imageFormat)) {
422 if ((aspectMask & VK_IMAGE_ASPECT_COLOR_BIT) != VK_IMAGE_ASPECT_COLOR_BIT) {
423 std::stringstream ss;
424 ss << "vkCreateImageView: Color image formats must have the VK_IMAGE_ASPECT_COLOR_BIT set";
425 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_IMAGE,
Chia-I Wue420a332015-10-26 20:04:44 +0800426 (uint64_t)pCreateInfo->image, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", ss.str().c_str());
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600427 }
428 if ((aspectMask & VK_IMAGE_ASPECT_COLOR_BIT) != aspectMask) {
429 std::stringstream ss;
430 ss << "vkCreateImageView: Color image formats must have ONLY the VK_IMAGE_ASPECT_COLOR_BIT set";
431 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_IMAGE,
Chia-I Wue420a332015-10-26 20:04:44 +0800432 (uint64_t)pCreateInfo->image, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", ss.str().c_str());
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600433 }
434 if (VK_FALSE == vk_format_is_color(ivciFormat)) {
435 std::stringstream ss;
436 ss << "vkCreateImageView: The image view's format can differ from the parent image's format, but both must be "
437 << "color formats. ImageFormat is " << string_VkFormat(imageFormat) << " ImageViewFormat is " << string_VkFormat(ivciFormat);
438 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_IMAGE,
Chia-I Wue420a332015-10-26 20:04:44 +0800439 (uint64_t)pCreateInfo->image, 0, IMAGE_INVALID_FORMAT, "IMAGE", ss.str().c_str());
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600440 }
441 // TODO: Uncompressed formats are compatible if they occupy they same number of bits per pixel.
442 // Compressed formats are compatible if the only difference between them is the numerical type of
443 // the uncompressed pixels (e.g. signed vs. unsigned, or sRGB vs. UNORM encoding).
444 } else if (vk_format_is_depth_and_stencil(imageFormat)) {
445 if ((aspectMask & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) !=
446 (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) {
447 std::stringstream ss;
448 ss << "vkCreateImageView: Combination depth/stencil image formats must have both VK_IMAGE_ASPECT_DEPTH_BIT and VK_IMAGE_ASPECT_STENCIL_BIT set";
449 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_IMAGE,
Chia-I Wue420a332015-10-26 20:04:44 +0800450 (uint64_t)pCreateInfo->image, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", ss.str().c_str());
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600451 }
452 if ((aspectMask & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) != aspectMask) {
453 std::stringstream ss;
454 ss << "vkCreateImageView: Combination depth/stencil image formats can have only the VK_IMAGE_ASPECT_DEPTH_BIT and VK_IMAGE_ASPECT_STENCIL_BIT set";
455 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_IMAGE,
Chia-I Wue420a332015-10-26 20:04:44 +0800456 (uint64_t)pCreateInfo->image, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", ss.str().c_str());
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600457 }
458 } else if (vk_format_is_depth_only(imageFormat)) {
459 if ((aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT) != VK_IMAGE_ASPECT_DEPTH_BIT) {
460 std::stringstream ss;
461 ss << "vkCreateImageView: Depth-only image formats must have the VK_IMAGE_ASPECT_DEPTH_BIT set";
462 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_IMAGE,
Chia-I Wue420a332015-10-26 20:04:44 +0800463 (uint64_t)pCreateInfo->image, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", ss.str().c_str());
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600464 }
465 if ((aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT) != aspectMask) {
466 std::stringstream ss;
467 ss << "vkCreateImageView: Depth-only image formats can have only the VK_IMAGE_ASPECT_DEPTH_BIT set";
468 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_IMAGE,
Chia-I Wue420a332015-10-26 20:04:44 +0800469 (uint64_t)pCreateInfo->image, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", ss.str().c_str());
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600470 }
471 } else if (vk_format_is_stencil_only(imageFormat)) {
472 if ((aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT) != VK_IMAGE_ASPECT_STENCIL_BIT) {
473 std::stringstream ss;
474 ss << "vkCreateImageView: Stencil-only image formats must have the VK_IMAGE_ASPECT_STENCIL_BIT set";
475 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_IMAGE,
Chia-I Wue420a332015-10-26 20:04:44 +0800476 (uint64_t)pCreateInfo->image, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", ss.str().c_str());
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600477 }
478 if ((aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT) != aspectMask) {
479 std::stringstream ss;
480 ss << "vkCreateImageView: Stencil-only image formats can have only the VK_IMAGE_ASPECT_STENCIL_BIT set";
481 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_IMAGE,
Chia-I Wue420a332015-10-26 20:04:44 +0800482 (uint64_t)pCreateInfo->image, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", ss.str().c_str());
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600483 }
484 }
485 }
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600486
Tobin Ehlis65380532015-09-21 15:20:28 -0600487 if (skipCall)
488 return VK_ERROR_VALIDATION_FAILED;
Tobin Ehlis35613802015-09-22 08:40:52 -0600489
Tobin Ehlis65380532015-09-21 15:20:28 -0600490 VkResult result = get_dispatch_table(image_device_table_map, device)->CreateImageView(device, pCreateInfo, pView);
491 return result;
492}
493
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600494VK_LAYER_EXPORT void VKAPI vkCmdClearColorImage(
495 VkCmdBuffer cmdBuffer,
496 VkImage image,
497 VkImageLayout imageLayout,
498 const VkClearColorValue *pColor,
499 uint32_t rangeCount,
500 const VkImageSubresourceRange *pRanges)
501{
502 VkBool32 skipCall = VK_FALSE;
503
504 // For each range, image aspect must be color only
505 for (uint32_t i = 0; i < rangeCount; i++) {
506 if (pRanges[i].aspectMask != VK_IMAGE_ASPECT_COLOR_BIT) {
507 layer_data *device_data = get_my_data_ptr(get_dispatch_key(cmdBuffer), layer_data_map);
508 char const str[] = "vkCmdClearColorImage aspectMasks for all subresource ranges must be set to VK_IMAGE_ASPECT_COLOR_BIT";
509 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
510 (uint64_t)cmdBuffer, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", str);
511 }
512 }
513
514 if (VK_FALSE == skipCall) {
515 get_dispatch_table(image_device_table_map, cmdBuffer)->CmdClearColorImage(cmdBuffer, image, imageLayout,
516 pColor, rangeCount, pRanges);
517 }
518}
519
520VK_LAYER_EXPORT void VKAPI vkCmdClearDepthStencilImage(
521 VkCmdBuffer cmdBuffer,
522 VkImage image,
523 VkImageLayout imageLayout,
524 const VkClearDepthStencilValue *pDepthStencil,
525 uint32_t rangeCount,
526 const VkImageSubresourceRange *pRanges)
527{
528 VkBool32 skipCall = VK_FALSE;
529
530 // For each range, Image aspect must be depth or stencil or both
531 for (uint32_t i = 0; i < rangeCount; i++) {
532 if (((pRanges[i].aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT) != VK_IMAGE_ASPECT_DEPTH_BIT) &&
533 ((pRanges[i].aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT) != VK_IMAGE_ASPECT_STENCIL_BIT))
534 {
535 layer_data *device_data = get_my_data_ptr(get_dispatch_key(cmdBuffer), layer_data_map);
536 char const str[] = "vkCmdClearDepthStencilImage aspectMasks for all subresource ranges must be "
537 "set to VK_IMAGE_ASPECT_DEPTH_BIT and/or VK_IMAGE_ASPECT_STENCIL_BIT";
538 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
539 (uint64_t)cmdBuffer, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", str);
540 }
541 }
542
543 if (VK_FALSE == skipCall) {
544 get_dispatch_table(image_device_table_map, cmdBuffer)->CmdClearDepthStencilImage(cmdBuffer,
545 image, imageLayout, pDepthStencil, rangeCount, pRanges);
546 }
547}
548
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600549VK_LAYER_EXPORT void VKAPI vkCmdCopyImage(
550 VkCmdBuffer cmdBuffer,
551 VkImage srcImage,
552 VkImageLayout srcImageLayout,
553 VkImage destImage,
554 VkImageLayout destImageLayout,
555 uint32_t regionCount,
556 const VkImageCopy *pRegions)
557{
558 VkBool32 skipCall = VK_FALSE;
Mike Stroyan43909d82015-09-25 13:39:21 -0600559 layer_data *device_data = get_my_data_ptr(get_dispatch_key(cmdBuffer), layer_data_map);
Chia-I Wue420a332015-10-26 20:04:44 +0800560 auto srcImageEntry = device_data->imageMap.find(srcImage);
561 auto destImageEntry = device_data->imageMap.find(destImage);
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600562
Jeremy Hayesac8ed0b2015-10-28 13:01:39 -0600563 // For each region, src and dst number of layers should not be zero
564 // For each region, src and dst number of layers must match
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600565 // For each region, src aspect mask must match dest aspect mask
566 // For each region, color aspects cannot be mixed with depth/stencil aspects
567 for (uint32_t i = 0; i < regionCount; i++) {
Jeremy Hayesac8ed0b2015-10-28 13:01:39 -0600568 if(pRegions[i].srcSubresource.numLayers == 0)
569 {
570 char const str[] = "vkCmdCopyImage: number of layers in source subresource is zero";
571 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_WARN_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
572 (uint64_t)cmdBuffer, 0, IMAGE_MISMATCHED_IMAGE_ASPECT, "IMAGE", str);
573 }
574
575 if(pRegions[i].destSubresource.numLayers == 0)
576 {
577 char const str[] = "vkCmdCopyImage: number of layers in destination subresource is zero";
578 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_WARN_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
579 (uint64_t)cmdBuffer, 0, IMAGE_MISMATCHED_IMAGE_ASPECT, "IMAGE", str);
580 }
581
582 if(pRegions[i].srcSubresource.numLayers != pRegions[i].destSubresource.numLayers)
583 {
584 char const str[] = "vkCmdCopyImage: number of layers in source and destination subresources must match";
585 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
586 (uint64_t)cmdBuffer, 0, IMAGE_MISMATCHED_IMAGE_ASPECT, "IMAGE", str);
587 }
588
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600589 if (pRegions[i].srcSubresource.aspect != pRegions[i].destSubresource.aspect) {
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600590 char const str[] = "vkCmdCopyImage: Src and dest aspectMasks for each region must match";
591 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
592 (uint64_t)cmdBuffer, 0, IMAGE_MISMATCHED_IMAGE_ASPECT, "IMAGE", str);
593 }
Courtney Goeltzenleuchterba11ebe2015-10-21 17:00:51 -0600594 if ((pRegions[i].srcSubresource.aspect & VK_IMAGE_ASPECT_COLOR_BIT) &&
595 (pRegions[i].srcSubresource.aspect & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT))) {
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600596 char const str[] = "vkCmdCopyImage aspectMask cannot specify both COLOR and DEPTH/STENCIL aspects";
597 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
598 (uint64_t)cmdBuffer, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", str);
599 }
600 }
601
Mike Stroyan43909d82015-09-25 13:39:21 -0600602 if ((srcImageEntry != device_data->imageMap.end())
603 && (destImageEntry != device_data->imageMap.end())) {
Tobin Ehlis6fa437d2015-09-25 14:49:43 -0600604 if (srcImageEntry->second.imageType != destImageEntry->second.imageType) {
Mike Stroyan43909d82015-09-25 13:39:21 -0600605 char const str[] = "vkCmdCopyImage called with unmatched source and dest image types.";
606 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
607 (uint64_t)cmdBuffer, 0, IMAGE_MISMATCHED_IMAGE_TYPE, "IMAGE", str);
608 }
609 // Check that format is same size or exact stencil/depth
Tobin Ehlis6fa437d2015-09-25 14:49:43 -0600610 if (is_depth_format(srcImageEntry->second.format)) {
611 if (srcImageEntry->second.format != destImageEntry->second.format) {
Mike Stroyan43909d82015-09-25 13:39:21 -0600612 char const str[] = "vkCmdCopyImage called with unmatched source and dest image depth/stencil formats.";
613 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
614 (uint64_t)cmdBuffer, 0, IMAGE_MISMATCHED_IMAGE_FORMAT, "IMAGE", str);
615 }
616 } else {
Tobin Ehlis6fa437d2015-09-25 14:49:43 -0600617 size_t srcSize = vk_format_get_size(srcImageEntry->second.format);
618 size_t destSize = vk_format_get_size(destImageEntry->second.format);
Mike Stroyan43909d82015-09-25 13:39:21 -0600619 if (srcSize != destSize) {
620 char const str[] = "vkCmdCopyImage called with unmatched source and dest image format sizes.";
621 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
622 (uint64_t)cmdBuffer, 0, IMAGE_MISMATCHED_IMAGE_FORMAT, "IMAGE", str);
623 }
624 }
625 }
626
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600627 if (VK_FALSE == skipCall) {
628 get_dispatch_table(image_device_table_map, cmdBuffer)->CmdCopyImage(cmdBuffer, srcImage,
629 srcImageLayout, destImage, destImageLayout, regionCount, pRegions);
630 }
631}
632
Courtney Goeltzenleuchter9feb0732015-10-15 16:51:05 -0600633void VKAPI vkCmdClearAttachments(
634 VkCmdBuffer cmdBuffer,
635 uint32_t attachmentCount,
636 const VkClearAttachment* pAttachments,
637 uint32_t rectCount,
Courtney Goeltzenleuchtera12e2912015-10-15 18:22:08 -0600638 const VkClearRect* pRects)
Courtney Goeltzenleuchter9feb0732015-10-15 16:51:05 -0600639{
640 VkBool32 skipCall = VK_FALSE;
641 VkImageAspectFlags aspectMask;
642
643 for (uint32_t i = 0; i < attachmentCount; i++) {
644 aspectMask = pAttachments[i].aspectMask;
645 if (aspectMask & VK_IMAGE_ASPECT_COLOR_BIT) {
646 if (aspectMask != VK_IMAGE_ASPECT_COLOR_BIT) {
647 // VK_IMAGE_ASPECT_COLOR_BIT is not the only bit set for this attachment
648 layer_data *device_data = get_my_data_ptr(get_dispatch_key(cmdBuffer), layer_data_map);
649 char const str[] = "vkCmdClearAttachments aspectMask [%d] must set only VK_IMAGE_ASPECT_COLOR_BIT of a color attachment.";
650 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
651 (uint64_t)cmdBuffer, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", str, i);
652 }
653 } else {
654 // Image aspect must be depth or stencil or both
655 if (((aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT) != VK_IMAGE_ASPECT_DEPTH_BIT) &&
656 ((aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT) != VK_IMAGE_ASPECT_STENCIL_BIT))
657 {
658 layer_data *device_data = get_my_data_ptr(get_dispatch_key(cmdBuffer), layer_data_map);
659 char const str[] = "vkCmdClearAttachments aspectMask [%d] must be set to VK_IMAGE_ASPECT_DEPTH_BIT and/or VK_IMAGE_ASPECT_STENCIL_BIT";
660 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
661 (uint64_t)cmdBuffer, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", str, i);
662 }
663 }
664 }
665
666 if (VK_FALSE == skipCall) {
667 get_dispatch_table(image_device_table_map, cmdBuffer)->CmdClearAttachments(cmdBuffer,
668 attachmentCount, pAttachments, rectCount, pRects);
669 }
670}
671
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600672VK_LAYER_EXPORT void VKAPI vkCmdCopyImageToBuffer(
673 VkCmdBuffer cmdBuffer,
674 VkImage srcImage,
675 VkImageLayout srcImageLayout,
676 VkBuffer destBuffer,
677 uint32_t regionCount,
678 const VkBufferImageCopy *pRegions)
679{
680 VkBool32 skipCall = VK_FALSE;
681
Jeremy Hayesac8ed0b2015-10-28 13:01:39 -0600682 // For each region, the number of layers in the image subresource should not be zero
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600683 // Image aspect must be ONE OF color, depth, stencil
684 for (uint32_t i = 0; i < regionCount; i++) {
Jeremy Hayesac8ed0b2015-10-28 13:01:39 -0600685 if(pRegions[i].imageSubresource.numLayers == 0)
686 {
687 layer_data *device_data = get_my_data_ptr(get_dispatch_key(cmdBuffer), layer_data_map);
688 char const str[] = "vkCmdCopyImageToBuffer: number of layers in image subresource is zero";
689 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_WARN_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
690 (uint64_t)cmdBuffer, 0, IMAGE_MISMATCHED_IMAGE_ASPECT, "IMAGE", str);
691 }
692
Courtney Goeltzenleuchterba11ebe2015-10-21 17:00:51 -0600693 VkImageAspectFlags aspect = pRegions[i].imageSubresource.aspect;
694 if ((aspect != VK_IMAGE_ASPECT_COLOR_BIT) &&
695 (aspect != VK_IMAGE_ASPECT_DEPTH_BIT) &&
696 (aspect != VK_IMAGE_ASPECT_STENCIL_BIT)) {
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600697 layer_data *device_data = get_my_data_ptr(get_dispatch_key(cmdBuffer), layer_data_map);
698 char const str[] = "vkCmdCopyImageToBuffer: aspectMasks for each region must specify only COLOR or DEPTH or STENCIL";
699 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
700 (uint64_t)cmdBuffer, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", str);
701 }
702 }
703
704 if (VK_FALSE == skipCall) {
705 get_dispatch_table(image_device_table_map, cmdBuffer)->CmdCopyImageToBuffer(cmdBuffer,
706 srcImage, srcImageLayout, destBuffer, regionCount, pRegions);
707 }
708}
709
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600710VK_LAYER_EXPORT void VKAPI vkCmdCopyBufferToImage(
711 VkCmdBuffer cmdBuffer,
712 VkBuffer srcBuffer,
713 VkImage destImage,
714 VkImageLayout destImageLayout,
715 uint32_t regionCount,
716 const VkBufferImageCopy *pRegions)
717{
718 VkBool32 skipCall = VK_FALSE;
719
Jeremy Hayesac8ed0b2015-10-28 13:01:39 -0600720 // For each region, the number of layers in the image subresource should not be zero
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600721 // Image aspect must be ONE OF color, depth, stencil
722 for (uint32_t i = 0; i < regionCount; i++) {
Jeremy Hayesac8ed0b2015-10-28 13:01:39 -0600723 if(pRegions[i].imageSubresource.numLayers == 0)
724 {
725 layer_data *device_data = get_my_data_ptr(get_dispatch_key(cmdBuffer), layer_data_map);
726 char const str[] = "vkCmdCopyBufferToImage: number of layers in image subresource is zero";
727 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_WARN_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
728 (uint64_t)cmdBuffer, 0, IMAGE_MISMATCHED_IMAGE_ASPECT, "IMAGE", str);
729 }
730
Courtney Goeltzenleuchterba11ebe2015-10-21 17:00:51 -0600731 VkImageAspectFlags aspect = pRegions[i].imageSubresource.aspect;
732 if ((aspect != VK_IMAGE_ASPECT_COLOR_BIT) &&
733 (aspect != VK_IMAGE_ASPECT_DEPTH_BIT) &&
734 (aspect != VK_IMAGE_ASPECT_STENCIL_BIT)) {
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600735 layer_data *device_data = get_my_data_ptr(get_dispatch_key(cmdBuffer), layer_data_map);
736 char const str[] = "vkCmdCopyBufferToImage: aspectMasks for each region must specify only COLOR or DEPTH or STENCIL";
737 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
738 (uint64_t)cmdBuffer, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", str);
739 }
740 }
741
742 if (VK_FALSE == skipCall) {
743 get_dispatch_table(image_device_table_map, cmdBuffer)->CmdCopyBufferToImage(cmdBuffer,
744 srcBuffer, destImage, destImageLayout, regionCount, pRegions);
745 }
746}
747
748VK_LAYER_EXPORT void VKAPI vkCmdBlitImage(
749 VkCmdBuffer cmdBuffer,
750 VkImage srcImage,
751 VkImageLayout srcImageLayout,
752 VkImage destImage,
753 VkImageLayout destImageLayout,
754 uint32_t regionCount,
755 const VkImageBlit *pRegions,
756 VkTexFilter filter)
757{
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600758 VkBool32 skipCall = VK_FALSE;
759 layer_data *device_data = get_my_data_ptr(get_dispatch_key(cmdBuffer), layer_data_map);
760
Chia-I Wue420a332015-10-26 20:04:44 +0800761 auto srcImageEntry = device_data->imageMap.find(srcImage);
762 auto destImageEntry = device_data->imageMap.find(destImage);
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600763
764 if ((srcImageEntry != device_data->imageMap.end()) &&
765 (destImageEntry != device_data->imageMap.end())) {
766
Tobin Ehlis6fa437d2015-09-25 14:49:43 -0600767 VkFormat srcFormat = srcImageEntry->second.format;
768 VkFormat dstFormat = destImageEntry->second.format;
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600769
770 // Validate consistency for signed and unsigned formats
771 if ((vk_format_is_sint(srcFormat) && !vk_format_is_sint(dstFormat)) ||
772 (vk_format_is_uint(srcFormat) && !vk_format_is_uint(dstFormat))) {
773 std::stringstream ss;
774 ss << "vkCmdBlitImage: If one of srcImage and destImage images has signed/unsigned integer format, "
775 << "the other one must also have signed/unsigned integer format. "
776 << "Source format is " << string_VkFormat(srcFormat) << " Destinatino format is " << string_VkFormat(dstFormat);
777 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
778 (uint64_t)cmdBuffer, 0, IMAGE_INVALID_FORMAT, "IMAGE", ss.str().c_str());
779 }
780
781 // Validate aspect bits and formats for depth/stencil images
782 if (vk_format_is_depth_or_stencil(srcFormat) ||
783 vk_format_is_depth_or_stencil(dstFormat)) {
784 if (srcFormat != dstFormat) {
785 std::stringstream ss;
786 ss << "vkCmdBlitImage: If one of srcImage and destImage images has a format of depth, stencil or depth "
787 << "stencil, the other one must have exactly the same format. "
788 << "Source format is " << string_VkFormat(srcFormat) << " Destinatino format is " << string_VkFormat(dstFormat);
789 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
790 (uint64_t)cmdBuffer, 0, IMAGE_INVALID_FORMAT, "IMAGE", ss.str().c_str());
791 }
792
793 for (uint32_t i = 0; i < regionCount; i++) {
Jeremy Hayesac8ed0b2015-10-28 13:01:39 -0600794 if(pRegions[i].srcSubresource.numLayers == 0)
795 {
796 char const str[] = "vkCmdBlitImage: number of layers in source subresource is zero";
797 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_WARN_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
798 (uint64_t)cmdBuffer, 0, IMAGE_MISMATCHED_IMAGE_ASPECT, "IMAGE", str);
799 }
800
801 if(pRegions[i].destSubresource.numLayers == 0)
802 {
803 char const str[] = "vkCmdBlitImage: number of layers in destination subresource is zero";
804 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_WARN_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
805 (uint64_t)cmdBuffer, 0, IMAGE_MISMATCHED_IMAGE_ASPECT, "IMAGE", str);
806 }
807
808 if(pRegions[i].srcSubresource.numLayers != pRegions[i].destSubresource.numLayers)
809 {
810 char const str[] = "vkCmdBlitImage: number of layers in source and destination subresources must match";
811 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
812 (uint64_t)cmdBuffer, 0, IMAGE_MISMATCHED_IMAGE_ASPECT, "IMAGE", str);
813 }
814
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600815 VkImageAspectFlags srcAspect = pRegions[i].srcSubresource.aspect;
816 VkImageAspectFlags dstAspect = pRegions[i].destSubresource.aspect;
817
818 if (srcAspect != dstAspect) {
819 std::stringstream ss;
820 ss << "vkCmdBlitImage: Image aspects of depth/stencil images should match";
821 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_WARN_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
822 (uint64_t)cmdBuffer, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", ss.str().c_str());
823 }
824 if (vk_format_is_depth_and_stencil(srcFormat)) {
825 if (srcAspect != (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) {
826 std::stringstream ss;
827 ss << "vkCmdBlitImage: Combination depth/stencil image formats must have both VK_IMAGE_ASPECT_DEPTH_BIT "
828 << "and VK_IMAGE_ASPECT_STENCIL_BIT set in both the srcImage and destImage";
829 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
830 (uint64_t)cmdBuffer, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", ss.str().c_str());
831 }
832 } else if (vk_format_is_stencil_only(srcFormat)) {
833 if (srcAspect != VK_IMAGE_ASPECT_STENCIL_BIT) {
834 std::stringstream ss;
835 ss << "vkCmdBlitImage: Stencil-only image formats must have only the VK_IMAGE_ASPECT_STENCIL_BIT "
836 << "set in both the srcImage and destImage";
837 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
838 (uint64_t)cmdBuffer, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", ss.str().c_str());
839 }
840 } else if (vk_format_is_depth_only(srcFormat)) {
841 if (srcAspect != VK_IMAGE_ASPECT_DEPTH_BIT) {
842 std::stringstream ss;
843 ss << "vkCmdBlitImage: Depth-only image formats must have only the VK_IMAGE_ASPECT_DEPTH "
844 << "set in both the srcImage and destImage";
845 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
846 (uint64_t)cmdBuffer, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", ss.str().c_str());
847 }
848 }
849 }
850 }
851
852 // Validate filter
853 if (vk_format_is_depth_or_stencil(srcFormat) ||
854 vk_format_is_int(srcFormat)) {
855 if (filter != VK_TEX_FILTER_NEAREST) {
856 std::stringstream ss;
857 ss << "vkCmdBlitImage: If the format of srcImage is a depth, stencil, depth stencil or integer-based format "
858 << "then filter must be VK_TEX_FILTER_NEAREST.";
859 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
860 (uint64_t)cmdBuffer, 0, IMAGE_INVALID_FILTER, "IMAGE", ss.str().c_str());
861 }
862 }
863 }
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600864
865 get_dispatch_table(image_device_table_map, cmdBuffer)->CmdBlitImage(cmdBuffer, srcImage,
866 srcImageLayout, destImage, destImageLayout, regionCount, pRegions, filter);
867}
868
869VK_LAYER_EXPORT void VKAPI vkCmdResolveImage(
870 VkCmdBuffer cmdBuffer,
871 VkImage srcImage,
872 VkImageLayout srcImageLayout,
873 VkImage destImage,
874 VkImageLayout destImageLayout,
875 uint32_t regionCount,
876 const VkImageResolve *pRegions)
877{
878 VkBool32 skipCall = VK_FALSE;
Mike Stroyan43909d82015-09-25 13:39:21 -0600879 layer_data *device_data = get_my_data_ptr(get_dispatch_key(cmdBuffer), layer_data_map);
Chia-I Wue420a332015-10-26 20:04:44 +0800880 auto srcImageEntry = device_data->imageMap.find(srcImage);
881 auto destImageEntry = device_data->imageMap.find(destImage);
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600882
Jeremy Hayesac8ed0b2015-10-28 13:01:39 -0600883 // For each region, the number of layers in the image subresource should not be zero
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600884 // For each region, src and dest image aspect must be color only
885 for (uint32_t i = 0; i < regionCount; i++) {
Jeremy Hayesac8ed0b2015-10-28 13:01:39 -0600886 if(pRegions[i].srcSubresource.numLayers == 0)
887 {
888 char const str[] = "vkCmdResolveImage: number of layers in source subresource is zero";
889 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_WARN_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
890 (uint64_t)cmdBuffer, 0, IMAGE_MISMATCHED_IMAGE_ASPECT, "IMAGE", str);
891 }
892
893 if(pRegions[i].destSubresource.numLayers == 0)
894 {
895 char const str[] = "vkCmdResolveImage: number of layers in destination subresource is zero";
896 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_WARN_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
897 (uint64_t)cmdBuffer, 0, IMAGE_MISMATCHED_IMAGE_ASPECT, "IMAGE", str);
898 }
899
Courtney Goeltzenleuchterba11ebe2015-10-21 17:00:51 -0600900 if ((pRegions[i].srcSubresource.aspect != VK_IMAGE_ASPECT_COLOR_BIT) ||
901 (pRegions[i].destSubresource.aspect != VK_IMAGE_ASPECT_COLOR_BIT)) {
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600902 char const str[] = "vkCmdResolveImage: src and dest aspectMasks for each region must specify only VK_IMAGE_ASPECT_COLOR_BIT";
903 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
904 (uint64_t)cmdBuffer, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", str);
905 }
906 }
907
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600908 if ((srcImageEntry != device_data->imageMap.end()) &&
909 (destImageEntry != device_data->imageMap.end())) {
Tobin Ehlis6fa437d2015-09-25 14:49:43 -0600910 if (srcImageEntry->second.format != destImageEntry->second.format) {
Mike Stroyan43909d82015-09-25 13:39:21 -0600911 char const str[] = "vkCmdResolveImage called with unmatched source and dest formats.";
912 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
913 (uint64_t)cmdBuffer, 0, IMAGE_MISMATCHED_IMAGE_FORMAT, "IMAGE", str);
914 }
Tobin Ehlis6fa437d2015-09-25 14:49:43 -0600915 if (srcImageEntry->second.imageType != destImageEntry->second.imageType) {
Mike Stroyan43909d82015-09-25 13:39:21 -0600916 char const str[] = "vkCmdResolveImage called with unmatched source and dest image types.";
917 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
918 (uint64_t)cmdBuffer, 0, IMAGE_MISMATCHED_IMAGE_TYPE, "IMAGE", str);
919 }
Tobin Ehlis6fa437d2015-09-25 14:49:43 -0600920 if (srcImageEntry->second.samples <= 1) {
Mike Stroyan43909d82015-09-25 13:39:21 -0600921 char const str[] = "vkCmdResolveImage called with source sample count less than 2.";
922 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
923 (uint64_t)cmdBuffer, 0, IMAGE_INVALID_RESOLVE_SAMPLES, "IMAGE", str);
924 }
Tobin Ehlis6fa437d2015-09-25 14:49:43 -0600925 if (destImageEntry->second.samples > 1) {
Mike Stroyan43909d82015-09-25 13:39:21 -0600926 char const str[] = "vkCmdResolveImage called with dest sample count greater than 1.";
927 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
928 (uint64_t)cmdBuffer, 0, IMAGE_INVALID_RESOLVE_SAMPLES, "IMAGE", str);
929 }
930 }
931
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600932 if (VK_FALSE == skipCall) {
933 get_dispatch_table(image_device_table_map, cmdBuffer)->CmdResolveImage(cmdBuffer, srcImage,
934 srcImageLayout, destImage, destImageLayout, regionCount, pRegions);
935 }
936}
937
Courtney Goeltzenleuchter01d2ae12015-10-20 16:40:38 -0600938VK_LAYER_EXPORT void VKAPI vkGetImageSubresourceLayout(
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600939 VkDevice device,
940 VkImage image,
941 const VkImageSubresource *pSubresource,
942 VkSubresourceLayout *pLayout)
943{
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600944 VkBool32 skipCall = VK_FALSE;
945 layer_data *device_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
946 VkFormat format;
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600947
Chia-I Wue420a332015-10-26 20:04:44 +0800948 auto imageEntry = device_data->imageMap.find(image);
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600949
950 // Validate that image aspects match formats
951 if (imageEntry != device_data->imageMap.end()) {
Tobin Ehlis6fa437d2015-09-25 14:49:43 -0600952 format = imageEntry->second.format;
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600953 if (vk_format_is_color(format)) {
954 if (pSubresource->aspect != VK_IMAGE_ASPECT_COLOR_BIT) {
955 std::stringstream ss;
956 ss << "vkGetImageSubresourceLayout: For color formats, the aspect field of VkImageSubresource must be VK_IMAGE_ASPECT_COLOR.";
957 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_IMAGE,
Chia-I Wue420a332015-10-26 20:04:44 +0800958 (uint64_t)image, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", ss.str().c_str());
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600959 }
960 } else if (vk_format_is_depth_or_stencil(format)) {
961 if ((pSubresource->aspect != VK_IMAGE_ASPECT_DEPTH_BIT) &&
962 (pSubresource->aspect != VK_IMAGE_ASPECT_STENCIL_BIT)) {
963 std::stringstream ss;
964 ss << "vkGetImageSubresourceLayout: For depth/stencil formats, the aspect selects either the depth or stencil image aspect.";
965 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_IMAGE,
Chia-I Wue420a332015-10-26 20:04:44 +0800966 (uint64_t)image, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", ss.str().c_str());
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600967 }
968 }
969 }
970
971 if (VK_FALSE == skipCall) {
972 get_dispatch_table(image_device_table_map, device)->GetImageSubresourceLayout(device,
973 image, pSubresource, pLayout);
974 }
975
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600976}
977
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -0600978VK_LAYER_EXPORT PFN_vkVoidFunction VKAPI vkGetDeviceProcAddr(VkDevice device, const char* funcName)
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600979{
980 if (device == NULL) {
981 return NULL;
982 }
983
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600984 // loader uses this to force layer initialization; device object is wrapped
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600985 if (!strcmp(funcName, "vkGetDeviceProcAddr")) {
986 initDeviceTable(image_device_table_map, (const VkBaseLayerObject *) device);
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -0600987 return (PFN_vkVoidFunction) vkGetDeviceProcAddr;
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600988 }
989
Courtney Goeltzenleuchterbe637992015-06-25 18:01:43 -0600990 if (!strcmp(funcName, "vkCreateDevice"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -0600991 return (PFN_vkVoidFunction) vkCreateDevice;
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600992 if (!strcmp(funcName, "vkDestroyDevice"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -0600993 return (PFN_vkVoidFunction) vkDestroyDevice;
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600994 if (!strcmp(funcName, "vkCreateImage"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -0600995 return (PFN_vkVoidFunction) vkCreateImage;
Mark Lobodzinski9eb1ce42015-10-29 12:58:33 -0600996 if (!strcmp(funcName, "vkDestroyImage"))
997 return (PFN_vkVoidFunction) vkDestroyImage;
Tobin Ehlis342b9bf2015-09-22 10:11:37 -0600998 if (!strcmp(funcName, "vkCreateImageView"))
999 return (PFN_vkVoidFunction) vkCreateImageView;
Jeremy Hayesb707aa52015-06-18 10:12:39 -06001000 if (!strcmp(funcName, "vkCreateRenderPass"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06001001 return (PFN_vkVoidFunction) vkCreateRenderPass;
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -06001002 if (!strcmp(funcName, "vkCmdClearColorImage"))
1003 return (PFN_vkVoidFunction) vkCmdClearColorImage;
1004 if (!strcmp(funcName, "vkCmdClearDepthStencilImage"))
1005 return (PFN_vkVoidFunction) vkCmdClearDepthStencilImage;
Courtney Goeltzenleuchter9feb0732015-10-15 16:51:05 -06001006 if (!strcmp(funcName, "vkCmdClearAttachments"))
1007 return (PFN_vkVoidFunction) vkCmdClearAttachments;
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -06001008 if (!strcmp(funcName, "vkCmdCopyImage"))
1009 return (PFN_vkVoidFunction) vkCmdCopyImage;
1010 if (!strcmp(funcName, "vkCmdCopyImageToBuffer"))
1011 return (PFN_vkVoidFunction) vkCmdCopyImageToBuffer;
1012 if (!strcmp(funcName, "vkCmdCopyBufferToImage"))
1013 return (PFN_vkVoidFunction) vkCmdCopyBufferToImage;
1014 if (!strcmp(funcName, "vkCmdBlitImage"))
1015 return (PFN_vkVoidFunction) vkCmdBlitImage;
1016 if (!strcmp(funcName, "vkCmdResolveImage"))
1017 return (PFN_vkVoidFunction) vkCmdResolveImage;
1018 if (!strcmp(funcName, "vkGetImageSubresourceLayout"))
1019 return (PFN_vkVoidFunction) vkGetImageSubresourceLayout;
Jeremy Hayesb707aa52015-06-18 10:12:39 -06001020 {
1021 if (get_dispatch_table(image_device_table_map, device)->GetDeviceProcAddr == NULL)
1022 return NULL;
1023 return get_dispatch_table(image_device_table_map, device)->GetDeviceProcAddr(device, funcName);
1024 }
1025}
1026
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06001027VK_LAYER_EXPORT PFN_vkVoidFunction VKAPI vkGetInstanceProcAddr(VkInstance instance, const char* funcName)
Jeremy Hayesb707aa52015-06-18 10:12:39 -06001028{
1029 if (instance == NULL) {
1030 return NULL;
1031 }
1032
Mark Lobodzinskib4092de2015-10-23 14:20:31 -06001033 // loader uses this to force layer initialization; instance object is wrapped
Jeremy Hayesb707aa52015-06-18 10:12:39 -06001034 if (!strcmp(funcName, "vkGetInstanceProcAddr")) {
1035 initInstanceTable(image_instance_table_map, (const VkBaseLayerObject *) instance);
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06001036 return (PFN_vkVoidFunction) vkGetInstanceProcAddr;
Jeremy Hayesb707aa52015-06-18 10:12:39 -06001037 }
1038
1039 if (!strcmp(funcName, "vkCreateInstance"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06001040 return (PFN_vkVoidFunction) vkCreateInstance;
Jeremy Hayesb707aa52015-06-18 10:12:39 -06001041 if (!strcmp(funcName, "vkDestroyInstance"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06001042 return (PFN_vkVoidFunction) vkDestroyInstance;
Courtney Goeltzenleuchter74c4ce92015-09-14 17:22:16 -06001043 if (!strcmp(funcName, "vkEnumerateInstanceLayerProperties"))
1044 return (PFN_vkVoidFunction) vkEnumerateInstanceLayerProperties;
1045 if (!strcmp(funcName, "vkEnumerateInstanceExtensionProperties"))
1046 return (PFN_vkVoidFunction) vkEnumerateInstanceExtensionProperties;
1047 if (!strcmp(funcName, "vkEnumerateDeviceLayerProperties"))
1048 return (PFN_vkVoidFunction) vkEnumerateDeviceLayerProperties;
1049 if (!strcmp(funcName, "vkEnumerateDeviceExtensionProperties"))
1050 return (PFN_vkVoidFunction) vkEnumerateDeviceExtensionProperties;
Jeremy Hayesb707aa52015-06-18 10:12:39 -06001051
1052 layer_data *data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06001053 PFN_vkVoidFunction fptr = debug_report_get_instance_proc_addr(data->report_data, funcName);
Jeremy Hayesb707aa52015-06-18 10:12:39 -06001054 if(fptr)
1055 return fptr;
1056
1057 {
1058 if (get_dispatch_table(image_instance_table_map, instance)->GetInstanceProcAddr == NULL)
1059 return NULL;
1060 return get_dispatch_table(image_instance_table_map, instance)->GetInstanceProcAddr(instance, funcName);
1061 }
1062}