blob: a776961bd0ab9bf12a52e1a3d0b49f480a15afcd [file] [log] [blame]
Jeremy Hayesb707aa52015-06-18 10:12:39 -06001/*
2 * Vulkan
3 *
4 * Copyright (C) 2014 LunarG, Inc.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included
14 * in all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
23 */
24
Courtney Goeltzenleuchter6ff93732015-10-07 08:38:30 -060025#include <inttypes.h>
Jeremy Hayesb707aa52015-06-18 10:12:39 -060026#include <stdio.h>
27#include <stdlib.h>
28#include <string.h>
Courtney Goeltzenleuchter6ff93732015-10-07 08:38:30 -060029#include <assert.h>
30#include <vector>
Jeremy Hayesb707aa52015-06-18 10:12:39 -060031#include <unordered_map>
Tobin Ehlis65380532015-09-21 15:20:28 -060032#include <memory>
Courtney Goeltzenleuchter6ff93732015-10-07 08:38:30 -060033using namespace std;
Jeremy Hayesb707aa52015-06-18 10:12:39 -060034
Tobin Ehlis7a51d902015-07-03 10:34:49 -060035#include "vk_loader_platform.h"
Courtney Goeltzenleuchter6ff93732015-10-07 08:38:30 -060036#include "vk_dispatch_table_helper.h"
37#include "vk_struct_string_helper_cpp.h"
Jeremy Hayesb707aa52015-06-18 10:12:39 -060038#include "vk_enum_validate_helper.h"
Courtney Goeltzenleuchter6ff93732015-10-07 08:38:30 -060039#include "image.h"
40#include "vk_layer_config.h"
41#include "vk_layer_extension_utils.h"
Tobin Ehlis56d204a2015-07-03 10:15:26 -060042#include "vk_layer_table.h"
43#include "vk_layer_data.h"
Courtney Goeltzenleuchtereb1ddb02015-07-07 11:18:30 -060044#include "vk_layer_extension_utils.h"
Mike Stroyan43909d82015-09-25 13:39:21 -060045#include "vk_layer_utils.h"
Courtney Goeltzenleuchter6ff93732015-10-07 08:38:30 -060046#include "vk_layer_logging.h"
Jeremy Hayesb707aa52015-06-18 10:12:39 -060047
Tobin Ehlis65380532015-09-21 15:20:28 -060048using namespace std;
49
Cody Northrop73bb6572015-09-28 15:09:32 -060050struct layer_data {
Jeremy Hayesb707aa52015-06-18 10:12:39 -060051 debug_report_data *report_data;
Courtney Goeltzenleuchter9fac1572015-10-05 15:59:11 -060052 std::vector<VkDbgMsgCallback> logging_callback;
Chris Forbesd7576302015-06-21 22:55:02 +120053 VkPhysicalDevice physicalDevice;
Tobin 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),
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;
Jeremy Hayesb707aa52015-06-18 10:12:39 -060063static device_table_map image_device_table_map;
64static instance_table_map image_instance_table_map;
65
66// "my device data"
Tony Barbour2a199c12015-07-09 17:31:46 -060067debug_report_data *mdd(const void* object)
Jeremy Hayesb707aa52015-06-18 10:12:39 -060068{
69 dispatch_key key = get_dispatch_key(object);
70 layer_data *data = get_my_data_ptr(key, layer_data_map);
71#if DISPATCH_MAP_DEBUG
72 fprintf(stderr, "MDD: map: %p, object: %p, key: %p, data: %p\n", &layer_data_map, object, key, data);
73#endif
Jeremy Hayesb707aa52015-06-18 10:12:39 -060074 return data->report_data;
75}
76
77// "my instance data"
78debug_report_data *mid(VkInstance object)
79{
80 dispatch_key key = get_dispatch_key(object);
Courtney Goeltzenleuchter07199212015-06-22 16:19:14 -060081 layer_data *data = get_my_data_ptr(key, layer_data_map);
Jeremy Hayesb707aa52015-06-18 10:12:39 -060082#if DISPATCH_MAP_DEBUG
83 fprintf(stderr, "MID: map: %p, object: %p, key: %p, data: %p\n", &layer_data_map, object, key, data);
84#endif
Jeremy Hayesb707aa52015-06-18 10:12:39 -060085 return data->report_data;
86}
87
88static void InitImage(layer_data *data)
89{
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{
Courtney Goeltzenleuchtereb1ddb02015-07-07 11:18:30 -0600221 /* ParamChecker does not have any global extensions */
222 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{
Courtney Goeltzenleuchtereb1ddb02015-07-07 11:18:30 -0600240 /* ParamChecker does not have any physical device extensions */
241 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{
249 /* ParamChecker's physical device layers are the same as global */
250 return util_GetLayerProperties(ARRAY_SIZE(pc_global_layers), pc_global_layers,
251 pCount, pProperties);
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600252}
253
Mark Lobodzinski9cce7832015-07-29 09:21:22 -0600254// Start of the Image layer proper
255
256// Returns TRUE if a format is a depth-compatible format
257bool is_depth_format(VkFormat format)
258{
259 bool result = VK_FALSE;
260 switch (format) {
261 case VK_FORMAT_D16_UNORM:
Courtney Goeltzenleuchter7ed10592015-09-10 17:17:43 -0600262 case VK_FORMAT_D24_UNORM_X8:
Mark Lobodzinski9cce7832015-07-29 09:21:22 -0600263 case VK_FORMAT_D32_SFLOAT:
264 case VK_FORMAT_S8_UINT:
265 case VK_FORMAT_D16_UNORM_S8_UINT:
266 case VK_FORMAT_D24_UNORM_S8_UINT:
267 case VK_FORMAT_D32_SFLOAT_S8_UINT:
268 result = VK_TRUE;
269 break;
270 default:
271 break;
272 }
273 return result;
274}
275
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600276VK_LAYER_EXPORT VkResult VKAPI vkCreateImage(VkDevice device, const VkImageCreateInfo* pCreateInfo, VkImage* pImage)
277{
Tobin Ehlis35613802015-09-22 08:40:52 -0600278 VkBool32 skipCall = VK_FALSE;
Tobin Ehlis65380532015-09-21 15:20:28 -0600279 layer_data *device_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600280 if(pCreateInfo->format != VK_FORMAT_UNDEFINED)
281 {
282 VkFormatProperties properties;
Courtney Goeltzenleuchter01d2ae12015-10-20 16:40:38 -0600283 get_dispatch_table(image_instance_table_map, device_data->physicalDevice)->GetPhysicalDeviceFormatProperties(
Chris Forbesd7576302015-06-21 22:55:02 +1200284 device_data->physicalDevice, pCreateInfo->format, &properties);
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600285
286 if((properties.linearTilingFeatures) == 0 && (properties.optimalTilingFeatures == 0))
287 {
288 char const str[] = "vkCreateImage parameter, VkFormat pCreateInfo->format, contains unsupported format";
Tobin Ehlis35613802015-09-22 08:40:52 -0600289 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_WARN_BIT, (VkDbgObjectType)0, 0, 0, IMAGE_FORMAT_UNSUPPORTED, "IMAGE", str);
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600290 }
291 }
Tobin Ehlis35613802015-09-22 08:40:52 -0600292 if (skipCall)
293 return VK_ERROR_VALIDATION_FAILED;
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600294
295 VkResult result = get_dispatch_table(image_device_table_map, device)->CreateImage(device, pCreateInfo, pImage);
296
Tobin Ehlis65380532015-09-21 15:20:28 -0600297 if(result == VK_SUCCESS) {
Tobin Ehlis342b9bf2015-09-22 10:11:37 -0600298 device_data->imageMap[pImage->handle] = unique_ptr<IMAGE_STATE>(new IMAGE_STATE(pCreateInfo));
Tobin Ehlis65380532015-09-21 15:20:28 -0600299 }
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600300 return result;
301}
302
Tobin Ehlis65380532015-09-21 15:20:28 -0600303VK_LAYER_EXPORT void VKAPI vkDestroyImage(VkDevice device, VkImage image)
304{
305 layer_data *device_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
306 device_data->imageMap.erase(image.handle);
307 get_dispatch_table(image_device_table_map, device)->DestroyImage(device, image);
308}
309
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600310VK_LAYER_EXPORT VkResult VKAPI vkCreateRenderPass(VkDevice device, const VkRenderPassCreateInfo* pCreateInfo, VkRenderPass* pRenderPass)
311{
Tobin Ehlis35613802015-09-22 08:40:52 -0600312 VkBool32 skipCall = VK_FALSE;
Chia-I Wuc278df82015-07-07 11:50:03 +0800313 for(uint32_t i = 0; i < pCreateInfo->attachmentCount; ++i)
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600314 {
Chia-I Wuc278df82015-07-07 11:50:03 +0800315 if(pCreateInfo->pAttachments[i].format != VK_FORMAT_UNDEFINED)
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600316 {
Courtney Goeltzenleuchter07199212015-06-22 16:19:14 -0600317 layer_data *device_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600318 VkFormatProperties properties;
Courtney Goeltzenleuchter01d2ae12015-10-20 16:40:38 -0600319 get_dispatch_table(image_instance_table_map, device_data->physicalDevice)->GetPhysicalDeviceFormatProperties(
Chia-I Wuc278df82015-07-07 11:50:03 +0800320 device_data->physicalDevice, pCreateInfo->pAttachments[i].format, &properties);
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600321
322 if((properties.linearTilingFeatures) == 0 && (properties.optimalTilingFeatures == 0))
323 {
324 std::stringstream ss;
Chia-I Wuc278df82015-07-07 11:50:03 +0800325 ss << "vkCreateRenderPass parameter, VkFormat in pCreateInfo->pAttachments[" << i << "], contains unsupported format";
Tobin Ehlis35613802015-09-22 08:40:52 -0600326 skipCall |= log_msg(mdd(device), VK_DBG_REPORT_WARN_BIT, (VkDbgObjectType)0, 0, 0, IMAGE_FORMAT_UNSUPPORTED, "IMAGE", ss.str().c_str());
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600327 }
328 }
329 }
330
Chia-I Wuc278df82015-07-07 11:50:03 +0800331 for(uint32_t i = 0; i < pCreateInfo->attachmentCount; ++i)
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600332 {
Chia-I Wuc278df82015-07-07 11:50:03 +0800333 if(!validate_VkImageLayout(pCreateInfo->pAttachments[i].initialLayout) ||
334 !validate_VkImageLayout(pCreateInfo->pAttachments[i].finalLayout))
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600335 {
336 std::stringstream ss;
Chia-I Wuc278df82015-07-07 11:50:03 +0800337 ss << "vkCreateRenderPass parameter, VkImageLayout in pCreateInfo->pAttachments[" << i << "], is unrecognized";
Tobin Ehlis35613802015-09-22 08:40:52 -0600338 skipCall |= log_msg(mdd(device), VK_DBG_REPORT_WARN_BIT, (VkDbgObjectType)0, 0, 0, IMAGE_RENDERPASS_INVALID_ATTACHMENT, "IMAGE", ss.str().c_str());
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600339 }
340 }
341
Chia-I Wuc278df82015-07-07 11:50:03 +0800342 for(uint32_t i = 0; i < pCreateInfo->attachmentCount; ++i)
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600343 {
Chia-I Wuc278df82015-07-07 11:50:03 +0800344 if(!validate_VkAttachmentLoadOp(pCreateInfo->pAttachments[i].loadOp))
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600345 {
346 std::stringstream ss;
Chia-I Wuc278df82015-07-07 11:50:03 +0800347 ss << "vkCreateRenderPass parameter, VkAttachmentLoadOp in pCreateInfo->pAttachments[" << i << "], is unrecognized";
Tobin Ehlis35613802015-09-22 08:40:52 -0600348 skipCall |= log_msg(mdd(device), VK_DBG_REPORT_WARN_BIT, (VkDbgObjectType)0, 0, 0, IMAGE_RENDERPASS_INVALID_ATTACHMENT, "IMAGE", ss.str().c_str());
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600349 }
350 }
351
Chia-I Wuc278df82015-07-07 11:50:03 +0800352 for(uint32_t i = 0; i < pCreateInfo->attachmentCount; ++i)
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600353 {
Chia-I Wuc278df82015-07-07 11:50:03 +0800354 if(!validate_VkAttachmentStoreOp(pCreateInfo->pAttachments[i].storeOp))
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600355 {
356 std::stringstream ss;
Chia-I Wuc278df82015-07-07 11:50:03 +0800357 ss << "vkCreateRenderPass parameter, VkAttachmentStoreOp in pCreateInfo->pAttachments[" << i << "], is unrecognized";
Tobin Ehlis35613802015-09-22 08:40:52 -0600358 skipCall |= log_msg(mdd(device), VK_DBG_REPORT_WARN_BIT, (VkDbgObjectType)0, 0, 0, IMAGE_RENDERPASS_INVALID_ATTACHMENT, "IMAGE", ss.str().c_str());
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600359 }
360 }
361
Mark Lobodzinski9cce7832015-07-29 09:21:22 -0600362 // Any depth buffers specified as attachments?
363 bool depthFormatPresent = VK_FALSE;
364 for (uint32_t i = 0; i < pCreateInfo->attachmentCount; ++i)
365 {
366 depthFormatPresent |= is_depth_format(pCreateInfo->pAttachments[i].format);
367 }
368
369 if (depthFormatPresent == VK_FALSE) {
370 // No depth attachment is present, validate that subpasses set depthStencilAttachment to VK_ATTACHMENT_UNUSED;
371 for (uint32_t i = 0; i < pCreateInfo->subpassCount; i++) {
372 if (pCreateInfo->pSubpasses[i].depthStencilAttachment.attachment != VK_ATTACHMENT_UNUSED) {
373 std::stringstream ss;
374 ss << "vkCreateRenderPass has no depth/stencil attachment, yet subpass[" << i << "] has VkSubpassDescription::depthStencilAttachment value that is not VK_ATTACHMENT_UNUSED";
Tobin Ehlis35613802015-09-22 08:40:52 -0600375 skipCall |= log_msg(mdd(device), VK_DBG_REPORT_ERROR_BIT, (VkDbgObjectType)0, 0, 0, IMAGE_RENDERPASS_INVALID_DS_ATTACHMENT, "IMAGE", ss.str().c_str());
Mark Lobodzinski9cce7832015-07-29 09:21:22 -0600376 }
377 }
378 }
Tobin Ehlis35613802015-09-22 08:40:52 -0600379 if (skipCall)
380 return VK_ERROR_VALIDATION_FAILED;
Mark Lobodzinski9cce7832015-07-29 09:21:22 -0600381
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600382 VkResult result = get_dispatch_table(image_device_table_map, device)->CreateRenderPass(device, pCreateInfo, pRenderPass);
383
384 return result;
385}
386
Tobin Ehlis65380532015-09-21 15:20:28 -0600387VK_LAYER_EXPORT VkResult VKAPI vkCreateImageView(VkDevice device, const VkImageViewCreateInfo* pCreateInfo, VkImageView* pView)
388{
389 VkBool32 skipCall = VK_FALSE;
390 layer_data *device_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
391 auto imageEntry = device_data->imageMap.find(pCreateInfo->image.handle);
392 if (imageEntry != device_data->imageMap.end()) {
393 if (pCreateInfo->subresourceRange.baseMipLevel >= imageEntry->second->mipLevels) {
394 std::stringstream ss;
395 ss << "vkCreateImageView called with baseMipLevel " << pCreateInfo->subresourceRange.baseMipLevel << " for image " << pCreateInfo->image.handle << " that only has " << imageEntry->second->mipLevels << " mip levels.";
396 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());
397 }
398 if (pCreateInfo->subresourceRange.baseArrayLayer >= imageEntry->second->arraySize) {
399 std::stringstream ss;
400 ss << "vkCreateImageView called with baseArrayLayer " << pCreateInfo->subresourceRange.baseArrayLayer << " for image " << pCreateInfo->image.handle << " that only has " << imageEntry->second->arraySize << " mip levels.";
401 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());
402 }
403 if (!pCreateInfo->subresourceRange.mipLevels) {
404 std::stringstream ss;
405 ss << "vkCreateImageView called with 0 in pCreateInfo->subresourceRange.mipLevels.";
406 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());
407 }
408 if (!pCreateInfo->subresourceRange.arraySize) {
409 std::stringstream ss;
410 ss << "vkCreateImageView called with 0 in pCreateInfo->subresourceRange.arraySize.";
411 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());
412 }
413 }
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600414
415 // TODO: Image aspect mask must be only VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_ASPECT_DEPTH_BIT or VK_IMAGE_ASPECT_STENCIL_BIT
416 // if the format is a color, depth-only or stencil-only format respectively. If using a depth/stencil format,
417 // aspectMask must include at least one of VK_IMAGE_ASPECT_DEPTH_BIT and VK_IMAGE_ASPECT_STENCIL_BIT, and may include both.
418 // Add after image/buffer state tracking is implemented.
419
Tobin Ehlis65380532015-09-21 15:20:28 -0600420 if (skipCall)
421 return VK_ERROR_VALIDATION_FAILED;
Tobin Ehlis35613802015-09-22 08:40:52 -0600422
Tobin Ehlis65380532015-09-21 15:20:28 -0600423 VkResult result = get_dispatch_table(image_device_table_map, device)->CreateImageView(device, pCreateInfo, pView);
424 return result;
425}
426
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600427VK_LAYER_EXPORT void VKAPI vkCmdClearColorImage(
428 VkCmdBuffer cmdBuffer,
429 VkImage image,
430 VkImageLayout imageLayout,
431 const VkClearColorValue *pColor,
432 uint32_t rangeCount,
433 const VkImageSubresourceRange *pRanges)
434{
435 VkBool32 skipCall = VK_FALSE;
436
437 // For each range, image aspect must be color only
438 for (uint32_t i = 0; i < rangeCount; i++) {
439 if (pRanges[i].aspectMask != VK_IMAGE_ASPECT_COLOR_BIT) {
440 layer_data *device_data = get_my_data_ptr(get_dispatch_key(cmdBuffer), layer_data_map);
441 char const str[] = "vkCmdClearColorImage aspectMasks for all subresource ranges must be set to VK_IMAGE_ASPECT_COLOR_BIT";
442 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
443 (uint64_t)cmdBuffer, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", str);
444 }
445 }
446
447 if (VK_FALSE == skipCall) {
448 get_dispatch_table(image_device_table_map, cmdBuffer)->CmdClearColorImage(cmdBuffer, image, imageLayout,
449 pColor, rangeCount, pRanges);
450 }
451}
452
453VK_LAYER_EXPORT void VKAPI vkCmdClearDepthStencilImage(
454 VkCmdBuffer cmdBuffer,
455 VkImage image,
456 VkImageLayout imageLayout,
457 const VkClearDepthStencilValue *pDepthStencil,
458 uint32_t rangeCount,
459 const VkImageSubresourceRange *pRanges)
460{
461 VkBool32 skipCall = VK_FALSE;
462
463 // For each range, Image aspect must be depth or stencil or both
464 for (uint32_t i = 0; i < rangeCount; i++) {
465 if (((pRanges[i].aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT) != VK_IMAGE_ASPECT_DEPTH_BIT) &&
466 ((pRanges[i].aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT) != VK_IMAGE_ASPECT_STENCIL_BIT))
467 {
468 layer_data *device_data = get_my_data_ptr(get_dispatch_key(cmdBuffer), layer_data_map);
469 char const str[] = "vkCmdClearDepthStencilImage aspectMasks for all subresource ranges must be "
470 "set to VK_IMAGE_ASPECT_DEPTH_BIT and/or VK_IMAGE_ASPECT_STENCIL_BIT";
471 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
472 (uint64_t)cmdBuffer, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", str);
473 }
474 }
475
476 if (VK_FALSE == skipCall) {
477 get_dispatch_table(image_device_table_map, cmdBuffer)->CmdClearDepthStencilImage(cmdBuffer,
478 image, imageLayout, pDepthStencil, rangeCount, pRanges);
479 }
480}
481
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600482VK_LAYER_EXPORT void VKAPI vkCmdCopyImage(
483 VkCmdBuffer cmdBuffer,
484 VkImage srcImage,
485 VkImageLayout srcImageLayout,
486 VkImage destImage,
487 VkImageLayout destImageLayout,
488 uint32_t regionCount,
489 const VkImageCopy *pRegions)
490{
491 VkBool32 skipCall = VK_FALSE;
Mike Stroyan43909d82015-09-25 13:39:21 -0600492 layer_data *device_data = get_my_data_ptr(get_dispatch_key(cmdBuffer), layer_data_map);
493 auto srcImageEntry = device_data->imageMap.find(srcImage.handle);
494 auto destImageEntry = device_data->imageMap.find(destImage.handle);
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600495
496 // For each region, src aspect mask must match dest aspect mask
497 // For each region, color aspects cannot be mixed with depth/stencil aspects
498 for (uint32_t i = 0; i < regionCount; i++) {
499 if (pRegions[i].srcSubresource.aspect != pRegions[i].destSubresource.aspect) {
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600500 char const str[] = "vkCmdCopyImage: Src and dest aspectMasks for each region must match";
501 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
502 (uint64_t)cmdBuffer, 0, IMAGE_MISMATCHED_IMAGE_ASPECT, "IMAGE", str);
503 }
Courtney Goeltzenleuchterba11ebe2015-10-21 17:00:51 -0600504 if ((pRegions[i].srcSubresource.aspect & VK_IMAGE_ASPECT_COLOR_BIT) &&
505 (pRegions[i].srcSubresource.aspect & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT))) {
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600506 char const str[] = "vkCmdCopyImage aspectMask cannot specify both COLOR and DEPTH/STENCIL aspects";
507 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
508 (uint64_t)cmdBuffer, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", str);
509 }
510 }
511
Mike Stroyan43909d82015-09-25 13:39:21 -0600512 if ((srcImageEntry != device_data->imageMap.end())
513 && (destImageEntry != device_data->imageMap.end())) {
514 if (srcImageEntry->second->imageType != destImageEntry->second->imageType) {
515 char const str[] = "vkCmdCopyImage called with unmatched source and dest image types.";
516 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
517 (uint64_t)cmdBuffer, 0, IMAGE_MISMATCHED_IMAGE_TYPE, "IMAGE", str);
518 }
519 // Check that format is same size or exact stencil/depth
520 if (is_depth_format(srcImageEntry->second->format)) {
521 if (srcImageEntry->second->format != destImageEntry->second->format) {
522 char const str[] = "vkCmdCopyImage called with unmatched source and dest image depth/stencil formats.";
523 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
524 (uint64_t)cmdBuffer, 0, IMAGE_MISMATCHED_IMAGE_FORMAT, "IMAGE", str);
525 }
526 } else {
527 size_t srcSize = vk_format_get_size(srcImageEntry->second->format);
528 size_t destSize = vk_format_get_size(destImageEntry->second->format);
529 if (srcSize != destSize) {
530 char const str[] = "vkCmdCopyImage called with unmatched source and dest image format sizes.";
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_FORMAT, "IMAGE", str);
533 }
534 }
535 }
536
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600537 if (VK_FALSE == skipCall) {
538 get_dispatch_table(image_device_table_map, cmdBuffer)->CmdCopyImage(cmdBuffer, srcImage,
539 srcImageLayout, destImage, destImageLayout, regionCount, pRegions);
540 }
541}
542
Courtney Goeltzenleuchter9feb0732015-10-15 16:51:05 -0600543void VKAPI vkCmdClearAttachments(
544 VkCmdBuffer cmdBuffer,
545 uint32_t attachmentCount,
546 const VkClearAttachment* pAttachments,
547 uint32_t rectCount,
548 const VkRect3D* pRects)
549{
550 VkBool32 skipCall = VK_FALSE;
551 VkImageAspectFlags aspectMask;
552
553 for (uint32_t i = 0; i < attachmentCount; i++) {
554 aspectMask = pAttachments[i].aspectMask;
555 if (aspectMask & VK_IMAGE_ASPECT_COLOR_BIT) {
556 if (aspectMask != VK_IMAGE_ASPECT_COLOR_BIT) {
557 // VK_IMAGE_ASPECT_COLOR_BIT is not the only bit set for this attachment
558 layer_data *device_data = get_my_data_ptr(get_dispatch_key(cmdBuffer), layer_data_map);
559 char const str[] = "vkCmdClearAttachments aspectMask [%d] must set only VK_IMAGE_ASPECT_COLOR_BIT of a color attachment.";
560 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
561 (uint64_t)cmdBuffer, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", str, i);
562 }
563 } else {
564 // Image aspect must be depth or stencil or both
565 if (((aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT) != VK_IMAGE_ASPECT_DEPTH_BIT) &&
566 ((aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT) != VK_IMAGE_ASPECT_STENCIL_BIT))
567 {
568 layer_data *device_data = get_my_data_ptr(get_dispatch_key(cmdBuffer), layer_data_map);
569 char const str[] = "vkCmdClearAttachments aspectMask [%d] must be set to VK_IMAGE_ASPECT_DEPTH_BIT and/or VK_IMAGE_ASPECT_STENCIL_BIT";
570 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
571 (uint64_t)cmdBuffer, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", str, i);
572 }
573 }
574 }
575
576 if (VK_FALSE == skipCall) {
577 get_dispatch_table(image_device_table_map, cmdBuffer)->CmdClearAttachments(cmdBuffer,
578 attachmentCount, pAttachments, rectCount, pRects);
579 }
580}
581
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600582VK_LAYER_EXPORT void VKAPI vkCmdCopyImageToBuffer(
583 VkCmdBuffer cmdBuffer,
584 VkImage srcImage,
585 VkImageLayout srcImageLayout,
586 VkBuffer destBuffer,
587 uint32_t regionCount,
588 const VkBufferImageCopy *pRegions)
589{
590 VkBool32 skipCall = VK_FALSE;
591
592 // Image aspect must be ONE OF color, depth, stencil
593 for (uint32_t i = 0; i < regionCount; i++) {
Courtney Goeltzenleuchterba11ebe2015-10-21 17:00:51 -0600594 VkImageAspectFlags aspect = pRegions[i].imageSubresource.aspect;
595 if ((aspect != VK_IMAGE_ASPECT_COLOR_BIT) &&
596 (aspect != VK_IMAGE_ASPECT_DEPTH_BIT) &&
597 (aspect != VK_IMAGE_ASPECT_STENCIL_BIT)) {
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600598 layer_data *device_data = get_my_data_ptr(get_dispatch_key(cmdBuffer), layer_data_map);
599 char const str[] = "vkCmdCopyImageToBuffer: aspectMasks for each region must specify only COLOR or DEPTH or STENCIL";
600 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
601 (uint64_t)cmdBuffer, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", str);
602 }
603 }
604
605 if (VK_FALSE == skipCall) {
606 get_dispatch_table(image_device_table_map, cmdBuffer)->CmdCopyImageToBuffer(cmdBuffer,
607 srcImage, srcImageLayout, destBuffer, regionCount, pRegions);
608 }
609}
610
611
612VK_LAYER_EXPORT void VKAPI vkCmdCopyBufferToImage(
613 VkCmdBuffer cmdBuffer,
614 VkBuffer srcBuffer,
615 VkImage destImage,
616 VkImageLayout destImageLayout,
617 uint32_t regionCount,
618 const VkBufferImageCopy *pRegions)
619{
620 VkBool32 skipCall = VK_FALSE;
621
622 // Image aspect must be ONE OF color, depth, stencil
623 for (uint32_t i = 0; i < regionCount; i++) {
Courtney Goeltzenleuchterba11ebe2015-10-21 17:00:51 -0600624 VkImageAspectFlags aspect = pRegions[i].imageSubresource.aspect;
625 if ((aspect != VK_IMAGE_ASPECT_COLOR_BIT) &&
626 (aspect != VK_IMAGE_ASPECT_DEPTH_BIT) &&
627 (aspect != VK_IMAGE_ASPECT_STENCIL_BIT)) {
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600628 layer_data *device_data = get_my_data_ptr(get_dispatch_key(cmdBuffer), layer_data_map);
629 char const str[] = "vkCmdCopyBufferToImage: aspectMasks for each region must specify only COLOR or DEPTH or STENCIL";
630 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
631 (uint64_t)cmdBuffer, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", str);
632 }
633 }
634
635 if (VK_FALSE == skipCall) {
636 get_dispatch_table(image_device_table_map, cmdBuffer)->CmdCopyBufferToImage(cmdBuffer,
637 srcBuffer, destImage, destImageLayout, regionCount, pRegions);
638 }
639}
640
641VK_LAYER_EXPORT void VKAPI vkCmdBlitImage(
642 VkCmdBuffer cmdBuffer,
643 VkImage srcImage,
644 VkImageLayout srcImageLayout,
645 VkImage destImage,
646 VkImageLayout destImageLayout,
647 uint32_t regionCount,
648 const VkImageBlit *pRegions,
649 VkTexFilter filter)
650{
651 // TODO: From the spec -- these validation items will require the image layer to maintain image/buffer state.
652 // If one of srcImage and destImage images has signed integer format, the other one must also have be signed integer format.
653 // If one of srcImage and destImage images has unsigned integer format, the other one must also have be an unsigned integer format.
654 // If the format of srcImage is a depth, stencil, depth stencil or integer-based format then filter must be VK_TEX_FILTER_NEAREST.
655 // 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.
656 // Additionally the allowed aspect bits in srcSubresource and destSubresource are only VK_IMAGE_ASPECT_DEPTH_BIT and
657 // VK_IMAGE_ASPECT_STENCIL_BIT and the given aspect must exist in the format of both srcImage and destImage images.
658
659 get_dispatch_table(image_device_table_map, cmdBuffer)->CmdBlitImage(cmdBuffer, srcImage,
660 srcImageLayout, destImage, destImageLayout, regionCount, pRegions, filter);
661}
662
663VK_LAYER_EXPORT void VKAPI vkCmdResolveImage(
664 VkCmdBuffer cmdBuffer,
665 VkImage srcImage,
666 VkImageLayout srcImageLayout,
667 VkImage destImage,
668 VkImageLayout destImageLayout,
669 uint32_t regionCount,
670 const VkImageResolve *pRegions)
671{
672 VkBool32 skipCall = VK_FALSE;
Mike Stroyan43909d82015-09-25 13:39:21 -0600673 layer_data *device_data = get_my_data_ptr(get_dispatch_key(cmdBuffer), layer_data_map);
674 auto srcImageEntry = device_data->imageMap.find(srcImage.handle);
675 auto destImageEntry = device_data->imageMap.find(destImage.handle);
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600676
677 // For each region, src and dest image aspect must be color only
678 for (uint32_t i = 0; i < regionCount; i++) {
Courtney Goeltzenleuchterba11ebe2015-10-21 17:00:51 -0600679 if ((pRegions[i].srcSubresource.aspect != VK_IMAGE_ASPECT_COLOR_BIT) ||
680 (pRegions[i].destSubresource.aspect != VK_IMAGE_ASPECT_COLOR_BIT)) {
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600681 char const str[] = "vkCmdResolveImage: src and dest aspectMasks for each region must specify only VK_IMAGE_ASPECT_COLOR_BIT";
682 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
683 (uint64_t)cmdBuffer, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", str);
684 }
685 }
686
Mike Stroyan43909d82015-09-25 13:39:21 -0600687 if ((srcImageEntry != device_data->imageMap.end())
688 && (destImageEntry != device_data->imageMap.end())) {
689 if (srcImageEntry->second->format != destImageEntry->second->format) {
690 char const str[] = "vkCmdResolveImage called with unmatched source and dest formats.";
691 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
692 (uint64_t)cmdBuffer, 0, IMAGE_MISMATCHED_IMAGE_FORMAT, "IMAGE", str);
693 }
694 if (srcImageEntry->second->imageType != destImageEntry->second->imageType) {
695 char const str[] = "vkCmdResolveImage called with unmatched source and dest image types.";
696 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
697 (uint64_t)cmdBuffer, 0, IMAGE_MISMATCHED_IMAGE_TYPE, "IMAGE", str);
698 }
699 if (srcImageEntry->second->samples <= 1) {
700 char const str[] = "vkCmdResolveImage called with source sample count less than 2.";
701 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
702 (uint64_t)cmdBuffer, 0, IMAGE_INVALID_RESOLVE_SAMPLES, "IMAGE", str);
703 }
704 if (destImageEntry->second->samples > 1) {
705 char const str[] = "vkCmdResolveImage called with dest sample count greater than 1.";
706 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
707 (uint64_t)cmdBuffer, 0, IMAGE_INVALID_RESOLVE_SAMPLES, "IMAGE", str);
708 }
709 }
710
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600711 if (VK_FALSE == skipCall) {
712 get_dispatch_table(image_device_table_map, cmdBuffer)->CmdResolveImage(cmdBuffer, srcImage,
713 srcImageLayout, destImage, destImageLayout, regionCount, pRegions);
714 }
715}
716
Courtney Goeltzenleuchter01d2ae12015-10-20 16:40:38 -0600717VK_LAYER_EXPORT void VKAPI vkGetImageSubresourceLayout(
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600718 VkDevice device,
719 VkImage image,
720 const VkImageSubresource *pSubresource,
721 VkSubresourceLayout *pLayout)
722{
Courtney Goeltzenleuchter01d2ae12015-10-20 16:40:38 -0600723 get_dispatch_table(image_device_table_map, device)->GetImageSubresourceLayout(device,
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600724 image, pSubresource, pLayout);
725
726 // TODO: After state tracking for images/buffers is implemented, validate that returned aspects match
727 // the created formats -- color for color formats, depth|stencil for ds formats
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600728}
729
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -0600730VK_LAYER_EXPORT PFN_vkVoidFunction VKAPI vkGetDeviceProcAddr(VkDevice device, const char* funcName)
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600731{
732 if (device == NULL) {
733 return NULL;
734 }
735
736 /* loader uses this to force layer initialization; device object is wrapped */
737 if (!strcmp(funcName, "vkGetDeviceProcAddr")) {
738 initDeviceTable(image_device_table_map, (const VkBaseLayerObject *) device);
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -0600739 return (PFN_vkVoidFunction) vkGetDeviceProcAddr;
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600740 }
741
Courtney Goeltzenleuchterbe637992015-06-25 18:01:43 -0600742 if (!strcmp(funcName, "vkCreateDevice"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -0600743 return (PFN_vkVoidFunction) vkCreateDevice;
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600744 if (!strcmp(funcName, "vkDestroyDevice"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -0600745 return (PFN_vkVoidFunction) vkDestroyDevice;
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600746 if (!strcmp(funcName, "vkCreateImage"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -0600747 return (PFN_vkVoidFunction) vkCreateImage;
Tobin Ehlis342b9bf2015-09-22 10:11:37 -0600748 if (!strcmp(funcName, "vkCreateImageView"))
749 return (PFN_vkVoidFunction) vkCreateImageView;
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600750 if (!strcmp(funcName, "vkCreateRenderPass"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -0600751 return (PFN_vkVoidFunction) vkCreateRenderPass;
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600752 if (!strcmp(funcName, "vkCmdClearColorImage"))
753 return (PFN_vkVoidFunction) vkCmdClearColorImage;
754 if (!strcmp(funcName, "vkCmdClearDepthStencilImage"))
755 return (PFN_vkVoidFunction) vkCmdClearDepthStencilImage;
Courtney Goeltzenleuchter9feb0732015-10-15 16:51:05 -0600756 if (!strcmp(funcName, "vkCmdClearAttachments"))
757 return (PFN_vkVoidFunction) vkCmdClearAttachments;
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600758 if (!strcmp(funcName, "vkCmdCopyImage"))
759 return (PFN_vkVoidFunction) vkCmdCopyImage;
760 if (!strcmp(funcName, "vkCmdCopyImageToBuffer"))
761 return (PFN_vkVoidFunction) vkCmdCopyImageToBuffer;
762 if (!strcmp(funcName, "vkCmdCopyBufferToImage"))
763 return (PFN_vkVoidFunction) vkCmdCopyBufferToImage;
764 if (!strcmp(funcName, "vkCmdBlitImage"))
765 return (PFN_vkVoidFunction) vkCmdBlitImage;
766 if (!strcmp(funcName, "vkCmdResolveImage"))
767 return (PFN_vkVoidFunction) vkCmdResolveImage;
768 if (!strcmp(funcName, "vkGetImageSubresourceLayout"))
769 return (PFN_vkVoidFunction) vkGetImageSubresourceLayout;
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600770 {
771 if (get_dispatch_table(image_device_table_map, device)->GetDeviceProcAddr == NULL)
772 return NULL;
773 return get_dispatch_table(image_device_table_map, device)->GetDeviceProcAddr(device, funcName);
774 }
775}
776
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -0600777VK_LAYER_EXPORT PFN_vkVoidFunction VKAPI vkGetInstanceProcAddr(VkInstance instance, const char* funcName)
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600778{
779 if (instance == NULL) {
780 return NULL;
781 }
782
783 /* loader uses this to force layer initialization; instance object is wrapped */
784 if (!strcmp(funcName, "vkGetInstanceProcAddr")) {
785 initInstanceTable(image_instance_table_map, (const VkBaseLayerObject *) instance);
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -0600786 return (PFN_vkVoidFunction) vkGetInstanceProcAddr;
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600787 }
788
789 if (!strcmp(funcName, "vkCreateInstance"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -0600790 return (PFN_vkVoidFunction) vkCreateInstance;
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600791 if (!strcmp(funcName, "vkDestroyInstance"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -0600792 return (PFN_vkVoidFunction) vkDestroyInstance;
Courtney Goeltzenleuchter74c4ce92015-09-14 17:22:16 -0600793 if (!strcmp(funcName, "vkEnumerateInstanceLayerProperties"))
794 return (PFN_vkVoidFunction) vkEnumerateInstanceLayerProperties;
795 if (!strcmp(funcName, "vkEnumerateInstanceExtensionProperties"))
796 return (PFN_vkVoidFunction) vkEnumerateInstanceExtensionProperties;
797 if (!strcmp(funcName, "vkEnumerateDeviceLayerProperties"))
798 return (PFN_vkVoidFunction) vkEnumerateDeviceLayerProperties;
799 if (!strcmp(funcName, "vkEnumerateDeviceExtensionProperties"))
800 return (PFN_vkVoidFunction) vkEnumerateDeviceExtensionProperties;
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600801
802 layer_data *data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -0600803 PFN_vkVoidFunction fptr = debug_report_get_instance_proc_addr(data->report_data, funcName);
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600804 if(fptr)
805 return fptr;
806
807 {
808 if (get_dispatch_table(image_instance_table_map, instance)->GetInstanceProcAddr == NULL)
809 return NULL;
810 return get_dispatch_table(image_instance_table_map, instance)->GetInstanceProcAddr(instance, funcName);
811 }
812}