blob: 03801636fd9999bb9477a9d5a64bbd80e6865cf2 [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;
Tobin Ehlis049f1782015-10-29 14:19:18 -060053 VkLayerDispatchTable* device_dispatch_table;
54 VkLayerInstanceDispatchTable* instance_dispatch_table;
Chris Forbesd7576302015-06-21 22:55:02 +120055 VkPhysicalDevice physicalDevice;
Chia-I Wue420a332015-10-26 20:04:44 +080056 unordered_map<VkImage, IMAGE_STATE> imageMap;
Cody Northrop73bb6572015-09-28 15:09:32 -060057
58 layer_data() :
59 report_data(nullptr),
Tobin Ehlis049f1782015-10-29 14:19:18 -060060 device_dispatch_table(nullptr),
61 instance_dispatch_table(nullptr),
Cody Northrop73bb6572015-09-28 15:09:32 -060062 physicalDevice(0)
63 {};
64};
Jeremy Hayesb707aa52015-06-18 10:12:39 -060065
Tobin Ehlis65380532015-09-21 15:20:28 -060066static unordered_map<void*, layer_data*> layer_data_map;
Jeremy Hayesb707aa52015-06-18 10:12:39 -060067
68static void InitImage(layer_data *data)
69{
Courtney Goeltzenleuchter9fac1572015-10-05 15:59:11 -060070 VkDbgMsgCallback callback;
Jeremy Hayesb707aa52015-06-18 10:12:39 -060071 uint32_t report_flags = getLayerOptionFlags("ImageReportFlags", 0);
72
73 uint32_t debug_action = 0;
74 getLayerOptionEnum("ImageDebugAction", (uint32_t *) &debug_action);
75 if(debug_action & VK_DBG_LAYER_ACTION_LOG_MSG)
76 {
77 FILE *log_output = NULL;
78 const char* option_str = getLayerOption("ImageLogFilename");
Tobin Ehlisb4b6e7c2015-09-15 09:55:54 -060079 log_output = getLayerLogOutput(option_str, "Image");
Courtney Goeltzenleuchter9fac1572015-10-05 15:59:11 -060080 layer_create_msg_callback(data->report_data, report_flags, log_callback, (void *) log_output, &callback);
81 data->logging_callback.push_back(callback);
82 }
83
84 if (debug_action & VK_DBG_LAYER_ACTION_DEBUG_OUTPUT) {
85 layer_create_msg_callback(data->report_data, report_flags, win32_debug_output_msg, NULL, &callback);
86 data->logging_callback.push_back(callback);
Jeremy Hayesb707aa52015-06-18 10:12:39 -060087 }
88}
89
90VK_LAYER_EXPORT VkResult VKAPI vkDbgCreateMsgCallback(
91 VkInstance instance,
92 VkFlags msgFlags,
93 const PFN_vkDbgMsgCallback pfnMsgCallback,
94 void* pUserData,
95 VkDbgMsgCallback* pMsgCallback)
96{
Tobin Ehlis049f1782015-10-29 14:19:18 -060097 layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
98 VkResult res = my_data->instance_dispatch_table->DbgCreateMsgCallback(instance, msgFlags, pfnMsgCallback, pUserData, pMsgCallback);
Jeremy Hayesb707aa52015-06-18 10:12:39 -060099 if (res == VK_SUCCESS) {
Tobin Ehlis049f1782015-10-29 14:19:18 -0600100 res = layer_create_msg_callback(my_data->report_data, msgFlags, pfnMsgCallback, pUserData, pMsgCallback);
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600101 }
102 return res;
103}
104
105VK_LAYER_EXPORT VkResult VKAPI vkDbgDestroyMsgCallback(
106 VkInstance instance,
107 VkDbgMsgCallback msgCallback)
108{
Tobin Ehlis049f1782015-10-29 14:19:18 -0600109 layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
110 VkResult res = my_data->instance_dispatch_table->DbgDestroyMsgCallback(instance, msgCallback);
111 layer_destroy_msg_callback(my_data->report_data, msgCallback);
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600112 return res;
113}
114
Chia-I Wu1f851912015-10-27 18:04:07 +0800115VK_LAYER_EXPORT VkResult VKAPI vkCreateInstance(const VkInstanceCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkInstance* pInstance)
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600116{
Tobin Ehlis049f1782015-10-29 14:19:18 -0600117 layer_data *my_data = get_my_data_ptr(get_dispatch_key(*pInstance), layer_data_map);
118 VkLayerInstanceDispatchTable *pTable = my_data->instance_dispatch_table;
Chia-I Wu69f40122015-10-26 21:10:41 +0800119 VkResult result = pTable->CreateInstance(pCreateInfo, pAllocator, pInstance);
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600120
121 if (result == VK_SUCCESS) {
Chia-I Wu763a7492015-10-26 20:48:51 +0800122 my_data->report_data = debug_report_create_instance(pTable, *pInstance, pCreateInfo->enabledExtensionNameCount,
Courtney Goeltzenleuchtereb1ddb02015-07-07 11:18:30 -0600123 pCreateInfo->ppEnabledExtensionNames);
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600124
Tobin Ehlis049f1782015-10-29 14:19:18 -0600125 InitImage(my_data);
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600126 }
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600127 return result;
128}
129
Chia-I Wu1f851912015-10-27 18:04:07 +0800130VK_LAYER_EXPORT void VKAPI vkDestroyInstance(VkInstance instance, const VkAllocationCallbacks* pAllocator)
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600131{
132 // Grab the key before the instance is destroyed.
133 dispatch_key key = get_dispatch_key(instance);
Tobin Ehlis049f1782015-10-29 14:19:18 -0600134 layer_data *my_data = get_my_data_ptr(key, layer_data_map);
135 VkLayerInstanceDispatchTable *pTable = my_data->instance_dispatch_table;
Chia-I Wu69f40122015-10-26 21:10:41 +0800136 pTable->DestroyInstance(instance, pAllocator);
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600137
138 // Clean up logging callback, if any
Courtney Goeltzenleuchter9fac1572015-10-05 15:59:11 -0600139 while (my_data->logging_callback.size() > 0) {
140 VkDbgMsgCallback callback = my_data->logging_callback.back();
141 layer_destroy_msg_callback(my_data->report_data, callback);
142 my_data->logging_callback.pop_back();
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600143 }
144
Tobin Ehlis049f1782015-10-29 14:19:18 -0600145 layer_debug_report_destroy_instance(my_data->report_data);
146 delete my_data->instance_dispatch_table;
147 layer_data_map.erase(key);
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600148
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600149}
150
Chia-I Wu1f851912015-10-27 18:04:07 +0800151VK_LAYER_EXPORT VkResult VKAPI vkCreateDevice(VkPhysicalDevice physicalDevice, const VkDeviceCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDevice* pDevice)
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600152{
Tobin Ehlis049f1782015-10-29 14:19:18 -0600153 layer_data *instance_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);
154 layer_data *device_data = get_my_data_ptr(get_dispatch_key(*pDevice), layer_data_map);
Chia-I Wu69f40122015-10-26 21:10:41 +0800155 VkResult result = device_data->device_dispatch_table->CreateDevice(physicalDevice, pCreateInfo, pAllocator, pDevice);
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600156 if(result == VK_SUCCESS)
157 {
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600158 device_data->report_data = layer_debug_report_create_device(instance_data->report_data, *pDevice);
Chris Forbesd7576302015-06-21 22:55:02 +1200159 device_data->physicalDevice = physicalDevice;
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600160 }
161
162 return result;
163}
164
Chia-I Wu1f851912015-10-27 18:04:07 +0800165VK_LAYER_EXPORT void VKAPI vkDestroyDevice(VkDevice device, const VkAllocationCallbacks* pAllocator)
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600166{
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600167 dispatch_key key = get_dispatch_key(device);
Tobin Ehlis049f1782015-10-29 14:19:18 -0600168 layer_data *my_data = get_my_data_ptr(key, layer_data_map);
Chia-I Wu69f40122015-10-26 21:10:41 +0800169 my_data->device_dispatch_table->DestroyDevice(device, pAllocator);
Tobin Ehlis049f1782015-10-29 14:19:18 -0600170 delete my_data->device_dispatch_table;
171 layer_data_map.erase(key);
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600172}
173
Courtney Goeltzenleuchtereb1ddb02015-07-07 11:18:30 -0600174static const VkLayerProperties pc_global_layers[] = {
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600175 {
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600176 "Image",
Courtney Goeltzenleuchtereb1ddb02015-07-07 11:18:30 -0600177 VK_API_VERSION,
178 VK_MAKE_VERSION(0, 1, 0),
179 "Validation layer: Image ParamChecker",
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600180 }
181};
182
Courtney Goeltzenleuchter74c4ce92015-09-14 17:22:16 -0600183VK_LAYER_EXPORT VkResult VKAPI vkEnumerateInstanceExtensionProperties(
Courtney Goeltzenleuchtereb1ddb02015-07-07 11:18:30 -0600184 const char *pLayerName,
185 uint32_t *pCount,
186 VkExtensionProperties* pProperties)
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600187{
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600188 // ParamChecker does not have any global extensions
Courtney Goeltzenleuchtereb1ddb02015-07-07 11:18:30 -0600189 return util_GetExtensionProperties(0, NULL, pCount, pProperties);
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600190}
191
Courtney Goeltzenleuchter74c4ce92015-09-14 17:22:16 -0600192VK_LAYER_EXPORT VkResult VKAPI vkEnumerateInstanceLayerProperties(
Courtney Goeltzenleuchtereb1ddb02015-07-07 11:18:30 -0600193 uint32_t *pCount,
194 VkLayerProperties* pProperties)
Tony Barbour426b9052015-06-24 16:06:58 -0600195{
Courtney Goeltzenleuchtereb1ddb02015-07-07 11:18:30 -0600196 return util_GetLayerProperties(ARRAY_SIZE(pc_global_layers),
197 pc_global_layers,
198 pCount, pProperties);
Tony Barbour426b9052015-06-24 16:06:58 -0600199}
200
Courtney Goeltzenleuchter74c4ce92015-09-14 17:22:16 -0600201VK_LAYER_EXPORT VkResult VKAPI vkEnumerateDeviceExtensionProperties(
Courtney Goeltzenleuchtereb1ddb02015-07-07 11:18:30 -0600202 VkPhysicalDevice physicalDevice,
203 const char* pLayerName,
204 uint32_t* pCount,
205 VkExtensionProperties* pProperties)
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600206{
Jon Ashburnaff81ff2015-11-02 17:37:20 -0700207 // Image does not have any physical device extensions
208 if (pLayerName == NULL) {
209 dispatch_key key = get_dispatch_key(physicalDevice);
210 layer_data *my_data = get_my_data_ptr(key, layer_data_map);
211 VkLayerInstanceDispatchTable *pTable = my_data->instance_dispatch_table;
212 return pTable->EnumerateDeviceExtensionProperties(
213 physicalDevice,
214 NULL,
215 pCount,
216 pProperties);
217 } else {
218 return util_GetExtensionProperties(0, NULL, pCount, pProperties);
219 }
Courtney Goeltzenleuchtereb1ddb02015-07-07 11:18:30 -0600220}
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600221
Courtney Goeltzenleuchter74c4ce92015-09-14 17:22:16 -0600222VK_LAYER_EXPORT VkResult VKAPI vkEnumerateDeviceLayerProperties(
Courtney Goeltzenleuchtereb1ddb02015-07-07 11:18:30 -0600223 VkPhysicalDevice physicalDevice,
224 uint32_t* pCount,
225 VkLayerProperties* pProperties)
226{
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600227 // ParamChecker's physical device layers are the same as global
Courtney Goeltzenleuchtereb1ddb02015-07-07 11:18:30 -0600228 return util_GetLayerProperties(ARRAY_SIZE(pc_global_layers), pc_global_layers,
229 pCount, pProperties);
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600230}
231
Mark Lobodzinski9cce7832015-07-29 09:21:22 -0600232// Start of the Image layer proper
233
234// Returns TRUE if a format is a depth-compatible format
235bool is_depth_format(VkFormat format)
236{
237 bool result = VK_FALSE;
238 switch (format) {
239 case VK_FORMAT_D16_UNORM:
Courtney Goeltzenleuchter7ed10592015-09-10 17:17:43 -0600240 case VK_FORMAT_D24_UNORM_X8:
Mark Lobodzinski9cce7832015-07-29 09:21:22 -0600241 case VK_FORMAT_D32_SFLOAT:
242 case VK_FORMAT_S8_UINT:
243 case VK_FORMAT_D16_UNORM_S8_UINT:
244 case VK_FORMAT_D24_UNORM_S8_UINT:
245 case VK_FORMAT_D32_SFLOAT_S8_UINT:
246 result = VK_TRUE;
247 break;
248 default:
249 break;
250 }
251 return result;
252}
253
Chia-I Wu1f851912015-10-27 18:04:07 +0800254VK_LAYER_EXPORT VkResult VKAPI vkCreateImage(VkDevice device, const VkImageCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkImage* pImage)
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600255{
Tobin Ehlis35613802015-09-22 08:40:52 -0600256 VkBool32 skipCall = VK_FALSE;
Tobin Ehlis65380532015-09-21 15:20:28 -0600257 layer_data *device_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600258 if(pCreateInfo->format != VK_FORMAT_UNDEFINED)
259 {
260 VkFormatProperties properties;
Tobin Ehlis049f1782015-10-29 14:19:18 -0600261 get_my_data_ptr(get_dispatch_key(device_data->physicalDevice), layer_data_map)->instance_dispatch_table->GetPhysicalDeviceFormatProperties(
Chris Forbesd7576302015-06-21 22:55:02 +1200262 device_data->physicalDevice, pCreateInfo->format, &properties);
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600263
264 if((properties.linearTilingFeatures) == 0 && (properties.optimalTilingFeatures == 0))
265 {
266 char const str[] = "vkCreateImage parameter, VkFormat pCreateInfo->format, contains unsupported format";
Tobin Ehlis35613802015-09-22 08:40:52 -0600267 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 -0600268 }
269 }
Tobin Ehlis35613802015-09-22 08:40:52 -0600270 if (skipCall)
271 return VK_ERROR_VALIDATION_FAILED;
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600272
Chia-I Wu69f40122015-10-26 21:10:41 +0800273 VkResult result = device_data->device_dispatch_table->CreateImage(device, pCreateInfo, pAllocator, pImage);
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600274
Tobin Ehlis65380532015-09-21 15:20:28 -0600275 if(result == VK_SUCCESS) {
Chia-I Wue420a332015-10-26 20:04:44 +0800276 device_data->imageMap[*pImage] = IMAGE_STATE(pCreateInfo);
Tobin Ehlis65380532015-09-21 15:20:28 -0600277 }
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600278 return result;
279}
280
Chia-I Wu1f851912015-10-27 18:04:07 +0800281VK_LAYER_EXPORT void VKAPI vkDestroyImage(VkDevice device, VkImage image, const VkAllocationCallbacks* pAllocator)
Tobin Ehlis65380532015-09-21 15:20:28 -0600282{
283 layer_data *device_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
Chia-I Wue420a332015-10-26 20:04:44 +0800284 device_data->imageMap.erase(image);
Chia-I Wu69f40122015-10-26 21:10:41 +0800285 device_data->device_dispatch_table->DestroyImage(device, image, pAllocator);
Tobin Ehlis65380532015-09-21 15:20:28 -0600286}
287
Chia-I Wu1f851912015-10-27 18:04:07 +0800288VK_LAYER_EXPORT VkResult VKAPI vkCreateRenderPass(VkDevice device, const VkRenderPassCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkRenderPass* pRenderPass)
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600289{
Tobin Ehlis049f1782015-10-29 14:19:18 -0600290 layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
Tobin Ehlis35613802015-09-22 08:40:52 -0600291 VkBool32 skipCall = VK_FALSE;
Chia-I Wuc278df82015-07-07 11:50:03 +0800292 for(uint32_t i = 0; i < pCreateInfo->attachmentCount; ++i)
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600293 {
Chia-I Wuc278df82015-07-07 11:50:03 +0800294 if(pCreateInfo->pAttachments[i].format != VK_FORMAT_UNDEFINED)
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600295 {
296 VkFormatProperties properties;
Tobin Ehlis049f1782015-10-29 14:19:18 -0600297 get_my_data_ptr(get_dispatch_key(my_data->physicalDevice), layer_data_map)->instance_dispatch_table->GetPhysicalDeviceFormatProperties(
298 my_data->physicalDevice, pCreateInfo->pAttachments[i].format, &properties);
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600299
300 if((properties.linearTilingFeatures) == 0 && (properties.optimalTilingFeatures == 0))
301 {
302 std::stringstream ss;
Chia-I Wuc278df82015-07-07 11:50:03 +0800303 ss << "vkCreateRenderPass parameter, VkFormat in pCreateInfo->pAttachments[" << i << "], contains unsupported format";
Tobin Ehlis049f1782015-10-29 14:19:18 -0600304 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 -0600305 }
306 }
307 }
308
Chia-I Wuc278df82015-07-07 11:50:03 +0800309 for(uint32_t i = 0; i < pCreateInfo->attachmentCount; ++i)
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600310 {
Chia-I Wuc278df82015-07-07 11:50:03 +0800311 if(!validate_VkImageLayout(pCreateInfo->pAttachments[i].initialLayout) ||
312 !validate_VkImageLayout(pCreateInfo->pAttachments[i].finalLayout))
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600313 {
314 std::stringstream ss;
Chia-I Wuc278df82015-07-07 11:50:03 +0800315 ss << "vkCreateRenderPass parameter, VkImageLayout in pCreateInfo->pAttachments[" << i << "], is unrecognized";
Tobin Ehlis049f1782015-10-29 14:19:18 -0600316 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 -0600317 }
318 }
319
Chia-I Wuc278df82015-07-07 11:50:03 +0800320 for(uint32_t i = 0; i < pCreateInfo->attachmentCount; ++i)
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600321 {
Chia-I Wuc278df82015-07-07 11:50:03 +0800322 if(!validate_VkAttachmentLoadOp(pCreateInfo->pAttachments[i].loadOp))
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600323 {
324 std::stringstream ss;
Chia-I Wuc278df82015-07-07 11:50:03 +0800325 ss << "vkCreateRenderPass parameter, VkAttachmentLoadOp in pCreateInfo->pAttachments[" << i << "], is unrecognized";
Tobin Ehlis049f1782015-10-29 14:19:18 -0600326 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 -0600327 }
328 }
329
Chia-I Wuc278df82015-07-07 11:50:03 +0800330 for(uint32_t i = 0; i < pCreateInfo->attachmentCount; ++i)
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600331 {
Chia-I Wuc278df82015-07-07 11:50:03 +0800332 if(!validate_VkAttachmentStoreOp(pCreateInfo->pAttachments[i].storeOp))
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600333 {
334 std::stringstream ss;
Chia-I Wuc278df82015-07-07 11:50:03 +0800335 ss << "vkCreateRenderPass parameter, VkAttachmentStoreOp in pCreateInfo->pAttachments[" << i << "], is unrecognized";
Tobin Ehlis049f1782015-10-29 14:19:18 -0600336 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 -0600337 }
338 }
339
Mark Lobodzinski9cce7832015-07-29 09:21:22 -0600340 // Any depth buffers specified as attachments?
341 bool depthFormatPresent = VK_FALSE;
342 for (uint32_t i = 0; i < pCreateInfo->attachmentCount; ++i)
343 {
344 depthFormatPresent |= is_depth_format(pCreateInfo->pAttachments[i].format);
345 }
346
347 if (depthFormatPresent == VK_FALSE) {
348 // No depth attachment is present, validate that subpasses set depthStencilAttachment to VK_ATTACHMENT_UNUSED;
349 for (uint32_t i = 0; i < pCreateInfo->subpassCount; i++) {
Chia-I Wuce532f72015-10-26 17:32:47 +0800350 if (pCreateInfo->pSubpasses[i].pDepthStencilAttachment &&
351 pCreateInfo->pSubpasses[i].pDepthStencilAttachment->attachment != VK_ATTACHMENT_UNUSED) {
Mark Lobodzinski9cce7832015-07-29 09:21:22 -0600352 std::stringstream ss;
353 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 -0600354 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 -0600355 }
356 }
357 }
Tobin Ehlis35613802015-09-22 08:40:52 -0600358 if (skipCall)
359 return VK_ERROR_VALIDATION_FAILED;
Mark Lobodzinski9cce7832015-07-29 09:21:22 -0600360
Chia-I Wu69f40122015-10-26 21:10:41 +0800361 VkResult result = my_data->device_dispatch_table->CreateRenderPass(device, pCreateInfo, pAllocator, pRenderPass);
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600362
363 return result;
364}
365
Chia-I Wu1f851912015-10-27 18:04:07 +0800366VK_LAYER_EXPORT VkResult VKAPI vkCreateImageView(VkDevice device, const VkImageViewCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkImageView* pView)
Tobin Ehlis65380532015-09-21 15:20:28 -0600367{
368 VkBool32 skipCall = VK_FALSE;
369 layer_data *device_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
Chia-I Wue420a332015-10-26 20:04:44 +0800370 auto imageEntry = device_data->imageMap.find(pCreateInfo->image);
Tobin Ehlis65380532015-09-21 15:20:28 -0600371 if (imageEntry != device_data->imageMap.end()) {
Tobin Ehlis6fa437d2015-09-25 14:49:43 -0600372 if (pCreateInfo->subresourceRange.baseMipLevel >= imageEntry->second.mipLevels) {
Tobin Ehlis65380532015-09-21 15:20:28 -0600373 std::stringstream ss;
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600374 ss << "vkCreateImageView called with baseMipLevel " << pCreateInfo->subresourceRange.baseMipLevel
Chia-I Wue420a332015-10-26 20:04:44 +0800375 << " for image " << pCreateInfo->image << " that only has " << imageEntry->second.mipLevels << " mip levels.";
Tobin Ehlis65380532015-09-21 15:20:28 -0600376 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());
377 }
Tobin Ehlis6fa437d2015-09-25 14:49:43 -0600378 if (pCreateInfo->subresourceRange.baseArrayLayer >= imageEntry->second.arraySize) {
Tobin Ehlis65380532015-09-21 15:20:28 -0600379 std::stringstream ss;
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600380 ss << "vkCreateImageView called with baseArrayLayer " << pCreateInfo->subresourceRange.baseArrayLayer << " for image "
Chia-I Wue420a332015-10-26 20:04:44 +0800381 << pCreateInfo->image << " that only has " << imageEntry->second.arraySize << " mip levels.";
Tobin Ehlis65380532015-09-21 15:20:28 -0600382 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());
383 }
Chia-I Wu1f851912015-10-27 18:04:07 +0800384 if (!pCreateInfo->subresourceRange.levelCount) {
Tobin Ehlis65380532015-09-21 15:20:28 -0600385 std::stringstream ss;
386 ss << "vkCreateImageView called with 0 in pCreateInfo->subresourceRange.mipLevels.";
387 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());
388 }
Chia-I Wu1f851912015-10-27 18:04:07 +0800389 if (!pCreateInfo->subresourceRange.layerCount) {
Tobin Ehlis65380532015-09-21 15:20:28 -0600390 std::stringstream ss;
391 ss << "vkCreateImageView called with 0 in pCreateInfo->subresourceRange.arraySize.";
392 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());
393 }
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600394
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600395 // Validate correct image aspect bits for desired formats and format consistency
Tobin Ehlis6fa437d2015-09-25 14:49:43 -0600396 VkFormat imageFormat = imageEntry->second.format;
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600397 VkFormat ivciFormat = pCreateInfo->format;
398 VkImageAspectFlags aspectMask = pCreateInfo->subresourceRange.aspectMask;
399
400 if (vk_format_is_color(imageFormat)) {
401 if ((aspectMask & VK_IMAGE_ASPECT_COLOR_BIT) != VK_IMAGE_ASPECT_COLOR_BIT) {
402 std::stringstream ss;
403 ss << "vkCreateImageView: Color image formats must have the VK_IMAGE_ASPECT_COLOR_BIT set";
404 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_IMAGE,
Chia-I Wue420a332015-10-26 20:04:44 +0800405 (uint64_t)pCreateInfo->image, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", ss.str().c_str());
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600406 }
407 if ((aspectMask & VK_IMAGE_ASPECT_COLOR_BIT) != aspectMask) {
408 std::stringstream ss;
409 ss << "vkCreateImageView: Color image formats must have ONLY the VK_IMAGE_ASPECT_COLOR_BIT set";
410 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_IMAGE,
Chia-I Wue420a332015-10-26 20:04:44 +0800411 (uint64_t)pCreateInfo->image, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", ss.str().c_str());
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600412 }
413 if (VK_FALSE == vk_format_is_color(ivciFormat)) {
414 std::stringstream ss;
415 ss << "vkCreateImageView: The image view's format can differ from the parent image's format, but both must be "
416 << "color formats. ImageFormat is " << string_VkFormat(imageFormat) << " ImageViewFormat is " << string_VkFormat(ivciFormat);
417 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_IMAGE,
Chia-I Wue420a332015-10-26 20:04:44 +0800418 (uint64_t)pCreateInfo->image, 0, IMAGE_INVALID_FORMAT, "IMAGE", ss.str().c_str());
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600419 }
420 // TODO: Uncompressed formats are compatible if they occupy they same number of bits per pixel.
421 // Compressed formats are compatible if the only difference between them is the numerical type of
422 // the uncompressed pixels (e.g. signed vs. unsigned, or sRGB vs. UNORM encoding).
423 } else if (vk_format_is_depth_and_stencil(imageFormat)) {
424 if ((aspectMask & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) !=
425 (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) {
426 std::stringstream ss;
427 ss << "vkCreateImageView: Combination depth/stencil image formats must have both VK_IMAGE_ASPECT_DEPTH_BIT and VK_IMAGE_ASPECT_STENCIL_BIT set";
428 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_IMAGE,
Chia-I Wue420a332015-10-26 20:04:44 +0800429 (uint64_t)pCreateInfo->image, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", ss.str().c_str());
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600430 }
431 if ((aspectMask & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) != aspectMask) {
432 std::stringstream ss;
433 ss << "vkCreateImageView: Combination depth/stencil image formats can have only the VK_IMAGE_ASPECT_DEPTH_BIT and VK_IMAGE_ASPECT_STENCIL_BIT set";
434 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_IMAGE,
Chia-I Wue420a332015-10-26 20:04:44 +0800435 (uint64_t)pCreateInfo->image, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", ss.str().c_str());
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600436 }
437 } else if (vk_format_is_depth_only(imageFormat)) {
438 if ((aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT) != VK_IMAGE_ASPECT_DEPTH_BIT) {
439 std::stringstream ss;
440 ss << "vkCreateImageView: Depth-only image formats must have the VK_IMAGE_ASPECT_DEPTH_BIT set";
441 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_IMAGE,
Chia-I Wue420a332015-10-26 20:04:44 +0800442 (uint64_t)pCreateInfo->image, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", ss.str().c_str());
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600443 }
444 if ((aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT) != aspectMask) {
445 std::stringstream ss;
446 ss << "vkCreateImageView: Depth-only image formats can have only the VK_IMAGE_ASPECT_DEPTH_BIT set";
447 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_IMAGE,
Chia-I Wue420a332015-10-26 20:04:44 +0800448 (uint64_t)pCreateInfo->image, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", ss.str().c_str());
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600449 }
450 } else if (vk_format_is_stencil_only(imageFormat)) {
451 if ((aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT) != VK_IMAGE_ASPECT_STENCIL_BIT) {
452 std::stringstream ss;
453 ss << "vkCreateImageView: Stencil-only image formats must have the VK_IMAGE_ASPECT_STENCIL_BIT set";
454 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_IMAGE,
Chia-I Wue420a332015-10-26 20:04:44 +0800455 (uint64_t)pCreateInfo->image, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", ss.str().c_str());
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600456 }
457 if ((aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT) != aspectMask) {
458 std::stringstream ss;
459 ss << "vkCreateImageView: Stencil-only image formats can have only the VK_IMAGE_ASPECT_STENCIL_BIT set";
460 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_IMAGE,
Chia-I Wue420a332015-10-26 20:04:44 +0800461 (uint64_t)pCreateInfo->image, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", ss.str().c_str());
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600462 }
463 }
464 }
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600465
Tobin Ehlis65380532015-09-21 15:20:28 -0600466 if (skipCall)
467 return VK_ERROR_VALIDATION_FAILED;
Tobin Ehlis35613802015-09-22 08:40:52 -0600468
Chia-I Wu69f40122015-10-26 21:10:41 +0800469 VkResult result = device_data->device_dispatch_table->CreateImageView(device, pCreateInfo, pAllocator, pView);
Tobin Ehlis65380532015-09-21 15:20:28 -0600470 return result;
471}
472
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600473VK_LAYER_EXPORT void VKAPI vkCmdClearColorImage(
Chia-I Wu1f851912015-10-27 18:04:07 +0800474 VkCommandBuffer commandBuffer,
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600475 VkImage image,
476 VkImageLayout imageLayout,
477 const VkClearColorValue *pColor,
478 uint32_t rangeCount,
479 const VkImageSubresourceRange *pRanges)
480{
481 VkBool32 skipCall = VK_FALSE;
Chia-I Wu1f851912015-10-27 18:04:07 +0800482 layer_data *device_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600483 // For each range, image aspect must be color only
484 for (uint32_t i = 0; i < rangeCount; i++) {
485 if (pRanges[i].aspectMask != VK_IMAGE_ASPECT_COLOR_BIT) {
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600486 char const str[] = "vkCmdClearColorImage aspectMasks for all subresource ranges must be set to VK_IMAGE_ASPECT_COLOR_BIT";
487 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 +0800488 (uint64_t)commandBuffer, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", str);
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600489 }
490 }
491
492 if (VK_FALSE == skipCall) {
Chia-I Wu1f851912015-10-27 18:04:07 +0800493 device_data->device_dispatch_table->CmdClearColorImage(commandBuffer, image, imageLayout,
494 pColor, rangeCount, pRanges);
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600495 }
496}
497
498VK_LAYER_EXPORT void VKAPI vkCmdClearDepthStencilImage(
Chia-I Wu1f851912015-10-27 18:04:07 +0800499 VkCommandBuffer commandBuffer,
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600500 VkImage image,
501 VkImageLayout imageLayout,
502 const VkClearDepthStencilValue *pDepthStencil,
503 uint32_t rangeCount,
504 const VkImageSubresourceRange *pRanges)
505{
506 VkBool32 skipCall = VK_FALSE;
Chia-I Wu1f851912015-10-27 18:04:07 +0800507 layer_data *device_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600508 // For each range, Image aspect must be depth or stencil or both
509 for (uint32_t i = 0; i < rangeCount; i++) {
510 if (((pRanges[i].aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT) != VK_IMAGE_ASPECT_DEPTH_BIT) &&
511 ((pRanges[i].aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT) != VK_IMAGE_ASPECT_STENCIL_BIT))
512 {
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600513 char const str[] = "vkCmdClearDepthStencilImage aspectMasks for all subresource ranges must be "
514 "set to VK_IMAGE_ASPECT_DEPTH_BIT and/or VK_IMAGE_ASPECT_STENCIL_BIT";
515 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 +0800516 (uint64_t)commandBuffer, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", str);
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600517 }
518 }
519
520 if (VK_FALSE == skipCall) {
Chia-I Wu1f851912015-10-27 18:04:07 +0800521 device_data->device_dispatch_table->CmdClearDepthStencilImage(commandBuffer,
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600522 image, imageLayout, pDepthStencil, rangeCount, pRanges);
523 }
524}
525
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600526VK_LAYER_EXPORT void VKAPI vkCmdCopyImage(
Chia-I Wu1f851912015-10-27 18:04:07 +0800527 VkCommandBuffer commandBuffer,
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600528 VkImage srcImage,
529 VkImageLayout srcImageLayout,
Chia-I Wu1f851912015-10-27 18:04:07 +0800530 VkImage dstImage,
531 VkImageLayout dstImageLayout,
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600532 uint32_t regionCount,
533 const VkImageCopy *pRegions)
534{
535 VkBool32 skipCall = VK_FALSE;
Chia-I Wu1f851912015-10-27 18:04:07 +0800536 layer_data *device_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
Chia-I Wue420a332015-10-26 20:04:44 +0800537 auto srcImageEntry = device_data->imageMap.find(srcImage);
Chia-I Wu1f851912015-10-27 18:04:07 +0800538 auto dstImageEntry = device_data->imageMap.find(dstImage);
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600539
Jeremy Hayesac8ed0b2015-10-28 13:01:39 -0600540 // For each region, src and dst number of layers should not be zero
541 // For each region, src and dst number of layers must match
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600542 // For each region, src aspect mask must match dest aspect mask
543 // For each region, color aspects cannot be mixed with depth/stencil aspects
544 for (uint32_t i = 0; i < regionCount; i++) {
Chia-I Wu1f851912015-10-27 18:04:07 +0800545 if(pRegions[i].srcSubresource.layerCount == 0)
Jeremy Hayesac8ed0b2015-10-28 13:01:39 -0600546 {
547 char const str[] = "vkCmdCopyImage: number of layers in source subresource is zero";
548 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 +0800549 (uint64_t)commandBuffer, 0, IMAGE_MISMATCHED_IMAGE_ASPECT, "IMAGE", str);
Jeremy Hayesac8ed0b2015-10-28 13:01:39 -0600550 }
551
Chia-I Wu1f851912015-10-27 18:04:07 +0800552 if(pRegions[i].dstSubresource.layerCount == 0)
Jeremy Hayesac8ed0b2015-10-28 13:01:39 -0600553 {
554 char const str[] = "vkCmdCopyImage: number of layers in destination subresource is zero";
555 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 +0800556 (uint64_t)commandBuffer, 0, IMAGE_MISMATCHED_IMAGE_ASPECT, "IMAGE", str);
Jeremy Hayesac8ed0b2015-10-28 13:01:39 -0600557 }
558
Chia-I Wu1f851912015-10-27 18:04:07 +0800559 if(pRegions[i].srcSubresource.layerCount != pRegions[i].dstSubresource.layerCount)
Jeremy Hayesac8ed0b2015-10-28 13:01:39 -0600560 {
561 char const str[] = "vkCmdCopyImage: number of layers in source and destination subresources must match";
562 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 +0800563 (uint64_t)commandBuffer, 0, IMAGE_MISMATCHED_IMAGE_ASPECT, "IMAGE", str);
Jeremy Hayesac8ed0b2015-10-28 13:01:39 -0600564 }
565
Chia-I Wu4291d882015-10-27 19:00:15 +0800566 if (pRegions[i].srcSubresource.aspectMask != pRegions[i].dstSubresource.aspectMask) {
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600567 char const str[] = "vkCmdCopyImage: Src and dest aspectMasks for each region must match";
568 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 +0800569 (uint64_t)commandBuffer, 0, IMAGE_MISMATCHED_IMAGE_ASPECT, "IMAGE", str);
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600570 }
Chia-I Wu4291d882015-10-27 19:00:15 +0800571 if ((pRegions[i].srcSubresource.aspectMask & VK_IMAGE_ASPECT_COLOR_BIT) &&
572 (pRegions[i].srcSubresource.aspectMask & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT))) {
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600573 char const str[] = "vkCmdCopyImage aspectMask cannot specify both COLOR and DEPTH/STENCIL aspects";
574 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 +0800575 (uint64_t)commandBuffer, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", str);
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600576 }
577 }
578
Mike Stroyan43909d82015-09-25 13:39:21 -0600579 if ((srcImageEntry != device_data->imageMap.end())
Chia-I Wu1f851912015-10-27 18:04:07 +0800580 && (dstImageEntry != device_data->imageMap.end())) {
581 if (srcImageEntry->second.imageType != dstImageEntry->second.imageType) {
Mike Stroyan43909d82015-09-25 13:39:21 -0600582 char const str[] = "vkCmdCopyImage called with unmatched source and dest image types.";
583 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 +0800584 (uint64_t)commandBuffer, 0, IMAGE_MISMATCHED_IMAGE_TYPE, "IMAGE", str);
Mike Stroyan43909d82015-09-25 13:39:21 -0600585 }
586 // Check that format is same size or exact stencil/depth
Tobin Ehlis6fa437d2015-09-25 14:49:43 -0600587 if (is_depth_format(srcImageEntry->second.format)) {
Chia-I Wu1f851912015-10-27 18:04:07 +0800588 if (srcImageEntry->second.format != dstImageEntry->second.format) {
Mike Stroyan43909d82015-09-25 13:39:21 -0600589 char const str[] = "vkCmdCopyImage called with unmatched source and dest image depth/stencil formats.";
590 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 +0800591 (uint64_t)commandBuffer, 0, IMAGE_MISMATCHED_IMAGE_FORMAT, "IMAGE", str);
Mike Stroyan43909d82015-09-25 13:39:21 -0600592 }
593 } else {
Tobin Ehlis6fa437d2015-09-25 14:49:43 -0600594 size_t srcSize = vk_format_get_size(srcImageEntry->second.format);
Chia-I Wu1f851912015-10-27 18:04:07 +0800595 size_t destSize = vk_format_get_size(dstImageEntry->second.format);
Mike Stroyan43909d82015-09-25 13:39:21 -0600596 if (srcSize != destSize) {
597 char const str[] = "vkCmdCopyImage called with unmatched source and dest image format sizes.";
598 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 +0800599 (uint64_t)commandBuffer, 0, IMAGE_MISMATCHED_IMAGE_FORMAT, "IMAGE", str);
Mike Stroyan43909d82015-09-25 13:39:21 -0600600 }
601 }
602 }
603
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600604 if (VK_FALSE == skipCall) {
Chia-I Wu1f851912015-10-27 18:04:07 +0800605 device_data->device_dispatch_table->CmdCopyImage(commandBuffer, srcImage,
606 srcImageLayout, dstImage, dstImageLayout, regionCount, pRegions);
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600607 }
608}
609
Courtney Goeltzenleuchter9feb0732015-10-15 16:51:05 -0600610void VKAPI vkCmdClearAttachments(
Chia-I Wu1f851912015-10-27 18:04:07 +0800611 VkCommandBuffer commandBuffer,
Courtney Goeltzenleuchter9feb0732015-10-15 16:51:05 -0600612 uint32_t attachmentCount,
613 const VkClearAttachment* pAttachments,
614 uint32_t rectCount,
Courtney Goeltzenleuchtera12e2912015-10-15 18:22:08 -0600615 const VkClearRect* pRects)
Courtney Goeltzenleuchter9feb0732015-10-15 16:51:05 -0600616{
617 VkBool32 skipCall = VK_FALSE;
618 VkImageAspectFlags aspectMask;
Chia-I Wu1f851912015-10-27 18:04:07 +0800619 layer_data *device_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
Courtney Goeltzenleuchter9feb0732015-10-15 16:51:05 -0600620 for (uint32_t i = 0; i < attachmentCount; i++) {
621 aspectMask = pAttachments[i].aspectMask;
622 if (aspectMask & VK_IMAGE_ASPECT_COLOR_BIT) {
623 if (aspectMask != VK_IMAGE_ASPECT_COLOR_BIT) {
624 // VK_IMAGE_ASPECT_COLOR_BIT is not the only bit set for this attachment
Courtney Goeltzenleuchter9feb0732015-10-15 16:51:05 -0600625 char const str[] = "vkCmdClearAttachments aspectMask [%d] must set only VK_IMAGE_ASPECT_COLOR_BIT of a color attachment.";
626 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 +0800627 (uint64_t)commandBuffer, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", str, i);
Courtney Goeltzenleuchter9feb0732015-10-15 16:51:05 -0600628 }
629 } else {
630 // Image aspect must be depth or stencil or both
631 if (((aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT) != VK_IMAGE_ASPECT_DEPTH_BIT) &&
632 ((aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT) != VK_IMAGE_ASPECT_STENCIL_BIT))
633 {
Courtney Goeltzenleuchter9feb0732015-10-15 16:51:05 -0600634 char const str[] = "vkCmdClearAttachments aspectMask [%d] must be set to VK_IMAGE_ASPECT_DEPTH_BIT and/or VK_IMAGE_ASPECT_STENCIL_BIT";
635 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 +0800636 (uint64_t)commandBuffer, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", str, i);
Courtney Goeltzenleuchter9feb0732015-10-15 16:51:05 -0600637 }
638 }
639 }
640
641 if (VK_FALSE == skipCall) {
Chia-I Wu1f851912015-10-27 18:04:07 +0800642 device_data->device_dispatch_table->CmdClearAttachments(commandBuffer,
Courtney Goeltzenleuchter9feb0732015-10-15 16:51:05 -0600643 attachmentCount, pAttachments, rectCount, pRects);
644 }
645}
646
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600647VK_LAYER_EXPORT void VKAPI vkCmdCopyImageToBuffer(
Chia-I Wu1f851912015-10-27 18:04:07 +0800648 VkCommandBuffer commandBuffer,
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600649 VkImage srcImage,
650 VkImageLayout srcImageLayout,
Chia-I Wu1f851912015-10-27 18:04:07 +0800651 VkBuffer dstBuffer,
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600652 uint32_t regionCount,
653 const VkBufferImageCopy *pRegions)
654{
655 VkBool32 skipCall = VK_FALSE;
Chia-I Wu1f851912015-10-27 18:04:07 +0800656 layer_data *device_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
Jeremy Hayesac8ed0b2015-10-28 13:01:39 -0600657 // For each region, the number of layers in the image subresource should not be zero
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600658 // Image aspect must be ONE OF color, depth, stencil
659 for (uint32_t i = 0; i < regionCount; i++) {
Chia-I Wu1f851912015-10-27 18:04:07 +0800660 if(pRegions[i].imageSubresource.layerCount == 0)
Jeremy Hayesac8ed0b2015-10-28 13:01:39 -0600661 {
Jeremy Hayesac8ed0b2015-10-28 13:01:39 -0600662 char const str[] = "vkCmdCopyImageToBuffer: number of layers in image subresource is zero";
663 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 +0800664 (uint64_t)commandBuffer, 0, IMAGE_MISMATCHED_IMAGE_ASPECT, "IMAGE", str);
Jeremy Hayesac8ed0b2015-10-28 13:01:39 -0600665 }
666
Chia-I Wu4291d882015-10-27 19:00:15 +0800667 VkImageAspectFlags aspectMask = pRegions[i].imageSubresource.aspectMask;
668 if ((aspectMask != VK_IMAGE_ASPECT_COLOR_BIT) &&
669 (aspectMask != VK_IMAGE_ASPECT_DEPTH_BIT) &&
670 (aspectMask != VK_IMAGE_ASPECT_STENCIL_BIT)) {
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600671 char const str[] = "vkCmdCopyImageToBuffer: aspectMasks for each region must specify only COLOR or DEPTH or STENCIL";
672 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 +0800673 (uint64_t)commandBuffer, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", str);
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600674 }
675 }
676
677 if (VK_FALSE == skipCall) {
Chia-I Wu1f851912015-10-27 18:04:07 +0800678 device_data->device_dispatch_table->CmdCopyImageToBuffer(commandBuffer,
679 srcImage, srcImageLayout, dstBuffer, regionCount, pRegions);
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600680 }
681}
682
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600683VK_LAYER_EXPORT void VKAPI vkCmdCopyBufferToImage(
Chia-I Wu1f851912015-10-27 18:04:07 +0800684 VkCommandBuffer commandBuffer,
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600685 VkBuffer srcBuffer,
Chia-I Wu1f851912015-10-27 18:04:07 +0800686 VkImage dstImage,
687 VkImageLayout dstImageLayout,
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600688 uint32_t regionCount,
689 const VkBufferImageCopy *pRegions)
690{
691 VkBool32 skipCall = VK_FALSE;
Chia-I Wu1f851912015-10-27 18:04:07 +0800692 layer_data *device_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
Jeremy Hayesac8ed0b2015-10-28 13:01:39 -0600693 // For each region, the number of layers in the image subresource should not be zero
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600694 // Image aspect must be ONE OF color, depth, stencil
695 for (uint32_t i = 0; i < regionCount; i++) {
Chia-I Wu1f851912015-10-27 18:04:07 +0800696 if(pRegions[i].imageSubresource.layerCount == 0)
Jeremy Hayesac8ed0b2015-10-28 13:01:39 -0600697 {
Jeremy Hayesac8ed0b2015-10-28 13:01:39 -0600698 char const str[] = "vkCmdCopyBufferToImage: number of layers in image subresource is zero";
699 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 +0800700 (uint64_t)commandBuffer, 0, IMAGE_MISMATCHED_IMAGE_ASPECT, "IMAGE", str);
Jeremy Hayesac8ed0b2015-10-28 13:01:39 -0600701 }
702
Chia-I Wu4291d882015-10-27 19:00:15 +0800703 VkImageAspectFlags aspectMask = pRegions[i].imageSubresource.aspectMask;
704 if ((aspectMask != VK_IMAGE_ASPECT_COLOR_BIT) &&
705 (aspectMask != VK_IMAGE_ASPECT_DEPTH_BIT) &&
706 (aspectMask != VK_IMAGE_ASPECT_STENCIL_BIT)) {
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600707 char const str[] = "vkCmdCopyBufferToImage: aspectMasks for each region must specify only COLOR or DEPTH or STENCIL";
708 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 +0800709 (uint64_t)commandBuffer, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", str);
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600710 }
711 }
712
713 if (VK_FALSE == skipCall) {
Chia-I Wu1f851912015-10-27 18:04:07 +0800714 device_data->device_dispatch_table->CmdCopyBufferToImage(commandBuffer,
715 srcBuffer, dstImage, dstImageLayout, regionCount, pRegions);
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600716 }
717}
718
719VK_LAYER_EXPORT void VKAPI vkCmdBlitImage(
Chia-I Wu1f851912015-10-27 18:04:07 +0800720 VkCommandBuffer commandBuffer,
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600721 VkImage srcImage,
722 VkImageLayout srcImageLayout,
Chia-I Wu1f851912015-10-27 18:04:07 +0800723 VkImage dstImage,
724 VkImageLayout dstImageLayout,
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600725 uint32_t regionCount,
726 const VkImageBlit *pRegions,
Chia-I Wu3603b082015-10-26 16:49:32 +0800727 VkFilter filter)
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600728{
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600729 VkBool32 skipCall = VK_FALSE;
Chia-I Wu1f851912015-10-27 18:04:07 +0800730 layer_data *device_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600731
Chia-I Wue420a332015-10-26 20:04:44 +0800732 auto srcImageEntry = device_data->imageMap.find(srcImage);
Chia-I Wu1f851912015-10-27 18:04:07 +0800733 auto dstImageEntry = device_data->imageMap.find(dstImage);
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600734
735 if ((srcImageEntry != device_data->imageMap.end()) &&
Chia-I Wu1f851912015-10-27 18:04:07 +0800736 (dstImageEntry != device_data->imageMap.end())) {
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600737
Tobin Ehlis6fa437d2015-09-25 14:49:43 -0600738 VkFormat srcFormat = srcImageEntry->second.format;
Chia-I Wu1f851912015-10-27 18:04:07 +0800739 VkFormat dstFormat = dstImageEntry->second.format;
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600740
741 // Validate consistency for signed and unsigned formats
742 if ((vk_format_is_sint(srcFormat) && !vk_format_is_sint(dstFormat)) ||
743 (vk_format_is_uint(srcFormat) && !vk_format_is_uint(dstFormat))) {
744 std::stringstream ss;
Chia-I Wu1f851912015-10-27 18:04:07 +0800745 ss << "vkCmdBlitImage: If one of srcImage and dstImage images has signed/unsigned integer format, "
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600746 << "the other one must also have signed/unsigned integer format. "
747 << "Source format is " << string_VkFormat(srcFormat) << " Destinatino format is " << string_VkFormat(dstFormat);
748 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 +0800749 (uint64_t)commandBuffer, 0, IMAGE_INVALID_FORMAT, "IMAGE", ss.str().c_str());
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600750 }
751
752 // Validate aspect bits and formats for depth/stencil images
753 if (vk_format_is_depth_or_stencil(srcFormat) ||
754 vk_format_is_depth_or_stencil(dstFormat)) {
755 if (srcFormat != dstFormat) {
756 std::stringstream ss;
Chia-I Wu1f851912015-10-27 18:04:07 +0800757 ss << "vkCmdBlitImage: If one of srcImage and dstImage images has a format of depth, stencil or depth "
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600758 << "stencil, the other one must have exactly the same format. "
759 << "Source format is " << string_VkFormat(srcFormat) << " Destinatino format is " << string_VkFormat(dstFormat);
760 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 +0800761 (uint64_t)commandBuffer, 0, IMAGE_INVALID_FORMAT, "IMAGE", ss.str().c_str());
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600762 }
763
764 for (uint32_t i = 0; i < regionCount; i++) {
Chia-I Wu1f851912015-10-27 18:04:07 +0800765 if(pRegions[i].srcSubresource.layerCount == 0)
Jeremy Hayesac8ed0b2015-10-28 13:01:39 -0600766 {
767 char const str[] = "vkCmdBlitImage: number of layers in source subresource is zero";
768 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 +0800769 (uint64_t)commandBuffer, 0, IMAGE_MISMATCHED_IMAGE_ASPECT, "IMAGE", str);
Jeremy Hayesac8ed0b2015-10-28 13:01:39 -0600770 }
771
Chia-I Wu1f851912015-10-27 18:04:07 +0800772 if(pRegions[i].dstSubresource.layerCount == 0)
Jeremy Hayesac8ed0b2015-10-28 13:01:39 -0600773 {
774 char const str[] = "vkCmdBlitImage: number of layers in destination subresource is zero";
775 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 +0800776 (uint64_t)commandBuffer, 0, IMAGE_MISMATCHED_IMAGE_ASPECT, "IMAGE", str);
Jeremy Hayesac8ed0b2015-10-28 13:01:39 -0600777 }
778
Chia-I Wu1f851912015-10-27 18:04:07 +0800779 if(pRegions[i].srcSubresource.layerCount != pRegions[i].dstSubresource.layerCount)
Jeremy Hayesac8ed0b2015-10-28 13:01:39 -0600780 {
781 char const str[] = "vkCmdBlitImage: number of layers in source and destination subresources must match";
782 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 +0800783 (uint64_t)commandBuffer, 0, IMAGE_MISMATCHED_IMAGE_ASPECT, "IMAGE", str);
Jeremy Hayesac8ed0b2015-10-28 13:01:39 -0600784 }
785
Chia-I Wu4291d882015-10-27 19:00:15 +0800786 VkImageAspectFlags srcAspect = pRegions[i].srcSubresource.aspectMask;
787 VkImageAspectFlags dstAspect = pRegions[i].dstSubresource.aspectMask;
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600788
789 if (srcAspect != dstAspect) {
790 std::stringstream ss;
791 ss << "vkCmdBlitImage: Image aspects of depth/stencil images should match";
792 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 +0800793 (uint64_t)commandBuffer, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", ss.str().c_str());
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600794 }
795 if (vk_format_is_depth_and_stencil(srcFormat)) {
796 if (srcAspect != (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) {
797 std::stringstream ss;
798 ss << "vkCmdBlitImage: Combination depth/stencil image formats must have both VK_IMAGE_ASPECT_DEPTH_BIT "
Chia-I Wu1f851912015-10-27 18:04:07 +0800799 << "and VK_IMAGE_ASPECT_STENCIL_BIT set in both the srcImage and dstImage";
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600800 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 +0800801 (uint64_t)commandBuffer, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", ss.str().c_str());
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600802 }
803 } else if (vk_format_is_stencil_only(srcFormat)) {
804 if (srcAspect != VK_IMAGE_ASPECT_STENCIL_BIT) {
805 std::stringstream ss;
806 ss << "vkCmdBlitImage: Stencil-only image formats must have only the VK_IMAGE_ASPECT_STENCIL_BIT "
Chia-I Wu1f851912015-10-27 18:04:07 +0800807 << "set in both the srcImage and dstImage";
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600808 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 +0800809 (uint64_t)commandBuffer, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", ss.str().c_str());
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600810 }
811 } else if (vk_format_is_depth_only(srcFormat)) {
812 if (srcAspect != VK_IMAGE_ASPECT_DEPTH_BIT) {
813 std::stringstream ss;
814 ss << "vkCmdBlitImage: Depth-only image formats must have only the VK_IMAGE_ASPECT_DEPTH "
Chia-I Wu1f851912015-10-27 18:04:07 +0800815 << "set in both the srcImage and dstImage";
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600816 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 +0800817 (uint64_t)commandBuffer, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", ss.str().c_str());
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600818 }
819 }
820 }
821 }
822
823 // Validate filter
824 if (vk_format_is_depth_or_stencil(srcFormat) ||
825 vk_format_is_int(srcFormat)) {
Chia-I Wu3603b082015-10-26 16:49:32 +0800826 if (filter != VK_FILTER_NEAREST) {
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600827 std::stringstream ss;
828 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 +0800829 << "then filter must be VK_FILTER_NEAREST.";
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600830 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 +0800831 (uint64_t)commandBuffer, 0, IMAGE_INVALID_FILTER, "IMAGE", ss.str().c_str());
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600832 }
833 }
834 }
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600835
Chia-I Wu1f851912015-10-27 18:04:07 +0800836 device_data->device_dispatch_table->CmdBlitImage(commandBuffer, srcImage,
837 srcImageLayout, dstImage, dstImageLayout, regionCount, pRegions, filter);
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600838}
839
840VK_LAYER_EXPORT void VKAPI vkCmdResolveImage(
Chia-I Wu1f851912015-10-27 18:04:07 +0800841 VkCommandBuffer commandBuffer,
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600842 VkImage srcImage,
843 VkImageLayout srcImageLayout,
Chia-I Wu1f851912015-10-27 18:04:07 +0800844 VkImage dstImage,
845 VkImageLayout dstImageLayout,
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600846 uint32_t regionCount,
847 const VkImageResolve *pRegions)
848{
849 VkBool32 skipCall = VK_FALSE;
Chia-I Wu1f851912015-10-27 18:04:07 +0800850 layer_data *device_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
Chia-I Wue420a332015-10-26 20:04:44 +0800851 auto srcImageEntry = device_data->imageMap.find(srcImage);
Chia-I Wu1f851912015-10-27 18:04:07 +0800852 auto dstImageEntry = device_data->imageMap.find(dstImage);
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600853
Jeremy Hayesac8ed0b2015-10-28 13:01:39 -0600854 // For each region, the number of layers in the image subresource should not be zero
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600855 // For each region, src and dest image aspect must be color only
856 for (uint32_t i = 0; i < regionCount; i++) {
Chia-I Wu1f851912015-10-27 18:04:07 +0800857 if(pRegions[i].srcSubresource.layerCount == 0)
Jeremy Hayesac8ed0b2015-10-28 13:01:39 -0600858 {
859 char const str[] = "vkCmdResolveImage: number of layers in source subresource is zero";
860 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 +0800861 (uint64_t)commandBuffer, 0, IMAGE_MISMATCHED_IMAGE_ASPECT, "IMAGE", str);
Jeremy Hayesac8ed0b2015-10-28 13:01:39 -0600862 }
863
Chia-I Wu1f851912015-10-27 18:04:07 +0800864 if(pRegions[i].dstSubresource.layerCount == 0)
Jeremy Hayesac8ed0b2015-10-28 13:01:39 -0600865 {
866 char const str[] = "vkCmdResolveImage: number of layers in destination subresource is zero";
867 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 +0800868 (uint64_t)commandBuffer, 0, IMAGE_MISMATCHED_IMAGE_ASPECT, "IMAGE", str);
Jeremy Hayesac8ed0b2015-10-28 13:01:39 -0600869 }
870
Chia-I Wu4291d882015-10-27 19:00:15 +0800871 if ((pRegions[i].srcSubresource.aspectMask != VK_IMAGE_ASPECT_COLOR_BIT) ||
872 (pRegions[i].dstSubresource.aspectMask != VK_IMAGE_ASPECT_COLOR_BIT)) {
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600873 char const str[] = "vkCmdResolveImage: src and dest aspectMasks for each region must specify only VK_IMAGE_ASPECT_COLOR_BIT";
874 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 +0800875 (uint64_t)commandBuffer, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", str);
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600876 }
877 }
878
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600879 if ((srcImageEntry != device_data->imageMap.end()) &&
Chia-I Wu1f851912015-10-27 18:04:07 +0800880 (dstImageEntry != device_data->imageMap.end())) {
881 if (srcImageEntry->second.format != dstImageEntry->second.format) {
Mike Stroyan43909d82015-09-25 13:39:21 -0600882 char const str[] = "vkCmdResolveImage called with unmatched source and dest formats.";
883 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 +0800884 (uint64_t)commandBuffer, 0, IMAGE_MISMATCHED_IMAGE_FORMAT, "IMAGE", str);
Mike Stroyan43909d82015-09-25 13:39:21 -0600885 }
Chia-I Wu1f851912015-10-27 18:04:07 +0800886 if (srcImageEntry->second.imageType != dstImageEntry->second.imageType) {
Mike Stroyan43909d82015-09-25 13:39:21 -0600887 char const str[] = "vkCmdResolveImage called with unmatched source and dest image types.";
888 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 +0800889 (uint64_t)commandBuffer, 0, IMAGE_MISMATCHED_IMAGE_TYPE, "IMAGE", str);
Mike Stroyan43909d82015-09-25 13:39:21 -0600890 }
Chia-I Wu3138d6a2015-10-31 00:31:16 +0800891 if (srcImageEntry->second.samples == VK_SAMPLE_COUNT_1_BIT) {
Mike Stroyan43909d82015-09-25 13:39:21 -0600892 char const str[] = "vkCmdResolveImage called with source sample count less than 2.";
893 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 +0800894 (uint64_t)commandBuffer, 0, IMAGE_INVALID_RESOLVE_SAMPLES, "IMAGE", str);
Mike Stroyan43909d82015-09-25 13:39:21 -0600895 }
Chia-I Wu3138d6a2015-10-31 00:31:16 +0800896 if (dstImageEntry->second.samples != VK_SAMPLE_COUNT_1_BIT) {
Mike Stroyan43909d82015-09-25 13:39:21 -0600897 char const str[] = "vkCmdResolveImage called with dest sample count greater than 1.";
898 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 +0800899 (uint64_t)commandBuffer, 0, IMAGE_INVALID_RESOLVE_SAMPLES, "IMAGE", str);
Mike Stroyan43909d82015-09-25 13:39:21 -0600900 }
901 }
902
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600903 if (VK_FALSE == skipCall) {
Chia-I Wu1f851912015-10-27 18:04:07 +0800904 device_data->device_dispatch_table->CmdResolveImage(commandBuffer, srcImage,
905 srcImageLayout, dstImage, dstImageLayout, regionCount, pRegions);
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600906 }
907}
908
Courtney Goeltzenleuchter01d2ae12015-10-20 16:40:38 -0600909VK_LAYER_EXPORT void VKAPI vkGetImageSubresourceLayout(
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600910 VkDevice device,
911 VkImage image,
912 const VkImageSubresource *pSubresource,
913 VkSubresourceLayout *pLayout)
914{
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600915 VkBool32 skipCall = VK_FALSE;
916 layer_data *device_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
917 VkFormat format;
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600918
Chia-I Wue420a332015-10-26 20:04:44 +0800919 auto imageEntry = device_data->imageMap.find(image);
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600920
921 // Validate that image aspects match formats
922 if (imageEntry != device_data->imageMap.end()) {
Tobin Ehlis6fa437d2015-09-25 14:49:43 -0600923 format = imageEntry->second.format;
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600924 if (vk_format_is_color(format)) {
Chia-I Wu195c9e12015-10-27 19:55:05 +0800925 if (pSubresource->aspectMask != VK_IMAGE_ASPECT_COLOR_BIT) {
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600926 std::stringstream ss;
Chia-I Wu195c9e12015-10-27 19:55:05 +0800927 ss << "vkGetImageSubresourceLayout: For color formats, the aspectMask field of VkImageSubresource must be VK_IMAGE_ASPECT_COLOR.";
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600928 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_IMAGE,
Chia-I Wue420a332015-10-26 20:04:44 +0800929 (uint64_t)image, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", ss.str().c_str());
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600930 }
931 } else if (vk_format_is_depth_or_stencil(format)) {
Chia-I Wu195c9e12015-10-27 19:55:05 +0800932 if ((pSubresource->aspectMask != VK_IMAGE_ASPECT_DEPTH_BIT) &&
933 (pSubresource->aspectMask != VK_IMAGE_ASPECT_STENCIL_BIT)) {
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600934 std::stringstream ss;
Chia-I Wu195c9e12015-10-27 19:55:05 +0800935 ss << "vkGetImageSubresourceLayout: For depth/stencil formats, the aspectMask selects either the depth or stencil image aspectMask.";
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600936 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_IMAGE,
Chia-I Wue420a332015-10-26 20:04:44 +0800937 (uint64_t)image, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", ss.str().c_str());
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600938 }
939 }
940 }
941
942 if (VK_FALSE == skipCall) {
Tobin Ehlis049f1782015-10-29 14:19:18 -0600943 device_data->device_dispatch_table->GetImageSubresourceLayout(device,
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600944 image, pSubresource, pLayout);
945 }
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600946}
947
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -0600948VK_LAYER_EXPORT PFN_vkVoidFunction VKAPI vkGetDeviceProcAddr(VkDevice device, const char* funcName)
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600949{
950 if (device == NULL) {
951 return NULL;
952 }
953
Tobin Ehlis049f1782015-10-29 14:19:18 -0600954 layer_data *my_data;
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600955 // loader uses this to force layer initialization; device object is wrapped
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600956 if (!strcmp(funcName, "vkGetDeviceProcAddr")) {
Tobin Ehlis049f1782015-10-29 14:19:18 -0600957 VkBaseLayerObject* wrapped_dev = (VkBaseLayerObject*) device;
958 my_data = get_my_data_ptr(get_dispatch_key(wrapped_dev->baseObject), layer_data_map);
959 my_data->device_dispatch_table = new VkLayerDispatchTable;
960 layer_initialize_dispatch_table(my_data->device_dispatch_table, wrapped_dev);
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -0600961 return (PFN_vkVoidFunction) vkGetDeviceProcAddr;
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600962 }
963
Tobin Ehlis049f1782015-10-29 14:19:18 -0600964 my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
Courtney Goeltzenleuchterbe637992015-06-25 18:01:43 -0600965 if (!strcmp(funcName, "vkCreateDevice"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -0600966 return (PFN_vkVoidFunction) vkCreateDevice;
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600967 if (!strcmp(funcName, "vkDestroyDevice"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -0600968 return (PFN_vkVoidFunction) vkDestroyDevice;
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600969 if (!strcmp(funcName, "vkCreateImage"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -0600970 return (PFN_vkVoidFunction) vkCreateImage;
Mark Lobodzinski9eb1ce42015-10-29 12:58:33 -0600971 if (!strcmp(funcName, "vkDestroyImage"))
972 return (PFN_vkVoidFunction) vkDestroyImage;
Tobin Ehlis342b9bf2015-09-22 10:11:37 -0600973 if (!strcmp(funcName, "vkCreateImageView"))
974 return (PFN_vkVoidFunction) vkCreateImageView;
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600975 if (!strcmp(funcName, "vkCreateRenderPass"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -0600976 return (PFN_vkVoidFunction) vkCreateRenderPass;
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600977 if (!strcmp(funcName, "vkCmdClearColorImage"))
978 return (PFN_vkVoidFunction) vkCmdClearColorImage;
979 if (!strcmp(funcName, "vkCmdClearDepthStencilImage"))
980 return (PFN_vkVoidFunction) vkCmdClearDepthStencilImage;
Courtney Goeltzenleuchter9feb0732015-10-15 16:51:05 -0600981 if (!strcmp(funcName, "vkCmdClearAttachments"))
982 return (PFN_vkVoidFunction) vkCmdClearAttachments;
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600983 if (!strcmp(funcName, "vkCmdCopyImage"))
984 return (PFN_vkVoidFunction) vkCmdCopyImage;
985 if (!strcmp(funcName, "vkCmdCopyImageToBuffer"))
986 return (PFN_vkVoidFunction) vkCmdCopyImageToBuffer;
987 if (!strcmp(funcName, "vkCmdCopyBufferToImage"))
988 return (PFN_vkVoidFunction) vkCmdCopyBufferToImage;
989 if (!strcmp(funcName, "vkCmdBlitImage"))
990 return (PFN_vkVoidFunction) vkCmdBlitImage;
991 if (!strcmp(funcName, "vkCmdResolveImage"))
992 return (PFN_vkVoidFunction) vkCmdResolveImage;
993 if (!strcmp(funcName, "vkGetImageSubresourceLayout"))
994 return (PFN_vkVoidFunction) vkGetImageSubresourceLayout;
Tobin Ehlis049f1782015-10-29 14:19:18 -0600995
996 VkLayerDispatchTable* pTable = my_data->device_dispatch_table;
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600997 {
Tobin Ehlis049f1782015-10-29 14:19:18 -0600998 if (pTable->GetDeviceProcAddr == NULL)
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600999 return NULL;
Tobin Ehlis049f1782015-10-29 14:19:18 -06001000 return pTable->GetDeviceProcAddr(device, funcName);
Jeremy Hayesb707aa52015-06-18 10:12:39 -06001001 }
1002}
1003
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06001004VK_LAYER_EXPORT PFN_vkVoidFunction VKAPI vkGetInstanceProcAddr(VkInstance instance, const char* funcName)
Jeremy Hayesb707aa52015-06-18 10:12:39 -06001005{
1006 if (instance == NULL) {
1007 return NULL;
1008 }
1009
Tobin Ehlis049f1782015-10-29 14:19:18 -06001010 layer_data *my_data;
Mark Lobodzinskib4092de2015-10-23 14:20:31 -06001011 // loader uses this to force layer initialization; instance object is wrapped
Jeremy Hayesb707aa52015-06-18 10:12:39 -06001012 if (!strcmp(funcName, "vkGetInstanceProcAddr")) {
Tobin Ehlis049f1782015-10-29 14:19:18 -06001013 VkBaseLayerObject* wrapped_inst = (VkBaseLayerObject*) instance;
1014 my_data = get_my_data_ptr(get_dispatch_key(wrapped_inst->baseObject), layer_data_map);
1015 my_data->instance_dispatch_table = new VkLayerInstanceDispatchTable;
1016 layer_init_instance_dispatch_table(my_data->instance_dispatch_table, wrapped_inst);
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06001017 return (PFN_vkVoidFunction) vkGetInstanceProcAddr;
Jeremy Hayesb707aa52015-06-18 10:12:39 -06001018 }
1019
Tobin Ehlis049f1782015-10-29 14:19:18 -06001020 my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
Jeremy Hayesb707aa52015-06-18 10:12:39 -06001021 if (!strcmp(funcName, "vkCreateInstance"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06001022 return (PFN_vkVoidFunction) vkCreateInstance;
Jeremy Hayesb707aa52015-06-18 10:12:39 -06001023 if (!strcmp(funcName, "vkDestroyInstance"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06001024 return (PFN_vkVoidFunction) vkDestroyInstance;
Courtney Goeltzenleuchter74c4ce92015-09-14 17:22:16 -06001025 if (!strcmp(funcName, "vkEnumerateInstanceLayerProperties"))
1026 return (PFN_vkVoidFunction) vkEnumerateInstanceLayerProperties;
1027 if (!strcmp(funcName, "vkEnumerateInstanceExtensionProperties"))
1028 return (PFN_vkVoidFunction) vkEnumerateInstanceExtensionProperties;
1029 if (!strcmp(funcName, "vkEnumerateDeviceLayerProperties"))
1030 return (PFN_vkVoidFunction) vkEnumerateDeviceLayerProperties;
1031 if (!strcmp(funcName, "vkEnumerateDeviceExtensionProperties"))
1032 return (PFN_vkVoidFunction) vkEnumerateDeviceExtensionProperties;
Jeremy Hayesb707aa52015-06-18 10:12:39 -06001033
Tobin Ehlis049f1782015-10-29 14:19:18 -06001034 PFN_vkVoidFunction fptr = debug_report_get_instance_proc_addr(my_data->report_data, funcName);
Jeremy Hayesb707aa52015-06-18 10:12:39 -06001035 if(fptr)
1036 return fptr;
1037
1038 {
Tobin Ehlis049f1782015-10-29 14:19:18 -06001039 VkLayerInstanceDispatchTable* pTable = my_data->instance_dispatch_table;
1040 if (pTable->GetInstanceProcAddr == NULL)
Jeremy Hayesb707aa52015-06-18 10:12:39 -06001041 return NULL;
Tobin Ehlis049f1782015-10-29 14:19:18 -06001042 return pTable->GetInstanceProcAddr(instance, funcName);
Jeremy Hayesb707aa52015-06-18 10:12:39 -06001043 }
1044}