blob: 52800bfa6a77a1d56b9dbad11d5af8592e0dc420 [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 Goeltzenleuchterab36aa62015-07-12 12:40:29 -0600283 VkResult result = 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);
Tobin Ehlis65380532015-09-21 15:20:28 -0600285 if(result != VK_SUCCESS) {
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600286 char const str[] = "vkCreateImage parameter, VkFormat pCreateInfo->format, cannot be validated";
Tobin Ehlis35613802015-09-22 08:40:52 -0600287 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 -0600288 }
289
290 if((properties.linearTilingFeatures) == 0 && (properties.optimalTilingFeatures == 0))
291 {
292 char const str[] = "vkCreateImage parameter, VkFormat pCreateInfo->format, contains unsupported format";
Tobin Ehlis35613802015-09-22 08:40:52 -0600293 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 -0600294 }
295 }
Tobin Ehlis35613802015-09-22 08:40:52 -0600296 if (skipCall)
297 return VK_ERROR_VALIDATION_FAILED;
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600298
299 VkResult result = get_dispatch_table(image_device_table_map, device)->CreateImage(device, pCreateInfo, pImage);
300
Tobin Ehlis65380532015-09-21 15:20:28 -0600301 if(result == VK_SUCCESS) {
Tobin Ehlis342b9bf2015-09-22 10:11:37 -0600302 device_data->imageMap[pImage->handle] = unique_ptr<IMAGE_STATE>(new IMAGE_STATE(pCreateInfo));
Tobin Ehlis65380532015-09-21 15:20:28 -0600303 }
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600304 return result;
305}
306
Tobin Ehlis65380532015-09-21 15:20:28 -0600307VK_LAYER_EXPORT void VKAPI vkDestroyImage(VkDevice device, VkImage image)
308{
309 layer_data *device_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
310 device_data->imageMap.erase(image.handle);
311 get_dispatch_table(image_device_table_map, device)->DestroyImage(device, image);
312}
313
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600314VK_LAYER_EXPORT VkResult VKAPI vkCreateRenderPass(VkDevice device, const VkRenderPassCreateInfo* pCreateInfo, VkRenderPass* pRenderPass)
315{
Tobin Ehlis35613802015-09-22 08:40:52 -0600316 VkBool32 skipCall = VK_FALSE;
Chia-I Wuc278df82015-07-07 11:50:03 +0800317 for(uint32_t i = 0; i < pCreateInfo->attachmentCount; ++i)
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600318 {
Chia-I Wuc278df82015-07-07 11:50:03 +0800319 if(pCreateInfo->pAttachments[i].format != VK_FORMAT_UNDEFINED)
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600320 {
Courtney Goeltzenleuchter07199212015-06-22 16:19:14 -0600321 layer_data *device_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600322 VkFormatProperties properties;
Courtney Goeltzenleuchterab36aa62015-07-12 12:40:29 -0600323 VkResult result = get_dispatch_table(image_instance_table_map, device_data->physicalDevice)->GetPhysicalDeviceFormatProperties(
Chia-I Wuc278df82015-07-07 11:50:03 +0800324 device_data->physicalDevice, pCreateInfo->pAttachments[i].format, &properties);
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600325 if(result != VK_SUCCESS)
326 {
327 std::stringstream ss;
Chia-I Wuc278df82015-07-07 11:50:03 +0800328 ss << "vkCreateRenderPass parameter, VkFormat in pCreateInfo->pAttachments[" << i << "], cannot be validated";
Tobin Ehlis35613802015-09-22 08:40:52 -0600329 skipCall |= log_msg(mdd(device), VK_DBG_REPORT_WARN_BIT, (VkDbgObjectType)0, 0, 0, IMAGE_FORMAT_UNSUPPORTED, "IMAGE", ss.str().c_str());
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600330 continue;
331 }
332
333 if((properties.linearTilingFeatures) == 0 && (properties.optimalTilingFeatures == 0))
334 {
335 std::stringstream ss;
Chia-I Wuc278df82015-07-07 11:50:03 +0800336 ss << "vkCreateRenderPass parameter, VkFormat in pCreateInfo->pAttachments[" << i << "], contains unsupported format";
Tobin Ehlis35613802015-09-22 08:40:52 -0600337 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 -0600338 }
339 }
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_VkImageLayout(pCreateInfo->pAttachments[i].initialLayout) ||
345 !validate_VkImageLayout(pCreateInfo->pAttachments[i].finalLayout))
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600346 {
347 std::stringstream ss;
Chia-I Wuc278df82015-07-07 11:50:03 +0800348 ss << "vkCreateRenderPass parameter, VkImageLayout in pCreateInfo->pAttachments[" << i << "], is unrecognized";
Tobin Ehlis35613802015-09-22 08:40:52 -0600349 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 -0600350 }
351 }
352
Chia-I Wuc278df82015-07-07 11:50:03 +0800353 for(uint32_t i = 0; i < pCreateInfo->attachmentCount; ++i)
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600354 {
Chia-I Wuc278df82015-07-07 11:50:03 +0800355 if(!validate_VkAttachmentLoadOp(pCreateInfo->pAttachments[i].loadOp))
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600356 {
357 std::stringstream ss;
Chia-I Wuc278df82015-07-07 11:50:03 +0800358 ss << "vkCreateRenderPass parameter, VkAttachmentLoadOp in pCreateInfo->pAttachments[" << i << "], is unrecognized";
Tobin Ehlis35613802015-09-22 08:40:52 -0600359 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 -0600360 }
361 }
362
Chia-I Wuc278df82015-07-07 11:50:03 +0800363 for(uint32_t i = 0; i < pCreateInfo->attachmentCount; ++i)
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600364 {
Chia-I Wuc278df82015-07-07 11:50:03 +0800365 if(!validate_VkAttachmentStoreOp(pCreateInfo->pAttachments[i].storeOp))
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600366 {
367 std::stringstream ss;
Chia-I Wuc278df82015-07-07 11:50:03 +0800368 ss << "vkCreateRenderPass parameter, VkAttachmentStoreOp in pCreateInfo->pAttachments[" << i << "], is unrecognized";
Tobin Ehlis35613802015-09-22 08:40:52 -0600369 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 -0600370 }
371 }
372
Mark Lobodzinski9cce7832015-07-29 09:21:22 -0600373 // Any depth buffers specified as attachments?
374 bool depthFormatPresent = VK_FALSE;
375 for (uint32_t i = 0; i < pCreateInfo->attachmentCount; ++i)
376 {
377 depthFormatPresent |= is_depth_format(pCreateInfo->pAttachments[i].format);
378 }
379
380 if (depthFormatPresent == VK_FALSE) {
381 // No depth attachment is present, validate that subpasses set depthStencilAttachment to VK_ATTACHMENT_UNUSED;
382 for (uint32_t i = 0; i < pCreateInfo->subpassCount; i++) {
383 if (pCreateInfo->pSubpasses[i].depthStencilAttachment.attachment != VK_ATTACHMENT_UNUSED) {
384 std::stringstream ss;
385 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 -0600386 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 -0600387 }
388 }
389 }
Tobin Ehlis35613802015-09-22 08:40:52 -0600390 if (skipCall)
391 return VK_ERROR_VALIDATION_FAILED;
Mark Lobodzinski9cce7832015-07-29 09:21:22 -0600392
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600393 VkResult result = get_dispatch_table(image_device_table_map, device)->CreateRenderPass(device, pCreateInfo, pRenderPass);
394
395 return result;
396}
397
Tobin Ehlis65380532015-09-21 15:20:28 -0600398VK_LAYER_EXPORT VkResult VKAPI vkCreateImageView(VkDevice device, const VkImageViewCreateInfo* pCreateInfo, VkImageView* pView)
399{
400 VkBool32 skipCall = VK_FALSE;
401 layer_data *device_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
402 auto imageEntry = device_data->imageMap.find(pCreateInfo->image.handle);
403 if (imageEntry != device_data->imageMap.end()) {
404 if (pCreateInfo->subresourceRange.baseMipLevel >= imageEntry->second->mipLevels) {
405 std::stringstream ss;
406 ss << "vkCreateImageView called with baseMipLevel " << pCreateInfo->subresourceRange.baseMipLevel << " for image " << pCreateInfo->image.handle << " that only has " << imageEntry->second->mipLevels << " mip levels.";
407 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());
408 }
409 if (pCreateInfo->subresourceRange.baseArrayLayer >= imageEntry->second->arraySize) {
410 std::stringstream ss;
411 ss << "vkCreateImageView called with baseArrayLayer " << pCreateInfo->subresourceRange.baseArrayLayer << " for image " << pCreateInfo->image.handle << " that only has " << imageEntry->second->arraySize << " mip levels.";
412 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());
413 }
414 if (!pCreateInfo->subresourceRange.mipLevels) {
415 std::stringstream ss;
416 ss << "vkCreateImageView called with 0 in pCreateInfo->subresourceRange.mipLevels.";
417 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());
418 }
419 if (!pCreateInfo->subresourceRange.arraySize) {
420 std::stringstream ss;
421 ss << "vkCreateImageView called with 0 in pCreateInfo->subresourceRange.arraySize.";
422 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());
423 }
424 }
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600425
426 // TODO: Image aspect mask must be only VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_ASPECT_DEPTH_BIT or VK_IMAGE_ASPECT_STENCIL_BIT
427 // if the format is a color, depth-only or stencil-only format respectively. If using a depth/stencil format,
428 // aspectMask must include at least one of VK_IMAGE_ASPECT_DEPTH_BIT and VK_IMAGE_ASPECT_STENCIL_BIT, and may include both.
429 // Add after image/buffer state tracking is implemented.
430
Tobin Ehlis65380532015-09-21 15:20:28 -0600431 if (skipCall)
432 return VK_ERROR_VALIDATION_FAILED;
Tobin Ehlis35613802015-09-22 08:40:52 -0600433
Tobin Ehlis65380532015-09-21 15:20:28 -0600434 VkResult result = get_dispatch_table(image_device_table_map, device)->CreateImageView(device, pCreateInfo, pView);
435 return result;
436}
437
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600438VK_LAYER_EXPORT void VKAPI vkCmdClearColorImage(
439 VkCmdBuffer cmdBuffer,
440 VkImage image,
441 VkImageLayout imageLayout,
442 const VkClearColorValue *pColor,
443 uint32_t rangeCount,
444 const VkImageSubresourceRange *pRanges)
445{
446 VkBool32 skipCall = VK_FALSE;
447
448 // For each range, image aspect must be color only
449 for (uint32_t i = 0; i < rangeCount; i++) {
450 if (pRanges[i].aspectMask != VK_IMAGE_ASPECT_COLOR_BIT) {
451 layer_data *device_data = get_my_data_ptr(get_dispatch_key(cmdBuffer), layer_data_map);
452 char const str[] = "vkCmdClearColorImage aspectMasks for all subresource ranges must be set to VK_IMAGE_ASPECT_COLOR_BIT";
453 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
454 (uint64_t)cmdBuffer, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", str);
455 }
456 }
457
458 if (VK_FALSE == skipCall) {
459 get_dispatch_table(image_device_table_map, cmdBuffer)->CmdClearColorImage(cmdBuffer, image, imageLayout,
460 pColor, rangeCount, pRanges);
461 }
462}
463
464VK_LAYER_EXPORT void VKAPI vkCmdClearDepthStencilImage(
465 VkCmdBuffer cmdBuffer,
466 VkImage image,
467 VkImageLayout imageLayout,
468 const VkClearDepthStencilValue *pDepthStencil,
469 uint32_t rangeCount,
470 const VkImageSubresourceRange *pRanges)
471{
472 VkBool32 skipCall = VK_FALSE;
473
474 // For each range, Image aspect must be depth or stencil or both
475 for (uint32_t i = 0; i < rangeCount; i++) {
476 if (((pRanges[i].aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT) != VK_IMAGE_ASPECT_DEPTH_BIT) &&
477 ((pRanges[i].aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT) != VK_IMAGE_ASPECT_STENCIL_BIT))
478 {
479 layer_data *device_data = get_my_data_ptr(get_dispatch_key(cmdBuffer), layer_data_map);
480 char const str[] = "vkCmdClearDepthStencilImage aspectMasks for all subresource ranges must be "
481 "set to VK_IMAGE_ASPECT_DEPTH_BIT and/or VK_IMAGE_ASPECT_STENCIL_BIT";
482 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
483 (uint64_t)cmdBuffer, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", str);
484 }
485 }
486
487 if (VK_FALSE == skipCall) {
488 get_dispatch_table(image_device_table_map, cmdBuffer)->CmdClearDepthStencilImage(cmdBuffer,
489 image, imageLayout, pDepthStencil, rangeCount, pRanges);
490 }
491}
492
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600493VK_LAYER_EXPORT void VKAPI vkCmdCopyImage(
494 VkCmdBuffer cmdBuffer,
495 VkImage srcImage,
496 VkImageLayout srcImageLayout,
497 VkImage destImage,
498 VkImageLayout destImageLayout,
499 uint32_t regionCount,
500 const VkImageCopy *pRegions)
501{
502 VkBool32 skipCall = VK_FALSE;
Mike Stroyan43909d82015-09-25 13:39:21 -0600503 layer_data *device_data = get_my_data_ptr(get_dispatch_key(cmdBuffer), layer_data_map);
504 auto srcImageEntry = device_data->imageMap.find(srcImage.handle);
505 auto destImageEntry = device_data->imageMap.find(destImage.handle);
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600506
507 // For each region, src aspect mask must match dest aspect mask
508 // For each region, color aspects cannot be mixed with depth/stencil aspects
509 for (uint32_t i = 0; i < regionCount; i++) {
510 if (pRegions[i].srcSubresource.aspect != pRegions[i].destSubresource.aspect) {
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600511 char const str[] = "vkCmdCopyImage: Src and dest aspectMasks for each region must match";
512 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
513 (uint64_t)cmdBuffer, 0, IMAGE_MISMATCHED_IMAGE_ASPECT, "IMAGE", str);
514 }
515 if ((pRegions[i].srcSubresource.aspect & VK_IMAGE_ASPECT_COLOR) &&
516 (pRegions[i].srcSubresource.aspect & (VK_IMAGE_ASPECT_DEPTH | VK_IMAGE_ASPECT_STENCIL))) {
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600517 char const str[] = "vkCmdCopyImage aspectMask cannot specify both COLOR and DEPTH/STENCIL aspects";
518 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
519 (uint64_t)cmdBuffer, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", str);
520 }
521 }
522
Mike Stroyan43909d82015-09-25 13:39:21 -0600523 if ((srcImageEntry != device_data->imageMap.end())
524 && (destImageEntry != device_data->imageMap.end())) {
525 if (srcImageEntry->second->imageType != destImageEntry->second->imageType) {
526 char const str[] = "vkCmdCopyImage called with unmatched source and dest image types.";
527 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
528 (uint64_t)cmdBuffer, 0, IMAGE_MISMATCHED_IMAGE_TYPE, "IMAGE", str);
529 }
530 // Check that format is same size or exact stencil/depth
531 if (is_depth_format(srcImageEntry->second->format)) {
532 if (srcImageEntry->second->format != destImageEntry->second->format) {
533 char const str[] = "vkCmdCopyImage called with unmatched source and dest image depth/stencil formats.";
534 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
535 (uint64_t)cmdBuffer, 0, IMAGE_MISMATCHED_IMAGE_FORMAT, "IMAGE", str);
536 }
537 } else {
538 size_t srcSize = vk_format_get_size(srcImageEntry->second->format);
539 size_t destSize = vk_format_get_size(destImageEntry->second->format);
540 if (srcSize != destSize) {
541 char const str[] = "vkCmdCopyImage called with unmatched source and dest image format sizes.";
542 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
543 (uint64_t)cmdBuffer, 0, IMAGE_MISMATCHED_IMAGE_FORMAT, "IMAGE", str);
544 }
545 }
546 }
547
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600548 if (VK_FALSE == skipCall) {
549 get_dispatch_table(image_device_table_map, cmdBuffer)->CmdCopyImage(cmdBuffer, srcImage,
550 srcImageLayout, destImage, destImageLayout, regionCount, pRegions);
551 }
552}
553
Courtney Goeltzenleuchter9feb0732015-10-15 16:51:05 -0600554void VKAPI vkCmdClearAttachments(
555 VkCmdBuffer cmdBuffer,
556 uint32_t attachmentCount,
557 const VkClearAttachment* pAttachments,
558 uint32_t rectCount,
559 const VkRect3D* pRects)
560{
561 VkBool32 skipCall = VK_FALSE;
562 VkImageAspectFlags aspectMask;
563
564 for (uint32_t i = 0; i < attachmentCount; i++) {
565 aspectMask = pAttachments[i].aspectMask;
566 if (aspectMask & VK_IMAGE_ASPECT_COLOR_BIT) {
567 if (aspectMask != VK_IMAGE_ASPECT_COLOR_BIT) {
568 // VK_IMAGE_ASPECT_COLOR_BIT is not the only bit set for this attachment
569 layer_data *device_data = get_my_data_ptr(get_dispatch_key(cmdBuffer), layer_data_map);
570 char const str[] = "vkCmdClearAttachments aspectMask [%d] must set only VK_IMAGE_ASPECT_COLOR_BIT of a color attachment.";
571 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
572 (uint64_t)cmdBuffer, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", str, i);
573 }
574 } else {
575 // Image aspect must be depth or stencil or both
576 if (((aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT) != VK_IMAGE_ASPECT_DEPTH_BIT) &&
577 ((aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT) != VK_IMAGE_ASPECT_STENCIL_BIT))
578 {
579 layer_data *device_data = get_my_data_ptr(get_dispatch_key(cmdBuffer), layer_data_map);
580 char const str[] = "vkCmdClearAttachments aspectMask [%d] must be set to VK_IMAGE_ASPECT_DEPTH_BIT and/or VK_IMAGE_ASPECT_STENCIL_BIT";
581 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
582 (uint64_t)cmdBuffer, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", str, i);
583 }
584 }
585 }
586
587 if (VK_FALSE == skipCall) {
588 get_dispatch_table(image_device_table_map, cmdBuffer)->CmdClearAttachments(cmdBuffer,
589 attachmentCount, pAttachments, rectCount, pRects);
590 }
591}
592
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600593VK_LAYER_EXPORT void VKAPI vkCmdCopyImageToBuffer(
594 VkCmdBuffer cmdBuffer,
595 VkImage srcImage,
596 VkImageLayout srcImageLayout,
597 VkBuffer destBuffer,
598 uint32_t regionCount,
599 const VkBufferImageCopy *pRegions)
600{
601 VkBool32 skipCall = VK_FALSE;
602
603 // Image aspect must be ONE OF color, depth, stencil
604 for (uint32_t i = 0; i < regionCount; i++) {
605 VkImageAspect aspect = pRegions[i].imageSubresource.aspect;
606 if ((aspect != VK_IMAGE_ASPECT_COLOR) &&
607 (aspect != VK_IMAGE_ASPECT_DEPTH) &&
608 (aspect != VK_IMAGE_ASPECT_STENCIL)) {
609 layer_data *device_data = get_my_data_ptr(get_dispatch_key(cmdBuffer), layer_data_map);
610 char const str[] = "vkCmdCopyImageToBuffer: aspectMasks for each region must specify only COLOR or DEPTH or STENCIL";
611 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
612 (uint64_t)cmdBuffer, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", str);
613 }
614 }
615
616 if (VK_FALSE == skipCall) {
617 get_dispatch_table(image_device_table_map, cmdBuffer)->CmdCopyImageToBuffer(cmdBuffer,
618 srcImage, srcImageLayout, destBuffer, regionCount, pRegions);
619 }
620}
621
622
623VK_LAYER_EXPORT void VKAPI vkCmdCopyBufferToImage(
624 VkCmdBuffer cmdBuffer,
625 VkBuffer srcBuffer,
626 VkImage destImage,
627 VkImageLayout destImageLayout,
628 uint32_t regionCount,
629 const VkBufferImageCopy *pRegions)
630{
631 VkBool32 skipCall = VK_FALSE;
632
633 // Image aspect must be ONE OF color, depth, stencil
634 for (uint32_t i = 0; i < regionCount; i++) {
635 VkImageAspect aspect = pRegions[i].imageSubresource.aspect;
636 if ((aspect != VK_IMAGE_ASPECT_COLOR) &&
637 (aspect != VK_IMAGE_ASPECT_DEPTH) &&
638 (aspect != VK_IMAGE_ASPECT_STENCIL)) {
639 layer_data *device_data = get_my_data_ptr(get_dispatch_key(cmdBuffer), layer_data_map);
640 char const str[] = "vkCmdCopyBufferToImage: aspectMasks for each region must specify only COLOR or DEPTH or STENCIL";
641 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
642 (uint64_t)cmdBuffer, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", str);
643 }
644 }
645
646 if (VK_FALSE == skipCall) {
647 get_dispatch_table(image_device_table_map, cmdBuffer)->CmdCopyBufferToImage(cmdBuffer,
648 srcBuffer, destImage, destImageLayout, regionCount, pRegions);
649 }
650}
651
652VK_LAYER_EXPORT void VKAPI vkCmdBlitImage(
653 VkCmdBuffer cmdBuffer,
654 VkImage srcImage,
655 VkImageLayout srcImageLayout,
656 VkImage destImage,
657 VkImageLayout destImageLayout,
658 uint32_t regionCount,
659 const VkImageBlit *pRegions,
660 VkTexFilter filter)
661{
662 // TODO: From the spec -- these validation items will require the image layer to maintain image/buffer state.
663 // If one of srcImage and destImage images has signed integer format, the other one must also have be signed integer format.
664 // If one of srcImage and destImage images has unsigned integer format, the other one must also have be an unsigned integer format.
665 // If the format of srcImage is a depth, stencil, depth stencil or integer-based format then filter must be VK_TEX_FILTER_NEAREST.
666 // 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.
667 // Additionally the allowed aspect bits in srcSubresource and destSubresource are only VK_IMAGE_ASPECT_DEPTH_BIT and
668 // VK_IMAGE_ASPECT_STENCIL_BIT and the given aspect must exist in the format of both srcImage and destImage images.
669
670 get_dispatch_table(image_device_table_map, cmdBuffer)->CmdBlitImage(cmdBuffer, srcImage,
671 srcImageLayout, destImage, destImageLayout, regionCount, pRegions, filter);
672}
673
674VK_LAYER_EXPORT void VKAPI vkCmdResolveImage(
675 VkCmdBuffer cmdBuffer,
676 VkImage srcImage,
677 VkImageLayout srcImageLayout,
678 VkImage destImage,
679 VkImageLayout destImageLayout,
680 uint32_t regionCount,
681 const VkImageResolve *pRegions)
682{
683 VkBool32 skipCall = VK_FALSE;
Mike Stroyan43909d82015-09-25 13:39:21 -0600684 layer_data *device_data = get_my_data_ptr(get_dispatch_key(cmdBuffer), layer_data_map);
685 auto srcImageEntry = device_data->imageMap.find(srcImage.handle);
686 auto destImageEntry = device_data->imageMap.find(destImage.handle);
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600687
688 // For each region, src and dest image aspect must be color only
689 for (uint32_t i = 0; i < regionCount; i++) {
690 if ((pRegions[i].srcSubresource.aspect != VK_IMAGE_ASPECT_COLOR) ||
691 (pRegions[i].destSubresource.aspect != VK_IMAGE_ASPECT_COLOR)) {
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600692 char const str[] = "vkCmdResolveImage: src and dest aspectMasks for each region must specify only VK_IMAGE_ASPECT_COLOR_BIT";
693 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
694 (uint64_t)cmdBuffer, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", str);
695 }
696 }
697
Mike Stroyan43909d82015-09-25 13:39:21 -0600698 if ((srcImageEntry != device_data->imageMap.end())
699 && (destImageEntry != device_data->imageMap.end())) {
700 if (srcImageEntry->second->format != destImageEntry->second->format) {
701 char const str[] = "vkCmdResolveImage called with unmatched source and dest formats.";
702 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
703 (uint64_t)cmdBuffer, 0, IMAGE_MISMATCHED_IMAGE_FORMAT, "IMAGE", str);
704 }
705 if (srcImageEntry->second->imageType != destImageEntry->second->imageType) {
706 char const str[] = "vkCmdResolveImage called with unmatched source and dest image types.";
707 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
708 (uint64_t)cmdBuffer, 0, IMAGE_MISMATCHED_IMAGE_TYPE, "IMAGE", str);
709 }
710 if (srcImageEntry->second->samples <= 1) {
711 char const str[] = "vkCmdResolveImage called with source sample count less than 2.";
712 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
713 (uint64_t)cmdBuffer, 0, IMAGE_INVALID_RESOLVE_SAMPLES, "IMAGE", str);
714 }
715 if (destImageEntry->second->samples > 1) {
716 char const str[] = "vkCmdResolveImage called with dest sample count greater than 1.";
717 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
718 (uint64_t)cmdBuffer, 0, IMAGE_INVALID_RESOLVE_SAMPLES, "IMAGE", str);
719 }
720 }
721
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600722 if (VK_FALSE == skipCall) {
723 get_dispatch_table(image_device_table_map, cmdBuffer)->CmdResolveImage(cmdBuffer, srcImage,
724 srcImageLayout, destImage, destImageLayout, regionCount, pRegions);
725 }
726}
727
728VK_LAYER_EXPORT VkResult VKAPI vkGetImageSubresourceLayout(
729 VkDevice device,
730 VkImage image,
731 const VkImageSubresource *pSubresource,
732 VkSubresourceLayout *pLayout)
733{
734 VkResult result = get_dispatch_table(image_device_table_map, device)->GetImageSubresourceLayout(device,
735 image, pSubresource, pLayout);
736
737 // TODO: After state tracking for images/buffers is implemented, validate that returned aspects match
738 // the created formats -- color for color formats, depth|stencil for ds formats
739
740 return result;
741}
742
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -0600743VK_LAYER_EXPORT PFN_vkVoidFunction VKAPI vkGetDeviceProcAddr(VkDevice device, const char* funcName)
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600744{
745 if (device == NULL) {
746 return NULL;
747 }
748
749 /* loader uses this to force layer initialization; device object is wrapped */
750 if (!strcmp(funcName, "vkGetDeviceProcAddr")) {
751 initDeviceTable(image_device_table_map, (const VkBaseLayerObject *) device);
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -0600752 return (PFN_vkVoidFunction) vkGetDeviceProcAddr;
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600753 }
754
Courtney Goeltzenleuchterbe637992015-06-25 18:01:43 -0600755 if (!strcmp(funcName, "vkCreateDevice"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -0600756 return (PFN_vkVoidFunction) vkCreateDevice;
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600757 if (!strcmp(funcName, "vkDestroyDevice"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -0600758 return (PFN_vkVoidFunction) vkDestroyDevice;
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600759 if (!strcmp(funcName, "vkCreateImage"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -0600760 return (PFN_vkVoidFunction) vkCreateImage;
Tobin Ehlis342b9bf2015-09-22 10:11:37 -0600761 if (!strcmp(funcName, "vkCreateImageView"))
762 return (PFN_vkVoidFunction) vkCreateImageView;
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600763 if (!strcmp(funcName, "vkCreateRenderPass"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -0600764 return (PFN_vkVoidFunction) vkCreateRenderPass;
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600765 if (!strcmp(funcName, "vkCmdClearColorImage"))
766 return (PFN_vkVoidFunction) vkCmdClearColorImage;
767 if (!strcmp(funcName, "vkCmdClearDepthStencilImage"))
768 return (PFN_vkVoidFunction) vkCmdClearDepthStencilImage;
Courtney Goeltzenleuchter9feb0732015-10-15 16:51:05 -0600769 if (!strcmp(funcName, "vkCmdClearAttachments"))
770 return (PFN_vkVoidFunction) vkCmdClearAttachments;
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600771 if (!strcmp(funcName, "vkCmdCopyImage"))
772 return (PFN_vkVoidFunction) vkCmdCopyImage;
773 if (!strcmp(funcName, "vkCmdCopyImageToBuffer"))
774 return (PFN_vkVoidFunction) vkCmdCopyImageToBuffer;
775 if (!strcmp(funcName, "vkCmdCopyBufferToImage"))
776 return (PFN_vkVoidFunction) vkCmdCopyBufferToImage;
777 if (!strcmp(funcName, "vkCmdBlitImage"))
778 return (PFN_vkVoidFunction) vkCmdBlitImage;
779 if (!strcmp(funcName, "vkCmdResolveImage"))
780 return (PFN_vkVoidFunction) vkCmdResolveImage;
781 if (!strcmp(funcName, "vkGetImageSubresourceLayout"))
782 return (PFN_vkVoidFunction) vkGetImageSubresourceLayout;
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600783 {
784 if (get_dispatch_table(image_device_table_map, device)->GetDeviceProcAddr == NULL)
785 return NULL;
786 return get_dispatch_table(image_device_table_map, device)->GetDeviceProcAddr(device, funcName);
787 }
788}
789
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -0600790VK_LAYER_EXPORT PFN_vkVoidFunction VKAPI vkGetInstanceProcAddr(VkInstance instance, const char* funcName)
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600791{
792 if (instance == NULL) {
793 return NULL;
794 }
795
796 /* loader uses this to force layer initialization; instance object is wrapped */
797 if (!strcmp(funcName, "vkGetInstanceProcAddr")) {
798 initInstanceTable(image_instance_table_map, (const VkBaseLayerObject *) instance);
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -0600799 return (PFN_vkVoidFunction) vkGetInstanceProcAddr;
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600800 }
801
802 if (!strcmp(funcName, "vkCreateInstance"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -0600803 return (PFN_vkVoidFunction) vkCreateInstance;
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600804 if (!strcmp(funcName, "vkDestroyInstance"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -0600805 return (PFN_vkVoidFunction) vkDestroyInstance;
Courtney Goeltzenleuchter74c4ce92015-09-14 17:22:16 -0600806 if (!strcmp(funcName, "vkEnumerateInstanceLayerProperties"))
807 return (PFN_vkVoidFunction) vkEnumerateInstanceLayerProperties;
808 if (!strcmp(funcName, "vkEnumerateInstanceExtensionProperties"))
809 return (PFN_vkVoidFunction) vkEnumerateInstanceExtensionProperties;
810 if (!strcmp(funcName, "vkEnumerateDeviceLayerProperties"))
811 return (PFN_vkVoidFunction) vkEnumerateDeviceLayerProperties;
812 if (!strcmp(funcName, "vkEnumerateDeviceExtensionProperties"))
813 return (PFN_vkVoidFunction) vkEnumerateDeviceExtensionProperties;
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600814
815 layer_data *data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -0600816 PFN_vkVoidFunction fptr = debug_report_get_instance_proc_addr(data->report_data, funcName);
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600817 if(fptr)
818 return fptr;
819
820 {
821 if (get_dispatch_table(image_instance_table_map, instance)->GetInstanceProcAddr == NULL)
822 return NULL;
823 return get_dispatch_table(image_instance_table_map, instance)->GetInstanceProcAddr(instance, funcName);
824 }
825}