blob: 64deef4ed4e88e14eff530539a6c96ce7b29f52a [file] [log] [blame]
Jeremy Hayesb707aa52015-06-18 10:12:39 -06001/*
Jeremy Hayesb707aa52015-06-18 10:12:39 -06002 *
Courtney Goeltzenleuchter8a17da52015-10-29 13:50:34 -06003 * Copyright (C) 2015 Valve Corporation
Jeremy Hayesb707aa52015-06-18 10:12:39 -06004 *
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.
Courtney Goeltzenleuchter96cd7952015-10-30 11:14:30 -060022 *
23 * Author: Jeremy Hayes <jeremy@lunarg.com>
24 * Author: Mark Lobodzinski <mark@lunarg.com>
25 * Author: Mike Stroyan <mike@LunarG.com>
26 * Author: Tobin Ehlis <tobin@lunarg.com>
Jeremy Hayesb707aa52015-06-18 10:12:39 -060027 */
28
Courtney Goeltzenleuchter6ff93732015-10-07 08:38:30 -060029#include <inttypes.h>
Jeremy Hayesb707aa52015-06-18 10:12:39 -060030#include <stdio.h>
31#include <stdlib.h>
32#include <string.h>
Courtney Goeltzenleuchter6ff93732015-10-07 08:38:30 -060033#include <assert.h>
34#include <vector>
Jeremy Hayesb707aa52015-06-18 10:12:39 -060035#include <unordered_map>
Tobin Ehlis65380532015-09-21 15:20:28 -060036#include <memory>
Courtney Goeltzenleuchter6ff93732015-10-07 08:38:30 -060037using namespace std;
Jeremy Hayesb707aa52015-06-18 10:12:39 -060038
Tobin Ehlis7a51d902015-07-03 10:34:49 -060039#include "vk_loader_platform.h"
Courtney Goeltzenleuchter6ff93732015-10-07 08:38:30 -060040#include "vk_dispatch_table_helper.h"
41#include "vk_struct_string_helper_cpp.h"
Jeremy Hayesb707aa52015-06-18 10:12:39 -060042#include "vk_enum_validate_helper.h"
Courtney Goeltzenleuchter6ff93732015-10-07 08:38:30 -060043#include "image.h"
44#include "vk_layer_config.h"
45#include "vk_layer_extension_utils.h"
Tobin Ehlis56d204a2015-07-03 10:15:26 -060046#include "vk_layer_table.h"
47#include "vk_layer_data.h"
Courtney Goeltzenleuchtereb1ddb02015-07-07 11:18:30 -060048#include "vk_layer_extension_utils.h"
Mike Stroyan43909d82015-09-25 13:39:21 -060049#include "vk_layer_utils.h"
Courtney Goeltzenleuchter6ff93732015-10-07 08:38:30 -060050#include "vk_layer_logging.h"
Jeremy Hayesb707aa52015-06-18 10:12:39 -060051
Tobin Ehlis65380532015-09-21 15:20:28 -060052using namespace std;
53
Cody Northrop73bb6572015-09-28 15:09:32 -060054struct layer_data {
Jeremy Hayesb707aa52015-06-18 10:12:39 -060055 debug_report_data *report_data;
Courtney Goeltzenleuchter9fac1572015-10-05 15:59:11 -060056 std::vector<VkDbgMsgCallback> logging_callback;
Tobin Ehlis049f1782015-10-29 14:19:18 -060057 VkLayerDispatchTable* device_dispatch_table;
58 VkLayerInstanceDispatchTable* instance_dispatch_table;
Chris Forbesd7576302015-06-21 22:55:02 +120059 VkPhysicalDevice physicalDevice;
Chia-I Wue420a332015-10-26 20:04:44 +080060 unordered_map<VkImage, IMAGE_STATE> imageMap;
Cody Northrop73bb6572015-09-28 15:09:32 -060061
62 layer_data() :
63 report_data(nullptr),
Tobin Ehlis049f1782015-10-29 14:19:18 -060064 device_dispatch_table(nullptr),
65 instance_dispatch_table(nullptr),
Cody Northrop73bb6572015-09-28 15:09:32 -060066 physicalDevice(0)
67 {};
68};
Jeremy Hayesb707aa52015-06-18 10:12:39 -060069
Tobin Ehlis65380532015-09-21 15:20:28 -060070static unordered_map<void*, layer_data*> layer_data_map;
Jeremy Hayesb707aa52015-06-18 10:12:39 -060071
72static void InitImage(layer_data *data)
73{
Courtney Goeltzenleuchter9fac1572015-10-05 15:59:11 -060074 VkDbgMsgCallback callback;
Jeremy Hayesb707aa52015-06-18 10:12:39 -060075 uint32_t report_flags = getLayerOptionFlags("ImageReportFlags", 0);
76
77 uint32_t debug_action = 0;
78 getLayerOptionEnum("ImageDebugAction", (uint32_t *) &debug_action);
79 if(debug_action & VK_DBG_LAYER_ACTION_LOG_MSG)
80 {
81 FILE *log_output = NULL;
82 const char* option_str = getLayerOption("ImageLogFilename");
Tobin Ehlisb4b6e7c2015-09-15 09:55:54 -060083 log_output = getLayerLogOutput(option_str, "Image");
Courtney Goeltzenleuchter9fac1572015-10-05 15:59:11 -060084 layer_create_msg_callback(data->report_data, report_flags, log_callback, (void *) log_output, &callback);
85 data->logging_callback.push_back(callback);
86 }
87
88 if (debug_action & VK_DBG_LAYER_ACTION_DEBUG_OUTPUT) {
89 layer_create_msg_callback(data->report_data, report_flags, win32_debug_output_msg, NULL, &callback);
90 data->logging_callback.push_back(callback);
Jeremy Hayesb707aa52015-06-18 10:12:39 -060091 }
92}
93
Chia-I Wuaf9e4fd2015-11-06 06:42:02 +080094VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkDbgCreateMsgCallback(
Jeremy Hayesb707aa52015-06-18 10:12:39 -060095 VkInstance instance,
96 VkFlags msgFlags,
97 const PFN_vkDbgMsgCallback pfnMsgCallback,
98 void* pUserData,
99 VkDbgMsgCallback* pMsgCallback)
100{
Tobin Ehlis049f1782015-10-29 14:19:18 -0600101 layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
102 VkResult res = my_data->instance_dispatch_table->DbgCreateMsgCallback(instance, msgFlags, pfnMsgCallback, pUserData, pMsgCallback);
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600103 if (res == VK_SUCCESS) {
Tobin Ehlis049f1782015-10-29 14:19:18 -0600104 res = layer_create_msg_callback(my_data->report_data, msgFlags, pfnMsgCallback, pUserData, pMsgCallback);
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600105 }
106 return res;
107}
108
Chia-I Wuaf9e4fd2015-11-06 06:42:02 +0800109VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkDbgDestroyMsgCallback(
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600110 VkInstance instance,
111 VkDbgMsgCallback msgCallback)
112{
Tobin Ehlis049f1782015-10-29 14:19:18 -0600113 layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
114 VkResult res = my_data->instance_dispatch_table->DbgDestroyMsgCallback(instance, msgCallback);
115 layer_destroy_msg_callback(my_data->report_data, msgCallback);
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600116 return res;
117}
118
Chia-I Wuaf9e4fd2015-11-06 06:42:02 +0800119VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateInstance(const VkInstanceCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkInstance* pInstance)
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600120{
Tobin Ehlis049f1782015-10-29 14:19:18 -0600121 layer_data *my_data = get_my_data_ptr(get_dispatch_key(*pInstance), layer_data_map);
122 VkLayerInstanceDispatchTable *pTable = my_data->instance_dispatch_table;
Chia-I Wu69f40122015-10-26 21:10:41 +0800123 VkResult result = pTable->CreateInstance(pCreateInfo, pAllocator, pInstance);
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600124
125 if (result == VK_SUCCESS) {
Chia-I Wu763a7492015-10-26 20:48:51 +0800126 my_data->report_data = debug_report_create_instance(pTable, *pInstance, pCreateInfo->enabledExtensionNameCount,
Courtney Goeltzenleuchtereb1ddb02015-07-07 11:18:30 -0600127 pCreateInfo->ppEnabledExtensionNames);
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600128
Tobin Ehlis049f1782015-10-29 14:19:18 -0600129 InitImage(my_data);
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600130 }
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600131 return result;
132}
133
Chia-I Wuaf9e4fd2015-11-06 06:42:02 +0800134VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL vkDestroyInstance(VkInstance instance, const VkAllocationCallbacks* pAllocator)
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600135{
136 // Grab the key before the instance is destroyed.
137 dispatch_key key = get_dispatch_key(instance);
Tobin Ehlis049f1782015-10-29 14:19:18 -0600138 layer_data *my_data = get_my_data_ptr(key, layer_data_map);
139 VkLayerInstanceDispatchTable *pTable = my_data->instance_dispatch_table;
Chia-I Wu69f40122015-10-26 21:10:41 +0800140 pTable->DestroyInstance(instance, pAllocator);
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600141
142 // Clean up logging callback, if any
Courtney Goeltzenleuchter9fac1572015-10-05 15:59:11 -0600143 while (my_data->logging_callback.size() > 0) {
144 VkDbgMsgCallback callback = my_data->logging_callback.back();
145 layer_destroy_msg_callback(my_data->report_data, callback);
146 my_data->logging_callback.pop_back();
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600147 }
148
Tobin Ehlis049f1782015-10-29 14:19:18 -0600149 layer_debug_report_destroy_instance(my_data->report_data);
150 delete my_data->instance_dispatch_table;
151 layer_data_map.erase(key);
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600152
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600153}
154
Chia-I Wuaf9e4fd2015-11-06 06:42:02 +0800155VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateDevice(VkPhysicalDevice physicalDevice, const VkDeviceCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDevice* pDevice)
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600156{
Tobin Ehlis049f1782015-10-29 14:19:18 -0600157 layer_data *instance_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);
158 layer_data *device_data = get_my_data_ptr(get_dispatch_key(*pDevice), layer_data_map);
Chia-I Wu69f40122015-10-26 21:10:41 +0800159 VkResult result = device_data->device_dispatch_table->CreateDevice(physicalDevice, pCreateInfo, pAllocator, pDevice);
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600160 if(result == VK_SUCCESS)
161 {
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600162 device_data->report_data = layer_debug_report_create_device(instance_data->report_data, *pDevice);
Chris Forbesd7576302015-06-21 22:55:02 +1200163 device_data->physicalDevice = physicalDevice;
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600164 }
165
166 return result;
167}
168
Chia-I Wuaf9e4fd2015-11-06 06:42:02 +0800169VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL vkDestroyDevice(VkDevice device, const VkAllocationCallbacks* pAllocator)
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600170{
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600171 dispatch_key key = get_dispatch_key(device);
Tobin Ehlis049f1782015-10-29 14:19:18 -0600172 layer_data *my_data = get_my_data_ptr(key, layer_data_map);
Chia-I Wu69f40122015-10-26 21:10:41 +0800173 my_data->device_dispatch_table->DestroyDevice(device, pAllocator);
Tobin Ehlis049f1782015-10-29 14:19:18 -0600174 delete my_data->device_dispatch_table;
175 layer_data_map.erase(key);
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600176}
177
Courtney Goeltzenleuchtereb1ddb02015-07-07 11:18:30 -0600178static const VkLayerProperties pc_global_layers[] = {
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600179 {
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600180 "Image",
Courtney Goeltzenleuchtereb1ddb02015-07-07 11:18:30 -0600181 VK_API_VERSION,
182 VK_MAKE_VERSION(0, 1, 0),
183 "Validation layer: Image ParamChecker",
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600184 }
185};
186
Chia-I Wuaf9e4fd2015-11-06 06:42:02 +0800187VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateInstanceExtensionProperties(
Courtney Goeltzenleuchtereb1ddb02015-07-07 11:18:30 -0600188 const char *pLayerName,
189 uint32_t *pCount,
190 VkExtensionProperties* pProperties)
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600191{
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600192 // ParamChecker does not have any global extensions
Courtney Goeltzenleuchtereb1ddb02015-07-07 11:18:30 -0600193 return util_GetExtensionProperties(0, NULL, pCount, pProperties);
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600194}
195
Chia-I Wuaf9e4fd2015-11-06 06:42:02 +0800196VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateInstanceLayerProperties(
Courtney Goeltzenleuchtereb1ddb02015-07-07 11:18:30 -0600197 uint32_t *pCount,
198 VkLayerProperties* pProperties)
Tony Barbour426b9052015-06-24 16:06:58 -0600199{
Courtney Goeltzenleuchtereb1ddb02015-07-07 11:18:30 -0600200 return util_GetLayerProperties(ARRAY_SIZE(pc_global_layers),
201 pc_global_layers,
202 pCount, pProperties);
Tony Barbour426b9052015-06-24 16:06:58 -0600203}
204
Chia-I Wuaf9e4fd2015-11-06 06:42:02 +0800205VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateDeviceExtensionProperties(
Courtney Goeltzenleuchtereb1ddb02015-07-07 11:18:30 -0600206 VkPhysicalDevice physicalDevice,
207 const char* pLayerName,
208 uint32_t* pCount,
209 VkExtensionProperties* pProperties)
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600210{
Jon Ashburnaff81ff2015-11-02 17:37:20 -0700211 // Image does not have any physical device extensions
212 if (pLayerName == NULL) {
213 dispatch_key key = get_dispatch_key(physicalDevice);
214 layer_data *my_data = get_my_data_ptr(key, layer_data_map);
215 VkLayerInstanceDispatchTable *pTable = my_data->instance_dispatch_table;
216 return pTable->EnumerateDeviceExtensionProperties(
217 physicalDevice,
218 NULL,
219 pCount,
220 pProperties);
221 } else {
222 return util_GetExtensionProperties(0, NULL, pCount, pProperties);
223 }
Courtney Goeltzenleuchtereb1ddb02015-07-07 11:18:30 -0600224}
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600225
Chia-I Wuaf9e4fd2015-11-06 06:42:02 +0800226VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateDeviceLayerProperties(
Courtney Goeltzenleuchtereb1ddb02015-07-07 11:18:30 -0600227 VkPhysicalDevice physicalDevice,
228 uint32_t* pCount,
229 VkLayerProperties* pProperties)
230{
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600231 // ParamChecker's physical device layers are the same as global
Courtney Goeltzenleuchtereb1ddb02015-07-07 11:18:30 -0600232 return util_GetLayerProperties(ARRAY_SIZE(pc_global_layers), pc_global_layers,
233 pCount, pProperties);
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600234}
235
Mark Lobodzinski9cce7832015-07-29 09:21:22 -0600236// Start of the Image layer proper
237
238// Returns TRUE if a format is a depth-compatible format
239bool is_depth_format(VkFormat format)
240{
241 bool result = VK_FALSE;
242 switch (format) {
243 case VK_FORMAT_D16_UNORM:
Chia-I Wu9eabb8f2015-11-10 17:01:22 +0800244 case VK_FORMAT_X8_D24_UNORM_PACK32:
Mark Lobodzinski9cce7832015-07-29 09:21:22 -0600245 case VK_FORMAT_D32_SFLOAT:
246 case VK_FORMAT_S8_UINT:
247 case VK_FORMAT_D16_UNORM_S8_UINT:
248 case VK_FORMAT_D24_UNORM_S8_UINT:
249 case VK_FORMAT_D32_SFLOAT_S8_UINT:
250 result = VK_TRUE;
251 break;
252 default:
253 break;
254 }
255 return result;
256}
257
Mark Lobodzinski0e10db02015-11-10 11:01:32 -0700258static inline uint32_t validate_VkImageLayoutKHR(VkImageLayout input_value)
259{
260 return ((validate_VkImageLayout(input_value) == 1) ||
261 (input_value == VK_IMAGE_LAYOUT_PRESENT_SOURCE_KHR));
262}
263
Chia-I Wuaf9e4fd2015-11-06 06:42:02 +0800264VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateImage(VkDevice device, const VkImageCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkImage* pImage)
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600265{
Tobin Ehlis35613802015-09-22 08:40:52 -0600266 VkBool32 skipCall = VK_FALSE;
Tobin Ehlis65380532015-09-21 15:20:28 -0600267 layer_data *device_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600268 if(pCreateInfo->format != VK_FORMAT_UNDEFINED)
269 {
270 VkFormatProperties properties;
Tobin Ehlis049f1782015-10-29 14:19:18 -0600271 get_my_data_ptr(get_dispatch_key(device_data->physicalDevice), layer_data_map)->instance_dispatch_table->GetPhysicalDeviceFormatProperties(
Chris Forbesd7576302015-06-21 22:55:02 +1200272 device_data->physicalDevice, pCreateInfo->format, &properties);
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600273
274 if((properties.linearTilingFeatures) == 0 && (properties.optimalTilingFeatures == 0))
275 {
276 char const str[] = "vkCreateImage parameter, VkFormat pCreateInfo->format, contains unsupported format";
Tobin Ehlis35613802015-09-22 08:40:52 -0600277 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 -0600278 }
279 }
Tobin Ehlis35613802015-09-22 08:40:52 -0600280 if (skipCall)
281 return VK_ERROR_VALIDATION_FAILED;
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600282
Chia-I Wu69f40122015-10-26 21:10:41 +0800283 VkResult result = device_data->device_dispatch_table->CreateImage(device, pCreateInfo, pAllocator, pImage);
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600284
Tobin Ehlis65380532015-09-21 15:20:28 -0600285 if(result == VK_SUCCESS) {
Chia-I Wue420a332015-10-26 20:04:44 +0800286 device_data->imageMap[*pImage] = IMAGE_STATE(pCreateInfo);
Tobin Ehlis65380532015-09-21 15:20:28 -0600287 }
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600288 return result;
289}
290
Chia-I Wuaf9e4fd2015-11-06 06:42:02 +0800291VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL vkDestroyImage(VkDevice device, VkImage image, const VkAllocationCallbacks* pAllocator)
Tobin Ehlis65380532015-09-21 15:20:28 -0600292{
293 layer_data *device_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
Chia-I Wue420a332015-10-26 20:04:44 +0800294 device_data->imageMap.erase(image);
Chia-I Wu69f40122015-10-26 21:10:41 +0800295 device_data->device_dispatch_table->DestroyImage(device, image, pAllocator);
Tobin Ehlis65380532015-09-21 15:20:28 -0600296}
297
Chia-I Wuaf9e4fd2015-11-06 06:42:02 +0800298VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateRenderPass(VkDevice device, const VkRenderPassCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkRenderPass* pRenderPass)
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600299{
Tobin Ehlis049f1782015-10-29 14:19:18 -0600300 layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
Tobin Ehlis35613802015-09-22 08:40:52 -0600301 VkBool32 skipCall = VK_FALSE;
Chia-I Wuc278df82015-07-07 11:50:03 +0800302 for(uint32_t i = 0; i < pCreateInfo->attachmentCount; ++i)
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600303 {
Chia-I Wuc278df82015-07-07 11:50:03 +0800304 if(pCreateInfo->pAttachments[i].format != VK_FORMAT_UNDEFINED)
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600305 {
306 VkFormatProperties properties;
Tobin Ehlis049f1782015-10-29 14:19:18 -0600307 get_my_data_ptr(get_dispatch_key(my_data->physicalDevice), layer_data_map)->instance_dispatch_table->GetPhysicalDeviceFormatProperties(
308 my_data->physicalDevice, pCreateInfo->pAttachments[i].format, &properties);
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600309
310 if((properties.linearTilingFeatures) == 0 && (properties.optimalTilingFeatures == 0))
311 {
312 std::stringstream ss;
Chia-I Wuc278df82015-07-07 11:50:03 +0800313 ss << "vkCreateRenderPass parameter, VkFormat in pCreateInfo->pAttachments[" << i << "], contains unsupported format";
Michael Lentinecbc4a5e2015-11-03 16:19:46 -0800314 skipCall |= log_msg(my_data->report_data, VK_DBG_REPORT_WARN_BIT, (VkDbgObjectType)0, 0, 0, IMAGE_FORMAT_UNSUPPORTED, "IMAGE", "%s", ss.str().c_str());
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600315 }
316 }
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 {
Mark Lobodzinski0e10db02015-11-10 11:01:32 -0700321 if(!validate_VkImageLayoutKHR(pCreateInfo->pAttachments[i].initialLayout) ||
322 !validate_VkImageLayoutKHR(pCreateInfo->pAttachments[i].finalLayout))
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600323 {
324 std::stringstream ss;
Chia-I Wuc278df82015-07-07 11:50:03 +0800325 ss << "vkCreateRenderPass parameter, VkImageLayout in pCreateInfo->pAttachments[" << i << "], is unrecognized";
Michael Lentinecbc4a5e2015-11-03 16:19:46 -0800326 skipCall |= log_msg(my_data->report_data, VK_DBG_REPORT_WARN_BIT, (VkDbgObjectType)0, 0, 0, IMAGE_RENDERPASS_INVALID_ATTACHMENT, "IMAGE", "%s", 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_VkAttachmentLoadOp(pCreateInfo->pAttachments[i].loadOp))
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600333 {
334 std::stringstream ss;
Chia-I Wuc278df82015-07-07 11:50:03 +0800335 ss << "vkCreateRenderPass parameter, VkAttachmentLoadOp in pCreateInfo->pAttachments[" << i << "], is unrecognized";
Michael Lentinecbc4a5e2015-11-03 16:19:46 -0800336 skipCall |= log_msg(my_data->report_data, VK_DBG_REPORT_WARN_BIT, (VkDbgObjectType)0, 0, 0, IMAGE_RENDERPASS_INVALID_ATTACHMENT, "IMAGE", "%s", ss.str().c_str());
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600337 }
338 }
339
Chia-I Wuc278df82015-07-07 11:50:03 +0800340 for(uint32_t i = 0; i < pCreateInfo->attachmentCount; ++i)
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600341 {
Chia-I Wuc278df82015-07-07 11:50:03 +0800342 if(!validate_VkAttachmentStoreOp(pCreateInfo->pAttachments[i].storeOp))
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600343 {
344 std::stringstream ss;
Chia-I Wuc278df82015-07-07 11:50:03 +0800345 ss << "vkCreateRenderPass parameter, VkAttachmentStoreOp in pCreateInfo->pAttachments[" << i << "], is unrecognized";
Michael Lentinecbc4a5e2015-11-03 16:19:46 -0800346 skipCall |= log_msg(my_data->report_data, VK_DBG_REPORT_WARN_BIT, (VkDbgObjectType)0, 0, 0, IMAGE_RENDERPASS_INVALID_ATTACHMENT, "IMAGE", "%s", ss.str().c_str());
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600347 }
348 }
349
Mark Lobodzinski9cce7832015-07-29 09:21:22 -0600350 // Any depth buffers specified as attachments?
351 bool depthFormatPresent = VK_FALSE;
352 for (uint32_t i = 0; i < pCreateInfo->attachmentCount; ++i)
353 {
354 depthFormatPresent |= is_depth_format(pCreateInfo->pAttachments[i].format);
355 }
356
357 if (depthFormatPresent == VK_FALSE) {
358 // No depth attachment is present, validate that subpasses set depthStencilAttachment to VK_ATTACHMENT_UNUSED;
359 for (uint32_t i = 0; i < pCreateInfo->subpassCount; i++) {
Chia-I Wuce532f72015-10-26 17:32:47 +0800360 if (pCreateInfo->pSubpasses[i].pDepthStencilAttachment &&
361 pCreateInfo->pSubpasses[i].pDepthStencilAttachment->attachment != VK_ATTACHMENT_UNUSED) {
Mark Lobodzinski9cce7832015-07-29 09:21:22 -0600362 std::stringstream ss;
363 ss << "vkCreateRenderPass has no depth/stencil attachment, yet subpass[" << i << "] has VkSubpassDescription::depthStencilAttachment value that is not VK_ATTACHMENT_UNUSED";
Michael Lentinecbc4a5e2015-11-03 16:19:46 -0800364 skipCall |= log_msg(my_data->report_data, VK_DBG_REPORT_ERROR_BIT, (VkDbgObjectType)0, 0, 0, IMAGE_RENDERPASS_INVALID_DS_ATTACHMENT, "IMAGE", "%s", ss.str().c_str());
Mark Lobodzinski9cce7832015-07-29 09:21:22 -0600365 }
366 }
367 }
Tobin Ehlis35613802015-09-22 08:40:52 -0600368 if (skipCall)
369 return VK_ERROR_VALIDATION_FAILED;
Mark Lobodzinski9cce7832015-07-29 09:21:22 -0600370
Chia-I Wu69f40122015-10-26 21:10:41 +0800371 VkResult result = my_data->device_dispatch_table->CreateRenderPass(device, pCreateInfo, pAllocator, pRenderPass);
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600372
373 return result;
374}
375
Chia-I Wuaf9e4fd2015-11-06 06:42:02 +0800376VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateImageView(VkDevice device, const VkImageViewCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkImageView* pView)
Tobin Ehlis65380532015-09-21 15:20:28 -0600377{
378 VkBool32 skipCall = VK_FALSE;
379 layer_data *device_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
Chia-I Wue420a332015-10-26 20:04:44 +0800380 auto imageEntry = device_data->imageMap.find(pCreateInfo->image);
Tobin Ehlis65380532015-09-21 15:20:28 -0600381 if (imageEntry != device_data->imageMap.end()) {
Tobin Ehlis6fa437d2015-09-25 14:49:43 -0600382 if (pCreateInfo->subresourceRange.baseMipLevel >= imageEntry->second.mipLevels) {
Tobin Ehlis65380532015-09-21 15:20:28 -0600383 std::stringstream ss;
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600384 ss << "vkCreateImageView called with baseMipLevel " << pCreateInfo->subresourceRange.baseMipLevel
Chia-I Wue420a332015-10-26 20:04:44 +0800385 << " for image " << pCreateInfo->image << " that only has " << imageEntry->second.mipLevels << " mip levels.";
Michael Lentinecbc4a5e2015-11-03 16:19:46 -0800386 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, (VkDbgObjectType)0, 0, 0, IMAGE_VIEW_CREATE_ERROR, "IMAGE", "%s", ss.str().c_str());
Tobin Ehlis65380532015-09-21 15:20:28 -0600387 }
Tobin Ehlis6fa437d2015-09-25 14:49:43 -0600388 if (pCreateInfo->subresourceRange.baseArrayLayer >= imageEntry->second.arraySize) {
Tobin Ehlis65380532015-09-21 15:20:28 -0600389 std::stringstream ss;
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600390 ss << "vkCreateImageView called with baseArrayLayer " << pCreateInfo->subresourceRange.baseArrayLayer << " for image "
Chia-I Wue420a332015-10-26 20:04:44 +0800391 << pCreateInfo->image << " that only has " << imageEntry->second.arraySize << " mip levels.";
Michael Lentinecbc4a5e2015-11-03 16:19:46 -0800392 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, (VkDbgObjectType)0, 0, 0, IMAGE_VIEW_CREATE_ERROR, "IMAGE", "%s", ss.str().c_str());
Tobin Ehlis65380532015-09-21 15:20:28 -0600393 }
Chia-I Wu1f851912015-10-27 18:04:07 +0800394 if (!pCreateInfo->subresourceRange.levelCount) {
Tobin Ehlis65380532015-09-21 15:20:28 -0600395 std::stringstream ss;
396 ss << "vkCreateImageView called with 0 in pCreateInfo->subresourceRange.mipLevels.";
Michael Lentinecbc4a5e2015-11-03 16:19:46 -0800397 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, (VkDbgObjectType)0, 0, 0, IMAGE_VIEW_CREATE_ERROR, "IMAGE", "%s", ss.str().c_str());
Tobin Ehlis65380532015-09-21 15:20:28 -0600398 }
Chia-I Wu1f851912015-10-27 18:04:07 +0800399 if (!pCreateInfo->subresourceRange.layerCount) {
Tobin Ehlis65380532015-09-21 15:20:28 -0600400 std::stringstream ss;
401 ss << "vkCreateImageView called with 0 in pCreateInfo->subresourceRange.arraySize.";
Michael Lentinecbc4a5e2015-11-03 16:19:46 -0800402 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, (VkDbgObjectType)0, 0, 0, IMAGE_VIEW_CREATE_ERROR, "IMAGE", "%s", ss.str().c_str());
Tobin Ehlis65380532015-09-21 15:20:28 -0600403 }
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600404
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600405 // Validate correct image aspect bits for desired formats and format consistency
Tobin Ehlis6fa437d2015-09-25 14:49:43 -0600406 VkFormat imageFormat = imageEntry->second.format;
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600407 VkFormat ivciFormat = pCreateInfo->format;
408 VkImageAspectFlags aspectMask = pCreateInfo->subresourceRange.aspectMask;
409
410 if (vk_format_is_color(imageFormat)) {
411 if ((aspectMask & VK_IMAGE_ASPECT_COLOR_BIT) != VK_IMAGE_ASPECT_COLOR_BIT) {
412 std::stringstream ss;
413 ss << "vkCreateImageView: Color image formats must have the VK_IMAGE_ASPECT_COLOR_BIT set";
414 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_IMAGE,
Michael Lentinecbc4a5e2015-11-03 16:19:46 -0800415 (uint64_t)pCreateInfo->image, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", "%s", ss.str().c_str());
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600416 }
417 if ((aspectMask & VK_IMAGE_ASPECT_COLOR_BIT) != aspectMask) {
418 std::stringstream ss;
419 ss << "vkCreateImageView: Color image formats must have ONLY the VK_IMAGE_ASPECT_COLOR_BIT set";
420 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_IMAGE,
Michael Lentinecbc4a5e2015-11-03 16:19:46 -0800421 (uint64_t)pCreateInfo->image, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", "%s", ss.str().c_str());
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600422 }
423 if (VK_FALSE == vk_format_is_color(ivciFormat)) {
424 std::stringstream ss;
425 ss << "vkCreateImageView: The image view's format can differ from the parent image's format, but both must be "
426 << "color formats. ImageFormat is " << string_VkFormat(imageFormat) << " ImageViewFormat is " << string_VkFormat(ivciFormat);
427 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_IMAGE,
Michael Lentinecbc4a5e2015-11-03 16:19:46 -0800428 (uint64_t)pCreateInfo->image, 0, IMAGE_INVALID_FORMAT, "IMAGE", "%s", ss.str().c_str());
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600429 }
430 // TODO: Uncompressed formats are compatible if they occupy they same number of bits per pixel.
431 // Compressed formats are compatible if the only difference between them is the numerical type of
432 // the uncompressed pixels (e.g. signed vs. unsigned, or sRGB vs. UNORM encoding).
433 } else if (vk_format_is_depth_and_stencil(imageFormat)) {
Mark Lobodzinskidbffb1f2015-11-18 09:14:04 -0700434 if ((aspectMask & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) != 0) {
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600435 std::stringstream ss;
Mark Lobodzinskidbffb1f2015-11-18 09:14:04 -0700436 ss << "vkCreateImageView: Depth/stencil image formats must have at least one of VK_IMAGE_ASPECT_DEPTH_BIT and VK_IMAGE_ASPECT_STENCIL_BIT set";
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600437 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_IMAGE,
Michael Lentinecbc4a5e2015-11-03 16:19:46 -0800438 (uint64_t)pCreateInfo->image, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", "%s", ss.str().c_str());
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600439 }
440 if ((aspectMask & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) != aspectMask) {
441 std::stringstream ss;
442 ss << "vkCreateImageView: Combination depth/stencil image formats can have only the VK_IMAGE_ASPECT_DEPTH_BIT and VK_IMAGE_ASPECT_STENCIL_BIT set";
443 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_IMAGE,
Michael Lentinecbc4a5e2015-11-03 16:19:46 -0800444 (uint64_t)pCreateInfo->image, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", "%s", ss.str().c_str());
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600445 }
446 } else if (vk_format_is_depth_only(imageFormat)) {
447 if ((aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT) != VK_IMAGE_ASPECT_DEPTH_BIT) {
448 std::stringstream ss;
449 ss << "vkCreateImageView: Depth-only image formats must have the VK_IMAGE_ASPECT_DEPTH_BIT set";
450 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_IMAGE,
Michael Lentinecbc4a5e2015-11-03 16:19:46 -0800451 (uint64_t)pCreateInfo->image, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", "%s", ss.str().c_str());
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600452 }
453 if ((aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT) != aspectMask) {
454 std::stringstream ss;
455 ss << "vkCreateImageView: Depth-only image formats can have only the VK_IMAGE_ASPECT_DEPTH_BIT set";
456 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_IMAGE,
Michael Lentinecbc4a5e2015-11-03 16:19:46 -0800457 (uint64_t)pCreateInfo->image, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", "%s", ss.str().c_str());
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600458 }
459 } else if (vk_format_is_stencil_only(imageFormat)) {
460 if ((aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT) != VK_IMAGE_ASPECT_STENCIL_BIT) {
461 std::stringstream ss;
462 ss << "vkCreateImageView: Stencil-only image formats must have the VK_IMAGE_ASPECT_STENCIL_BIT set";
463 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_IMAGE,
Michael Lentinecbc4a5e2015-11-03 16:19:46 -0800464 (uint64_t)pCreateInfo->image, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", "%s", ss.str().c_str());
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600465 }
466 if ((aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT) != aspectMask) {
467 std::stringstream ss;
468 ss << "vkCreateImageView: Stencil-only image formats can have only the VK_IMAGE_ASPECT_STENCIL_BIT set";
469 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_IMAGE,
Michael Lentinecbc4a5e2015-11-03 16:19:46 -0800470 (uint64_t)pCreateInfo->image, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", "%s", ss.str().c_str());
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600471 }
472 }
473 }
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600474
Tobin Ehlis65380532015-09-21 15:20:28 -0600475 if (skipCall)
476 return VK_ERROR_VALIDATION_FAILED;
Tobin Ehlis35613802015-09-22 08:40:52 -0600477
Chia-I Wu69f40122015-10-26 21:10:41 +0800478 VkResult result = device_data->device_dispatch_table->CreateImageView(device, pCreateInfo, pAllocator, pView);
Tobin Ehlis65380532015-09-21 15:20:28 -0600479 return result;
480}
481
Chia-I Wuaf9e4fd2015-11-06 06:42:02 +0800482VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdClearColorImage(
Chia-I Wu1f851912015-10-27 18:04:07 +0800483 VkCommandBuffer commandBuffer,
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600484 VkImage image,
485 VkImageLayout imageLayout,
486 const VkClearColorValue *pColor,
487 uint32_t rangeCount,
488 const VkImageSubresourceRange *pRanges)
489{
490 VkBool32 skipCall = VK_FALSE;
Chia-I Wu1f851912015-10-27 18:04:07 +0800491 layer_data *device_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600492 // For each range, image aspect must be color only
493 for (uint32_t i = 0; i < rangeCount; i++) {
494 if (pRanges[i].aspectMask != VK_IMAGE_ASPECT_COLOR_BIT) {
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600495 char const str[] = "vkCmdClearColorImage aspectMasks for all subresource ranges must be set to VK_IMAGE_ASPECT_COLOR_BIT";
496 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 +0800497 (uint64_t)commandBuffer, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", str);
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600498 }
499 }
500
501 if (VK_FALSE == skipCall) {
Chia-I Wu1f851912015-10-27 18:04:07 +0800502 device_data->device_dispatch_table->CmdClearColorImage(commandBuffer, image, imageLayout,
503 pColor, rangeCount, pRanges);
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600504 }
505}
506
Chia-I Wuaf9e4fd2015-11-06 06:42:02 +0800507VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdClearDepthStencilImage(
Chia-I Wu1f851912015-10-27 18:04:07 +0800508 VkCommandBuffer commandBuffer,
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600509 VkImage image,
510 VkImageLayout imageLayout,
511 const VkClearDepthStencilValue *pDepthStencil,
512 uint32_t rangeCount,
513 const VkImageSubresourceRange *pRanges)
514{
515 VkBool32 skipCall = VK_FALSE;
Chia-I Wu1f851912015-10-27 18:04:07 +0800516 layer_data *device_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600517 // For each range, Image aspect must be depth or stencil or both
518 for (uint32_t i = 0; i < rangeCount; i++) {
519 if (((pRanges[i].aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT) != VK_IMAGE_ASPECT_DEPTH_BIT) &&
520 ((pRanges[i].aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT) != VK_IMAGE_ASPECT_STENCIL_BIT))
521 {
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600522 char const str[] = "vkCmdClearDepthStencilImage aspectMasks for all subresource ranges must be "
523 "set to VK_IMAGE_ASPECT_DEPTH_BIT and/or VK_IMAGE_ASPECT_STENCIL_BIT";
524 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 +0800525 (uint64_t)commandBuffer, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", str);
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600526 }
527 }
528
529 if (VK_FALSE == skipCall) {
Chia-I Wu1f851912015-10-27 18:04:07 +0800530 device_data->device_dispatch_table->CmdClearDepthStencilImage(commandBuffer,
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600531 image, imageLayout, pDepthStencil, rangeCount, pRanges);
532 }
533}
534
Chia-I Wuaf9e4fd2015-11-06 06:42:02 +0800535VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdCopyImage(
Chia-I Wu1f851912015-10-27 18:04:07 +0800536 VkCommandBuffer commandBuffer,
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600537 VkImage srcImage,
538 VkImageLayout srcImageLayout,
Chia-I Wu1f851912015-10-27 18:04:07 +0800539 VkImage dstImage,
540 VkImageLayout dstImageLayout,
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600541 uint32_t regionCount,
542 const VkImageCopy *pRegions)
543{
544 VkBool32 skipCall = VK_FALSE;
Chia-I Wu1f851912015-10-27 18:04:07 +0800545 layer_data *device_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
Chia-I Wue420a332015-10-26 20:04:44 +0800546 auto srcImageEntry = device_data->imageMap.find(srcImage);
Chia-I Wu1f851912015-10-27 18:04:07 +0800547 auto dstImageEntry = device_data->imageMap.find(dstImage);
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600548
Jeremy Hayesac8ed0b2015-10-28 13:01:39 -0600549 // For each region, src and dst number of layers should not be zero
550 // For each region, src and dst number of layers must match
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600551 // For each region, src aspect mask must match dest aspect mask
552 // For each region, color aspects cannot be mixed with depth/stencil aspects
553 for (uint32_t i = 0; i < regionCount; i++) {
Chia-I Wu1f851912015-10-27 18:04:07 +0800554 if(pRegions[i].srcSubresource.layerCount == 0)
Jeremy Hayesac8ed0b2015-10-28 13:01:39 -0600555 {
556 char const str[] = "vkCmdCopyImage: number of layers in source subresource is zero";
557 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 +0800558 (uint64_t)commandBuffer, 0, IMAGE_MISMATCHED_IMAGE_ASPECT, "IMAGE", str);
Jeremy Hayesac8ed0b2015-10-28 13:01:39 -0600559 }
560
Chia-I Wu1f851912015-10-27 18:04:07 +0800561 if(pRegions[i].dstSubresource.layerCount == 0)
Jeremy Hayesac8ed0b2015-10-28 13:01:39 -0600562 {
563 char const str[] = "vkCmdCopyImage: number of layers in destination subresource is zero";
564 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 +0800565 (uint64_t)commandBuffer, 0, IMAGE_MISMATCHED_IMAGE_ASPECT, "IMAGE", str);
Jeremy Hayesac8ed0b2015-10-28 13:01:39 -0600566 }
567
Chia-I Wu1f851912015-10-27 18:04:07 +0800568 if(pRegions[i].srcSubresource.layerCount != pRegions[i].dstSubresource.layerCount)
Jeremy Hayesac8ed0b2015-10-28 13:01:39 -0600569 {
570 char const str[] = "vkCmdCopyImage: number of layers in source and destination subresources must match";
571 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 +0800572 (uint64_t)commandBuffer, 0, IMAGE_MISMATCHED_IMAGE_ASPECT, "IMAGE", str);
Jeremy Hayesac8ed0b2015-10-28 13:01:39 -0600573 }
574
Chia-I Wu4291d882015-10-27 19:00:15 +0800575 if (pRegions[i].srcSubresource.aspectMask != pRegions[i].dstSubresource.aspectMask) {
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600576 char const str[] = "vkCmdCopyImage: Src and dest aspectMasks for each region must match";
577 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 +0800578 (uint64_t)commandBuffer, 0, IMAGE_MISMATCHED_IMAGE_ASPECT, "IMAGE", str);
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600579 }
Chia-I Wu4291d882015-10-27 19:00:15 +0800580 if ((pRegions[i].srcSubresource.aspectMask & VK_IMAGE_ASPECT_COLOR_BIT) &&
581 (pRegions[i].srcSubresource.aspectMask & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT))) {
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600582 char const str[] = "vkCmdCopyImage aspectMask cannot specify both COLOR and DEPTH/STENCIL aspects";
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_INVALID_IMAGE_ASPECT, "IMAGE", str);
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600585 }
586 }
587
Mike Stroyan43909d82015-09-25 13:39:21 -0600588 if ((srcImageEntry != device_data->imageMap.end())
Chia-I Wu1f851912015-10-27 18:04:07 +0800589 && (dstImageEntry != device_data->imageMap.end())) {
590 if (srcImageEntry->second.imageType != dstImageEntry->second.imageType) {
Mike Stroyan43909d82015-09-25 13:39:21 -0600591 char const str[] = "vkCmdCopyImage called with unmatched source and dest image types.";
592 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 +0800593 (uint64_t)commandBuffer, 0, IMAGE_MISMATCHED_IMAGE_TYPE, "IMAGE", str);
Mike Stroyan43909d82015-09-25 13:39:21 -0600594 }
595 // Check that format is same size or exact stencil/depth
Tobin Ehlis6fa437d2015-09-25 14:49:43 -0600596 if (is_depth_format(srcImageEntry->second.format)) {
Chia-I Wu1f851912015-10-27 18:04:07 +0800597 if (srcImageEntry->second.format != dstImageEntry->second.format) {
Mike Stroyan43909d82015-09-25 13:39:21 -0600598 char const str[] = "vkCmdCopyImage called with unmatched source and dest image depth/stencil formats.";
599 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 +0800600 (uint64_t)commandBuffer, 0, IMAGE_MISMATCHED_IMAGE_FORMAT, "IMAGE", str);
Mike Stroyan43909d82015-09-25 13:39:21 -0600601 }
602 } else {
Tobin Ehlis6fa437d2015-09-25 14:49:43 -0600603 size_t srcSize = vk_format_get_size(srcImageEntry->second.format);
Chia-I Wu1f851912015-10-27 18:04:07 +0800604 size_t destSize = vk_format_get_size(dstImageEntry->second.format);
Mike Stroyan43909d82015-09-25 13:39:21 -0600605 if (srcSize != destSize) {
606 char const str[] = "vkCmdCopyImage called with unmatched source and dest image format sizes.";
607 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 +0800608 (uint64_t)commandBuffer, 0, IMAGE_MISMATCHED_IMAGE_FORMAT, "IMAGE", str);
Mike Stroyan43909d82015-09-25 13:39:21 -0600609 }
610 }
611 }
612
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600613 if (VK_FALSE == skipCall) {
Chia-I Wu1f851912015-10-27 18:04:07 +0800614 device_data->device_dispatch_table->CmdCopyImage(commandBuffer, srcImage,
615 srcImageLayout, dstImage, dstImageLayout, regionCount, pRegions);
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600616 }
617}
618
Chia-I Wuaf9e4fd2015-11-06 06:42:02 +0800619VKAPI_ATTR void VKAPI_CALL vkCmdClearAttachments(
Chia-I Wu1f851912015-10-27 18:04:07 +0800620 VkCommandBuffer commandBuffer,
Courtney Goeltzenleuchter9feb0732015-10-15 16:51:05 -0600621 uint32_t attachmentCount,
622 const VkClearAttachment* pAttachments,
623 uint32_t rectCount,
Courtney Goeltzenleuchtera12e2912015-10-15 18:22:08 -0600624 const VkClearRect* pRects)
Courtney Goeltzenleuchter9feb0732015-10-15 16:51:05 -0600625{
626 VkBool32 skipCall = VK_FALSE;
627 VkImageAspectFlags aspectMask;
Chia-I Wu1f851912015-10-27 18:04:07 +0800628 layer_data *device_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
Courtney Goeltzenleuchter9feb0732015-10-15 16:51:05 -0600629 for (uint32_t i = 0; i < attachmentCount; i++) {
630 aspectMask = pAttachments[i].aspectMask;
631 if (aspectMask & VK_IMAGE_ASPECT_COLOR_BIT) {
632 if (aspectMask != VK_IMAGE_ASPECT_COLOR_BIT) {
633 // VK_IMAGE_ASPECT_COLOR_BIT is not the only bit set for this attachment
Courtney Goeltzenleuchter9feb0732015-10-15 16:51:05 -0600634 char const str[] = "vkCmdClearAttachments aspectMask [%d] must set only VK_IMAGE_ASPECT_COLOR_BIT of a color attachment.";
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 } else {
639 // Image aspect must be depth or stencil or both
640 if (((aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT) != VK_IMAGE_ASPECT_DEPTH_BIT) &&
641 ((aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT) != VK_IMAGE_ASPECT_STENCIL_BIT))
642 {
Courtney Goeltzenleuchter9feb0732015-10-15 16:51:05 -0600643 char const str[] = "vkCmdClearAttachments aspectMask [%d] must be set to VK_IMAGE_ASPECT_DEPTH_BIT and/or VK_IMAGE_ASPECT_STENCIL_BIT";
644 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 +0800645 (uint64_t)commandBuffer, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", str, i);
Courtney Goeltzenleuchter9feb0732015-10-15 16:51:05 -0600646 }
647 }
648 }
649
650 if (VK_FALSE == skipCall) {
Chia-I Wu1f851912015-10-27 18:04:07 +0800651 device_data->device_dispatch_table->CmdClearAttachments(commandBuffer,
Courtney Goeltzenleuchter9feb0732015-10-15 16:51:05 -0600652 attachmentCount, pAttachments, rectCount, pRects);
653 }
654}
655
Chia-I Wuaf9e4fd2015-11-06 06:42:02 +0800656VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdCopyImageToBuffer(
Chia-I Wu1f851912015-10-27 18:04:07 +0800657 VkCommandBuffer commandBuffer,
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600658 VkImage srcImage,
659 VkImageLayout srcImageLayout,
Chia-I Wu1f851912015-10-27 18:04:07 +0800660 VkBuffer dstBuffer,
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600661 uint32_t regionCount,
662 const VkBufferImageCopy *pRegions)
663{
664 VkBool32 skipCall = VK_FALSE;
Chia-I Wu1f851912015-10-27 18:04:07 +0800665 layer_data *device_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
Jeremy Hayesac8ed0b2015-10-28 13:01:39 -0600666 // For each region, the number of layers in the image subresource should not be zero
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600667 // Image aspect must be ONE OF color, depth, stencil
668 for (uint32_t i = 0; i < regionCount; i++) {
Chia-I Wu1f851912015-10-27 18:04:07 +0800669 if(pRegions[i].imageSubresource.layerCount == 0)
Jeremy Hayesac8ed0b2015-10-28 13:01:39 -0600670 {
Jeremy Hayesac8ed0b2015-10-28 13:01:39 -0600671 char const str[] = "vkCmdCopyImageToBuffer: number of layers in image subresource is zero";
672 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 +0800673 (uint64_t)commandBuffer, 0, IMAGE_MISMATCHED_IMAGE_ASPECT, "IMAGE", str);
Jeremy Hayesac8ed0b2015-10-28 13:01:39 -0600674 }
675
Chia-I Wu4291d882015-10-27 19:00:15 +0800676 VkImageAspectFlags aspectMask = pRegions[i].imageSubresource.aspectMask;
677 if ((aspectMask != VK_IMAGE_ASPECT_COLOR_BIT) &&
678 (aspectMask != VK_IMAGE_ASPECT_DEPTH_BIT) &&
679 (aspectMask != VK_IMAGE_ASPECT_STENCIL_BIT)) {
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600680 char const str[] = "vkCmdCopyImageToBuffer: aspectMasks for each region must specify only COLOR or DEPTH or STENCIL";
681 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 +0800682 (uint64_t)commandBuffer, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", str);
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600683 }
684 }
685
686 if (VK_FALSE == skipCall) {
Chia-I Wu1f851912015-10-27 18:04:07 +0800687 device_data->device_dispatch_table->CmdCopyImageToBuffer(commandBuffer,
688 srcImage, srcImageLayout, dstBuffer, regionCount, pRegions);
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600689 }
690}
691
Chia-I Wuaf9e4fd2015-11-06 06:42:02 +0800692VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdCopyBufferToImage(
Chia-I Wu1f851912015-10-27 18:04:07 +0800693 VkCommandBuffer commandBuffer,
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600694 VkBuffer srcBuffer,
Chia-I Wu1f851912015-10-27 18:04:07 +0800695 VkImage dstImage,
696 VkImageLayout dstImageLayout,
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600697 uint32_t regionCount,
698 const VkBufferImageCopy *pRegions)
699{
700 VkBool32 skipCall = VK_FALSE;
Chia-I Wu1f851912015-10-27 18:04:07 +0800701 layer_data *device_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
Jeremy Hayesac8ed0b2015-10-28 13:01:39 -0600702 // For each region, the number of layers in the image subresource should not be zero
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600703 // Image aspect must be ONE OF color, depth, stencil
704 for (uint32_t i = 0; i < regionCount; i++) {
Chia-I Wu1f851912015-10-27 18:04:07 +0800705 if(pRegions[i].imageSubresource.layerCount == 0)
Jeremy Hayesac8ed0b2015-10-28 13:01:39 -0600706 {
Jeremy Hayesac8ed0b2015-10-28 13:01:39 -0600707 char const str[] = "vkCmdCopyBufferToImage: number of layers in image subresource is zero";
708 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 +0800709 (uint64_t)commandBuffer, 0, IMAGE_MISMATCHED_IMAGE_ASPECT, "IMAGE", str);
Jeremy Hayesac8ed0b2015-10-28 13:01:39 -0600710 }
711
Chia-I Wu4291d882015-10-27 19:00:15 +0800712 VkImageAspectFlags aspectMask = pRegions[i].imageSubresource.aspectMask;
713 if ((aspectMask != VK_IMAGE_ASPECT_COLOR_BIT) &&
714 (aspectMask != VK_IMAGE_ASPECT_DEPTH_BIT) &&
715 (aspectMask != VK_IMAGE_ASPECT_STENCIL_BIT)) {
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600716 char const str[] = "vkCmdCopyBufferToImage: aspectMasks for each region must specify only COLOR or DEPTH or STENCIL";
717 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 +0800718 (uint64_t)commandBuffer, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", str);
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600719 }
720 }
721
722 if (VK_FALSE == skipCall) {
Chia-I Wu1f851912015-10-27 18:04:07 +0800723 device_data->device_dispatch_table->CmdCopyBufferToImage(commandBuffer,
724 srcBuffer, dstImage, dstImageLayout, regionCount, pRegions);
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600725 }
726}
727
Chia-I Wuaf9e4fd2015-11-06 06:42:02 +0800728VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdBlitImage(
Chia-I Wu1f851912015-10-27 18:04:07 +0800729 VkCommandBuffer commandBuffer,
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600730 VkImage srcImage,
731 VkImageLayout srcImageLayout,
Chia-I Wu1f851912015-10-27 18:04:07 +0800732 VkImage dstImage,
733 VkImageLayout dstImageLayout,
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600734 uint32_t regionCount,
735 const VkImageBlit *pRegions,
Chia-I Wu3603b082015-10-26 16:49:32 +0800736 VkFilter filter)
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600737{
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600738 VkBool32 skipCall = VK_FALSE;
Chia-I Wu1f851912015-10-27 18:04:07 +0800739 layer_data *device_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600740
Chia-I Wue420a332015-10-26 20:04:44 +0800741 auto srcImageEntry = device_data->imageMap.find(srcImage);
Chia-I Wu1f851912015-10-27 18:04:07 +0800742 auto dstImageEntry = device_data->imageMap.find(dstImage);
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600743
744 if ((srcImageEntry != device_data->imageMap.end()) &&
Chia-I Wu1f851912015-10-27 18:04:07 +0800745 (dstImageEntry != device_data->imageMap.end())) {
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600746
Tobin Ehlis6fa437d2015-09-25 14:49:43 -0600747 VkFormat srcFormat = srcImageEntry->second.format;
Chia-I Wu1f851912015-10-27 18:04:07 +0800748 VkFormat dstFormat = dstImageEntry->second.format;
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600749
750 // Validate consistency for signed and unsigned formats
751 if ((vk_format_is_sint(srcFormat) && !vk_format_is_sint(dstFormat)) ||
752 (vk_format_is_uint(srcFormat) && !vk_format_is_uint(dstFormat))) {
753 std::stringstream ss;
Chia-I Wu1f851912015-10-27 18:04:07 +0800754 ss << "vkCmdBlitImage: If one of srcImage and dstImage images has signed/unsigned integer format, "
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600755 << "the other one must also have signed/unsigned integer format. "
756 << "Source format is " << string_VkFormat(srcFormat) << " Destinatino format is " << string_VkFormat(dstFormat);
757 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
Michael Lentinecbc4a5e2015-11-03 16:19:46 -0800758 (uint64_t)commandBuffer, 0, IMAGE_INVALID_FORMAT, "IMAGE", "%s", ss.str().c_str());
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600759 }
760
761 // Validate aspect bits and formats for depth/stencil images
762 if (vk_format_is_depth_or_stencil(srcFormat) ||
763 vk_format_is_depth_or_stencil(dstFormat)) {
764 if (srcFormat != dstFormat) {
765 std::stringstream ss;
Chia-I Wu1f851912015-10-27 18:04:07 +0800766 ss << "vkCmdBlitImage: If one of srcImage and dstImage images has a format of depth, stencil or depth "
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600767 << "stencil, the other one must have exactly the same format. "
768 << "Source format is " << string_VkFormat(srcFormat) << " Destinatino format is " << string_VkFormat(dstFormat);
769 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
Michael Lentinecbc4a5e2015-11-03 16:19:46 -0800770 (uint64_t)commandBuffer, 0, IMAGE_INVALID_FORMAT, "IMAGE", "%s", ss.str().c_str());
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600771 }
772
773 for (uint32_t i = 0; i < regionCount; i++) {
Chia-I Wu1f851912015-10-27 18:04:07 +0800774 if(pRegions[i].srcSubresource.layerCount == 0)
Jeremy Hayesac8ed0b2015-10-28 13:01:39 -0600775 {
776 char const str[] = "vkCmdBlitImage: number of layers in source subresource is zero";
777 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 +0800778 (uint64_t)commandBuffer, 0, IMAGE_MISMATCHED_IMAGE_ASPECT, "IMAGE", str);
Jeremy Hayesac8ed0b2015-10-28 13:01:39 -0600779 }
780
Chia-I Wu1f851912015-10-27 18:04:07 +0800781 if(pRegions[i].dstSubresource.layerCount == 0)
Jeremy Hayesac8ed0b2015-10-28 13:01:39 -0600782 {
783 char const str[] = "vkCmdBlitImage: number of layers in destination subresource is zero";
784 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 +0800785 (uint64_t)commandBuffer, 0, IMAGE_MISMATCHED_IMAGE_ASPECT, "IMAGE", str);
Jeremy Hayesac8ed0b2015-10-28 13:01:39 -0600786 }
787
Chia-I Wu1f851912015-10-27 18:04:07 +0800788 if(pRegions[i].srcSubresource.layerCount != pRegions[i].dstSubresource.layerCount)
Jeremy Hayesac8ed0b2015-10-28 13:01:39 -0600789 {
790 char const str[] = "vkCmdBlitImage: number of layers in source and destination subresources must match";
791 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 +0800792 (uint64_t)commandBuffer, 0, IMAGE_MISMATCHED_IMAGE_ASPECT, "IMAGE", str);
Jeremy Hayesac8ed0b2015-10-28 13:01:39 -0600793 }
794
Chia-I Wu4291d882015-10-27 19:00:15 +0800795 VkImageAspectFlags srcAspect = pRegions[i].srcSubresource.aspectMask;
796 VkImageAspectFlags dstAspect = pRegions[i].dstSubresource.aspectMask;
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600797
798 if (srcAspect != dstAspect) {
799 std::stringstream ss;
800 ss << "vkCmdBlitImage: Image aspects of depth/stencil images should match";
801 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_WARN_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
Michael Lentinecbc4a5e2015-11-03 16:19:46 -0800802 (uint64_t)commandBuffer, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", "%s", ss.str().c_str());
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600803 }
804 if (vk_format_is_depth_and_stencil(srcFormat)) {
805 if (srcAspect != (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) {
806 std::stringstream ss;
807 ss << "vkCmdBlitImage: Combination depth/stencil image formats must have both VK_IMAGE_ASPECT_DEPTH_BIT "
Chia-I Wu1f851912015-10-27 18:04:07 +0800808 << "and VK_IMAGE_ASPECT_STENCIL_BIT set in both the srcImage and dstImage";
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600809 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
Michael Lentinecbc4a5e2015-11-03 16:19:46 -0800810 (uint64_t)commandBuffer, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", "%s", ss.str().c_str());
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600811 }
812 } else if (vk_format_is_stencil_only(srcFormat)) {
813 if (srcAspect != VK_IMAGE_ASPECT_STENCIL_BIT) {
814 std::stringstream ss;
815 ss << "vkCmdBlitImage: Stencil-only image formats must have only the VK_IMAGE_ASPECT_STENCIL_BIT "
Chia-I Wu1f851912015-10-27 18:04:07 +0800816 << "set in both the srcImage and dstImage";
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600817 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
Michael Lentinecbc4a5e2015-11-03 16:19:46 -0800818 (uint64_t)commandBuffer, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", "%s", ss.str().c_str());
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600819 }
820 } else if (vk_format_is_depth_only(srcFormat)) {
821 if (srcAspect != VK_IMAGE_ASPECT_DEPTH_BIT) {
822 std::stringstream ss;
823 ss << "vkCmdBlitImage: Depth-only image formats must have only the VK_IMAGE_ASPECT_DEPTH "
Chia-I Wu1f851912015-10-27 18:04:07 +0800824 << "set in both the srcImage and dstImage";
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600825 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
Michael Lentinecbc4a5e2015-11-03 16:19:46 -0800826 (uint64_t)commandBuffer, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", "%s", ss.str().c_str());
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600827 }
828 }
829 }
830 }
831
832 // Validate filter
833 if (vk_format_is_depth_or_stencil(srcFormat) ||
834 vk_format_is_int(srcFormat)) {
Chia-I Wu3603b082015-10-26 16:49:32 +0800835 if (filter != VK_FILTER_NEAREST) {
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600836 std::stringstream ss;
837 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 +0800838 << "then filter must be VK_FILTER_NEAREST.";
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600839 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
Michael Lentinecbc4a5e2015-11-03 16:19:46 -0800840 (uint64_t)commandBuffer, 0, IMAGE_INVALID_FILTER, "IMAGE", "%s", ss.str().c_str());
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600841 }
842 }
843 }
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600844
Chia-I Wu1f851912015-10-27 18:04:07 +0800845 device_data->device_dispatch_table->CmdBlitImage(commandBuffer, srcImage,
846 srcImageLayout, dstImage, dstImageLayout, regionCount, pRegions, filter);
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600847}
848
Chia-I Wuaf9e4fd2015-11-06 06:42:02 +0800849VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdResolveImage(
Chia-I Wu1f851912015-10-27 18:04:07 +0800850 VkCommandBuffer commandBuffer,
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600851 VkImage srcImage,
852 VkImageLayout srcImageLayout,
Chia-I Wu1f851912015-10-27 18:04:07 +0800853 VkImage dstImage,
854 VkImageLayout dstImageLayout,
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600855 uint32_t regionCount,
856 const VkImageResolve *pRegions)
857{
858 VkBool32 skipCall = VK_FALSE;
Chia-I Wu1f851912015-10-27 18:04:07 +0800859 layer_data *device_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
Chia-I Wue420a332015-10-26 20:04:44 +0800860 auto srcImageEntry = device_data->imageMap.find(srcImage);
Chia-I Wu1f851912015-10-27 18:04:07 +0800861 auto dstImageEntry = device_data->imageMap.find(dstImage);
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600862
Jeremy Hayesac8ed0b2015-10-28 13:01:39 -0600863 // For each region, the number of layers in the image subresource should not be zero
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600864 // For each region, src and dest image aspect must be color only
865 for (uint32_t i = 0; i < regionCount; i++) {
Chia-I Wu1f851912015-10-27 18:04:07 +0800866 if(pRegions[i].srcSubresource.layerCount == 0)
Jeremy Hayesac8ed0b2015-10-28 13:01:39 -0600867 {
868 char const str[] = "vkCmdResolveImage: number of layers in source subresource is zero";
869 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 +0800870 (uint64_t)commandBuffer, 0, IMAGE_MISMATCHED_IMAGE_ASPECT, "IMAGE", str);
Jeremy Hayesac8ed0b2015-10-28 13:01:39 -0600871 }
872
Chia-I Wu1f851912015-10-27 18:04:07 +0800873 if(pRegions[i].dstSubresource.layerCount == 0)
Jeremy Hayesac8ed0b2015-10-28 13:01:39 -0600874 {
875 char const str[] = "vkCmdResolveImage: number of layers in destination subresource is zero";
876 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 +0800877 (uint64_t)commandBuffer, 0, IMAGE_MISMATCHED_IMAGE_ASPECT, "IMAGE", str);
Jeremy Hayesac8ed0b2015-10-28 13:01:39 -0600878 }
879
Chia-I Wu4291d882015-10-27 19:00:15 +0800880 if ((pRegions[i].srcSubresource.aspectMask != VK_IMAGE_ASPECT_COLOR_BIT) ||
881 (pRegions[i].dstSubresource.aspectMask != VK_IMAGE_ASPECT_COLOR_BIT)) {
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600882 char const str[] = "vkCmdResolveImage: src and dest aspectMasks for each region must specify only VK_IMAGE_ASPECT_COLOR_BIT";
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_INVALID_IMAGE_ASPECT, "IMAGE", str);
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600885 }
886 }
887
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600888 if ((srcImageEntry != device_data->imageMap.end()) &&
Chia-I Wu1f851912015-10-27 18:04:07 +0800889 (dstImageEntry != device_data->imageMap.end())) {
890 if (srcImageEntry->second.format != dstImageEntry->second.format) {
Mike Stroyan43909d82015-09-25 13:39:21 -0600891 char const str[] = "vkCmdResolveImage called with unmatched source and dest formats.";
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_MISMATCHED_IMAGE_FORMAT, "IMAGE", str);
Mike Stroyan43909d82015-09-25 13:39:21 -0600894 }
Chia-I Wu1f851912015-10-27 18:04:07 +0800895 if (srcImageEntry->second.imageType != dstImageEntry->second.imageType) {
Mike Stroyan43909d82015-09-25 13:39:21 -0600896 char const str[] = "vkCmdResolveImage called with unmatched source and dest image types.";
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_MISMATCHED_IMAGE_TYPE, "IMAGE", str);
Mike Stroyan43909d82015-09-25 13:39:21 -0600899 }
Chia-I Wu3138d6a2015-10-31 00:31:16 +0800900 if (srcImageEntry->second.samples == VK_SAMPLE_COUNT_1_BIT) {
Mike Stroyan43909d82015-09-25 13:39:21 -0600901 char const str[] = "vkCmdResolveImage called with source sample count less than 2.";
902 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 +0800903 (uint64_t)commandBuffer, 0, IMAGE_INVALID_RESOLVE_SAMPLES, "IMAGE", str);
Mike Stroyan43909d82015-09-25 13:39:21 -0600904 }
Chia-I Wu3138d6a2015-10-31 00:31:16 +0800905 if (dstImageEntry->second.samples != VK_SAMPLE_COUNT_1_BIT) {
Mike Stroyan43909d82015-09-25 13:39:21 -0600906 char const str[] = "vkCmdResolveImage called with dest sample count greater than 1.";
907 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 +0800908 (uint64_t)commandBuffer, 0, IMAGE_INVALID_RESOLVE_SAMPLES, "IMAGE", str);
Mike Stroyan43909d82015-09-25 13:39:21 -0600909 }
910 }
911
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600912 if (VK_FALSE == skipCall) {
Chia-I Wu1f851912015-10-27 18:04:07 +0800913 device_data->device_dispatch_table->CmdResolveImage(commandBuffer, srcImage,
914 srcImageLayout, dstImage, dstImageLayout, regionCount, pRegions);
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600915 }
916}
917
Chia-I Wuaf9e4fd2015-11-06 06:42:02 +0800918VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL vkGetImageSubresourceLayout(
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600919 VkDevice device,
920 VkImage image,
921 const VkImageSubresource *pSubresource,
922 VkSubresourceLayout *pLayout)
923{
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600924 VkBool32 skipCall = VK_FALSE;
925 layer_data *device_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
926 VkFormat format;
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600927
Chia-I Wue420a332015-10-26 20:04:44 +0800928 auto imageEntry = device_data->imageMap.find(image);
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600929
930 // Validate that image aspects match formats
931 if (imageEntry != device_data->imageMap.end()) {
Tobin Ehlis6fa437d2015-09-25 14:49:43 -0600932 format = imageEntry->second.format;
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600933 if (vk_format_is_color(format)) {
Chia-I Wu195c9e12015-10-27 19:55:05 +0800934 if (pSubresource->aspectMask != VK_IMAGE_ASPECT_COLOR_BIT) {
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600935 std::stringstream ss;
Chia-I Wu195c9e12015-10-27 19:55:05 +0800936 ss << "vkGetImageSubresourceLayout: For color formats, the aspectMask field of VkImageSubresource must be VK_IMAGE_ASPECT_COLOR.";
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600937 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_IMAGE,
Michael Lentinecbc4a5e2015-11-03 16:19:46 -0800938 (uint64_t)image, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", "%s", ss.str().c_str());
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600939 }
940 } else if (vk_format_is_depth_or_stencil(format)) {
Chia-I Wu195c9e12015-10-27 19:55:05 +0800941 if ((pSubresource->aspectMask != VK_IMAGE_ASPECT_DEPTH_BIT) &&
942 (pSubresource->aspectMask != VK_IMAGE_ASPECT_STENCIL_BIT)) {
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600943 std::stringstream ss;
Chia-I Wu195c9e12015-10-27 19:55:05 +0800944 ss << "vkGetImageSubresourceLayout: For depth/stencil formats, the aspectMask selects either the depth or stencil image aspectMask.";
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600945 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_IMAGE,
Michael Lentinecbc4a5e2015-11-03 16:19:46 -0800946 (uint64_t)image, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", "%s", ss.str().c_str());
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600947 }
948 }
949 }
950
951 if (VK_FALSE == skipCall) {
Tobin Ehlis049f1782015-10-29 14:19:18 -0600952 device_data->device_dispatch_table->GetImageSubresourceLayout(device,
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600953 image, pSubresource, pLayout);
954 }
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600955}
956
Chia-I Wuaf9e4fd2015-11-06 06:42:02 +0800957VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetDeviceProcAddr(VkDevice device, const char* funcName)
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600958{
959 if (device == NULL) {
960 return NULL;
961 }
962
Tobin Ehlis049f1782015-10-29 14:19:18 -0600963 layer_data *my_data;
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600964 // loader uses this to force layer initialization; device object is wrapped
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600965 if (!strcmp(funcName, "vkGetDeviceProcAddr")) {
Tobin Ehlis049f1782015-10-29 14:19:18 -0600966 VkBaseLayerObject* wrapped_dev = (VkBaseLayerObject*) device;
967 my_data = get_my_data_ptr(get_dispatch_key(wrapped_dev->baseObject), layer_data_map);
968 my_data->device_dispatch_table = new VkLayerDispatchTable;
969 layer_initialize_dispatch_table(my_data->device_dispatch_table, wrapped_dev);
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -0600970 return (PFN_vkVoidFunction) vkGetDeviceProcAddr;
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600971 }
972
Tobin Ehlis049f1782015-10-29 14:19:18 -0600973 my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
Courtney Goeltzenleuchterbe637992015-06-25 18:01:43 -0600974 if (!strcmp(funcName, "vkCreateDevice"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -0600975 return (PFN_vkVoidFunction) vkCreateDevice;
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600976 if (!strcmp(funcName, "vkDestroyDevice"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -0600977 return (PFN_vkVoidFunction) vkDestroyDevice;
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600978 if (!strcmp(funcName, "vkCreateImage"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -0600979 return (PFN_vkVoidFunction) vkCreateImage;
Mark Lobodzinski9eb1ce42015-10-29 12:58:33 -0600980 if (!strcmp(funcName, "vkDestroyImage"))
981 return (PFN_vkVoidFunction) vkDestroyImage;
Tobin Ehlis342b9bf2015-09-22 10:11:37 -0600982 if (!strcmp(funcName, "vkCreateImageView"))
983 return (PFN_vkVoidFunction) vkCreateImageView;
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600984 if (!strcmp(funcName, "vkCreateRenderPass"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -0600985 return (PFN_vkVoidFunction) vkCreateRenderPass;
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600986 if (!strcmp(funcName, "vkCmdClearColorImage"))
987 return (PFN_vkVoidFunction) vkCmdClearColorImage;
988 if (!strcmp(funcName, "vkCmdClearDepthStencilImage"))
989 return (PFN_vkVoidFunction) vkCmdClearDepthStencilImage;
Courtney Goeltzenleuchter9feb0732015-10-15 16:51:05 -0600990 if (!strcmp(funcName, "vkCmdClearAttachments"))
991 return (PFN_vkVoidFunction) vkCmdClearAttachments;
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600992 if (!strcmp(funcName, "vkCmdCopyImage"))
993 return (PFN_vkVoidFunction) vkCmdCopyImage;
994 if (!strcmp(funcName, "vkCmdCopyImageToBuffer"))
995 return (PFN_vkVoidFunction) vkCmdCopyImageToBuffer;
996 if (!strcmp(funcName, "vkCmdCopyBufferToImage"))
997 return (PFN_vkVoidFunction) vkCmdCopyBufferToImage;
998 if (!strcmp(funcName, "vkCmdBlitImage"))
999 return (PFN_vkVoidFunction) vkCmdBlitImage;
1000 if (!strcmp(funcName, "vkCmdResolveImage"))
1001 return (PFN_vkVoidFunction) vkCmdResolveImage;
1002 if (!strcmp(funcName, "vkGetImageSubresourceLayout"))
1003 return (PFN_vkVoidFunction) vkGetImageSubresourceLayout;
Tobin Ehlis049f1782015-10-29 14:19:18 -06001004
1005 VkLayerDispatchTable* pTable = my_data->device_dispatch_table;
Jeremy Hayesb707aa52015-06-18 10:12:39 -06001006 {
Tobin Ehlis049f1782015-10-29 14:19:18 -06001007 if (pTable->GetDeviceProcAddr == NULL)
Jeremy Hayesb707aa52015-06-18 10:12:39 -06001008 return NULL;
Tobin Ehlis049f1782015-10-29 14:19:18 -06001009 return pTable->GetDeviceProcAddr(device, funcName);
Jeremy Hayesb707aa52015-06-18 10:12:39 -06001010 }
1011}
1012
Chia-I Wuaf9e4fd2015-11-06 06:42:02 +08001013VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetInstanceProcAddr(VkInstance instance, const char* funcName)
Jeremy Hayesb707aa52015-06-18 10:12:39 -06001014{
1015 if (instance == NULL) {
1016 return NULL;
1017 }
1018
Tobin Ehlis049f1782015-10-29 14:19:18 -06001019 layer_data *my_data;
Mark Lobodzinskib4092de2015-10-23 14:20:31 -06001020 // loader uses this to force layer initialization; instance object is wrapped
Jeremy Hayesb707aa52015-06-18 10:12:39 -06001021 if (!strcmp(funcName, "vkGetInstanceProcAddr")) {
Tobin Ehlis049f1782015-10-29 14:19:18 -06001022 VkBaseLayerObject* wrapped_inst = (VkBaseLayerObject*) instance;
1023 my_data = get_my_data_ptr(get_dispatch_key(wrapped_inst->baseObject), layer_data_map);
1024 my_data->instance_dispatch_table = new VkLayerInstanceDispatchTable;
1025 layer_init_instance_dispatch_table(my_data->instance_dispatch_table, wrapped_inst);
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06001026 return (PFN_vkVoidFunction) vkGetInstanceProcAddr;
Jeremy Hayesb707aa52015-06-18 10:12:39 -06001027 }
1028
Tobin Ehlis049f1782015-10-29 14:19:18 -06001029 my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
Jeremy Hayesb707aa52015-06-18 10:12:39 -06001030 if (!strcmp(funcName, "vkCreateInstance"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06001031 return (PFN_vkVoidFunction) vkCreateInstance;
Jeremy Hayesb707aa52015-06-18 10:12:39 -06001032 if (!strcmp(funcName, "vkDestroyInstance"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06001033 return (PFN_vkVoidFunction) vkDestroyInstance;
Courtney Goeltzenleuchter74c4ce92015-09-14 17:22:16 -06001034 if (!strcmp(funcName, "vkEnumerateInstanceLayerProperties"))
1035 return (PFN_vkVoidFunction) vkEnumerateInstanceLayerProperties;
1036 if (!strcmp(funcName, "vkEnumerateInstanceExtensionProperties"))
1037 return (PFN_vkVoidFunction) vkEnumerateInstanceExtensionProperties;
1038 if (!strcmp(funcName, "vkEnumerateDeviceLayerProperties"))
1039 return (PFN_vkVoidFunction) vkEnumerateDeviceLayerProperties;
1040 if (!strcmp(funcName, "vkEnumerateDeviceExtensionProperties"))
1041 return (PFN_vkVoidFunction) vkEnumerateDeviceExtensionProperties;
Jeremy Hayesb707aa52015-06-18 10:12:39 -06001042
Tobin Ehlis049f1782015-10-29 14:19:18 -06001043 PFN_vkVoidFunction fptr = debug_report_get_instance_proc_addr(my_data->report_data, funcName);
Jeremy Hayesb707aa52015-06-18 10:12:39 -06001044 if(fptr)
1045 return fptr;
1046
1047 {
Tobin Ehlis049f1782015-10-29 14:19:18 -06001048 VkLayerInstanceDispatchTable* pTable = my_data->instance_dispatch_table;
1049 if (pTable->GetInstanceProcAddr == NULL)
Jeremy Hayesb707aa52015-06-18 10:12:39 -06001050 return NULL;
Tobin Ehlis049f1782015-10-29 14:19:18 -06001051 return pTable->GetInstanceProcAddr(instance, funcName);
Jeremy Hayesb707aa52015-06-18 10:12:39 -06001052 }
1053}