blob: 426fcb9b17f9f3f58ad672500087f518af1e7fbd [file] [log] [blame]
Jeremy Hayesb707aa52015-06-18 10:12:39 -06001/*
Jeremy Hayesb707aa52015-06-18 10:12:39 -06002 *
3 * Copyright (C) 2014 LunarG, Inc.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be included
13 * in all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 * DEALINGS IN THE SOFTWARE.
22 */
23
Courtney Goeltzenleuchter6ff93732015-10-07 08:38:30 -060024#include <inttypes.h>
Jeremy Hayesb707aa52015-06-18 10:12:39 -060025#include <stdio.h>
26#include <stdlib.h>
27#include <string.h>
Courtney Goeltzenleuchter6ff93732015-10-07 08:38:30 -060028#include <assert.h>
29#include <vector>
Jeremy Hayesb707aa52015-06-18 10:12:39 -060030#include <unordered_map>
Tobin Ehlis65380532015-09-21 15:20:28 -060031#include <memory>
Courtney Goeltzenleuchter6ff93732015-10-07 08:38:30 -060032using namespace std;
Jeremy Hayesb707aa52015-06-18 10:12:39 -060033
Tobin Ehlis7a51d902015-07-03 10:34:49 -060034#include "vk_loader_platform.h"
Courtney Goeltzenleuchter6ff93732015-10-07 08:38:30 -060035#include "vk_dispatch_table_helper.h"
36#include "vk_struct_string_helper_cpp.h"
Jeremy Hayesb707aa52015-06-18 10:12:39 -060037#include "vk_enum_validate_helper.h"
Courtney Goeltzenleuchter6ff93732015-10-07 08:38:30 -060038#include "image.h"
39#include "vk_layer_config.h"
40#include "vk_layer_extension_utils.h"
Tobin Ehlis56d204a2015-07-03 10:15:26 -060041#include "vk_layer_table.h"
42#include "vk_layer_data.h"
Courtney Goeltzenleuchtereb1ddb02015-07-07 11:18:30 -060043#include "vk_layer_extension_utils.h"
Mike Stroyan43909d82015-09-25 13:39:21 -060044#include "vk_layer_utils.h"
Courtney Goeltzenleuchter6ff93732015-10-07 08:38:30 -060045#include "vk_layer_logging.h"
Jeremy Hayesb707aa52015-06-18 10:12:39 -060046
Tobin Ehlis65380532015-09-21 15:20:28 -060047using namespace std;
48
Cody Northrop73bb6572015-09-28 15:09:32 -060049struct layer_data {
Jeremy Hayesb707aa52015-06-18 10:12:39 -060050 debug_report_data *report_data;
Courtney Goeltzenleuchter9fac1572015-10-05 15:59:11 -060051 std::vector<VkDbgMsgCallback> logging_callback;
Tobin Ehlis049f1782015-10-29 14:19:18 -060052 VkLayerDispatchTable* device_dispatch_table;
53 VkLayerInstanceDispatchTable* instance_dispatch_table;
Chris Forbesd7576302015-06-21 22:55:02 +120054 VkPhysicalDevice physicalDevice;
Chia-I Wue420a332015-10-26 20:04:44 +080055 unordered_map<VkImage, IMAGE_STATE> imageMap;
Cody Northrop73bb6572015-09-28 15:09:32 -060056
57 layer_data() :
58 report_data(nullptr),
Tobin Ehlis049f1782015-10-29 14:19:18 -060059 device_dispatch_table(nullptr),
60 instance_dispatch_table(nullptr),
Cody Northrop73bb6572015-09-28 15:09:32 -060061 physicalDevice(0)
62 {};
63};
Jeremy Hayesb707aa52015-06-18 10:12:39 -060064
Tobin Ehlis65380532015-09-21 15:20:28 -060065static unordered_map<void*, layer_data*> layer_data_map;
Jeremy Hayesb707aa52015-06-18 10:12:39 -060066
67static void InitImage(layer_data *data)
68{
Courtney Goeltzenleuchter9fac1572015-10-05 15:59:11 -060069 VkDbgMsgCallback callback;
Jeremy Hayesb707aa52015-06-18 10:12:39 -060070 uint32_t report_flags = getLayerOptionFlags("ImageReportFlags", 0);
71
72 uint32_t debug_action = 0;
73 getLayerOptionEnum("ImageDebugAction", (uint32_t *) &debug_action);
74 if(debug_action & VK_DBG_LAYER_ACTION_LOG_MSG)
75 {
76 FILE *log_output = NULL;
77 const char* option_str = getLayerOption("ImageLogFilename");
Tobin Ehlisb4b6e7c2015-09-15 09:55:54 -060078 log_output = getLayerLogOutput(option_str, "Image");
Courtney Goeltzenleuchter9fac1572015-10-05 15:59:11 -060079 layer_create_msg_callback(data->report_data, report_flags, log_callback, (void *) log_output, &callback);
80 data->logging_callback.push_back(callback);
81 }
82
83 if (debug_action & VK_DBG_LAYER_ACTION_DEBUG_OUTPUT) {
84 layer_create_msg_callback(data->report_data, report_flags, win32_debug_output_msg, NULL, &callback);
85 data->logging_callback.push_back(callback);
Jeremy Hayesb707aa52015-06-18 10:12:39 -060086 }
87}
88
89VK_LAYER_EXPORT VkResult VKAPI vkDbgCreateMsgCallback(
90 VkInstance instance,
91 VkFlags msgFlags,
92 const PFN_vkDbgMsgCallback pfnMsgCallback,
93 void* pUserData,
94 VkDbgMsgCallback* pMsgCallback)
95{
Tobin Ehlis049f1782015-10-29 14:19:18 -060096 layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
97 VkResult res = my_data->instance_dispatch_table->DbgCreateMsgCallback(instance, msgFlags, pfnMsgCallback, pUserData, pMsgCallback);
Jeremy Hayesb707aa52015-06-18 10:12:39 -060098 if (res == VK_SUCCESS) {
Tobin Ehlis049f1782015-10-29 14:19:18 -060099 res = layer_create_msg_callback(my_data->report_data, msgFlags, pfnMsgCallback, pUserData, pMsgCallback);
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600100 }
101 return res;
102}
103
104VK_LAYER_EXPORT VkResult VKAPI vkDbgDestroyMsgCallback(
105 VkInstance instance,
106 VkDbgMsgCallback msgCallback)
107{
Tobin Ehlis049f1782015-10-29 14:19:18 -0600108 layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
109 VkResult res = my_data->instance_dispatch_table->DbgDestroyMsgCallback(instance, msgCallback);
110 layer_destroy_msg_callback(my_data->report_data, msgCallback);
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600111 return res;
112}
113
Chia-I Wu1f851912015-10-27 18:04:07 +0800114VK_LAYER_EXPORT VkResult VKAPI vkCreateInstance(const VkInstanceCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkInstance* pInstance)
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600115{
Tobin Ehlis049f1782015-10-29 14:19:18 -0600116 layer_data *my_data = get_my_data_ptr(get_dispatch_key(*pInstance), layer_data_map);
117 VkLayerInstanceDispatchTable *pTable = my_data->instance_dispatch_table;
Chia-I Wu69f40122015-10-26 21:10:41 +0800118 VkResult result = pTable->CreateInstance(pCreateInfo, pAllocator, pInstance);
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600119
120 if (result == VK_SUCCESS) {
Chia-I Wu763a7492015-10-26 20:48:51 +0800121 my_data->report_data = debug_report_create_instance(pTable, *pInstance, pCreateInfo->enabledExtensionNameCount,
Courtney Goeltzenleuchtereb1ddb02015-07-07 11:18:30 -0600122 pCreateInfo->ppEnabledExtensionNames);
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600123
Tobin Ehlis049f1782015-10-29 14:19:18 -0600124 InitImage(my_data);
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600125 }
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600126 return result;
127}
128
Chia-I Wu1f851912015-10-27 18:04:07 +0800129VK_LAYER_EXPORT void VKAPI vkDestroyInstance(VkInstance instance, const VkAllocationCallbacks* pAllocator)
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600130{
131 // Grab the key before the instance is destroyed.
132 dispatch_key key = get_dispatch_key(instance);
Tobin Ehlis049f1782015-10-29 14:19:18 -0600133 layer_data *my_data = get_my_data_ptr(key, layer_data_map);
134 VkLayerInstanceDispatchTable *pTable = my_data->instance_dispatch_table;
Chia-I Wu69f40122015-10-26 21:10:41 +0800135 pTable->DestroyInstance(instance, pAllocator);
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600136
137 // Clean up logging callback, if any
Courtney Goeltzenleuchter9fac1572015-10-05 15:59:11 -0600138 while (my_data->logging_callback.size() > 0) {
139 VkDbgMsgCallback callback = my_data->logging_callback.back();
140 layer_destroy_msg_callback(my_data->report_data, callback);
141 my_data->logging_callback.pop_back();
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600142 }
143
Tobin Ehlis049f1782015-10-29 14:19:18 -0600144 layer_debug_report_destroy_instance(my_data->report_data);
145 delete my_data->instance_dispatch_table;
146 layer_data_map.erase(key);
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600147
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600148}
149
Chia-I Wu1f851912015-10-27 18:04:07 +0800150VK_LAYER_EXPORT VkResult VKAPI vkCreateDevice(VkPhysicalDevice physicalDevice, const VkDeviceCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDevice* pDevice)
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600151{
Tobin Ehlis049f1782015-10-29 14:19:18 -0600152 layer_data *instance_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);
153 layer_data *device_data = get_my_data_ptr(get_dispatch_key(*pDevice), layer_data_map);
Chia-I Wu69f40122015-10-26 21:10:41 +0800154 VkResult result = device_data->device_dispatch_table->CreateDevice(physicalDevice, pCreateInfo, pAllocator, pDevice);
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600155 if(result == VK_SUCCESS)
156 {
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600157 device_data->report_data = layer_debug_report_create_device(instance_data->report_data, *pDevice);
Chris Forbesd7576302015-06-21 22:55:02 +1200158 device_data->physicalDevice = physicalDevice;
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600159 }
160
161 return result;
162}
163
Chia-I Wu1f851912015-10-27 18:04:07 +0800164VK_LAYER_EXPORT void VKAPI vkDestroyDevice(VkDevice device, const VkAllocationCallbacks* pAllocator)
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600165{
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600166 dispatch_key key = get_dispatch_key(device);
Tobin Ehlis049f1782015-10-29 14:19:18 -0600167 layer_data *my_data = get_my_data_ptr(key, layer_data_map);
Chia-I Wu69f40122015-10-26 21:10:41 +0800168 my_data->device_dispatch_table->DestroyDevice(device, pAllocator);
Tobin Ehlis049f1782015-10-29 14:19:18 -0600169 delete my_data->device_dispatch_table;
170 layer_data_map.erase(key);
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600171}
172
Courtney Goeltzenleuchtereb1ddb02015-07-07 11:18:30 -0600173static const VkLayerProperties pc_global_layers[] = {
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600174 {
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600175 "Image",
Courtney Goeltzenleuchtereb1ddb02015-07-07 11:18:30 -0600176 VK_API_VERSION,
177 VK_MAKE_VERSION(0, 1, 0),
178 "Validation layer: Image ParamChecker",
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600179 }
180};
181
Courtney Goeltzenleuchter74c4ce92015-09-14 17:22:16 -0600182VK_LAYER_EXPORT VkResult VKAPI vkEnumerateInstanceExtensionProperties(
Courtney Goeltzenleuchtereb1ddb02015-07-07 11:18:30 -0600183 const char *pLayerName,
184 uint32_t *pCount,
185 VkExtensionProperties* pProperties)
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600186{
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600187 // ParamChecker does not have any global extensions
Courtney Goeltzenleuchtereb1ddb02015-07-07 11:18:30 -0600188 return util_GetExtensionProperties(0, NULL, pCount, pProperties);
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600189}
190
Courtney Goeltzenleuchter74c4ce92015-09-14 17:22:16 -0600191VK_LAYER_EXPORT VkResult VKAPI vkEnumerateInstanceLayerProperties(
Courtney Goeltzenleuchtereb1ddb02015-07-07 11:18:30 -0600192 uint32_t *pCount,
193 VkLayerProperties* pProperties)
Tony Barbour426b9052015-06-24 16:06:58 -0600194{
Courtney Goeltzenleuchtereb1ddb02015-07-07 11:18:30 -0600195 return util_GetLayerProperties(ARRAY_SIZE(pc_global_layers),
196 pc_global_layers,
197 pCount, pProperties);
Tony Barbour426b9052015-06-24 16:06:58 -0600198}
199
Courtney Goeltzenleuchter74c4ce92015-09-14 17:22:16 -0600200VK_LAYER_EXPORT VkResult VKAPI vkEnumerateDeviceExtensionProperties(
Courtney Goeltzenleuchtereb1ddb02015-07-07 11:18:30 -0600201 VkPhysicalDevice physicalDevice,
202 const char* pLayerName,
203 uint32_t* pCount,
204 VkExtensionProperties* pProperties)
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600205{
Jon Ashburnaff81ff2015-11-02 17:37:20 -0700206 // Image does not have any physical device extensions
207 if (pLayerName == NULL) {
208 dispatch_key key = get_dispatch_key(physicalDevice);
209 layer_data *my_data = get_my_data_ptr(key, layer_data_map);
210 VkLayerInstanceDispatchTable *pTable = my_data->instance_dispatch_table;
211 return pTable->EnumerateDeviceExtensionProperties(
212 physicalDevice,
213 NULL,
214 pCount,
215 pProperties);
216 } else {
217 return util_GetExtensionProperties(0, NULL, pCount, pProperties);
218 }
Courtney Goeltzenleuchtereb1ddb02015-07-07 11:18:30 -0600219}
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600220
Courtney Goeltzenleuchter74c4ce92015-09-14 17:22:16 -0600221VK_LAYER_EXPORT VkResult VKAPI vkEnumerateDeviceLayerProperties(
Courtney Goeltzenleuchtereb1ddb02015-07-07 11:18:30 -0600222 VkPhysicalDevice physicalDevice,
223 uint32_t* pCount,
224 VkLayerProperties* pProperties)
225{
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600226 // ParamChecker's physical device layers are the same as global
Courtney Goeltzenleuchtereb1ddb02015-07-07 11:18:30 -0600227 return util_GetLayerProperties(ARRAY_SIZE(pc_global_layers), pc_global_layers,
228 pCount, pProperties);
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600229}
230
Mark Lobodzinski9cce7832015-07-29 09:21:22 -0600231// Start of the Image layer proper
232
233// Returns TRUE if a format is a depth-compatible format
234bool is_depth_format(VkFormat format)
235{
236 bool result = VK_FALSE;
237 switch (format) {
238 case VK_FORMAT_D16_UNORM:
Courtney Goeltzenleuchter7ed10592015-09-10 17:17:43 -0600239 case VK_FORMAT_D24_UNORM_X8:
Mark Lobodzinski9cce7832015-07-29 09:21:22 -0600240 case VK_FORMAT_D32_SFLOAT:
241 case VK_FORMAT_S8_UINT:
242 case VK_FORMAT_D16_UNORM_S8_UINT:
243 case VK_FORMAT_D24_UNORM_S8_UINT:
244 case VK_FORMAT_D32_SFLOAT_S8_UINT:
245 result = VK_TRUE;
246 break;
247 default:
248 break;
249 }
250 return result;
251}
252
Chia-I Wu1f851912015-10-27 18:04:07 +0800253VK_LAYER_EXPORT VkResult VKAPI vkCreateImage(VkDevice device, const VkImageCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkImage* pImage)
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600254{
Tobin Ehlis35613802015-09-22 08:40:52 -0600255 VkBool32 skipCall = VK_FALSE;
Tobin Ehlis65380532015-09-21 15:20:28 -0600256 layer_data *device_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600257 if(pCreateInfo->format != VK_FORMAT_UNDEFINED)
258 {
259 VkFormatProperties properties;
Tobin Ehlis049f1782015-10-29 14:19:18 -0600260 get_my_data_ptr(get_dispatch_key(device_data->physicalDevice), layer_data_map)->instance_dispatch_table->GetPhysicalDeviceFormatProperties(
Chris Forbesd7576302015-06-21 22:55:02 +1200261 device_data->physicalDevice, pCreateInfo->format, &properties);
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600262
263 if((properties.linearTilingFeatures) == 0 && (properties.optimalTilingFeatures == 0))
264 {
265 char const str[] = "vkCreateImage parameter, VkFormat pCreateInfo->format, contains unsupported format";
Tobin Ehlis35613802015-09-22 08:40:52 -0600266 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 -0600267 }
268 }
Tobin Ehlis35613802015-09-22 08:40:52 -0600269 if (skipCall)
270 return VK_ERROR_VALIDATION_FAILED;
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600271
Chia-I Wu69f40122015-10-26 21:10:41 +0800272 VkResult result = device_data->device_dispatch_table->CreateImage(device, pCreateInfo, pAllocator, pImage);
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600273
Tobin Ehlis65380532015-09-21 15:20:28 -0600274 if(result == VK_SUCCESS) {
Chia-I Wue420a332015-10-26 20:04:44 +0800275 device_data->imageMap[*pImage] = IMAGE_STATE(pCreateInfo);
Tobin Ehlis65380532015-09-21 15:20:28 -0600276 }
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600277 return result;
278}
279
Chia-I Wu1f851912015-10-27 18:04:07 +0800280VK_LAYER_EXPORT void VKAPI vkDestroyImage(VkDevice device, VkImage image, const VkAllocationCallbacks* pAllocator)
Tobin Ehlis65380532015-09-21 15:20:28 -0600281{
282 layer_data *device_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
Chia-I Wue420a332015-10-26 20:04:44 +0800283 device_data->imageMap.erase(image);
Chia-I Wu69f40122015-10-26 21:10:41 +0800284 device_data->device_dispatch_table->DestroyImage(device, image, pAllocator);
Tobin Ehlis65380532015-09-21 15:20:28 -0600285}
286
Chia-I Wu1f851912015-10-27 18:04:07 +0800287VK_LAYER_EXPORT VkResult VKAPI vkCreateRenderPass(VkDevice device, const VkRenderPassCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkRenderPass* pRenderPass)
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600288{
Tobin Ehlis049f1782015-10-29 14:19:18 -0600289 layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
Tobin Ehlis35613802015-09-22 08:40:52 -0600290 VkBool32 skipCall = VK_FALSE;
Chia-I Wuc278df82015-07-07 11:50:03 +0800291 for(uint32_t i = 0; i < pCreateInfo->attachmentCount; ++i)
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600292 {
Chia-I Wuc278df82015-07-07 11:50:03 +0800293 if(pCreateInfo->pAttachments[i].format != VK_FORMAT_UNDEFINED)
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600294 {
295 VkFormatProperties properties;
Tobin Ehlis049f1782015-10-29 14:19:18 -0600296 get_my_data_ptr(get_dispatch_key(my_data->physicalDevice), layer_data_map)->instance_dispatch_table->GetPhysicalDeviceFormatProperties(
297 my_data->physicalDevice, pCreateInfo->pAttachments[i].format, &properties);
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600298
299 if((properties.linearTilingFeatures) == 0 && (properties.optimalTilingFeatures == 0))
300 {
301 std::stringstream ss;
Chia-I Wuc278df82015-07-07 11:50:03 +0800302 ss << "vkCreateRenderPass parameter, VkFormat in pCreateInfo->pAttachments[" << i << "], contains unsupported format";
Tobin Ehlis049f1782015-10-29 14:19:18 -0600303 skipCall |= log_msg(my_data->report_data, VK_DBG_REPORT_WARN_BIT, (VkDbgObjectType)0, 0, 0, IMAGE_FORMAT_UNSUPPORTED, "IMAGE", ss.str().c_str());
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600304 }
305 }
306 }
307
Chia-I Wuc278df82015-07-07 11:50:03 +0800308 for(uint32_t i = 0; i < pCreateInfo->attachmentCount; ++i)
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600309 {
Chia-I Wuc278df82015-07-07 11:50:03 +0800310 if(!validate_VkImageLayout(pCreateInfo->pAttachments[i].initialLayout) ||
311 !validate_VkImageLayout(pCreateInfo->pAttachments[i].finalLayout))
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600312 {
313 std::stringstream ss;
Chia-I Wuc278df82015-07-07 11:50:03 +0800314 ss << "vkCreateRenderPass parameter, VkImageLayout in pCreateInfo->pAttachments[" << i << "], is unrecognized";
Tobin Ehlis049f1782015-10-29 14:19:18 -0600315 skipCall |= log_msg(my_data->report_data, 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 -0600316 }
317 }
318
Chia-I Wuc278df82015-07-07 11:50:03 +0800319 for(uint32_t i = 0; i < pCreateInfo->attachmentCount; ++i)
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600320 {
Chia-I Wuc278df82015-07-07 11:50:03 +0800321 if(!validate_VkAttachmentLoadOp(pCreateInfo->pAttachments[i].loadOp))
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600322 {
323 std::stringstream ss;
Chia-I Wuc278df82015-07-07 11:50:03 +0800324 ss << "vkCreateRenderPass parameter, VkAttachmentLoadOp in pCreateInfo->pAttachments[" << i << "], is unrecognized";
Tobin Ehlis049f1782015-10-29 14:19:18 -0600325 skipCall |= log_msg(my_data->report_data, 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 -0600326 }
327 }
328
Chia-I Wuc278df82015-07-07 11:50:03 +0800329 for(uint32_t i = 0; i < pCreateInfo->attachmentCount; ++i)
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600330 {
Chia-I Wuc278df82015-07-07 11:50:03 +0800331 if(!validate_VkAttachmentStoreOp(pCreateInfo->pAttachments[i].storeOp))
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600332 {
333 std::stringstream ss;
Chia-I Wuc278df82015-07-07 11:50:03 +0800334 ss << "vkCreateRenderPass parameter, VkAttachmentStoreOp in pCreateInfo->pAttachments[" << i << "], is unrecognized";
Tobin Ehlis049f1782015-10-29 14:19:18 -0600335 skipCall |= log_msg(my_data->report_data, 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 -0600336 }
337 }
338
Mark Lobodzinski9cce7832015-07-29 09:21:22 -0600339 // Any depth buffers specified as attachments?
340 bool depthFormatPresent = VK_FALSE;
341 for (uint32_t i = 0; i < pCreateInfo->attachmentCount; ++i)
342 {
343 depthFormatPresent |= is_depth_format(pCreateInfo->pAttachments[i].format);
344 }
345
346 if (depthFormatPresent == VK_FALSE) {
347 // No depth attachment is present, validate that subpasses set depthStencilAttachment to VK_ATTACHMENT_UNUSED;
348 for (uint32_t i = 0; i < pCreateInfo->subpassCount; i++) {
Chia-I Wuce532f72015-10-26 17:32:47 +0800349 if (pCreateInfo->pSubpasses[i].pDepthStencilAttachment &&
350 pCreateInfo->pSubpasses[i].pDepthStencilAttachment->attachment != VK_ATTACHMENT_UNUSED) {
Mark Lobodzinski9cce7832015-07-29 09:21:22 -0600351 std::stringstream ss;
352 ss << "vkCreateRenderPass has no depth/stencil attachment, yet subpass[" << i << "] has VkSubpassDescription::depthStencilAttachment value that is not VK_ATTACHMENT_UNUSED";
Tobin Ehlis049f1782015-10-29 14:19:18 -0600353 skipCall |= log_msg(my_data->report_data, 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 -0600354 }
355 }
356 }
Tobin Ehlis35613802015-09-22 08:40:52 -0600357 if (skipCall)
358 return VK_ERROR_VALIDATION_FAILED;
Mark Lobodzinski9cce7832015-07-29 09:21:22 -0600359
Chia-I Wu69f40122015-10-26 21:10:41 +0800360 VkResult result = my_data->device_dispatch_table->CreateRenderPass(device, pCreateInfo, pAllocator, pRenderPass);
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600361
362 return result;
363}
364
Chia-I Wu1f851912015-10-27 18:04:07 +0800365VK_LAYER_EXPORT VkResult VKAPI vkCreateImageView(VkDevice device, const VkImageViewCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkImageView* pView)
Tobin Ehlis65380532015-09-21 15:20:28 -0600366{
367 VkBool32 skipCall = VK_FALSE;
368 layer_data *device_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
Chia-I Wue420a332015-10-26 20:04:44 +0800369 auto imageEntry = device_data->imageMap.find(pCreateInfo->image);
Tobin Ehlis65380532015-09-21 15:20:28 -0600370 if (imageEntry != device_data->imageMap.end()) {
Tobin Ehlis6fa437d2015-09-25 14:49:43 -0600371 if (pCreateInfo->subresourceRange.baseMipLevel >= imageEntry->second.mipLevels) {
Tobin Ehlis65380532015-09-21 15:20:28 -0600372 std::stringstream ss;
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600373 ss << "vkCreateImageView called with baseMipLevel " << pCreateInfo->subresourceRange.baseMipLevel
Chia-I Wue420a332015-10-26 20:04:44 +0800374 << " for image " << pCreateInfo->image << " that only has " << imageEntry->second.mipLevels << " mip levels.";
Tobin Ehlis65380532015-09-21 15:20:28 -0600375 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());
376 }
Tobin Ehlis6fa437d2015-09-25 14:49:43 -0600377 if (pCreateInfo->subresourceRange.baseArrayLayer >= imageEntry->second.arraySize) {
Tobin Ehlis65380532015-09-21 15:20:28 -0600378 std::stringstream ss;
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600379 ss << "vkCreateImageView called with baseArrayLayer " << pCreateInfo->subresourceRange.baseArrayLayer << " for image "
Chia-I Wue420a332015-10-26 20:04:44 +0800380 << pCreateInfo->image << " that only has " << imageEntry->second.arraySize << " mip levels.";
Tobin Ehlis65380532015-09-21 15:20:28 -0600381 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());
382 }
Chia-I Wu1f851912015-10-27 18:04:07 +0800383 if (!pCreateInfo->subresourceRange.levelCount) {
Tobin Ehlis65380532015-09-21 15:20:28 -0600384 std::stringstream ss;
385 ss << "vkCreateImageView called with 0 in pCreateInfo->subresourceRange.mipLevels.";
386 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());
387 }
Chia-I Wu1f851912015-10-27 18:04:07 +0800388 if (!pCreateInfo->subresourceRange.layerCount) {
Tobin Ehlis65380532015-09-21 15:20:28 -0600389 std::stringstream ss;
390 ss << "vkCreateImageView called with 0 in pCreateInfo->subresourceRange.arraySize.";
391 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());
392 }
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600393
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600394 // Validate correct image aspect bits for desired formats and format consistency
Tobin Ehlis6fa437d2015-09-25 14:49:43 -0600395 VkFormat imageFormat = imageEntry->second.format;
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600396 VkFormat ivciFormat = pCreateInfo->format;
397 VkImageAspectFlags aspectMask = pCreateInfo->subresourceRange.aspectMask;
398
399 if (vk_format_is_color(imageFormat)) {
400 if ((aspectMask & VK_IMAGE_ASPECT_COLOR_BIT) != VK_IMAGE_ASPECT_COLOR_BIT) {
401 std::stringstream ss;
402 ss << "vkCreateImageView: Color image formats must have the VK_IMAGE_ASPECT_COLOR_BIT set";
403 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_IMAGE,
Chia-I Wue420a332015-10-26 20:04:44 +0800404 (uint64_t)pCreateInfo->image, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", ss.str().c_str());
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600405 }
406 if ((aspectMask & VK_IMAGE_ASPECT_COLOR_BIT) != aspectMask) {
407 std::stringstream ss;
408 ss << "vkCreateImageView: Color image formats must have ONLY the VK_IMAGE_ASPECT_COLOR_BIT set";
409 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_IMAGE,
Chia-I Wue420a332015-10-26 20:04:44 +0800410 (uint64_t)pCreateInfo->image, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", ss.str().c_str());
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600411 }
412 if (VK_FALSE == vk_format_is_color(ivciFormat)) {
413 std::stringstream ss;
414 ss << "vkCreateImageView: The image view's format can differ from the parent image's format, but both must be "
415 << "color formats. ImageFormat is " << string_VkFormat(imageFormat) << " ImageViewFormat is " << string_VkFormat(ivciFormat);
416 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_IMAGE,
Chia-I Wue420a332015-10-26 20:04:44 +0800417 (uint64_t)pCreateInfo->image, 0, IMAGE_INVALID_FORMAT, "IMAGE", ss.str().c_str());
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600418 }
419 // TODO: Uncompressed formats are compatible if they occupy they same number of bits per pixel.
420 // Compressed formats are compatible if the only difference between them is the numerical type of
421 // the uncompressed pixels (e.g. signed vs. unsigned, or sRGB vs. UNORM encoding).
422 } else if (vk_format_is_depth_and_stencil(imageFormat)) {
423 if ((aspectMask & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) !=
424 (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) {
425 std::stringstream ss;
426 ss << "vkCreateImageView: Combination depth/stencil image formats must have both VK_IMAGE_ASPECT_DEPTH_BIT and VK_IMAGE_ASPECT_STENCIL_BIT set";
427 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_IMAGE,
Chia-I Wue420a332015-10-26 20:04:44 +0800428 (uint64_t)pCreateInfo->image, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", ss.str().c_str());
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600429 }
430 if ((aspectMask & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) != aspectMask) {
431 std::stringstream ss;
432 ss << "vkCreateImageView: Combination depth/stencil image formats can have only the VK_IMAGE_ASPECT_DEPTH_BIT and VK_IMAGE_ASPECT_STENCIL_BIT set";
433 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_IMAGE,
Chia-I Wue420a332015-10-26 20:04:44 +0800434 (uint64_t)pCreateInfo->image, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", ss.str().c_str());
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600435 }
436 } else if (vk_format_is_depth_only(imageFormat)) {
437 if ((aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT) != VK_IMAGE_ASPECT_DEPTH_BIT) {
438 std::stringstream ss;
439 ss << "vkCreateImageView: Depth-only image formats must have the VK_IMAGE_ASPECT_DEPTH_BIT set";
440 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_IMAGE,
Chia-I Wue420a332015-10-26 20:04:44 +0800441 (uint64_t)pCreateInfo->image, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", ss.str().c_str());
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600442 }
443 if ((aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT) != aspectMask) {
444 std::stringstream ss;
445 ss << "vkCreateImageView: Depth-only image formats can have only the VK_IMAGE_ASPECT_DEPTH_BIT set";
446 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_IMAGE,
Chia-I Wue420a332015-10-26 20:04:44 +0800447 (uint64_t)pCreateInfo->image, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", ss.str().c_str());
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600448 }
449 } else if (vk_format_is_stencil_only(imageFormat)) {
450 if ((aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT) != VK_IMAGE_ASPECT_STENCIL_BIT) {
451 std::stringstream ss;
452 ss << "vkCreateImageView: Stencil-only image formats must have the VK_IMAGE_ASPECT_STENCIL_BIT set";
453 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_IMAGE,
Chia-I Wue420a332015-10-26 20:04:44 +0800454 (uint64_t)pCreateInfo->image, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", ss.str().c_str());
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600455 }
456 if ((aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT) != aspectMask) {
457 std::stringstream ss;
458 ss << "vkCreateImageView: Stencil-only image formats can have only the VK_IMAGE_ASPECT_STENCIL_BIT set";
459 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_IMAGE,
Chia-I Wue420a332015-10-26 20:04:44 +0800460 (uint64_t)pCreateInfo->image, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", ss.str().c_str());
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600461 }
462 }
463 }
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600464
Tobin Ehlis65380532015-09-21 15:20:28 -0600465 if (skipCall)
466 return VK_ERROR_VALIDATION_FAILED;
Tobin Ehlis35613802015-09-22 08:40:52 -0600467
Chia-I Wu69f40122015-10-26 21:10:41 +0800468 VkResult result = device_data->device_dispatch_table->CreateImageView(device, pCreateInfo, pAllocator, pView);
Tobin Ehlis65380532015-09-21 15:20:28 -0600469 return result;
470}
471
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600472VK_LAYER_EXPORT void VKAPI vkCmdClearColorImage(
Chia-I Wu1f851912015-10-27 18:04:07 +0800473 VkCommandBuffer commandBuffer,
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600474 VkImage image,
475 VkImageLayout imageLayout,
476 const VkClearColorValue *pColor,
477 uint32_t rangeCount,
478 const VkImageSubresourceRange *pRanges)
479{
480 VkBool32 skipCall = VK_FALSE;
Chia-I Wu1f851912015-10-27 18:04:07 +0800481 layer_data *device_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600482 // For each range, image aspect must be color only
483 for (uint32_t i = 0; i < rangeCount; i++) {
484 if (pRanges[i].aspectMask != VK_IMAGE_ASPECT_COLOR_BIT) {
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600485 char const str[] = "vkCmdClearColorImage aspectMasks for all subresource ranges must be set to VK_IMAGE_ASPECT_COLOR_BIT";
486 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
Chia-I Wu1f851912015-10-27 18:04:07 +0800487 (uint64_t)commandBuffer, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", str);
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600488 }
489 }
490
491 if (VK_FALSE == skipCall) {
Chia-I Wu1f851912015-10-27 18:04:07 +0800492 device_data->device_dispatch_table->CmdClearColorImage(commandBuffer, image, imageLayout,
493 pColor, rangeCount, pRanges);
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600494 }
495}
496
497VK_LAYER_EXPORT void VKAPI vkCmdClearDepthStencilImage(
Chia-I Wu1f851912015-10-27 18:04:07 +0800498 VkCommandBuffer commandBuffer,
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600499 VkImage image,
500 VkImageLayout imageLayout,
501 const VkClearDepthStencilValue *pDepthStencil,
502 uint32_t rangeCount,
503 const VkImageSubresourceRange *pRanges)
504{
505 VkBool32 skipCall = VK_FALSE;
Chia-I Wu1f851912015-10-27 18:04:07 +0800506 layer_data *device_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600507 // For each range, Image aspect must be depth or stencil or both
508 for (uint32_t i = 0; i < rangeCount; i++) {
509 if (((pRanges[i].aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT) != VK_IMAGE_ASPECT_DEPTH_BIT) &&
510 ((pRanges[i].aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT) != VK_IMAGE_ASPECT_STENCIL_BIT))
511 {
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600512 char const str[] = "vkCmdClearDepthStencilImage aspectMasks for all subresource ranges must be "
513 "set to VK_IMAGE_ASPECT_DEPTH_BIT and/or VK_IMAGE_ASPECT_STENCIL_BIT";
514 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
Chia-I Wu1f851912015-10-27 18:04:07 +0800515 (uint64_t)commandBuffer, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", str);
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600516 }
517 }
518
519 if (VK_FALSE == skipCall) {
Chia-I Wu1f851912015-10-27 18:04:07 +0800520 device_data->device_dispatch_table->CmdClearDepthStencilImage(commandBuffer,
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600521 image, imageLayout, pDepthStencil, rangeCount, pRanges);
522 }
523}
524
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600525VK_LAYER_EXPORT void VKAPI vkCmdCopyImage(
Chia-I Wu1f851912015-10-27 18:04:07 +0800526 VkCommandBuffer commandBuffer,
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600527 VkImage srcImage,
528 VkImageLayout srcImageLayout,
Chia-I Wu1f851912015-10-27 18:04:07 +0800529 VkImage dstImage,
530 VkImageLayout dstImageLayout,
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600531 uint32_t regionCount,
532 const VkImageCopy *pRegions)
533{
534 VkBool32 skipCall = VK_FALSE;
Chia-I Wu1f851912015-10-27 18:04:07 +0800535 layer_data *device_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
Chia-I Wue420a332015-10-26 20:04:44 +0800536 auto srcImageEntry = device_data->imageMap.find(srcImage);
Chia-I Wu1f851912015-10-27 18:04:07 +0800537 auto dstImageEntry = device_data->imageMap.find(dstImage);
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600538
Jeremy Hayesac8ed0b2015-10-28 13:01:39 -0600539 // For each region, src and dst number of layers should not be zero
540 // For each region, src and dst number of layers must match
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600541 // For each region, src aspect mask must match dest aspect mask
542 // For each region, color aspects cannot be mixed with depth/stencil aspects
543 for (uint32_t i = 0; i < regionCount; i++) {
Chia-I Wu1f851912015-10-27 18:04:07 +0800544 if(pRegions[i].srcSubresource.layerCount == 0)
Jeremy Hayesac8ed0b2015-10-28 13:01:39 -0600545 {
546 char const str[] = "vkCmdCopyImage: number of layers in source subresource is zero";
547 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_WARN_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
Chia-I Wu1f851912015-10-27 18:04:07 +0800548 (uint64_t)commandBuffer, 0, IMAGE_MISMATCHED_IMAGE_ASPECT, "IMAGE", str);
Jeremy Hayesac8ed0b2015-10-28 13:01:39 -0600549 }
550
Chia-I Wu1f851912015-10-27 18:04:07 +0800551 if(pRegions[i].dstSubresource.layerCount == 0)
Jeremy Hayesac8ed0b2015-10-28 13:01:39 -0600552 {
553 char const str[] = "vkCmdCopyImage: number of layers in destination subresource is zero";
554 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_WARN_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
Chia-I Wu1f851912015-10-27 18:04:07 +0800555 (uint64_t)commandBuffer, 0, IMAGE_MISMATCHED_IMAGE_ASPECT, "IMAGE", str);
Jeremy Hayesac8ed0b2015-10-28 13:01:39 -0600556 }
557
Chia-I Wu1f851912015-10-27 18:04:07 +0800558 if(pRegions[i].srcSubresource.layerCount != pRegions[i].dstSubresource.layerCount)
Jeremy Hayesac8ed0b2015-10-28 13:01:39 -0600559 {
560 char const str[] = "vkCmdCopyImage: number of layers in source and destination subresources must match";
561 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
Chia-I Wu1f851912015-10-27 18:04:07 +0800562 (uint64_t)commandBuffer, 0, IMAGE_MISMATCHED_IMAGE_ASPECT, "IMAGE", str);
Jeremy Hayesac8ed0b2015-10-28 13:01:39 -0600563 }
564
Chia-I Wu4291d882015-10-27 19:00:15 +0800565 if (pRegions[i].srcSubresource.aspectMask != pRegions[i].dstSubresource.aspectMask) {
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600566 char const str[] = "vkCmdCopyImage: Src and dest aspectMasks for each region must match";
567 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
Chia-I Wu1f851912015-10-27 18:04:07 +0800568 (uint64_t)commandBuffer, 0, IMAGE_MISMATCHED_IMAGE_ASPECT, "IMAGE", str);
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600569 }
Chia-I Wu4291d882015-10-27 19:00:15 +0800570 if ((pRegions[i].srcSubresource.aspectMask & VK_IMAGE_ASPECT_COLOR_BIT) &&
571 (pRegions[i].srcSubresource.aspectMask & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT))) {
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600572 char const str[] = "vkCmdCopyImage aspectMask cannot specify both COLOR and DEPTH/STENCIL aspects";
573 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
Chia-I Wu1f851912015-10-27 18:04:07 +0800574 (uint64_t)commandBuffer, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", str);
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600575 }
576 }
577
Mike Stroyan43909d82015-09-25 13:39:21 -0600578 if ((srcImageEntry != device_data->imageMap.end())
Chia-I Wu1f851912015-10-27 18:04:07 +0800579 && (dstImageEntry != device_data->imageMap.end())) {
580 if (srcImageEntry->second.imageType != dstImageEntry->second.imageType) {
Mike Stroyan43909d82015-09-25 13:39:21 -0600581 char const str[] = "vkCmdCopyImage called with unmatched source and dest image types.";
582 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
Chia-I Wu1f851912015-10-27 18:04:07 +0800583 (uint64_t)commandBuffer, 0, IMAGE_MISMATCHED_IMAGE_TYPE, "IMAGE", str);
Mike Stroyan43909d82015-09-25 13:39:21 -0600584 }
585 // Check that format is same size or exact stencil/depth
Tobin Ehlis6fa437d2015-09-25 14:49:43 -0600586 if (is_depth_format(srcImageEntry->second.format)) {
Chia-I Wu1f851912015-10-27 18:04:07 +0800587 if (srcImageEntry->second.format != dstImageEntry->second.format) {
Mike Stroyan43909d82015-09-25 13:39:21 -0600588 char const str[] = "vkCmdCopyImage called with unmatched source and dest image depth/stencil formats.";
589 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
Chia-I Wu1f851912015-10-27 18:04:07 +0800590 (uint64_t)commandBuffer, 0, IMAGE_MISMATCHED_IMAGE_FORMAT, "IMAGE", str);
Mike Stroyan43909d82015-09-25 13:39:21 -0600591 }
592 } else {
Tobin Ehlis6fa437d2015-09-25 14:49:43 -0600593 size_t srcSize = vk_format_get_size(srcImageEntry->second.format);
Chia-I Wu1f851912015-10-27 18:04:07 +0800594 size_t destSize = vk_format_get_size(dstImageEntry->second.format);
Mike Stroyan43909d82015-09-25 13:39:21 -0600595 if (srcSize != destSize) {
596 char const str[] = "vkCmdCopyImage called with unmatched source and dest image format sizes.";
597 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
Chia-I Wu1f851912015-10-27 18:04:07 +0800598 (uint64_t)commandBuffer, 0, IMAGE_MISMATCHED_IMAGE_FORMAT, "IMAGE", str);
Mike Stroyan43909d82015-09-25 13:39:21 -0600599 }
600 }
601 }
602
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600603 if (VK_FALSE == skipCall) {
Chia-I Wu1f851912015-10-27 18:04:07 +0800604 device_data->device_dispatch_table->CmdCopyImage(commandBuffer, srcImage,
605 srcImageLayout, dstImage, dstImageLayout, regionCount, pRegions);
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600606 }
607}
608
Courtney Goeltzenleuchter9feb0732015-10-15 16:51:05 -0600609void VKAPI vkCmdClearAttachments(
Chia-I Wu1f851912015-10-27 18:04:07 +0800610 VkCommandBuffer commandBuffer,
Courtney Goeltzenleuchter9feb0732015-10-15 16:51:05 -0600611 uint32_t attachmentCount,
612 const VkClearAttachment* pAttachments,
613 uint32_t rectCount,
Courtney Goeltzenleuchtera12e2912015-10-15 18:22:08 -0600614 const VkClearRect* pRects)
Courtney Goeltzenleuchter9feb0732015-10-15 16:51:05 -0600615{
616 VkBool32 skipCall = VK_FALSE;
617 VkImageAspectFlags aspectMask;
Chia-I Wu1f851912015-10-27 18:04:07 +0800618 layer_data *device_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
Courtney Goeltzenleuchter9feb0732015-10-15 16:51:05 -0600619 for (uint32_t i = 0; i < attachmentCount; i++) {
620 aspectMask = pAttachments[i].aspectMask;
621 if (aspectMask & VK_IMAGE_ASPECT_COLOR_BIT) {
622 if (aspectMask != VK_IMAGE_ASPECT_COLOR_BIT) {
623 // VK_IMAGE_ASPECT_COLOR_BIT is not the only bit set for this attachment
Courtney Goeltzenleuchter9feb0732015-10-15 16:51:05 -0600624 char const str[] = "vkCmdClearAttachments aspectMask [%d] must set only VK_IMAGE_ASPECT_COLOR_BIT of a color attachment.";
625 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
Chia-I Wu1f851912015-10-27 18:04:07 +0800626 (uint64_t)commandBuffer, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", str, i);
Courtney Goeltzenleuchter9feb0732015-10-15 16:51:05 -0600627 }
628 } else {
629 // Image aspect must be depth or stencil or both
630 if (((aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT) != VK_IMAGE_ASPECT_DEPTH_BIT) &&
631 ((aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT) != VK_IMAGE_ASPECT_STENCIL_BIT))
632 {
Courtney Goeltzenleuchter9feb0732015-10-15 16:51:05 -0600633 char const str[] = "vkCmdClearAttachments aspectMask [%d] must be set to VK_IMAGE_ASPECT_DEPTH_BIT and/or VK_IMAGE_ASPECT_STENCIL_BIT";
634 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
Chia-I Wu1f851912015-10-27 18:04:07 +0800635 (uint64_t)commandBuffer, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", str, i);
Courtney Goeltzenleuchter9feb0732015-10-15 16:51:05 -0600636 }
637 }
638 }
639
640 if (VK_FALSE == skipCall) {
Chia-I Wu1f851912015-10-27 18:04:07 +0800641 device_data->device_dispatch_table->CmdClearAttachments(commandBuffer,
Courtney Goeltzenleuchter9feb0732015-10-15 16:51:05 -0600642 attachmentCount, pAttachments, rectCount, pRects);
643 }
644}
645
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600646VK_LAYER_EXPORT void VKAPI vkCmdCopyImageToBuffer(
Chia-I Wu1f851912015-10-27 18:04:07 +0800647 VkCommandBuffer commandBuffer,
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600648 VkImage srcImage,
649 VkImageLayout srcImageLayout,
Chia-I Wu1f851912015-10-27 18:04:07 +0800650 VkBuffer dstBuffer,
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600651 uint32_t regionCount,
652 const VkBufferImageCopy *pRegions)
653{
654 VkBool32 skipCall = VK_FALSE;
Chia-I Wu1f851912015-10-27 18:04:07 +0800655 layer_data *device_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
Jeremy Hayesac8ed0b2015-10-28 13:01:39 -0600656 // For each region, the number of layers in the image subresource should not be zero
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600657 // Image aspect must be ONE OF color, depth, stencil
658 for (uint32_t i = 0; i < regionCount; i++) {
Chia-I Wu1f851912015-10-27 18:04:07 +0800659 if(pRegions[i].imageSubresource.layerCount == 0)
Jeremy Hayesac8ed0b2015-10-28 13:01:39 -0600660 {
Jeremy Hayesac8ed0b2015-10-28 13:01:39 -0600661 char const str[] = "vkCmdCopyImageToBuffer: number of layers in image subresource is zero";
662 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_WARN_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
Chia-I Wu1f851912015-10-27 18:04:07 +0800663 (uint64_t)commandBuffer, 0, IMAGE_MISMATCHED_IMAGE_ASPECT, "IMAGE", str);
Jeremy Hayesac8ed0b2015-10-28 13:01:39 -0600664 }
665
Chia-I Wu4291d882015-10-27 19:00:15 +0800666 VkImageAspectFlags aspectMask = pRegions[i].imageSubresource.aspectMask;
667 if ((aspectMask != VK_IMAGE_ASPECT_COLOR_BIT) &&
668 (aspectMask != VK_IMAGE_ASPECT_DEPTH_BIT) &&
669 (aspectMask != VK_IMAGE_ASPECT_STENCIL_BIT)) {
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600670 char const str[] = "vkCmdCopyImageToBuffer: aspectMasks for each region must specify only COLOR or DEPTH or STENCIL";
671 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
Chia-I Wu1f851912015-10-27 18:04:07 +0800672 (uint64_t)commandBuffer, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", str);
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600673 }
674 }
675
676 if (VK_FALSE == skipCall) {
Chia-I Wu1f851912015-10-27 18:04:07 +0800677 device_data->device_dispatch_table->CmdCopyImageToBuffer(commandBuffer,
678 srcImage, srcImageLayout, dstBuffer, regionCount, pRegions);
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600679 }
680}
681
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600682VK_LAYER_EXPORT void VKAPI vkCmdCopyBufferToImage(
Chia-I Wu1f851912015-10-27 18:04:07 +0800683 VkCommandBuffer commandBuffer,
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600684 VkBuffer srcBuffer,
Chia-I Wu1f851912015-10-27 18:04:07 +0800685 VkImage dstImage,
686 VkImageLayout dstImageLayout,
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600687 uint32_t regionCount,
688 const VkBufferImageCopy *pRegions)
689{
690 VkBool32 skipCall = VK_FALSE;
Chia-I Wu1f851912015-10-27 18:04:07 +0800691 layer_data *device_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
Jeremy Hayesac8ed0b2015-10-28 13:01:39 -0600692 // For each region, the number of layers in the image subresource should not be zero
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600693 // Image aspect must be ONE OF color, depth, stencil
694 for (uint32_t i = 0; i < regionCount; i++) {
Chia-I Wu1f851912015-10-27 18:04:07 +0800695 if(pRegions[i].imageSubresource.layerCount == 0)
Jeremy Hayesac8ed0b2015-10-28 13:01:39 -0600696 {
Jeremy Hayesac8ed0b2015-10-28 13:01:39 -0600697 char const str[] = "vkCmdCopyBufferToImage: number of layers in image subresource is zero";
698 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_WARN_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
Chia-I Wu1f851912015-10-27 18:04:07 +0800699 (uint64_t)commandBuffer, 0, IMAGE_MISMATCHED_IMAGE_ASPECT, "IMAGE", str);
Jeremy Hayesac8ed0b2015-10-28 13:01:39 -0600700 }
701
Chia-I Wu4291d882015-10-27 19:00:15 +0800702 VkImageAspectFlags aspectMask = pRegions[i].imageSubresource.aspectMask;
703 if ((aspectMask != VK_IMAGE_ASPECT_COLOR_BIT) &&
704 (aspectMask != VK_IMAGE_ASPECT_DEPTH_BIT) &&
705 (aspectMask != VK_IMAGE_ASPECT_STENCIL_BIT)) {
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600706 char const str[] = "vkCmdCopyBufferToImage: aspectMasks for each region must specify only COLOR or DEPTH or STENCIL";
707 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
Chia-I Wu1f851912015-10-27 18:04:07 +0800708 (uint64_t)commandBuffer, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", str);
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600709 }
710 }
711
712 if (VK_FALSE == skipCall) {
Chia-I Wu1f851912015-10-27 18:04:07 +0800713 device_data->device_dispatch_table->CmdCopyBufferToImage(commandBuffer,
714 srcBuffer, dstImage, dstImageLayout, regionCount, pRegions);
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600715 }
716}
717
718VK_LAYER_EXPORT void VKAPI vkCmdBlitImage(
Chia-I Wu1f851912015-10-27 18:04:07 +0800719 VkCommandBuffer commandBuffer,
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600720 VkImage srcImage,
721 VkImageLayout srcImageLayout,
Chia-I Wu1f851912015-10-27 18:04:07 +0800722 VkImage dstImage,
723 VkImageLayout dstImageLayout,
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600724 uint32_t regionCount,
725 const VkImageBlit *pRegions,
Chia-I Wu3603b082015-10-26 16:49:32 +0800726 VkFilter filter)
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600727{
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600728 VkBool32 skipCall = VK_FALSE;
Chia-I Wu1f851912015-10-27 18:04:07 +0800729 layer_data *device_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600730
Chia-I Wue420a332015-10-26 20:04:44 +0800731 auto srcImageEntry = device_data->imageMap.find(srcImage);
Chia-I Wu1f851912015-10-27 18:04:07 +0800732 auto dstImageEntry = device_data->imageMap.find(dstImage);
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600733
734 if ((srcImageEntry != device_data->imageMap.end()) &&
Chia-I Wu1f851912015-10-27 18:04:07 +0800735 (dstImageEntry != device_data->imageMap.end())) {
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600736
Tobin Ehlis6fa437d2015-09-25 14:49:43 -0600737 VkFormat srcFormat = srcImageEntry->second.format;
Chia-I Wu1f851912015-10-27 18:04:07 +0800738 VkFormat dstFormat = dstImageEntry->second.format;
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600739
740 // Validate consistency for signed and unsigned formats
741 if ((vk_format_is_sint(srcFormat) && !vk_format_is_sint(dstFormat)) ||
742 (vk_format_is_uint(srcFormat) && !vk_format_is_uint(dstFormat))) {
743 std::stringstream ss;
Chia-I Wu1f851912015-10-27 18:04:07 +0800744 ss << "vkCmdBlitImage: If one of srcImage and dstImage images has signed/unsigned integer format, "
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600745 << "the other one must also have signed/unsigned integer format. "
746 << "Source format is " << string_VkFormat(srcFormat) << " Destinatino format is " << string_VkFormat(dstFormat);
747 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
Chia-I Wu1f851912015-10-27 18:04:07 +0800748 (uint64_t)commandBuffer, 0, IMAGE_INVALID_FORMAT, "IMAGE", ss.str().c_str());
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600749 }
750
751 // Validate aspect bits and formats for depth/stencil images
752 if (vk_format_is_depth_or_stencil(srcFormat) ||
753 vk_format_is_depth_or_stencil(dstFormat)) {
754 if (srcFormat != dstFormat) {
755 std::stringstream ss;
Chia-I Wu1f851912015-10-27 18:04:07 +0800756 ss << "vkCmdBlitImage: If one of srcImage and dstImage images has a format of depth, stencil or depth "
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600757 << "stencil, the other one must have exactly the same format. "
758 << "Source format is " << string_VkFormat(srcFormat) << " Destinatino format is " << string_VkFormat(dstFormat);
759 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
Chia-I Wu1f851912015-10-27 18:04:07 +0800760 (uint64_t)commandBuffer, 0, IMAGE_INVALID_FORMAT, "IMAGE", ss.str().c_str());
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600761 }
762
763 for (uint32_t i = 0; i < regionCount; i++) {
Chia-I Wu1f851912015-10-27 18:04:07 +0800764 if(pRegions[i].srcSubresource.layerCount == 0)
Jeremy Hayesac8ed0b2015-10-28 13:01:39 -0600765 {
766 char const str[] = "vkCmdBlitImage: number of layers in source subresource is zero";
767 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_WARN_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
Chia-I Wu1f851912015-10-27 18:04:07 +0800768 (uint64_t)commandBuffer, 0, IMAGE_MISMATCHED_IMAGE_ASPECT, "IMAGE", str);
Jeremy Hayesac8ed0b2015-10-28 13:01:39 -0600769 }
770
Chia-I Wu1f851912015-10-27 18:04:07 +0800771 if(pRegions[i].dstSubresource.layerCount == 0)
Jeremy Hayesac8ed0b2015-10-28 13:01:39 -0600772 {
773 char const str[] = "vkCmdBlitImage: number of layers in destination subresource is zero";
774 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_WARN_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
Chia-I Wu1f851912015-10-27 18:04:07 +0800775 (uint64_t)commandBuffer, 0, IMAGE_MISMATCHED_IMAGE_ASPECT, "IMAGE", str);
Jeremy Hayesac8ed0b2015-10-28 13:01:39 -0600776 }
777
Chia-I Wu1f851912015-10-27 18:04:07 +0800778 if(pRegions[i].srcSubresource.layerCount != pRegions[i].dstSubresource.layerCount)
Jeremy Hayesac8ed0b2015-10-28 13:01:39 -0600779 {
780 char const str[] = "vkCmdBlitImage: number of layers in source and destination subresources must match";
781 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
Chia-I Wu1f851912015-10-27 18:04:07 +0800782 (uint64_t)commandBuffer, 0, IMAGE_MISMATCHED_IMAGE_ASPECT, "IMAGE", str);
Jeremy Hayesac8ed0b2015-10-28 13:01:39 -0600783 }
784
Chia-I Wu4291d882015-10-27 19:00:15 +0800785 VkImageAspectFlags srcAspect = pRegions[i].srcSubresource.aspectMask;
786 VkImageAspectFlags dstAspect = pRegions[i].dstSubresource.aspectMask;
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600787
788 if (srcAspect != dstAspect) {
789 std::stringstream ss;
790 ss << "vkCmdBlitImage: Image aspects of depth/stencil images should match";
791 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_WARN_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
Chia-I Wu1f851912015-10-27 18:04:07 +0800792 (uint64_t)commandBuffer, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", ss.str().c_str());
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600793 }
794 if (vk_format_is_depth_and_stencil(srcFormat)) {
795 if (srcAspect != (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) {
796 std::stringstream ss;
797 ss << "vkCmdBlitImage: Combination depth/stencil image formats must have both VK_IMAGE_ASPECT_DEPTH_BIT "
Chia-I Wu1f851912015-10-27 18:04:07 +0800798 << "and VK_IMAGE_ASPECT_STENCIL_BIT set in both the srcImage and dstImage";
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600799 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
Chia-I Wu1f851912015-10-27 18:04:07 +0800800 (uint64_t)commandBuffer, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", ss.str().c_str());
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600801 }
802 } else if (vk_format_is_stencil_only(srcFormat)) {
803 if (srcAspect != VK_IMAGE_ASPECT_STENCIL_BIT) {
804 std::stringstream ss;
805 ss << "vkCmdBlitImage: Stencil-only image formats must have only the VK_IMAGE_ASPECT_STENCIL_BIT "
Chia-I Wu1f851912015-10-27 18:04:07 +0800806 << "set in both the srcImage and dstImage";
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600807 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
Chia-I Wu1f851912015-10-27 18:04:07 +0800808 (uint64_t)commandBuffer, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", ss.str().c_str());
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600809 }
810 } else if (vk_format_is_depth_only(srcFormat)) {
811 if (srcAspect != VK_IMAGE_ASPECT_DEPTH_BIT) {
812 std::stringstream ss;
813 ss << "vkCmdBlitImage: Depth-only image formats must have only the VK_IMAGE_ASPECT_DEPTH "
Chia-I Wu1f851912015-10-27 18:04:07 +0800814 << "set in both the srcImage and dstImage";
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600815 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
Chia-I Wu1f851912015-10-27 18:04:07 +0800816 (uint64_t)commandBuffer, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", ss.str().c_str());
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600817 }
818 }
819 }
820 }
821
822 // Validate filter
823 if (vk_format_is_depth_or_stencil(srcFormat) ||
824 vk_format_is_int(srcFormat)) {
Chia-I Wu3603b082015-10-26 16:49:32 +0800825 if (filter != VK_FILTER_NEAREST) {
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600826 std::stringstream ss;
827 ss << "vkCmdBlitImage: If the format of srcImage is a depth, stencil, depth stencil or integer-based format "
Chia-I Wu3603b082015-10-26 16:49:32 +0800828 << "then filter must be VK_FILTER_NEAREST.";
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600829 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
Chia-I Wu1f851912015-10-27 18:04:07 +0800830 (uint64_t)commandBuffer, 0, IMAGE_INVALID_FILTER, "IMAGE", ss.str().c_str());
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600831 }
832 }
833 }
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600834
Chia-I Wu1f851912015-10-27 18:04:07 +0800835 device_data->device_dispatch_table->CmdBlitImage(commandBuffer, srcImage,
836 srcImageLayout, dstImage, dstImageLayout, regionCount, pRegions, filter);
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600837}
838
839VK_LAYER_EXPORT void VKAPI vkCmdResolveImage(
Chia-I Wu1f851912015-10-27 18:04:07 +0800840 VkCommandBuffer commandBuffer,
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600841 VkImage srcImage,
842 VkImageLayout srcImageLayout,
Chia-I Wu1f851912015-10-27 18:04:07 +0800843 VkImage dstImage,
844 VkImageLayout dstImageLayout,
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600845 uint32_t regionCount,
846 const VkImageResolve *pRegions)
847{
848 VkBool32 skipCall = VK_FALSE;
Chia-I Wu1f851912015-10-27 18:04:07 +0800849 layer_data *device_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
Chia-I Wue420a332015-10-26 20:04:44 +0800850 auto srcImageEntry = device_data->imageMap.find(srcImage);
Chia-I Wu1f851912015-10-27 18:04:07 +0800851 auto dstImageEntry = device_data->imageMap.find(dstImage);
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600852
Jeremy Hayesac8ed0b2015-10-28 13:01:39 -0600853 // For each region, the number of layers in the image subresource should not be zero
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600854 // For each region, src and dest image aspect must be color only
855 for (uint32_t i = 0; i < regionCount; i++) {
Chia-I Wu1f851912015-10-27 18:04:07 +0800856 if(pRegions[i].srcSubresource.layerCount == 0)
Jeremy Hayesac8ed0b2015-10-28 13:01:39 -0600857 {
858 char const str[] = "vkCmdResolveImage: number of layers in source subresource is zero";
859 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_WARN_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
Chia-I Wu1f851912015-10-27 18:04:07 +0800860 (uint64_t)commandBuffer, 0, IMAGE_MISMATCHED_IMAGE_ASPECT, "IMAGE", str);
Jeremy Hayesac8ed0b2015-10-28 13:01:39 -0600861 }
862
Chia-I Wu1f851912015-10-27 18:04:07 +0800863 if(pRegions[i].dstSubresource.layerCount == 0)
Jeremy Hayesac8ed0b2015-10-28 13:01:39 -0600864 {
865 char const str[] = "vkCmdResolveImage: number of layers in destination subresource is zero";
866 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_WARN_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
Chia-I Wu1f851912015-10-27 18:04:07 +0800867 (uint64_t)commandBuffer, 0, IMAGE_MISMATCHED_IMAGE_ASPECT, "IMAGE", str);
Jeremy Hayesac8ed0b2015-10-28 13:01:39 -0600868 }
869
Chia-I Wu4291d882015-10-27 19:00:15 +0800870 if ((pRegions[i].srcSubresource.aspectMask != VK_IMAGE_ASPECT_COLOR_BIT) ||
871 (pRegions[i].dstSubresource.aspectMask != VK_IMAGE_ASPECT_COLOR_BIT)) {
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600872 char const str[] = "vkCmdResolveImage: src and dest aspectMasks for each region must specify only VK_IMAGE_ASPECT_COLOR_BIT";
873 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
Chia-I Wu1f851912015-10-27 18:04:07 +0800874 (uint64_t)commandBuffer, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", str);
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600875 }
876 }
877
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600878 if ((srcImageEntry != device_data->imageMap.end()) &&
Chia-I Wu1f851912015-10-27 18:04:07 +0800879 (dstImageEntry != device_data->imageMap.end())) {
880 if (srcImageEntry->second.format != dstImageEntry->second.format) {
Mike Stroyan43909d82015-09-25 13:39:21 -0600881 char const str[] = "vkCmdResolveImage called with unmatched source and dest formats.";
882 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
Chia-I Wu1f851912015-10-27 18:04:07 +0800883 (uint64_t)commandBuffer, 0, IMAGE_MISMATCHED_IMAGE_FORMAT, "IMAGE", str);
Mike Stroyan43909d82015-09-25 13:39:21 -0600884 }
Chia-I Wu1f851912015-10-27 18:04:07 +0800885 if (srcImageEntry->second.imageType != dstImageEntry->second.imageType) {
Mike Stroyan43909d82015-09-25 13:39:21 -0600886 char const str[] = "vkCmdResolveImage called with unmatched source and dest image types.";
887 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
Chia-I Wu1f851912015-10-27 18:04:07 +0800888 (uint64_t)commandBuffer, 0, IMAGE_MISMATCHED_IMAGE_TYPE, "IMAGE", str);
Mike Stroyan43909d82015-09-25 13:39:21 -0600889 }
Chia-I Wu3138d6a2015-10-31 00:31:16 +0800890 if (srcImageEntry->second.samples == VK_SAMPLE_COUNT_1_BIT) {
Mike Stroyan43909d82015-09-25 13:39:21 -0600891 char const str[] = "vkCmdResolveImage called with source sample count less than 2.";
892 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
Chia-I Wu1f851912015-10-27 18:04:07 +0800893 (uint64_t)commandBuffer, 0, IMAGE_INVALID_RESOLVE_SAMPLES, "IMAGE", str);
Mike Stroyan43909d82015-09-25 13:39:21 -0600894 }
Chia-I Wu3138d6a2015-10-31 00:31:16 +0800895 if (dstImageEntry->second.samples != VK_SAMPLE_COUNT_1_BIT) {
Mike Stroyan43909d82015-09-25 13:39:21 -0600896 char const str[] = "vkCmdResolveImage called with dest sample count greater than 1.";
897 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
Chia-I Wu1f851912015-10-27 18:04:07 +0800898 (uint64_t)commandBuffer, 0, IMAGE_INVALID_RESOLVE_SAMPLES, "IMAGE", str);
Mike Stroyan43909d82015-09-25 13:39:21 -0600899 }
900 }
901
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600902 if (VK_FALSE == skipCall) {
Chia-I Wu1f851912015-10-27 18:04:07 +0800903 device_data->device_dispatch_table->CmdResolveImage(commandBuffer, srcImage,
904 srcImageLayout, dstImage, dstImageLayout, regionCount, pRegions);
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600905 }
906}
907
Courtney Goeltzenleuchter01d2ae12015-10-20 16:40:38 -0600908VK_LAYER_EXPORT void VKAPI vkGetImageSubresourceLayout(
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600909 VkDevice device,
910 VkImage image,
911 const VkImageSubresource *pSubresource,
912 VkSubresourceLayout *pLayout)
913{
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600914 VkBool32 skipCall = VK_FALSE;
915 layer_data *device_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
916 VkFormat format;
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600917
Chia-I Wue420a332015-10-26 20:04:44 +0800918 auto imageEntry = device_data->imageMap.find(image);
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600919
920 // Validate that image aspects match formats
921 if (imageEntry != device_data->imageMap.end()) {
Tobin Ehlis6fa437d2015-09-25 14:49:43 -0600922 format = imageEntry->second.format;
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600923 if (vk_format_is_color(format)) {
Chia-I Wu195c9e12015-10-27 19:55:05 +0800924 if (pSubresource->aspectMask != VK_IMAGE_ASPECT_COLOR_BIT) {
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600925 std::stringstream ss;
Chia-I Wu195c9e12015-10-27 19:55:05 +0800926 ss << "vkGetImageSubresourceLayout: For color formats, the aspectMask field of VkImageSubresource must be VK_IMAGE_ASPECT_COLOR.";
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600927 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_IMAGE,
Chia-I Wue420a332015-10-26 20:04:44 +0800928 (uint64_t)image, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", ss.str().c_str());
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600929 }
930 } else if (vk_format_is_depth_or_stencil(format)) {
Chia-I Wu195c9e12015-10-27 19:55:05 +0800931 if ((pSubresource->aspectMask != VK_IMAGE_ASPECT_DEPTH_BIT) &&
932 (pSubresource->aspectMask != VK_IMAGE_ASPECT_STENCIL_BIT)) {
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600933 std::stringstream ss;
Chia-I Wu195c9e12015-10-27 19:55:05 +0800934 ss << "vkGetImageSubresourceLayout: For depth/stencil formats, the aspectMask selects either the depth or stencil image aspectMask.";
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600935 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_IMAGE,
Chia-I Wue420a332015-10-26 20:04:44 +0800936 (uint64_t)image, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", ss.str().c_str());
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600937 }
938 }
939 }
940
941 if (VK_FALSE == skipCall) {
Tobin Ehlis049f1782015-10-29 14:19:18 -0600942 device_data->device_dispatch_table->GetImageSubresourceLayout(device,
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600943 image, pSubresource, pLayout);
944 }
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600945}
946
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -0600947VK_LAYER_EXPORT PFN_vkVoidFunction VKAPI vkGetDeviceProcAddr(VkDevice device, const char* funcName)
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600948{
949 if (device == NULL) {
950 return NULL;
951 }
952
Tobin Ehlis049f1782015-10-29 14:19:18 -0600953 layer_data *my_data;
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600954 // loader uses this to force layer initialization; device object is wrapped
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600955 if (!strcmp(funcName, "vkGetDeviceProcAddr")) {
Tobin Ehlis049f1782015-10-29 14:19:18 -0600956 VkBaseLayerObject* wrapped_dev = (VkBaseLayerObject*) device;
957 my_data = get_my_data_ptr(get_dispatch_key(wrapped_dev->baseObject), layer_data_map);
958 my_data->device_dispatch_table = new VkLayerDispatchTable;
959 layer_initialize_dispatch_table(my_data->device_dispatch_table, wrapped_dev);
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -0600960 return (PFN_vkVoidFunction) vkGetDeviceProcAddr;
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600961 }
962
Tobin Ehlis049f1782015-10-29 14:19:18 -0600963 my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
Courtney Goeltzenleuchterbe637992015-06-25 18:01:43 -0600964 if (!strcmp(funcName, "vkCreateDevice"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -0600965 return (PFN_vkVoidFunction) vkCreateDevice;
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600966 if (!strcmp(funcName, "vkDestroyDevice"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -0600967 return (PFN_vkVoidFunction) vkDestroyDevice;
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600968 if (!strcmp(funcName, "vkCreateImage"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -0600969 return (PFN_vkVoidFunction) vkCreateImage;
Mark Lobodzinski9eb1ce42015-10-29 12:58:33 -0600970 if (!strcmp(funcName, "vkDestroyImage"))
971 return (PFN_vkVoidFunction) vkDestroyImage;
Tobin Ehlis342b9bf2015-09-22 10:11:37 -0600972 if (!strcmp(funcName, "vkCreateImageView"))
973 return (PFN_vkVoidFunction) vkCreateImageView;
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600974 if (!strcmp(funcName, "vkCreateRenderPass"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -0600975 return (PFN_vkVoidFunction) vkCreateRenderPass;
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600976 if (!strcmp(funcName, "vkCmdClearColorImage"))
977 return (PFN_vkVoidFunction) vkCmdClearColorImage;
978 if (!strcmp(funcName, "vkCmdClearDepthStencilImage"))
979 return (PFN_vkVoidFunction) vkCmdClearDepthStencilImage;
Courtney Goeltzenleuchter9feb0732015-10-15 16:51:05 -0600980 if (!strcmp(funcName, "vkCmdClearAttachments"))
981 return (PFN_vkVoidFunction) vkCmdClearAttachments;
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600982 if (!strcmp(funcName, "vkCmdCopyImage"))
983 return (PFN_vkVoidFunction) vkCmdCopyImage;
984 if (!strcmp(funcName, "vkCmdCopyImageToBuffer"))
985 return (PFN_vkVoidFunction) vkCmdCopyImageToBuffer;
986 if (!strcmp(funcName, "vkCmdCopyBufferToImage"))
987 return (PFN_vkVoidFunction) vkCmdCopyBufferToImage;
988 if (!strcmp(funcName, "vkCmdBlitImage"))
989 return (PFN_vkVoidFunction) vkCmdBlitImage;
990 if (!strcmp(funcName, "vkCmdResolveImage"))
991 return (PFN_vkVoidFunction) vkCmdResolveImage;
992 if (!strcmp(funcName, "vkGetImageSubresourceLayout"))
993 return (PFN_vkVoidFunction) vkGetImageSubresourceLayout;
Tobin Ehlis049f1782015-10-29 14:19:18 -0600994
995 VkLayerDispatchTable* pTable = my_data->device_dispatch_table;
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600996 {
Tobin Ehlis049f1782015-10-29 14:19:18 -0600997 if (pTable->GetDeviceProcAddr == NULL)
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600998 return NULL;
Tobin Ehlis049f1782015-10-29 14:19:18 -0600999 return pTable->GetDeviceProcAddr(device, funcName);
Jeremy Hayesb707aa52015-06-18 10:12:39 -06001000 }
1001}
1002
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06001003VK_LAYER_EXPORT PFN_vkVoidFunction VKAPI vkGetInstanceProcAddr(VkInstance instance, const char* funcName)
Jeremy Hayesb707aa52015-06-18 10:12:39 -06001004{
1005 if (instance == NULL) {
1006 return NULL;
1007 }
1008
Tobin Ehlis049f1782015-10-29 14:19:18 -06001009 layer_data *my_data;
Mark Lobodzinskib4092de2015-10-23 14:20:31 -06001010 // loader uses this to force layer initialization; instance object is wrapped
Jeremy Hayesb707aa52015-06-18 10:12:39 -06001011 if (!strcmp(funcName, "vkGetInstanceProcAddr")) {
Tobin Ehlis049f1782015-10-29 14:19:18 -06001012 VkBaseLayerObject* wrapped_inst = (VkBaseLayerObject*) instance;
1013 my_data = get_my_data_ptr(get_dispatch_key(wrapped_inst->baseObject), layer_data_map);
1014 my_data->instance_dispatch_table = new VkLayerInstanceDispatchTable;
1015 layer_init_instance_dispatch_table(my_data->instance_dispatch_table, wrapped_inst);
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06001016 return (PFN_vkVoidFunction) vkGetInstanceProcAddr;
Jeremy Hayesb707aa52015-06-18 10:12:39 -06001017 }
1018
Tobin Ehlis049f1782015-10-29 14:19:18 -06001019 my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
Jeremy Hayesb707aa52015-06-18 10:12:39 -06001020 if (!strcmp(funcName, "vkCreateInstance"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06001021 return (PFN_vkVoidFunction) vkCreateInstance;
Jeremy Hayesb707aa52015-06-18 10:12:39 -06001022 if (!strcmp(funcName, "vkDestroyInstance"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06001023 return (PFN_vkVoidFunction) vkDestroyInstance;
Courtney Goeltzenleuchter74c4ce92015-09-14 17:22:16 -06001024 if (!strcmp(funcName, "vkEnumerateInstanceLayerProperties"))
1025 return (PFN_vkVoidFunction) vkEnumerateInstanceLayerProperties;
1026 if (!strcmp(funcName, "vkEnumerateInstanceExtensionProperties"))
1027 return (PFN_vkVoidFunction) vkEnumerateInstanceExtensionProperties;
1028 if (!strcmp(funcName, "vkEnumerateDeviceLayerProperties"))
1029 return (PFN_vkVoidFunction) vkEnumerateDeviceLayerProperties;
1030 if (!strcmp(funcName, "vkEnumerateDeviceExtensionProperties"))
1031 return (PFN_vkVoidFunction) vkEnumerateDeviceExtensionProperties;
Jeremy Hayesb707aa52015-06-18 10:12:39 -06001032
Tobin Ehlis049f1782015-10-29 14:19:18 -06001033 PFN_vkVoidFunction fptr = debug_report_get_instance_proc_addr(my_data->report_data, funcName);
Jeremy Hayesb707aa52015-06-18 10:12:39 -06001034 if(fptr)
1035 return fptr;
1036
1037 {
Tobin Ehlis049f1782015-10-29 14:19:18 -06001038 VkLayerInstanceDispatchTable* pTable = my_data->instance_dispatch_table;
1039 if (pTable->GetInstanceProcAddr == NULL)
Jeremy Hayesb707aa52015-06-18 10:12:39 -06001040 return NULL;
Tobin Ehlis049f1782015-10-29 14:19:18 -06001041 return pTable->GetInstanceProcAddr(instance, funcName);
Jeremy Hayesb707aa52015-06-18 10:12:39 -06001042 }
1043}