blob: b9d49b328517281aaadcab07c47ca8780e9457b1 [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 Wu69f40122015-10-26 21:10:41 +0800115VK_LAYER_EXPORT VkResult VKAPI vkCreateInstance(const VkInstanceCreateInfo* pCreateInfo, const VkAllocCallbacks* 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 Wu69f40122015-10-26 21:10:41 +0800130VK_LAYER_EXPORT void VKAPI vkDestroyInstance(VkInstance instance, const VkAllocCallbacks* 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 Wu69f40122015-10-26 21:10:41 +0800151VK_LAYER_EXPORT VkResult VKAPI vkCreateDevice(VkPhysicalDevice physicalDevice, const VkDeviceCreateInfo* pCreateInfo, const VkAllocCallbacks* 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 Wu69f40122015-10-26 21:10:41 +0800165VK_LAYER_EXPORT void VKAPI vkDestroyDevice(VkDevice device, const VkAllocCallbacks* 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{
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600207 // ParamChecker does not have any physical device extensions
Courtney Goeltzenleuchtereb1ddb02015-07-07 11:18:30 -0600208 return util_GetExtensionProperties(0, NULL, pCount, pProperties);
209}
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600210
Courtney Goeltzenleuchter74c4ce92015-09-14 17:22:16 -0600211VK_LAYER_EXPORT VkResult VKAPI vkEnumerateDeviceLayerProperties(
Courtney Goeltzenleuchtereb1ddb02015-07-07 11:18:30 -0600212 VkPhysicalDevice physicalDevice,
213 uint32_t* pCount,
214 VkLayerProperties* pProperties)
215{
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600216 // ParamChecker's physical device layers are the same as global
Courtney Goeltzenleuchtereb1ddb02015-07-07 11:18:30 -0600217 return util_GetLayerProperties(ARRAY_SIZE(pc_global_layers), pc_global_layers,
218 pCount, pProperties);
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600219}
220
Mark Lobodzinski9cce7832015-07-29 09:21:22 -0600221// Start of the Image layer proper
222
223// Returns TRUE if a format is a depth-compatible format
224bool is_depth_format(VkFormat format)
225{
226 bool result = VK_FALSE;
227 switch (format) {
228 case VK_FORMAT_D16_UNORM:
Courtney Goeltzenleuchter7ed10592015-09-10 17:17:43 -0600229 case VK_FORMAT_D24_UNORM_X8:
Mark Lobodzinski9cce7832015-07-29 09:21:22 -0600230 case VK_FORMAT_D32_SFLOAT:
231 case VK_FORMAT_S8_UINT:
232 case VK_FORMAT_D16_UNORM_S8_UINT:
233 case VK_FORMAT_D24_UNORM_S8_UINT:
234 case VK_FORMAT_D32_SFLOAT_S8_UINT:
235 result = VK_TRUE;
236 break;
237 default:
238 break;
239 }
240 return result;
241}
242
Chia-I Wu69f40122015-10-26 21:10:41 +0800243VK_LAYER_EXPORT VkResult VKAPI vkCreateImage(VkDevice device, const VkImageCreateInfo* pCreateInfo, const VkAllocCallbacks* pAllocator, VkImage* pImage)
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600244{
Tobin Ehlis35613802015-09-22 08:40:52 -0600245 VkBool32 skipCall = VK_FALSE;
Tobin Ehlis65380532015-09-21 15:20:28 -0600246 layer_data *device_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600247 if(pCreateInfo->format != VK_FORMAT_UNDEFINED)
248 {
249 VkFormatProperties properties;
Tobin Ehlis049f1782015-10-29 14:19:18 -0600250 get_my_data_ptr(get_dispatch_key(device_data->physicalDevice), layer_data_map)->instance_dispatch_table->GetPhysicalDeviceFormatProperties(
Chris Forbesd7576302015-06-21 22:55:02 +1200251 device_data->physicalDevice, pCreateInfo->format, &properties);
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600252
253 if((properties.linearTilingFeatures) == 0 && (properties.optimalTilingFeatures == 0))
254 {
255 char const str[] = "vkCreateImage parameter, VkFormat pCreateInfo->format, contains unsupported format";
Tobin Ehlis35613802015-09-22 08:40:52 -0600256 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 -0600257 }
258 }
Tobin Ehlis35613802015-09-22 08:40:52 -0600259 if (skipCall)
260 return VK_ERROR_VALIDATION_FAILED;
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600261
Chia-I Wu69f40122015-10-26 21:10:41 +0800262 VkResult result = device_data->device_dispatch_table->CreateImage(device, pCreateInfo, pAllocator, pImage);
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600263
Tobin Ehlis65380532015-09-21 15:20:28 -0600264 if(result == VK_SUCCESS) {
Chia-I Wue420a332015-10-26 20:04:44 +0800265 device_data->imageMap[*pImage] = IMAGE_STATE(pCreateInfo);
Tobin Ehlis65380532015-09-21 15:20:28 -0600266 }
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600267 return result;
268}
269
Chia-I Wu69f40122015-10-26 21:10:41 +0800270VK_LAYER_EXPORT void VKAPI vkDestroyImage(VkDevice device, VkImage image, const VkAllocCallbacks* pAllocator)
Tobin Ehlis65380532015-09-21 15:20:28 -0600271{
272 layer_data *device_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
Chia-I Wue420a332015-10-26 20:04:44 +0800273 device_data->imageMap.erase(image);
Chia-I Wu69f40122015-10-26 21:10:41 +0800274 device_data->device_dispatch_table->DestroyImage(device, image, pAllocator);
Tobin Ehlis65380532015-09-21 15:20:28 -0600275}
276
Chia-I Wu69f40122015-10-26 21:10:41 +0800277VK_LAYER_EXPORT VkResult VKAPI vkCreateRenderPass(VkDevice device, const VkRenderPassCreateInfo* pCreateInfo, const VkAllocCallbacks* pAllocator, VkRenderPass* pRenderPass)
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600278{
Tobin Ehlis049f1782015-10-29 14:19:18 -0600279 layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
Tobin Ehlis35613802015-09-22 08:40:52 -0600280 VkBool32 skipCall = VK_FALSE;
Chia-I Wuc278df82015-07-07 11:50:03 +0800281 for(uint32_t i = 0; i < pCreateInfo->attachmentCount; ++i)
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600282 {
Chia-I Wuc278df82015-07-07 11:50:03 +0800283 if(pCreateInfo->pAttachments[i].format != VK_FORMAT_UNDEFINED)
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600284 {
285 VkFormatProperties properties;
Tobin Ehlis049f1782015-10-29 14:19:18 -0600286 get_my_data_ptr(get_dispatch_key(my_data->physicalDevice), layer_data_map)->instance_dispatch_table->GetPhysicalDeviceFormatProperties(
287 my_data->physicalDevice, pCreateInfo->pAttachments[i].format, &properties);
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600288
289 if((properties.linearTilingFeatures) == 0 && (properties.optimalTilingFeatures == 0))
290 {
291 std::stringstream ss;
Chia-I Wuc278df82015-07-07 11:50:03 +0800292 ss << "vkCreateRenderPass parameter, VkFormat in pCreateInfo->pAttachments[" << i << "], contains unsupported format";
Tobin Ehlis049f1782015-10-29 14:19:18 -0600293 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 -0600294 }
295 }
296 }
297
Chia-I Wuc278df82015-07-07 11:50:03 +0800298 for(uint32_t i = 0; i < pCreateInfo->attachmentCount; ++i)
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600299 {
Chia-I Wuc278df82015-07-07 11:50:03 +0800300 if(!validate_VkImageLayout(pCreateInfo->pAttachments[i].initialLayout) ||
301 !validate_VkImageLayout(pCreateInfo->pAttachments[i].finalLayout))
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600302 {
303 std::stringstream ss;
Chia-I Wuc278df82015-07-07 11:50:03 +0800304 ss << "vkCreateRenderPass parameter, VkImageLayout in pCreateInfo->pAttachments[" << i << "], is unrecognized";
Tobin Ehlis049f1782015-10-29 14:19:18 -0600305 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 -0600306 }
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_VkAttachmentLoadOp(pCreateInfo->pAttachments[i].loadOp))
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600312 {
313 std::stringstream ss;
Chia-I Wuc278df82015-07-07 11:50:03 +0800314 ss << "vkCreateRenderPass parameter, VkAttachmentLoadOp in pCreateInfo->pAttachments[" << i << "], is unrecognized";
Tobin Ehlis049f1782015-10-29 14:19:18 -0600315 skipCall |= log_msg(my_data->report_data, VK_DBG_REPORT_WARN_BIT, (VkDbgObjectType)0, 0, 0, IMAGE_RENDERPASS_INVALID_ATTACHMENT, "IMAGE", ss.str().c_str());
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600316 }
317 }
318
Chia-I Wuc278df82015-07-07 11:50:03 +0800319 for(uint32_t i = 0; i < pCreateInfo->attachmentCount; ++i)
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600320 {
Chia-I Wuc278df82015-07-07 11:50:03 +0800321 if(!validate_VkAttachmentStoreOp(pCreateInfo->pAttachments[i].storeOp))
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600322 {
323 std::stringstream ss;
Chia-I Wuc278df82015-07-07 11:50:03 +0800324 ss << "vkCreateRenderPass parameter, VkAttachmentStoreOp in pCreateInfo->pAttachments[" << i << "], is unrecognized";
Tobin Ehlis049f1782015-10-29 14:19:18 -0600325 skipCall |= log_msg(my_data->report_data, VK_DBG_REPORT_WARN_BIT, (VkDbgObjectType)0, 0, 0, IMAGE_RENDERPASS_INVALID_ATTACHMENT, "IMAGE", ss.str().c_str());
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600326 }
327 }
328
Mark Lobodzinski9cce7832015-07-29 09:21:22 -0600329 // Any depth buffers specified as attachments?
330 bool depthFormatPresent = VK_FALSE;
331 for (uint32_t i = 0; i < pCreateInfo->attachmentCount; ++i)
332 {
333 depthFormatPresent |= is_depth_format(pCreateInfo->pAttachments[i].format);
334 }
335
336 if (depthFormatPresent == VK_FALSE) {
337 // No depth attachment is present, validate that subpasses set depthStencilAttachment to VK_ATTACHMENT_UNUSED;
338 for (uint32_t i = 0; i < pCreateInfo->subpassCount; i++) {
Chia-I Wuce532f72015-10-26 17:32:47 +0800339 if (pCreateInfo->pSubpasses[i].pDepthStencilAttachment &&
340 pCreateInfo->pSubpasses[i].pDepthStencilAttachment->attachment != VK_ATTACHMENT_UNUSED) {
Mark Lobodzinski9cce7832015-07-29 09:21:22 -0600341 std::stringstream ss;
342 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 -0600343 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 -0600344 }
345 }
346 }
Tobin Ehlis35613802015-09-22 08:40:52 -0600347 if (skipCall)
348 return VK_ERROR_VALIDATION_FAILED;
Mark Lobodzinski9cce7832015-07-29 09:21:22 -0600349
Chia-I Wu69f40122015-10-26 21:10:41 +0800350 VkResult result = my_data->device_dispatch_table->CreateRenderPass(device, pCreateInfo, pAllocator, pRenderPass);
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600351
352 return result;
353}
354
Chia-I Wu69f40122015-10-26 21:10:41 +0800355VK_LAYER_EXPORT VkResult VKAPI vkCreateImageView(VkDevice device, const VkImageViewCreateInfo* pCreateInfo, const VkAllocCallbacks* pAllocator, VkImageView* pView)
Tobin Ehlis65380532015-09-21 15:20:28 -0600356{
357 VkBool32 skipCall = VK_FALSE;
358 layer_data *device_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
Chia-I Wue420a332015-10-26 20:04:44 +0800359 auto imageEntry = device_data->imageMap.find(pCreateInfo->image);
Tobin Ehlis65380532015-09-21 15:20:28 -0600360 if (imageEntry != device_data->imageMap.end()) {
Tobin Ehlis6fa437d2015-09-25 14:49:43 -0600361 if (pCreateInfo->subresourceRange.baseMipLevel >= imageEntry->second.mipLevels) {
Tobin Ehlis65380532015-09-21 15:20:28 -0600362 std::stringstream ss;
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600363 ss << "vkCreateImageView called with baseMipLevel " << pCreateInfo->subresourceRange.baseMipLevel
Chia-I Wue420a332015-10-26 20:04:44 +0800364 << " for image " << pCreateInfo->image << " that only has " << imageEntry->second.mipLevels << " mip levels.";
Tobin Ehlis65380532015-09-21 15:20:28 -0600365 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());
366 }
Tobin Ehlis6fa437d2015-09-25 14:49:43 -0600367 if (pCreateInfo->subresourceRange.baseArrayLayer >= imageEntry->second.arraySize) {
Tobin Ehlis65380532015-09-21 15:20:28 -0600368 std::stringstream ss;
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600369 ss << "vkCreateImageView called with baseArrayLayer " << pCreateInfo->subresourceRange.baseArrayLayer << " for image "
Chia-I Wue420a332015-10-26 20:04:44 +0800370 << pCreateInfo->image << " that only has " << imageEntry->second.arraySize << " mip levels.";
Tobin Ehlis65380532015-09-21 15:20:28 -0600371 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());
372 }
Courtney Goeltzenleuchter63f0ead2015-10-16 09:46:00 -0600373 if (!pCreateInfo->subresourceRange.numLevels) {
Tobin Ehlis65380532015-09-21 15:20:28 -0600374 std::stringstream ss;
375 ss << "vkCreateImageView called with 0 in pCreateInfo->subresourceRange.mipLevels.";
376 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 }
Courtney Goeltzenleuchter63f0ead2015-10-16 09:46:00 -0600378 if (!pCreateInfo->subresourceRange.numLayers) {
Tobin Ehlis65380532015-09-21 15:20:28 -0600379 std::stringstream ss;
380 ss << "vkCreateImageView called with 0 in pCreateInfo->subresourceRange.arraySize.";
381 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, (VkDbgObjectType)0, 0, 0, IMAGE_VIEW_CREATE_ERROR, "IMAGE", ss.str().c_str());
382 }
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600383
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600384 // Validate correct image aspect bits for desired formats and format consistency
Tobin Ehlis6fa437d2015-09-25 14:49:43 -0600385 VkFormat imageFormat = imageEntry->second.format;
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600386 VkFormat ivciFormat = pCreateInfo->format;
387 VkImageAspectFlags aspectMask = pCreateInfo->subresourceRange.aspectMask;
388
389 if (vk_format_is_color(imageFormat)) {
390 if ((aspectMask & VK_IMAGE_ASPECT_COLOR_BIT) != VK_IMAGE_ASPECT_COLOR_BIT) {
391 std::stringstream ss;
392 ss << "vkCreateImageView: Color image formats must have the VK_IMAGE_ASPECT_COLOR_BIT set";
393 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_IMAGE,
Chia-I Wue420a332015-10-26 20:04:44 +0800394 (uint64_t)pCreateInfo->image, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", ss.str().c_str());
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600395 }
396 if ((aspectMask & VK_IMAGE_ASPECT_COLOR_BIT) != aspectMask) {
397 std::stringstream ss;
398 ss << "vkCreateImageView: Color image formats must have ONLY the VK_IMAGE_ASPECT_COLOR_BIT set";
399 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_IMAGE,
Chia-I Wue420a332015-10-26 20:04:44 +0800400 (uint64_t)pCreateInfo->image, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", ss.str().c_str());
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600401 }
402 if (VK_FALSE == vk_format_is_color(ivciFormat)) {
403 std::stringstream ss;
404 ss << "vkCreateImageView: The image view's format can differ from the parent image's format, but both must be "
405 << "color formats. ImageFormat is " << string_VkFormat(imageFormat) << " ImageViewFormat is " << string_VkFormat(ivciFormat);
406 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_IMAGE,
Chia-I Wue420a332015-10-26 20:04:44 +0800407 (uint64_t)pCreateInfo->image, 0, IMAGE_INVALID_FORMAT, "IMAGE", ss.str().c_str());
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600408 }
409 // TODO: Uncompressed formats are compatible if they occupy they same number of bits per pixel.
410 // Compressed formats are compatible if the only difference between them is the numerical type of
411 // the uncompressed pixels (e.g. signed vs. unsigned, or sRGB vs. UNORM encoding).
412 } else if (vk_format_is_depth_and_stencil(imageFormat)) {
413 if ((aspectMask & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) !=
414 (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) {
415 std::stringstream ss;
416 ss << "vkCreateImageView: Combination depth/stencil image formats must have both VK_IMAGE_ASPECT_DEPTH_BIT and VK_IMAGE_ASPECT_STENCIL_BIT set";
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_IMAGE_ASPECT, "IMAGE", ss.str().c_str());
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600419 }
420 if ((aspectMask & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) != aspectMask) {
421 std::stringstream ss;
422 ss << "vkCreateImageView: Combination depth/stencil image formats can have only the VK_IMAGE_ASPECT_DEPTH_BIT and VK_IMAGE_ASPECT_STENCIL_BIT set";
423 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_IMAGE,
Chia-I Wue420a332015-10-26 20:04:44 +0800424 (uint64_t)pCreateInfo->image, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", ss.str().c_str());
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600425 }
426 } else if (vk_format_is_depth_only(imageFormat)) {
427 if ((aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT) != VK_IMAGE_ASPECT_DEPTH_BIT) {
428 std::stringstream ss;
429 ss << "vkCreateImageView: Depth-only image formats must have the VK_IMAGE_ASPECT_DEPTH_BIT set";
430 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_IMAGE,
Chia-I Wue420a332015-10-26 20:04:44 +0800431 (uint64_t)pCreateInfo->image, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", ss.str().c_str());
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600432 }
433 if ((aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT) != aspectMask) {
434 std::stringstream ss;
435 ss << "vkCreateImageView: Depth-only image formats can have only the VK_IMAGE_ASPECT_DEPTH_BIT set";
436 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_IMAGE,
Chia-I Wue420a332015-10-26 20:04:44 +0800437 (uint64_t)pCreateInfo->image, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", ss.str().c_str());
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600438 }
439 } else if (vk_format_is_stencil_only(imageFormat)) {
440 if ((aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT) != VK_IMAGE_ASPECT_STENCIL_BIT) {
441 std::stringstream ss;
442 ss << "vkCreateImageView: Stencil-only image formats must have the VK_IMAGE_ASPECT_STENCIL_BIT set";
443 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_IMAGE,
Chia-I Wue420a332015-10-26 20:04:44 +0800444 (uint64_t)pCreateInfo->image, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", ss.str().c_str());
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600445 }
446 if ((aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT) != aspectMask) {
447 std::stringstream ss;
448 ss << "vkCreateImageView: Stencil-only image formats can have only the VK_IMAGE_ASPECT_STENCIL_BIT set";
449 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_IMAGE,
Chia-I Wue420a332015-10-26 20:04:44 +0800450 (uint64_t)pCreateInfo->image, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", ss.str().c_str());
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600451 }
452 }
453 }
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600454
Tobin Ehlis65380532015-09-21 15:20:28 -0600455 if (skipCall)
456 return VK_ERROR_VALIDATION_FAILED;
Tobin Ehlis35613802015-09-22 08:40:52 -0600457
Chia-I Wu69f40122015-10-26 21:10:41 +0800458 VkResult result = device_data->device_dispatch_table->CreateImageView(device, pCreateInfo, pAllocator, pView);
Tobin Ehlis65380532015-09-21 15:20:28 -0600459 return result;
460}
461
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600462VK_LAYER_EXPORT void VKAPI vkCmdClearColorImage(
463 VkCmdBuffer cmdBuffer,
464 VkImage image,
465 VkImageLayout imageLayout,
466 const VkClearColorValue *pColor,
467 uint32_t rangeCount,
468 const VkImageSubresourceRange *pRanges)
469{
470 VkBool32 skipCall = VK_FALSE;
Tobin Ehlis049f1782015-10-29 14:19:18 -0600471 layer_data *device_data = get_my_data_ptr(get_dispatch_key(cmdBuffer), layer_data_map);
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600472 // For each range, image aspect must be color only
473 for (uint32_t i = 0; i < rangeCount; i++) {
474 if (pRanges[i].aspectMask != VK_IMAGE_ASPECT_COLOR_BIT) {
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600475 char const str[] = "vkCmdClearColorImage aspectMasks for all subresource ranges must be set to VK_IMAGE_ASPECT_COLOR_BIT";
476 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
477 (uint64_t)cmdBuffer, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", str);
478 }
479 }
480
481 if (VK_FALSE == skipCall) {
Tobin Ehlis049f1782015-10-29 14:19:18 -0600482 device_data->device_dispatch_table->CmdClearColorImage(cmdBuffer, image, imageLayout,
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600483 pColor, rangeCount, pRanges);
484 }
485}
486
487VK_LAYER_EXPORT void VKAPI vkCmdClearDepthStencilImage(
488 VkCmdBuffer cmdBuffer,
489 VkImage image,
490 VkImageLayout imageLayout,
491 const VkClearDepthStencilValue *pDepthStencil,
492 uint32_t rangeCount,
493 const VkImageSubresourceRange *pRanges)
494{
495 VkBool32 skipCall = VK_FALSE;
Tobin Ehlis049f1782015-10-29 14:19:18 -0600496 layer_data *device_data = get_my_data_ptr(get_dispatch_key(cmdBuffer), layer_data_map);
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600497 // For each range, Image aspect must be depth or stencil or both
498 for (uint32_t i = 0; i < rangeCount; i++) {
499 if (((pRanges[i].aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT) != VK_IMAGE_ASPECT_DEPTH_BIT) &&
500 ((pRanges[i].aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT) != VK_IMAGE_ASPECT_STENCIL_BIT))
501 {
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600502 char const str[] = "vkCmdClearDepthStencilImage aspectMasks for all subresource ranges must be "
503 "set to VK_IMAGE_ASPECT_DEPTH_BIT and/or VK_IMAGE_ASPECT_STENCIL_BIT";
504 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
505 (uint64_t)cmdBuffer, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", str);
506 }
507 }
508
509 if (VK_FALSE == skipCall) {
Tobin Ehlis049f1782015-10-29 14:19:18 -0600510 device_data->device_dispatch_table->CmdClearDepthStencilImage(cmdBuffer,
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600511 image, imageLayout, pDepthStencil, rangeCount, pRanges);
512 }
513}
514
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600515VK_LAYER_EXPORT void VKAPI vkCmdCopyImage(
516 VkCmdBuffer cmdBuffer,
517 VkImage srcImage,
518 VkImageLayout srcImageLayout,
519 VkImage destImage,
520 VkImageLayout destImageLayout,
521 uint32_t regionCount,
522 const VkImageCopy *pRegions)
523{
524 VkBool32 skipCall = VK_FALSE;
Mike Stroyan43909d82015-09-25 13:39:21 -0600525 layer_data *device_data = get_my_data_ptr(get_dispatch_key(cmdBuffer), layer_data_map);
Chia-I Wue420a332015-10-26 20:04:44 +0800526 auto srcImageEntry = device_data->imageMap.find(srcImage);
527 auto destImageEntry = device_data->imageMap.find(destImage);
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600528
Jeremy Hayesac8ed0b2015-10-28 13:01:39 -0600529 // For each region, src and dst number of layers should not be zero
530 // For each region, src and dst number of layers must match
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600531 // For each region, src aspect mask must match dest aspect mask
532 // For each region, color aspects cannot be mixed with depth/stencil aspects
533 for (uint32_t i = 0; i < regionCount; i++) {
Jeremy Hayesac8ed0b2015-10-28 13:01:39 -0600534 if(pRegions[i].srcSubresource.numLayers == 0)
535 {
536 char const str[] = "vkCmdCopyImage: number of layers in source subresource is zero";
537 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_WARN_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
538 (uint64_t)cmdBuffer, 0, IMAGE_MISMATCHED_IMAGE_ASPECT, "IMAGE", str);
539 }
540
541 if(pRegions[i].destSubresource.numLayers == 0)
542 {
543 char const str[] = "vkCmdCopyImage: number of layers in destination subresource is zero";
544 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_WARN_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
545 (uint64_t)cmdBuffer, 0, IMAGE_MISMATCHED_IMAGE_ASPECT, "IMAGE", str);
546 }
547
548 if(pRegions[i].srcSubresource.numLayers != pRegions[i].destSubresource.numLayers)
549 {
550 char const str[] = "vkCmdCopyImage: number of layers in source and destination subresources must match";
551 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
552 (uint64_t)cmdBuffer, 0, IMAGE_MISMATCHED_IMAGE_ASPECT, "IMAGE", str);
553 }
554
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600555 if (pRegions[i].srcSubresource.aspect != pRegions[i].destSubresource.aspect) {
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600556 char const str[] = "vkCmdCopyImage: Src and dest aspectMasks for each region must match";
557 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
558 (uint64_t)cmdBuffer, 0, IMAGE_MISMATCHED_IMAGE_ASPECT, "IMAGE", str);
559 }
Courtney Goeltzenleuchterba11ebe2015-10-21 17:00:51 -0600560 if ((pRegions[i].srcSubresource.aspect & VK_IMAGE_ASPECT_COLOR_BIT) &&
561 (pRegions[i].srcSubresource.aspect & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT))) {
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600562 char const str[] = "vkCmdCopyImage aspectMask cannot specify both COLOR and DEPTH/STENCIL aspects";
563 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
564 (uint64_t)cmdBuffer, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", str);
565 }
566 }
567
Mike Stroyan43909d82015-09-25 13:39:21 -0600568 if ((srcImageEntry != device_data->imageMap.end())
569 && (destImageEntry != device_data->imageMap.end())) {
Tobin Ehlis6fa437d2015-09-25 14:49:43 -0600570 if (srcImageEntry->second.imageType != destImageEntry->second.imageType) {
Mike Stroyan43909d82015-09-25 13:39:21 -0600571 char const str[] = "vkCmdCopyImage called with unmatched source and dest image types.";
572 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
573 (uint64_t)cmdBuffer, 0, IMAGE_MISMATCHED_IMAGE_TYPE, "IMAGE", str);
574 }
575 // Check that format is same size or exact stencil/depth
Tobin Ehlis6fa437d2015-09-25 14:49:43 -0600576 if (is_depth_format(srcImageEntry->second.format)) {
577 if (srcImageEntry->second.format != destImageEntry->second.format) {
Mike Stroyan43909d82015-09-25 13:39:21 -0600578 char const str[] = "vkCmdCopyImage called with unmatched source and dest image depth/stencil formats.";
579 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
580 (uint64_t)cmdBuffer, 0, IMAGE_MISMATCHED_IMAGE_FORMAT, "IMAGE", str);
581 }
582 } else {
Tobin Ehlis6fa437d2015-09-25 14:49:43 -0600583 size_t srcSize = vk_format_get_size(srcImageEntry->second.format);
584 size_t destSize = vk_format_get_size(destImageEntry->second.format);
Mike Stroyan43909d82015-09-25 13:39:21 -0600585 if (srcSize != destSize) {
586 char const str[] = "vkCmdCopyImage called with unmatched source and dest image format sizes.";
587 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
588 (uint64_t)cmdBuffer, 0, IMAGE_MISMATCHED_IMAGE_FORMAT, "IMAGE", str);
589 }
590 }
591 }
592
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600593 if (VK_FALSE == skipCall) {
Tobin Ehlis049f1782015-10-29 14:19:18 -0600594 device_data->device_dispatch_table->CmdCopyImage(cmdBuffer, srcImage,
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600595 srcImageLayout, destImage, destImageLayout, regionCount, pRegions);
596 }
597}
598
Courtney Goeltzenleuchter9feb0732015-10-15 16:51:05 -0600599void VKAPI vkCmdClearAttachments(
600 VkCmdBuffer cmdBuffer,
601 uint32_t attachmentCount,
602 const VkClearAttachment* pAttachments,
603 uint32_t rectCount,
Courtney Goeltzenleuchtera12e2912015-10-15 18:22:08 -0600604 const VkClearRect* pRects)
Courtney Goeltzenleuchter9feb0732015-10-15 16:51:05 -0600605{
606 VkBool32 skipCall = VK_FALSE;
607 VkImageAspectFlags aspectMask;
Tobin Ehlis049f1782015-10-29 14:19:18 -0600608 layer_data *device_data = get_my_data_ptr(get_dispatch_key(cmdBuffer), layer_data_map);
Courtney Goeltzenleuchter9feb0732015-10-15 16:51:05 -0600609 for (uint32_t i = 0; i < attachmentCount; i++) {
610 aspectMask = pAttachments[i].aspectMask;
611 if (aspectMask & VK_IMAGE_ASPECT_COLOR_BIT) {
612 if (aspectMask != VK_IMAGE_ASPECT_COLOR_BIT) {
613 // VK_IMAGE_ASPECT_COLOR_BIT is not the only bit set for this attachment
Courtney Goeltzenleuchter9feb0732015-10-15 16:51:05 -0600614 char const str[] = "vkCmdClearAttachments aspectMask [%d] must set only VK_IMAGE_ASPECT_COLOR_BIT of a color attachment.";
615 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
616 (uint64_t)cmdBuffer, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", str, i);
617 }
618 } else {
619 // Image aspect must be depth or stencil or both
620 if (((aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT) != VK_IMAGE_ASPECT_DEPTH_BIT) &&
621 ((aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT) != VK_IMAGE_ASPECT_STENCIL_BIT))
622 {
Courtney Goeltzenleuchter9feb0732015-10-15 16:51:05 -0600623 char const str[] = "vkCmdClearAttachments aspectMask [%d] must be set to VK_IMAGE_ASPECT_DEPTH_BIT and/or VK_IMAGE_ASPECT_STENCIL_BIT";
624 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
625 (uint64_t)cmdBuffer, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", str, i);
626 }
627 }
628 }
629
630 if (VK_FALSE == skipCall) {
Tobin Ehlis049f1782015-10-29 14:19:18 -0600631 device_data->device_dispatch_table->CmdClearAttachments(cmdBuffer,
Courtney Goeltzenleuchter9feb0732015-10-15 16:51:05 -0600632 attachmentCount, pAttachments, rectCount, pRects);
633 }
634}
635
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600636VK_LAYER_EXPORT void VKAPI vkCmdCopyImageToBuffer(
637 VkCmdBuffer cmdBuffer,
638 VkImage srcImage,
639 VkImageLayout srcImageLayout,
640 VkBuffer destBuffer,
641 uint32_t regionCount,
642 const VkBufferImageCopy *pRegions)
643{
644 VkBool32 skipCall = VK_FALSE;
Tobin Ehlis049f1782015-10-29 14:19:18 -0600645 layer_data *device_data = get_my_data_ptr(get_dispatch_key(cmdBuffer), layer_data_map);
Jeremy Hayesac8ed0b2015-10-28 13:01:39 -0600646 // For each region, the number of layers in the image subresource should not be zero
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600647 // Image aspect must be ONE OF color, depth, stencil
648 for (uint32_t i = 0; i < regionCount; i++) {
Jeremy Hayesac8ed0b2015-10-28 13:01:39 -0600649 if(pRegions[i].imageSubresource.numLayers == 0)
650 {
Jeremy Hayesac8ed0b2015-10-28 13:01:39 -0600651 char const str[] = "vkCmdCopyImageToBuffer: number of layers in image subresource is zero";
652 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_WARN_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
653 (uint64_t)cmdBuffer, 0, IMAGE_MISMATCHED_IMAGE_ASPECT, "IMAGE", str);
654 }
655
Courtney Goeltzenleuchterba11ebe2015-10-21 17:00:51 -0600656 VkImageAspectFlags aspect = pRegions[i].imageSubresource.aspect;
657 if ((aspect != VK_IMAGE_ASPECT_COLOR_BIT) &&
658 (aspect != VK_IMAGE_ASPECT_DEPTH_BIT) &&
659 (aspect != VK_IMAGE_ASPECT_STENCIL_BIT)) {
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600660 char const str[] = "vkCmdCopyImageToBuffer: aspectMasks for each region must specify only COLOR or DEPTH or STENCIL";
661 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
662 (uint64_t)cmdBuffer, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", str);
663 }
664 }
665
666 if (VK_FALSE == skipCall) {
Tobin Ehlis049f1782015-10-29 14:19:18 -0600667 device_data->device_dispatch_table->CmdCopyImageToBuffer(cmdBuffer,
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600668 srcImage, srcImageLayout, destBuffer, regionCount, pRegions);
669 }
670}
671
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600672VK_LAYER_EXPORT void VKAPI vkCmdCopyBufferToImage(
673 VkCmdBuffer cmdBuffer,
674 VkBuffer srcBuffer,
675 VkImage destImage,
676 VkImageLayout destImageLayout,
677 uint32_t regionCount,
678 const VkBufferImageCopy *pRegions)
679{
680 VkBool32 skipCall = VK_FALSE;
Tobin Ehlis049f1782015-10-29 14:19:18 -0600681 layer_data *device_data = get_my_data_ptr(get_dispatch_key(cmdBuffer), layer_data_map);
Jeremy Hayesac8ed0b2015-10-28 13:01:39 -0600682 // For each region, the number of layers in the image subresource should not be zero
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600683 // Image aspect must be ONE OF color, depth, stencil
684 for (uint32_t i = 0; i < regionCount; i++) {
Jeremy Hayesac8ed0b2015-10-28 13:01:39 -0600685 if(pRegions[i].imageSubresource.numLayers == 0)
686 {
Jeremy Hayesac8ed0b2015-10-28 13:01:39 -0600687 char const str[] = "vkCmdCopyBufferToImage: number of layers in image subresource is zero";
688 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_WARN_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
689 (uint64_t)cmdBuffer, 0, IMAGE_MISMATCHED_IMAGE_ASPECT, "IMAGE", str);
690 }
691
Courtney Goeltzenleuchterba11ebe2015-10-21 17:00:51 -0600692 VkImageAspectFlags aspect = pRegions[i].imageSubresource.aspect;
693 if ((aspect != VK_IMAGE_ASPECT_COLOR_BIT) &&
694 (aspect != VK_IMAGE_ASPECT_DEPTH_BIT) &&
695 (aspect != VK_IMAGE_ASPECT_STENCIL_BIT)) {
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600696 char const str[] = "vkCmdCopyBufferToImage: aspectMasks for each region must specify only COLOR or DEPTH or STENCIL";
697 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
698 (uint64_t)cmdBuffer, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", str);
699 }
700 }
701
702 if (VK_FALSE == skipCall) {
Tobin Ehlis049f1782015-10-29 14:19:18 -0600703 device_data->device_dispatch_table->CmdCopyBufferToImage(cmdBuffer,
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600704 srcBuffer, destImage, destImageLayout, regionCount, pRegions);
705 }
706}
707
708VK_LAYER_EXPORT void VKAPI vkCmdBlitImage(
709 VkCmdBuffer cmdBuffer,
710 VkImage srcImage,
711 VkImageLayout srcImageLayout,
712 VkImage destImage,
713 VkImageLayout destImageLayout,
714 uint32_t regionCount,
715 const VkImageBlit *pRegions,
Chia-I Wu3603b082015-10-26 16:49:32 +0800716 VkFilter filter)
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600717{
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600718 VkBool32 skipCall = VK_FALSE;
719 layer_data *device_data = get_my_data_ptr(get_dispatch_key(cmdBuffer), layer_data_map);
720
Chia-I Wue420a332015-10-26 20:04:44 +0800721 auto srcImageEntry = device_data->imageMap.find(srcImage);
722 auto destImageEntry = device_data->imageMap.find(destImage);
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600723
724 if ((srcImageEntry != device_data->imageMap.end()) &&
725 (destImageEntry != device_data->imageMap.end())) {
726
Tobin Ehlis6fa437d2015-09-25 14:49:43 -0600727 VkFormat srcFormat = srcImageEntry->second.format;
728 VkFormat dstFormat = destImageEntry->second.format;
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600729
730 // Validate consistency for signed and unsigned formats
731 if ((vk_format_is_sint(srcFormat) && !vk_format_is_sint(dstFormat)) ||
732 (vk_format_is_uint(srcFormat) && !vk_format_is_uint(dstFormat))) {
733 std::stringstream ss;
734 ss << "vkCmdBlitImage: If one of srcImage and destImage images has signed/unsigned integer format, "
735 << "the other one must also have signed/unsigned integer format. "
736 << "Source format is " << string_VkFormat(srcFormat) << " Destinatino format is " << string_VkFormat(dstFormat);
737 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
738 (uint64_t)cmdBuffer, 0, IMAGE_INVALID_FORMAT, "IMAGE", ss.str().c_str());
739 }
740
741 // Validate aspect bits and formats for depth/stencil images
742 if (vk_format_is_depth_or_stencil(srcFormat) ||
743 vk_format_is_depth_or_stencil(dstFormat)) {
744 if (srcFormat != dstFormat) {
745 std::stringstream ss;
746 ss << "vkCmdBlitImage: If one of srcImage and destImage images has a format of depth, stencil or depth "
747 << "stencil, the other one must have exactly the same format. "
748 << "Source format is " << string_VkFormat(srcFormat) << " Destinatino format is " << string_VkFormat(dstFormat);
749 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
750 (uint64_t)cmdBuffer, 0, IMAGE_INVALID_FORMAT, "IMAGE", ss.str().c_str());
751 }
752
753 for (uint32_t i = 0; i < regionCount; i++) {
Jeremy Hayesac8ed0b2015-10-28 13:01:39 -0600754 if(pRegions[i].srcSubresource.numLayers == 0)
755 {
756 char const str[] = "vkCmdBlitImage: number of layers in source subresource is zero";
757 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_WARN_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
758 (uint64_t)cmdBuffer, 0, IMAGE_MISMATCHED_IMAGE_ASPECT, "IMAGE", str);
759 }
760
761 if(pRegions[i].destSubresource.numLayers == 0)
762 {
763 char const str[] = "vkCmdBlitImage: number of layers in destination subresource is zero";
764 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_WARN_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
765 (uint64_t)cmdBuffer, 0, IMAGE_MISMATCHED_IMAGE_ASPECT, "IMAGE", str);
766 }
767
768 if(pRegions[i].srcSubresource.numLayers != pRegions[i].destSubresource.numLayers)
769 {
770 char const str[] = "vkCmdBlitImage: number of layers in source and destination subresources must match";
771 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
772 (uint64_t)cmdBuffer, 0, IMAGE_MISMATCHED_IMAGE_ASPECT, "IMAGE", str);
773 }
774
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600775 VkImageAspectFlags srcAspect = pRegions[i].srcSubresource.aspect;
776 VkImageAspectFlags dstAspect = pRegions[i].destSubresource.aspect;
777
778 if (srcAspect != dstAspect) {
779 std::stringstream ss;
780 ss << "vkCmdBlitImage: Image aspects of depth/stencil images should match";
781 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_WARN_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
782 (uint64_t)cmdBuffer, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", ss.str().c_str());
783 }
784 if (vk_format_is_depth_and_stencil(srcFormat)) {
785 if (srcAspect != (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) {
786 std::stringstream ss;
787 ss << "vkCmdBlitImage: Combination depth/stencil image formats must have both VK_IMAGE_ASPECT_DEPTH_BIT "
788 << "and VK_IMAGE_ASPECT_STENCIL_BIT set in both the srcImage and destImage";
789 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
790 (uint64_t)cmdBuffer, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", ss.str().c_str());
791 }
792 } else if (vk_format_is_stencil_only(srcFormat)) {
793 if (srcAspect != VK_IMAGE_ASPECT_STENCIL_BIT) {
794 std::stringstream ss;
795 ss << "vkCmdBlitImage: Stencil-only image formats must have only the VK_IMAGE_ASPECT_STENCIL_BIT "
796 << "set in both the srcImage and destImage";
797 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
798 (uint64_t)cmdBuffer, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", ss.str().c_str());
799 }
800 } else if (vk_format_is_depth_only(srcFormat)) {
801 if (srcAspect != VK_IMAGE_ASPECT_DEPTH_BIT) {
802 std::stringstream ss;
803 ss << "vkCmdBlitImage: Depth-only image formats must have only the VK_IMAGE_ASPECT_DEPTH "
804 << "set in both the srcImage and destImage";
805 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
806 (uint64_t)cmdBuffer, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", ss.str().c_str());
807 }
808 }
809 }
810 }
811
812 // Validate filter
813 if (vk_format_is_depth_or_stencil(srcFormat) ||
814 vk_format_is_int(srcFormat)) {
Chia-I Wu3603b082015-10-26 16:49:32 +0800815 if (filter != VK_FILTER_NEAREST) {
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600816 std::stringstream ss;
817 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 +0800818 << "then filter must be VK_FILTER_NEAREST.";
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600819 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
820 (uint64_t)cmdBuffer, 0, IMAGE_INVALID_FILTER, "IMAGE", ss.str().c_str());
821 }
822 }
823 }
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600824
Tobin Ehlis049f1782015-10-29 14:19:18 -0600825 device_data->device_dispatch_table->CmdBlitImage(cmdBuffer, srcImage,
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600826 srcImageLayout, destImage, destImageLayout, regionCount, pRegions, filter);
827}
828
829VK_LAYER_EXPORT void VKAPI vkCmdResolveImage(
830 VkCmdBuffer cmdBuffer,
831 VkImage srcImage,
832 VkImageLayout srcImageLayout,
833 VkImage destImage,
834 VkImageLayout destImageLayout,
835 uint32_t regionCount,
836 const VkImageResolve *pRegions)
837{
838 VkBool32 skipCall = VK_FALSE;
Mike Stroyan43909d82015-09-25 13:39:21 -0600839 layer_data *device_data = get_my_data_ptr(get_dispatch_key(cmdBuffer), layer_data_map);
Chia-I Wue420a332015-10-26 20:04:44 +0800840 auto srcImageEntry = device_data->imageMap.find(srcImage);
841 auto destImageEntry = device_data->imageMap.find(destImage);
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600842
Jeremy Hayesac8ed0b2015-10-28 13:01:39 -0600843 // For each region, the number of layers in the image subresource should not be zero
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600844 // For each region, src and dest image aspect must be color only
845 for (uint32_t i = 0; i < regionCount; i++) {
Jeremy Hayesac8ed0b2015-10-28 13:01:39 -0600846 if(pRegions[i].srcSubresource.numLayers == 0)
847 {
848 char const str[] = "vkCmdResolveImage: number of layers in source subresource is zero";
849 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_WARN_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
850 (uint64_t)cmdBuffer, 0, IMAGE_MISMATCHED_IMAGE_ASPECT, "IMAGE", str);
851 }
852
853 if(pRegions[i].destSubresource.numLayers == 0)
854 {
855 char const str[] = "vkCmdResolveImage: number of layers in destination subresource is zero";
856 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_WARN_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
857 (uint64_t)cmdBuffer, 0, IMAGE_MISMATCHED_IMAGE_ASPECT, "IMAGE", str);
858 }
859
Courtney Goeltzenleuchterba11ebe2015-10-21 17:00:51 -0600860 if ((pRegions[i].srcSubresource.aspect != VK_IMAGE_ASPECT_COLOR_BIT) ||
861 (pRegions[i].destSubresource.aspect != VK_IMAGE_ASPECT_COLOR_BIT)) {
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600862 char const str[] = "vkCmdResolveImage: src and dest aspectMasks for each region must specify only VK_IMAGE_ASPECT_COLOR_BIT";
863 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
864 (uint64_t)cmdBuffer, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", str);
865 }
866 }
867
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600868 if ((srcImageEntry != device_data->imageMap.end()) &&
869 (destImageEntry != device_data->imageMap.end())) {
Tobin Ehlis6fa437d2015-09-25 14:49:43 -0600870 if (srcImageEntry->second.format != destImageEntry->second.format) {
Mike Stroyan43909d82015-09-25 13:39:21 -0600871 char const str[] = "vkCmdResolveImage called with unmatched source and dest formats.";
872 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
873 (uint64_t)cmdBuffer, 0, IMAGE_MISMATCHED_IMAGE_FORMAT, "IMAGE", str);
874 }
Tobin Ehlis6fa437d2015-09-25 14:49:43 -0600875 if (srcImageEntry->second.imageType != destImageEntry->second.imageType) {
Mike Stroyan43909d82015-09-25 13:39:21 -0600876 char const str[] = "vkCmdResolveImage called with unmatched source and dest image types.";
877 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
878 (uint64_t)cmdBuffer, 0, IMAGE_MISMATCHED_IMAGE_TYPE, "IMAGE", str);
879 }
Tobin Ehlis6fa437d2015-09-25 14:49:43 -0600880 if (srcImageEntry->second.samples <= 1) {
Mike Stroyan43909d82015-09-25 13:39:21 -0600881 char const str[] = "vkCmdResolveImage called with source sample count less than 2.";
882 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
883 (uint64_t)cmdBuffer, 0, IMAGE_INVALID_RESOLVE_SAMPLES, "IMAGE", str);
884 }
Tobin Ehlis6fa437d2015-09-25 14:49:43 -0600885 if (destImageEntry->second.samples > 1) {
Mike Stroyan43909d82015-09-25 13:39:21 -0600886 char const str[] = "vkCmdResolveImage called with dest sample count greater than 1.";
887 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
888 (uint64_t)cmdBuffer, 0, IMAGE_INVALID_RESOLVE_SAMPLES, "IMAGE", str);
889 }
890 }
891
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600892 if (VK_FALSE == skipCall) {
Tobin Ehlis049f1782015-10-29 14:19:18 -0600893 device_data->device_dispatch_table->CmdResolveImage(cmdBuffer, srcImage,
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600894 srcImageLayout, destImage, destImageLayout, regionCount, pRegions);
895 }
896}
897
Courtney Goeltzenleuchter01d2ae12015-10-20 16:40:38 -0600898VK_LAYER_EXPORT void VKAPI vkGetImageSubresourceLayout(
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600899 VkDevice device,
900 VkImage image,
901 const VkImageSubresource *pSubresource,
902 VkSubresourceLayout *pLayout)
903{
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600904 VkBool32 skipCall = VK_FALSE;
905 layer_data *device_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
906 VkFormat format;
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600907
Chia-I Wue420a332015-10-26 20:04:44 +0800908 auto imageEntry = device_data->imageMap.find(image);
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600909
910 // Validate that image aspects match formats
911 if (imageEntry != device_data->imageMap.end()) {
Tobin Ehlis6fa437d2015-09-25 14:49:43 -0600912 format = imageEntry->second.format;
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600913 if (vk_format_is_color(format)) {
914 if (pSubresource->aspect != VK_IMAGE_ASPECT_COLOR_BIT) {
915 std::stringstream ss;
916 ss << "vkGetImageSubresourceLayout: For color formats, the aspect field of VkImageSubresource must be VK_IMAGE_ASPECT_COLOR.";
917 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_IMAGE,
Chia-I Wue420a332015-10-26 20:04:44 +0800918 (uint64_t)image, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", ss.str().c_str());
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600919 }
920 } else if (vk_format_is_depth_or_stencil(format)) {
921 if ((pSubresource->aspect != VK_IMAGE_ASPECT_DEPTH_BIT) &&
922 (pSubresource->aspect != VK_IMAGE_ASPECT_STENCIL_BIT)) {
923 std::stringstream ss;
924 ss << "vkGetImageSubresourceLayout: For depth/stencil formats, the aspect selects either the depth or stencil image aspect.";
925 skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_IMAGE,
Chia-I Wue420a332015-10-26 20:04:44 +0800926 (uint64_t)image, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", ss.str().c_str());
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600927 }
928 }
929 }
930
931 if (VK_FALSE == skipCall) {
Tobin Ehlis049f1782015-10-29 14:19:18 -0600932 device_data->device_dispatch_table->GetImageSubresourceLayout(device,
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600933 image, pSubresource, pLayout);
934 }
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600935}
936
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -0600937VK_LAYER_EXPORT PFN_vkVoidFunction VKAPI vkGetDeviceProcAddr(VkDevice device, const char* funcName)
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600938{
939 if (device == NULL) {
940 return NULL;
941 }
942
Tobin Ehlis049f1782015-10-29 14:19:18 -0600943 layer_data *my_data;
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600944 // loader uses this to force layer initialization; device object is wrapped
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600945 if (!strcmp(funcName, "vkGetDeviceProcAddr")) {
Tobin Ehlis049f1782015-10-29 14:19:18 -0600946 VkBaseLayerObject* wrapped_dev = (VkBaseLayerObject*) device;
947 my_data = get_my_data_ptr(get_dispatch_key(wrapped_dev->baseObject), layer_data_map);
948 my_data->device_dispatch_table = new VkLayerDispatchTable;
949 layer_initialize_dispatch_table(my_data->device_dispatch_table, wrapped_dev);
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -0600950 return (PFN_vkVoidFunction) vkGetDeviceProcAddr;
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600951 }
952
Tobin Ehlis049f1782015-10-29 14:19:18 -0600953 my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
Courtney Goeltzenleuchterbe637992015-06-25 18:01:43 -0600954 if (!strcmp(funcName, "vkCreateDevice"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -0600955 return (PFN_vkVoidFunction) vkCreateDevice;
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600956 if (!strcmp(funcName, "vkDestroyDevice"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -0600957 return (PFN_vkVoidFunction) vkDestroyDevice;
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600958 if (!strcmp(funcName, "vkCreateImage"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -0600959 return (PFN_vkVoidFunction) vkCreateImage;
Mark Lobodzinski9eb1ce42015-10-29 12:58:33 -0600960 if (!strcmp(funcName, "vkDestroyImage"))
961 return (PFN_vkVoidFunction) vkDestroyImage;
Tobin Ehlis342b9bf2015-09-22 10:11:37 -0600962 if (!strcmp(funcName, "vkCreateImageView"))
963 return (PFN_vkVoidFunction) vkCreateImageView;
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600964 if (!strcmp(funcName, "vkCreateRenderPass"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -0600965 return (PFN_vkVoidFunction) vkCreateRenderPass;
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600966 if (!strcmp(funcName, "vkCmdClearColorImage"))
967 return (PFN_vkVoidFunction) vkCmdClearColorImage;
968 if (!strcmp(funcName, "vkCmdClearDepthStencilImage"))
969 return (PFN_vkVoidFunction) vkCmdClearDepthStencilImage;
Courtney Goeltzenleuchter9feb0732015-10-15 16:51:05 -0600970 if (!strcmp(funcName, "vkCmdClearAttachments"))
971 return (PFN_vkVoidFunction) vkCmdClearAttachments;
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600972 if (!strcmp(funcName, "vkCmdCopyImage"))
973 return (PFN_vkVoidFunction) vkCmdCopyImage;
974 if (!strcmp(funcName, "vkCmdCopyImageToBuffer"))
975 return (PFN_vkVoidFunction) vkCmdCopyImageToBuffer;
976 if (!strcmp(funcName, "vkCmdCopyBufferToImage"))
977 return (PFN_vkVoidFunction) vkCmdCopyBufferToImage;
978 if (!strcmp(funcName, "vkCmdBlitImage"))
979 return (PFN_vkVoidFunction) vkCmdBlitImage;
980 if (!strcmp(funcName, "vkCmdResolveImage"))
981 return (PFN_vkVoidFunction) vkCmdResolveImage;
982 if (!strcmp(funcName, "vkGetImageSubresourceLayout"))
983 return (PFN_vkVoidFunction) vkGetImageSubresourceLayout;
Tobin Ehlis049f1782015-10-29 14:19:18 -0600984
985 VkLayerDispatchTable* pTable = my_data->device_dispatch_table;
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600986 {
Tobin Ehlis049f1782015-10-29 14:19:18 -0600987 if (pTable->GetDeviceProcAddr == NULL)
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600988 return NULL;
Tobin Ehlis049f1782015-10-29 14:19:18 -0600989 return pTable->GetDeviceProcAddr(device, funcName);
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600990 }
991}
992
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -0600993VK_LAYER_EXPORT PFN_vkVoidFunction VKAPI vkGetInstanceProcAddr(VkInstance instance, const char* funcName)
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600994{
995 if (instance == NULL) {
996 return NULL;
997 }
998
Tobin Ehlis049f1782015-10-29 14:19:18 -0600999 layer_data *my_data;
Mark Lobodzinskib4092de2015-10-23 14:20:31 -06001000 // loader uses this to force layer initialization; instance object is wrapped
Jeremy Hayesb707aa52015-06-18 10:12:39 -06001001 if (!strcmp(funcName, "vkGetInstanceProcAddr")) {
Tobin Ehlis049f1782015-10-29 14:19:18 -06001002 VkBaseLayerObject* wrapped_inst = (VkBaseLayerObject*) instance;
1003 my_data = get_my_data_ptr(get_dispatch_key(wrapped_inst->baseObject), layer_data_map);
1004 my_data->instance_dispatch_table = new VkLayerInstanceDispatchTable;
1005 layer_init_instance_dispatch_table(my_data->instance_dispatch_table, wrapped_inst);
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06001006 return (PFN_vkVoidFunction) vkGetInstanceProcAddr;
Jeremy Hayesb707aa52015-06-18 10:12:39 -06001007 }
1008
Tobin Ehlis049f1782015-10-29 14:19:18 -06001009 my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
Jeremy Hayesb707aa52015-06-18 10:12:39 -06001010 if (!strcmp(funcName, "vkCreateInstance"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06001011 return (PFN_vkVoidFunction) vkCreateInstance;
Jeremy Hayesb707aa52015-06-18 10:12:39 -06001012 if (!strcmp(funcName, "vkDestroyInstance"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06001013 return (PFN_vkVoidFunction) vkDestroyInstance;
Courtney Goeltzenleuchter74c4ce92015-09-14 17:22:16 -06001014 if (!strcmp(funcName, "vkEnumerateInstanceLayerProperties"))
1015 return (PFN_vkVoidFunction) vkEnumerateInstanceLayerProperties;
1016 if (!strcmp(funcName, "vkEnumerateInstanceExtensionProperties"))
1017 return (PFN_vkVoidFunction) vkEnumerateInstanceExtensionProperties;
1018 if (!strcmp(funcName, "vkEnumerateDeviceLayerProperties"))
1019 return (PFN_vkVoidFunction) vkEnumerateDeviceLayerProperties;
1020 if (!strcmp(funcName, "vkEnumerateDeviceExtensionProperties"))
1021 return (PFN_vkVoidFunction) vkEnumerateDeviceExtensionProperties;
Jeremy Hayesb707aa52015-06-18 10:12:39 -06001022
Tobin Ehlis049f1782015-10-29 14:19:18 -06001023 PFN_vkVoidFunction fptr = debug_report_get_instance_proc_addr(my_data->report_data, funcName);
Jeremy Hayesb707aa52015-06-18 10:12:39 -06001024 if(fptr)
1025 return fptr;
1026
1027 {
Tobin Ehlis049f1782015-10-29 14:19:18 -06001028 VkLayerInstanceDispatchTable* pTable = my_data->instance_dispatch_table;
1029 if (pTable->GetInstanceProcAddr == NULL)
Jeremy Hayesb707aa52015-06-18 10:12:39 -06001030 return NULL;
Tobin Ehlis049f1782015-10-29 14:19:18 -06001031 return pTable->GetInstanceProcAddr(instance, funcName);
Jeremy Hayesb707aa52015-06-18 10:12:39 -06001032 }
1033}