blob: 509fcecbea34a0261814afb9c1698d8a209d74c5 [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 {
Mark Lobodzinski69343212015-11-12 15:14:35 -070055 debug_report_data *report_data;
56 vector<VkDbgMsgCallback> logging_callback;
57 VkLayerDispatchTable* device_dispatch_table;
58 VkLayerInstanceDispatchTable *instance_dispatch_table;
59 VkPhysicalDevice physicalDevice;
60 VkPhysicalDeviceProperties physicalDeviceProperties;
61
Chia-I Wue420a332015-10-26 20:04:44 +080062 unordered_map<VkImage, IMAGE_STATE> imageMap;
Cody Northrop73bb6572015-09-28 15:09:32 -060063
64 layer_data() :
65 report_data(nullptr),
Tobin Ehlis049f1782015-10-29 14:19:18 -060066 device_dispatch_table(nullptr),
67 instance_dispatch_table(nullptr),
Mark Lobodzinski69343212015-11-12 15:14:35 -070068 physicalDevice(0),
69 physicalDeviceProperties()
Cody Northrop73bb6572015-09-28 15:09:32 -060070 {};
71};
Jeremy Hayesb707aa52015-06-18 10:12:39 -060072
Tobin Ehlis65380532015-09-21 15:20:28 -060073static unordered_map<void*, layer_data*> layer_data_map;
Jeremy Hayesb707aa52015-06-18 10:12:39 -060074
75static void InitImage(layer_data *data)
76{
Courtney Goeltzenleuchter9fac1572015-10-05 15:59:11 -060077 VkDbgMsgCallback callback;
Jeremy Hayesb707aa52015-06-18 10:12:39 -060078 uint32_t report_flags = getLayerOptionFlags("ImageReportFlags", 0);
79
80 uint32_t debug_action = 0;
81 getLayerOptionEnum("ImageDebugAction", (uint32_t *) &debug_action);
82 if(debug_action & VK_DBG_LAYER_ACTION_LOG_MSG)
83 {
84 FILE *log_output = NULL;
85 const char* option_str = getLayerOption("ImageLogFilename");
Tobin Ehlisb4b6e7c2015-09-15 09:55:54 -060086 log_output = getLayerLogOutput(option_str, "Image");
Courtney Goeltzenleuchter9fac1572015-10-05 15:59:11 -060087 layer_create_msg_callback(data->report_data, report_flags, log_callback, (void *) log_output, &callback);
88 data->logging_callback.push_back(callback);
89 }
90
91 if (debug_action & VK_DBG_LAYER_ACTION_DEBUG_OUTPUT) {
92 layer_create_msg_callback(data->report_data, report_flags, win32_debug_output_msg, NULL, &callback);
93 data->logging_callback.push_back(callback);
Jeremy Hayesb707aa52015-06-18 10:12:39 -060094 }
95}
96
Chia-I Wuaf9e4fd2015-11-06 06:42:02 +080097VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkDbgCreateMsgCallback(
Jeremy Hayesb707aa52015-06-18 10:12:39 -060098 VkInstance instance,
99 VkFlags msgFlags,
100 const PFN_vkDbgMsgCallback pfnMsgCallback,
101 void* pUserData,
102 VkDbgMsgCallback* pMsgCallback)
103{
Tobin Ehlis049f1782015-10-29 14:19:18 -0600104 layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
105 VkResult res = my_data->instance_dispatch_table->DbgCreateMsgCallback(instance, msgFlags, pfnMsgCallback, pUserData, pMsgCallback);
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600106 if (res == VK_SUCCESS) {
Tobin Ehlis049f1782015-10-29 14:19:18 -0600107 res = layer_create_msg_callback(my_data->report_data, msgFlags, pfnMsgCallback, pUserData, pMsgCallback);
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600108 }
109 return res;
110}
111
Chia-I Wuaf9e4fd2015-11-06 06:42:02 +0800112VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkDbgDestroyMsgCallback(
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600113 VkInstance instance,
114 VkDbgMsgCallback msgCallback)
115{
Tobin Ehlis049f1782015-10-29 14:19:18 -0600116 layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
117 VkResult res = my_data->instance_dispatch_table->DbgDestroyMsgCallback(instance, msgCallback);
118 layer_destroy_msg_callback(my_data->report_data, msgCallback);
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600119 return res;
120}
121
Chia-I Wuaf9e4fd2015-11-06 06:42:02 +0800122VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateInstance(const VkInstanceCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkInstance* pInstance)
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600123{
Tobin Ehlis049f1782015-10-29 14:19:18 -0600124 layer_data *my_data = get_my_data_ptr(get_dispatch_key(*pInstance), layer_data_map);
125 VkLayerInstanceDispatchTable *pTable = my_data->instance_dispatch_table;
Chia-I Wu69f40122015-10-26 21:10:41 +0800126 VkResult result = pTable->CreateInstance(pCreateInfo, pAllocator, pInstance);
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600127
128 if (result == VK_SUCCESS) {
Chia-I Wu763a7492015-10-26 20:48:51 +0800129 my_data->report_data = debug_report_create_instance(pTable, *pInstance, pCreateInfo->enabledExtensionNameCount,
Courtney Goeltzenleuchtereb1ddb02015-07-07 11:18:30 -0600130 pCreateInfo->ppEnabledExtensionNames);
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600131
Tobin Ehlis049f1782015-10-29 14:19:18 -0600132 InitImage(my_data);
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600133 }
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600134 return result;
135}
136
Chia-I Wuaf9e4fd2015-11-06 06:42:02 +0800137VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL vkDestroyInstance(VkInstance instance, const VkAllocationCallbacks* pAllocator)
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600138{
139 // Grab the key before the instance is destroyed.
140 dispatch_key key = get_dispatch_key(instance);
Tobin Ehlis049f1782015-10-29 14:19:18 -0600141 layer_data *my_data = get_my_data_ptr(key, layer_data_map);
142 VkLayerInstanceDispatchTable *pTable = my_data->instance_dispatch_table;
Chia-I Wu69f40122015-10-26 21:10:41 +0800143 pTable->DestroyInstance(instance, pAllocator);
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600144
145 // Clean up logging callback, if any
Courtney Goeltzenleuchter9fac1572015-10-05 15:59:11 -0600146 while (my_data->logging_callback.size() > 0) {
147 VkDbgMsgCallback callback = my_data->logging_callback.back();
148 layer_destroy_msg_callback(my_data->report_data, callback);
149 my_data->logging_callback.pop_back();
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600150 }
151
Tobin Ehlis049f1782015-10-29 14:19:18 -0600152 layer_debug_report_destroy_instance(my_data->report_data);
153 delete my_data->instance_dispatch_table;
154 layer_data_map.erase(key);
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600155
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600156}
157
Chia-I Wuaf9e4fd2015-11-06 06:42:02 +0800158VK_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 -0600159{
Tobin Ehlis049f1782015-10-29 14:19:18 -0600160 layer_data *instance_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);
161 layer_data *device_data = get_my_data_ptr(get_dispatch_key(*pDevice), layer_data_map);
Chia-I Wu69f40122015-10-26 21:10:41 +0800162 VkResult result = device_data->device_dispatch_table->CreateDevice(physicalDevice, pCreateInfo, pAllocator, pDevice);
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600163 if(result == VK_SUCCESS)
164 {
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600165 device_data->report_data = layer_debug_report_create_device(instance_data->report_data, *pDevice);
Chris Forbesd7576302015-06-21 22:55:02 +1200166 device_data->physicalDevice = physicalDevice;
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600167 }
168
Mark Lobodzinski69343212015-11-12 15:14:35 -0700169 instance_data->instance_dispatch_table->GetPhysicalDeviceProperties(physicalDevice, &(device_data->physicalDeviceProperties));
170
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600171 return result;
172}
173
Chia-I Wuaf9e4fd2015-11-06 06:42:02 +0800174VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL vkDestroyDevice(VkDevice device, const VkAllocationCallbacks* pAllocator)
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600175{
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600176 dispatch_key key = get_dispatch_key(device);
Tobin Ehlis049f1782015-10-29 14:19:18 -0600177 layer_data *my_data = get_my_data_ptr(key, layer_data_map);
Chia-I Wu69f40122015-10-26 21:10:41 +0800178 my_data->device_dispatch_table->DestroyDevice(device, pAllocator);
Tobin Ehlis049f1782015-10-29 14:19:18 -0600179 delete my_data->device_dispatch_table;
180 layer_data_map.erase(key);
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600181}
182
Courtney Goeltzenleuchtereb1ddb02015-07-07 11:18:30 -0600183static const VkLayerProperties pc_global_layers[] = {
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600184 {
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600185 "Image",
Courtney Goeltzenleuchtereb1ddb02015-07-07 11:18:30 -0600186 VK_API_VERSION,
187 VK_MAKE_VERSION(0, 1, 0),
188 "Validation layer: Image ParamChecker",
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600189 }
190};
191
Chia-I Wuaf9e4fd2015-11-06 06:42:02 +0800192VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateInstanceExtensionProperties(
Courtney Goeltzenleuchtereb1ddb02015-07-07 11:18:30 -0600193 const char *pLayerName,
194 uint32_t *pCount,
195 VkExtensionProperties* pProperties)
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600196{
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600197 // ParamChecker does not have any global extensions
Courtney Goeltzenleuchtereb1ddb02015-07-07 11:18:30 -0600198 return util_GetExtensionProperties(0, NULL, pCount, pProperties);
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600199}
200
Chia-I Wuaf9e4fd2015-11-06 06:42:02 +0800201VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateInstanceLayerProperties(
Courtney Goeltzenleuchtereb1ddb02015-07-07 11:18:30 -0600202 uint32_t *pCount,
203 VkLayerProperties* pProperties)
Tony Barbour426b9052015-06-24 16:06:58 -0600204{
Courtney Goeltzenleuchtereb1ddb02015-07-07 11:18:30 -0600205 return util_GetLayerProperties(ARRAY_SIZE(pc_global_layers),
206 pc_global_layers,
207 pCount, pProperties);
Tony Barbour426b9052015-06-24 16:06:58 -0600208}
209
Chia-I Wuaf9e4fd2015-11-06 06:42:02 +0800210VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateDeviceExtensionProperties(
Courtney Goeltzenleuchtereb1ddb02015-07-07 11:18:30 -0600211 VkPhysicalDevice physicalDevice,
212 const char* pLayerName,
213 uint32_t* pCount,
214 VkExtensionProperties* pProperties)
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600215{
Jon Ashburnaff81ff2015-11-02 17:37:20 -0700216 // Image does not have any physical device extensions
217 if (pLayerName == NULL) {
218 dispatch_key key = get_dispatch_key(physicalDevice);
219 layer_data *my_data = get_my_data_ptr(key, layer_data_map);
220 VkLayerInstanceDispatchTable *pTable = my_data->instance_dispatch_table;
221 return pTable->EnumerateDeviceExtensionProperties(
222 physicalDevice,
223 NULL,
224 pCount,
225 pProperties);
226 } else {
227 return util_GetExtensionProperties(0, NULL, pCount, pProperties);
228 }
Courtney Goeltzenleuchtereb1ddb02015-07-07 11:18:30 -0600229}
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600230
Chia-I Wuaf9e4fd2015-11-06 06:42:02 +0800231VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateDeviceLayerProperties(
Courtney Goeltzenleuchtereb1ddb02015-07-07 11:18:30 -0600232 VkPhysicalDevice physicalDevice,
233 uint32_t* pCount,
234 VkLayerProperties* pProperties)
235{
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600236 // ParamChecker's physical device layers are the same as global
Courtney Goeltzenleuchtereb1ddb02015-07-07 11:18:30 -0600237 return util_GetLayerProperties(ARRAY_SIZE(pc_global_layers), pc_global_layers,
238 pCount, pProperties);
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600239}
240
Mark Lobodzinski9cce7832015-07-29 09:21:22 -0600241// Start of the Image layer proper
242
243// Returns TRUE if a format is a depth-compatible format
244bool is_depth_format(VkFormat format)
245{
246 bool result = VK_FALSE;
247 switch (format) {
248 case VK_FORMAT_D16_UNORM:
Chia-I Wu9eabb8f2015-11-10 17:01:22 +0800249 case VK_FORMAT_X8_D24_UNORM_PACK32:
Mark Lobodzinski9cce7832015-07-29 09:21:22 -0600250 case VK_FORMAT_D32_SFLOAT:
251 case VK_FORMAT_S8_UINT:
252 case VK_FORMAT_D16_UNORM_S8_UINT:
253 case VK_FORMAT_D24_UNORM_S8_UINT:
254 case VK_FORMAT_D32_SFLOAT_S8_UINT:
255 result = VK_TRUE;
256 break;
257 default:
258 break;
259 }
260 return result;
261}
262
Mark Lobodzinski0e10db02015-11-10 11:01:32 -0700263static inline uint32_t validate_VkImageLayoutKHR(VkImageLayout input_value)
264{
265 return ((validate_VkImageLayout(input_value) == 1) ||
Ian Elliottc623ba52015-11-20 14:13:17 -0700266 (input_value == VK_IMAGE_LAYOUT_PRESENT_SRC_KHR));
Mark Lobodzinski0e10db02015-11-10 11:01:32 -0700267}
268
Chia-I Wuaf9e4fd2015-11-06 06:42:02 +0800269VK_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 -0600270{
Mark Lobodzinski69343212015-11-12 15:14:35 -0700271 VkBool32 skipCall = VK_FALSE;
272 VkResult result = VK_ERROR_VALIDATION_FAILED;
273 VkImageFormatProperties ImageFormatProperties = {0};
274
275 layer_data *device_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
276 VkPhysicalDevice physicalDevice = device_data->physicalDevice;
277 layer_data *phy_dev_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);
278
279 if (pCreateInfo->format != VK_FORMAT_UNDEFINED)
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600280 {
281 VkFormatProperties properties;
Mark Lobodzinski69343212015-11-12 15:14:35 -0700282 phy_dev_data->instance_dispatch_table->GetPhysicalDeviceFormatProperties(
Chris Forbesd7576302015-06-21 22:55:02 +1200283 device_data->physicalDevice, pCreateInfo->format, &properties);
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600284
Mark Lobodzinski69343212015-11-12 15:14:35 -0700285 if ((properties.linearTilingFeatures) == 0 && (properties.optimalTilingFeatures == 0))
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600286 {
287 char const str[] = "vkCreateImage parameter, VkFormat pCreateInfo->format, contains unsupported format";
Courtney Goeltzenleuchter95e6dba2015-11-25 11:38:54 -0700288 skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_WARN_BIT, (VkDebugReportObjectTypeLUNARG)0, 0, 0, IMAGE_FORMAT_UNSUPPORTED, "IMAGE", str);
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600289 }
290 }
291
Mark Lobodzinski69343212015-11-12 15:14:35 -0700292 // Internal call to get format info. Still goes through layers, could potentially go directly to ICD.
293 phy_dev_data->instance_dispatch_table->GetPhysicalDeviceImageFormatProperties(
294 physicalDevice, pCreateInfo->format, pCreateInfo->imageType, pCreateInfo->tiling,
295 pCreateInfo->usage, pCreateInfo->flags, &ImageFormatProperties);
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600296
Mark Lobodzinski69343212015-11-12 15:14:35 -0700297 VkDeviceSize imageGranularity = device_data->physicalDeviceProperties.limits.bufferImageGranularity;
298 imageGranularity = imageGranularity == 1 ? 0 : imageGranularity;
299
300 if ((pCreateInfo->extent.depth > ImageFormatProperties.maxExtent.depth) ||
301 (pCreateInfo->extent.width > ImageFormatProperties.maxExtent.width) ||
302 (pCreateInfo->extent.height > ImageFormatProperties.maxExtent.height)) {
Courtney Goeltzenleuchterf8fe1282015-11-25 10:30:56 -0700303 skipCall |= log_msg(phy_dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_IMAGE, (uint64_t)pImage, 0,
Mark Lobodzinski69343212015-11-12 15:14:35 -0700304 IMAGE_INVALID_FORMAT_LIMITS_VIOLATION, "Image",
305 "CreateImage extents exceed allowable limits for format: "
306 "Width = %d Height = %d Depth = %d: Limits for Width = %d Height = %d Depth = %d for format %s.",
307 pCreateInfo->extent.width, pCreateInfo->extent.height, pCreateInfo->extent.depth,
308 ImageFormatProperties.maxExtent.width, ImageFormatProperties.maxExtent.height, ImageFormatProperties.maxExtent.depth,
309 string_VkFormat(pCreateInfo->format));
310
311 }
312
313 uint64_t totalSize = ((uint64_t)pCreateInfo->extent.width *
314 (uint64_t)pCreateInfo->extent.height *
315 (uint64_t)pCreateInfo->extent.depth *
316 (uint64_t)pCreateInfo->arrayLayers *
317 (uint64_t)pCreateInfo->samples *
318 (uint64_t)vk_format_get_size(pCreateInfo->format) +
319 (uint64_t)imageGranularity ) & ~(uint64_t)imageGranularity;
320
321 if (totalSize > ImageFormatProperties.maxResourceSize) {
Courtney Goeltzenleuchterf8fe1282015-11-25 10:30:56 -0700322 skipCall |= log_msg(phy_dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_IMAGE, (uint64_t)pImage, 0,
Mark Lobodzinski69343212015-11-12 15:14:35 -0700323 IMAGE_INVALID_FORMAT_LIMITS_VIOLATION, "Image",
324 "CreateImage resource size exceeds allowable maximum "
325 "Image resource size = %#" PRIxLEAST64 ", maximum resource size = %#" PRIxLEAST64 " ",
326 totalSize, ImageFormatProperties.maxResourceSize);
327 }
328
329 if (pCreateInfo->mipLevels > ImageFormatProperties.maxMipLevels) {
Courtney Goeltzenleuchterf8fe1282015-11-25 10:30:56 -0700330 skipCall |= log_msg(phy_dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_IMAGE, (uint64_t)pImage, 0,
Mark Lobodzinski69343212015-11-12 15:14:35 -0700331 IMAGE_INVALID_FORMAT_LIMITS_VIOLATION, "Image",
332 "CreateImage mipLevels=%d exceeds allowable maximum supported by format of %d",
333 pCreateInfo->mipLevels, ImageFormatProperties.maxMipLevels);
334 }
335
336 if (pCreateInfo->arrayLayers > ImageFormatProperties.maxArrayLayers) {
Courtney Goeltzenleuchterf8fe1282015-11-25 10:30:56 -0700337 skipCall |= log_msg(phy_dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_IMAGE, (uint64_t)pImage, 0,
Mark Lobodzinski69343212015-11-12 15:14:35 -0700338 IMAGE_INVALID_FORMAT_LIMITS_VIOLATION, "Image",
339 "CreateImage arrayLayers=%d exceeds allowable maximum supported by format of %d",
340 pCreateInfo->arrayLayers, ImageFormatProperties.maxArrayLayers);
341 }
342
343 if ((pCreateInfo->samples & ImageFormatProperties.sampleCounts) == 0) {
Courtney Goeltzenleuchterf8fe1282015-11-25 10:30:56 -0700344 skipCall |= log_msg(phy_dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_IMAGE, (uint64_t)pImage, 0,
Mark Lobodzinski69343212015-11-12 15:14:35 -0700345 IMAGE_INVALID_FORMAT_LIMITS_VIOLATION, "Image",
346 "CreateImage samples %s is not supported by format 0x%.8X",
347 string_VkSampleCountFlagBits(pCreateInfo->samples), ImageFormatProperties.sampleCounts);
348 }
349
350 if (VK_FALSE == skipCall) {
351 result = device_data->device_dispatch_table->CreateImage(device, pCreateInfo, pAllocator, pImage);
352 }
353 if (result == VK_SUCCESS) {
Chia-I Wue420a332015-10-26 20:04:44 +0800354 device_data->imageMap[*pImage] = IMAGE_STATE(pCreateInfo);
Tobin Ehlis65380532015-09-21 15:20:28 -0600355 }
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600356 return result;
357}
358
Chia-I Wuaf9e4fd2015-11-06 06:42:02 +0800359VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL vkDestroyImage(VkDevice device, VkImage image, const VkAllocationCallbacks* pAllocator)
Tobin Ehlis65380532015-09-21 15:20:28 -0600360{
361 layer_data *device_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
Chia-I Wue420a332015-10-26 20:04:44 +0800362 device_data->imageMap.erase(image);
Chia-I Wu69f40122015-10-26 21:10:41 +0800363 device_data->device_dispatch_table->DestroyImage(device, image, pAllocator);
Tobin Ehlis65380532015-09-21 15:20:28 -0600364}
365
Chia-I Wuaf9e4fd2015-11-06 06:42:02 +0800366VK_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 -0600367{
Tobin Ehlis049f1782015-10-29 14:19:18 -0600368 layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
Tobin Ehlis35613802015-09-22 08:40:52 -0600369 VkBool32 skipCall = VK_FALSE;
Chia-I Wuc278df82015-07-07 11:50:03 +0800370 for(uint32_t i = 0; i < pCreateInfo->attachmentCount; ++i)
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600371 {
Chia-I Wuc278df82015-07-07 11:50:03 +0800372 if(pCreateInfo->pAttachments[i].format != VK_FORMAT_UNDEFINED)
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600373 {
374 VkFormatProperties properties;
Tobin Ehlis049f1782015-10-29 14:19:18 -0600375 get_my_data_ptr(get_dispatch_key(my_data->physicalDevice), layer_data_map)->instance_dispatch_table->GetPhysicalDeviceFormatProperties(
376 my_data->physicalDevice, pCreateInfo->pAttachments[i].format, &properties);
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600377
378 if((properties.linearTilingFeatures) == 0 && (properties.optimalTilingFeatures == 0))
379 {
380 std::stringstream ss;
Chia-I Wuc278df82015-07-07 11:50:03 +0800381 ss << "vkCreateRenderPass parameter, VkFormat in pCreateInfo->pAttachments[" << i << "], contains unsupported format";
Courtney Goeltzenleuchter95e6dba2015-11-25 11:38:54 -0700382 skipCall |= log_msg(my_data->report_data, VK_DEBUG_REPORT_WARN_BIT, (VkDebugReportObjectTypeLUNARG)0, 0, 0, IMAGE_FORMAT_UNSUPPORTED, "IMAGE", "%s", ss.str().c_str());
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600383 }
384 }
385 }
386
Chia-I Wuc278df82015-07-07 11:50:03 +0800387 for(uint32_t i = 0; i < pCreateInfo->attachmentCount; ++i)
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600388 {
Mark Lobodzinski0e10db02015-11-10 11:01:32 -0700389 if(!validate_VkImageLayoutKHR(pCreateInfo->pAttachments[i].initialLayout) ||
390 !validate_VkImageLayoutKHR(pCreateInfo->pAttachments[i].finalLayout))
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600391 {
392 std::stringstream ss;
Chia-I Wuc278df82015-07-07 11:50:03 +0800393 ss << "vkCreateRenderPass parameter, VkImageLayout in pCreateInfo->pAttachments[" << i << "], is unrecognized";
Courtney Goeltzenleuchter95e6dba2015-11-25 11:38:54 -0700394 skipCall |= log_msg(my_data->report_data, VK_DEBUG_REPORT_WARN_BIT, (VkDebugReportObjectTypeLUNARG)0, 0, 0, IMAGE_RENDERPASS_INVALID_ATTACHMENT, "IMAGE", "%s", ss.str().c_str());
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600395 }
396 }
397
Chia-I Wuc278df82015-07-07 11:50:03 +0800398 for(uint32_t i = 0; i < pCreateInfo->attachmentCount; ++i)
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600399 {
Chia-I Wuc278df82015-07-07 11:50:03 +0800400 if(!validate_VkAttachmentLoadOp(pCreateInfo->pAttachments[i].loadOp))
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600401 {
402 std::stringstream ss;
Chia-I Wuc278df82015-07-07 11:50:03 +0800403 ss << "vkCreateRenderPass parameter, VkAttachmentLoadOp in pCreateInfo->pAttachments[" << i << "], is unrecognized";
Courtney Goeltzenleuchter95e6dba2015-11-25 11:38:54 -0700404 skipCall |= log_msg(my_data->report_data, VK_DEBUG_REPORT_WARN_BIT, (VkDebugReportObjectTypeLUNARG)0, 0, 0, IMAGE_RENDERPASS_INVALID_ATTACHMENT, "IMAGE", "%s", ss.str().c_str());
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600405 }
406 }
407
Chia-I Wuc278df82015-07-07 11:50:03 +0800408 for(uint32_t i = 0; i < pCreateInfo->attachmentCount; ++i)
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600409 {
Chia-I Wuc278df82015-07-07 11:50:03 +0800410 if(!validate_VkAttachmentStoreOp(pCreateInfo->pAttachments[i].storeOp))
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600411 {
412 std::stringstream ss;
Chia-I Wuc278df82015-07-07 11:50:03 +0800413 ss << "vkCreateRenderPass parameter, VkAttachmentStoreOp in pCreateInfo->pAttachments[" << i << "], is unrecognized";
Courtney Goeltzenleuchter95e6dba2015-11-25 11:38:54 -0700414 skipCall |= log_msg(my_data->report_data, VK_DEBUG_REPORT_WARN_BIT, (VkDebugReportObjectTypeLUNARG)0, 0, 0, IMAGE_RENDERPASS_INVALID_ATTACHMENT, "IMAGE", "%s", ss.str().c_str());
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600415 }
416 }
417
Mark Lobodzinski9cce7832015-07-29 09:21:22 -0600418 // Any depth buffers specified as attachments?
419 bool depthFormatPresent = VK_FALSE;
420 for (uint32_t i = 0; i < pCreateInfo->attachmentCount; ++i)
421 {
422 depthFormatPresent |= is_depth_format(pCreateInfo->pAttachments[i].format);
423 }
424
425 if (depthFormatPresent == VK_FALSE) {
426 // No depth attachment is present, validate that subpasses set depthStencilAttachment to VK_ATTACHMENT_UNUSED;
427 for (uint32_t i = 0; i < pCreateInfo->subpassCount; i++) {
Chia-I Wuce532f72015-10-26 17:32:47 +0800428 if (pCreateInfo->pSubpasses[i].pDepthStencilAttachment &&
429 pCreateInfo->pSubpasses[i].pDepthStencilAttachment->attachment != VK_ATTACHMENT_UNUSED) {
Mark Lobodzinski9cce7832015-07-29 09:21:22 -0600430 std::stringstream ss;
431 ss << "vkCreateRenderPass has no depth/stencil attachment, yet subpass[" << i << "] has VkSubpassDescription::depthStencilAttachment value that is not VK_ATTACHMENT_UNUSED";
Courtney Goeltzenleuchter95e6dba2015-11-25 11:38:54 -0700432 skipCall |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT, (VkDebugReportObjectTypeLUNARG)0, 0, 0, IMAGE_RENDERPASS_INVALID_DS_ATTACHMENT, "IMAGE", "%s", ss.str().c_str());
Mark Lobodzinski9cce7832015-07-29 09:21:22 -0600433 }
434 }
435 }
Tobin Ehlis35613802015-09-22 08:40:52 -0600436 if (skipCall)
437 return VK_ERROR_VALIDATION_FAILED;
Mark Lobodzinski9cce7832015-07-29 09:21:22 -0600438
Chia-I Wu69f40122015-10-26 21:10:41 +0800439 VkResult result = my_data->device_dispatch_table->CreateRenderPass(device, pCreateInfo, pAllocator, pRenderPass);
Jeremy Hayesb707aa52015-06-18 10:12:39 -0600440
441 return result;
442}
443
Chia-I Wuaf9e4fd2015-11-06 06:42:02 +0800444VK_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 -0600445{
446 VkBool32 skipCall = VK_FALSE;
447 layer_data *device_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
Chia-I Wue420a332015-10-26 20:04:44 +0800448 auto imageEntry = device_data->imageMap.find(pCreateInfo->image);
Tobin Ehlis65380532015-09-21 15:20:28 -0600449 if (imageEntry != device_data->imageMap.end()) {
Tobin Ehlis6fa437d2015-09-25 14:49:43 -0600450 if (pCreateInfo->subresourceRange.baseMipLevel >= imageEntry->second.mipLevels) {
Tobin Ehlis65380532015-09-21 15:20:28 -0600451 std::stringstream ss;
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600452 ss << "vkCreateImageView called with baseMipLevel " << pCreateInfo->subresourceRange.baseMipLevel
Chia-I Wue420a332015-10-26 20:04:44 +0800453 << " for image " << pCreateInfo->image << " that only has " << imageEntry->second.mipLevels << " mip levels.";
Courtney Goeltzenleuchter95e6dba2015-11-25 11:38:54 -0700454 skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT, (VkDebugReportObjectTypeLUNARG)0, 0, 0, IMAGE_VIEW_CREATE_ERROR, "IMAGE", "%s", ss.str().c_str());
Tobin Ehlis65380532015-09-21 15:20:28 -0600455 }
Tobin Ehlis6fa437d2015-09-25 14:49:43 -0600456 if (pCreateInfo->subresourceRange.baseArrayLayer >= imageEntry->second.arraySize) {
Tobin Ehlis65380532015-09-21 15:20:28 -0600457 std::stringstream ss;
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600458 ss << "vkCreateImageView called with baseArrayLayer " << pCreateInfo->subresourceRange.baseArrayLayer << " for image "
Chia-I Wue420a332015-10-26 20:04:44 +0800459 << pCreateInfo->image << " that only has " << imageEntry->second.arraySize << " mip levels.";
Courtney Goeltzenleuchter95e6dba2015-11-25 11:38:54 -0700460 skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT, (VkDebugReportObjectTypeLUNARG)0, 0, 0, IMAGE_VIEW_CREATE_ERROR, "IMAGE", "%s", ss.str().c_str());
Tobin Ehlis65380532015-09-21 15:20:28 -0600461 }
Chia-I Wu1f851912015-10-27 18:04:07 +0800462 if (!pCreateInfo->subresourceRange.levelCount) {
Tobin Ehlis65380532015-09-21 15:20:28 -0600463 std::stringstream ss;
Jeremy Hayes00587c92015-11-17 18:24:56 -0700464 ss << "vkCreateImageView called with 0 in pCreateInfo->subresourceRange.levelCount.";
Courtney Goeltzenleuchter95e6dba2015-11-25 11:38:54 -0700465 skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT, (VkDebugReportObjectTypeLUNARG)0, 0, 0, IMAGE_VIEW_CREATE_ERROR, "IMAGE", "%s", ss.str().c_str());
Tobin Ehlis65380532015-09-21 15:20:28 -0600466 }
Chia-I Wu1f851912015-10-27 18:04:07 +0800467 if (!pCreateInfo->subresourceRange.layerCount) {
Tobin Ehlis65380532015-09-21 15:20:28 -0600468 std::stringstream ss;
Jeremy Hayes00587c92015-11-17 18:24:56 -0700469 ss << "vkCreateImageView called with 0 in pCreateInfo->subresourceRange.layerCount.";
Courtney Goeltzenleuchter95e6dba2015-11-25 11:38:54 -0700470 skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT, (VkDebugReportObjectTypeLUNARG)0, 0, 0, IMAGE_VIEW_CREATE_ERROR, "IMAGE", "%s", ss.str().c_str());
Tobin Ehlis65380532015-09-21 15:20:28 -0600471 }
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600472
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600473 // Validate correct image aspect bits for desired formats and format consistency
Tobin Ehlis6fa437d2015-09-25 14:49:43 -0600474 VkFormat imageFormat = imageEntry->second.format;
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600475 VkFormat ivciFormat = pCreateInfo->format;
476 VkImageAspectFlags aspectMask = pCreateInfo->subresourceRange.aspectMask;
477
478 if (vk_format_is_color(imageFormat)) {
479 if ((aspectMask & VK_IMAGE_ASPECT_COLOR_BIT) != VK_IMAGE_ASPECT_COLOR_BIT) {
480 std::stringstream ss;
481 ss << "vkCreateImageView: Color image formats must have the VK_IMAGE_ASPECT_COLOR_BIT set";
Courtney Goeltzenleuchterf8fe1282015-11-25 10:30:56 -0700482 skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_IMAGE,
Michael Lentinecbc4a5e2015-11-03 16:19:46 -0800483 (uint64_t)pCreateInfo->image, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", "%s", ss.str().c_str());
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600484 }
485 if ((aspectMask & VK_IMAGE_ASPECT_COLOR_BIT) != aspectMask) {
486 std::stringstream ss;
487 ss << "vkCreateImageView: Color image formats must have ONLY the VK_IMAGE_ASPECT_COLOR_BIT set";
Courtney Goeltzenleuchterf8fe1282015-11-25 10:30:56 -0700488 skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_IMAGE,
Michael Lentinecbc4a5e2015-11-03 16:19:46 -0800489 (uint64_t)pCreateInfo->image, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", "%s", ss.str().c_str());
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600490 }
491 if (VK_FALSE == vk_format_is_color(ivciFormat)) {
492 std::stringstream ss;
493 ss << "vkCreateImageView: The image view's format can differ from the parent image's format, but both must be "
494 << "color formats. ImageFormat is " << string_VkFormat(imageFormat) << " ImageViewFormat is " << string_VkFormat(ivciFormat);
Courtney Goeltzenleuchterf8fe1282015-11-25 10:30:56 -0700495 skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_IMAGE,
Michael Lentinecbc4a5e2015-11-03 16:19:46 -0800496 (uint64_t)pCreateInfo->image, 0, IMAGE_INVALID_FORMAT, "IMAGE", "%s", ss.str().c_str());
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600497 }
498 // TODO: Uncompressed formats are compatible if they occupy they same number of bits per pixel.
499 // Compressed formats are compatible if the only difference between them is the numerical type of
500 // the uncompressed pixels (e.g. signed vs. unsigned, or sRGB vs. UNORM encoding).
501 } else if (vk_format_is_depth_and_stencil(imageFormat)) {
Mark Lobodzinski168717e2015-11-23 09:07:20 -0700502 if ((aspectMask & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) == 0) {
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600503 std::stringstream ss;
Mark Lobodzinskidbffb1f2015-11-18 09:14:04 -0700504 ss << "vkCreateImageView: Depth/stencil image formats must have at least one of VK_IMAGE_ASPECT_DEPTH_BIT and VK_IMAGE_ASPECT_STENCIL_BIT set";
Courtney Goeltzenleuchterf8fe1282015-11-25 10:30:56 -0700505 skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_IMAGE,
Michael Lentinecbc4a5e2015-11-03 16:19:46 -0800506 (uint64_t)pCreateInfo->image, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", "%s", ss.str().c_str());
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600507 }
508 if ((aspectMask & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) != aspectMask) {
509 std::stringstream ss;
510 ss << "vkCreateImageView: Combination depth/stencil image formats can have only the VK_IMAGE_ASPECT_DEPTH_BIT and VK_IMAGE_ASPECT_STENCIL_BIT set";
Courtney Goeltzenleuchterf8fe1282015-11-25 10:30:56 -0700511 skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_IMAGE,
Michael Lentinecbc4a5e2015-11-03 16:19:46 -0800512 (uint64_t)pCreateInfo->image, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", "%s", ss.str().c_str());
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600513 }
514 } else if (vk_format_is_depth_only(imageFormat)) {
515 if ((aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT) != VK_IMAGE_ASPECT_DEPTH_BIT) {
516 std::stringstream ss;
517 ss << "vkCreateImageView: Depth-only image formats must have the VK_IMAGE_ASPECT_DEPTH_BIT set";
Courtney Goeltzenleuchterf8fe1282015-11-25 10:30:56 -0700518 skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_IMAGE,
Michael Lentinecbc4a5e2015-11-03 16:19:46 -0800519 (uint64_t)pCreateInfo->image, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", "%s", ss.str().c_str());
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600520 }
521 if ((aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT) != aspectMask) {
522 std::stringstream ss;
523 ss << "vkCreateImageView: Depth-only image formats can have only the VK_IMAGE_ASPECT_DEPTH_BIT set";
Courtney Goeltzenleuchterf8fe1282015-11-25 10:30:56 -0700524 skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_IMAGE,
Michael Lentinecbc4a5e2015-11-03 16:19:46 -0800525 (uint64_t)pCreateInfo->image, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", "%s", ss.str().c_str());
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600526 }
527 } else if (vk_format_is_stencil_only(imageFormat)) {
528 if ((aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT) != VK_IMAGE_ASPECT_STENCIL_BIT) {
529 std::stringstream ss;
530 ss << "vkCreateImageView: Stencil-only image formats must have the VK_IMAGE_ASPECT_STENCIL_BIT set";
Courtney Goeltzenleuchterf8fe1282015-11-25 10:30:56 -0700531 skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_IMAGE,
Michael Lentinecbc4a5e2015-11-03 16:19:46 -0800532 (uint64_t)pCreateInfo->image, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", "%s", ss.str().c_str());
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600533 }
534 if ((aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT) != aspectMask) {
535 std::stringstream ss;
536 ss << "vkCreateImageView: Stencil-only image formats can have only the VK_IMAGE_ASPECT_STENCIL_BIT set";
Courtney Goeltzenleuchterf8fe1282015-11-25 10:30:56 -0700537 skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_IMAGE,
Michael Lentinecbc4a5e2015-11-03 16:19:46 -0800538 (uint64_t)pCreateInfo->image, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", "%s", ss.str().c_str());
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600539 }
540 }
541 }
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600542
Tobin Ehlis65380532015-09-21 15:20:28 -0600543 if (skipCall)
544 return VK_ERROR_VALIDATION_FAILED;
Tobin Ehlis35613802015-09-22 08:40:52 -0600545
Chia-I Wu69f40122015-10-26 21:10:41 +0800546 VkResult result = device_data->device_dispatch_table->CreateImageView(device, pCreateInfo, pAllocator, pView);
Tobin Ehlis65380532015-09-21 15:20:28 -0600547 return result;
548}
549
Chia-I Wuaf9e4fd2015-11-06 06:42:02 +0800550VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdClearColorImage(
Chia-I Wu1f851912015-10-27 18:04:07 +0800551 VkCommandBuffer commandBuffer,
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600552 VkImage image,
553 VkImageLayout imageLayout,
554 const VkClearColorValue *pColor,
555 uint32_t rangeCount,
556 const VkImageSubresourceRange *pRanges)
557{
558 VkBool32 skipCall = VK_FALSE;
Chia-I Wu1f851912015-10-27 18:04:07 +0800559 layer_data *device_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600560 // For each range, image aspect must be color only
561 for (uint32_t i = 0; i < rangeCount; i++) {
562 if (pRanges[i].aspectMask != VK_IMAGE_ASPECT_COLOR_BIT) {
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600563 char const str[] = "vkCmdClearColorImage aspectMasks for all subresource ranges must be set to VK_IMAGE_ASPECT_COLOR_BIT";
Courtney Goeltzenleuchterf8fe1282015-11-25 10:30:56 -0700564 skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
Chia-I Wu1f851912015-10-27 18:04:07 +0800565 (uint64_t)commandBuffer, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", str);
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600566 }
567 }
568
569 if (VK_FALSE == skipCall) {
Chia-I Wu1f851912015-10-27 18:04:07 +0800570 device_data->device_dispatch_table->CmdClearColorImage(commandBuffer, image, imageLayout,
571 pColor, rangeCount, pRanges);
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600572 }
573}
574
Chia-I Wuaf9e4fd2015-11-06 06:42:02 +0800575VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdClearDepthStencilImage(
Chia-I Wu1f851912015-10-27 18:04:07 +0800576 VkCommandBuffer commandBuffer,
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600577 VkImage image,
578 VkImageLayout imageLayout,
579 const VkClearDepthStencilValue *pDepthStencil,
580 uint32_t rangeCount,
581 const VkImageSubresourceRange *pRanges)
582{
583 VkBool32 skipCall = VK_FALSE;
Chia-I Wu1f851912015-10-27 18:04:07 +0800584 layer_data *device_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600585 // For each range, Image aspect must be depth or stencil or both
586 for (uint32_t i = 0; i < rangeCount; i++) {
587 if (((pRanges[i].aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT) != VK_IMAGE_ASPECT_DEPTH_BIT) &&
588 ((pRanges[i].aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT) != VK_IMAGE_ASPECT_STENCIL_BIT))
589 {
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600590 char const str[] = "vkCmdClearDepthStencilImage aspectMasks for all subresource ranges must be "
591 "set to VK_IMAGE_ASPECT_DEPTH_BIT and/or VK_IMAGE_ASPECT_STENCIL_BIT";
Courtney Goeltzenleuchterf8fe1282015-11-25 10:30:56 -0700592 skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
Chia-I Wu1f851912015-10-27 18:04:07 +0800593 (uint64_t)commandBuffer, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", str);
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600594 }
595 }
596
597 if (VK_FALSE == skipCall) {
Chia-I Wu1f851912015-10-27 18:04:07 +0800598 device_data->device_dispatch_table->CmdClearDepthStencilImage(commandBuffer,
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600599 image, imageLayout, pDepthStencil, rangeCount, pRanges);
600 }
601}
602
Chia-I Wuaf9e4fd2015-11-06 06:42:02 +0800603VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdCopyImage(
Chia-I Wu1f851912015-10-27 18:04:07 +0800604 VkCommandBuffer commandBuffer,
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600605 VkImage srcImage,
606 VkImageLayout srcImageLayout,
Chia-I Wu1f851912015-10-27 18:04:07 +0800607 VkImage dstImage,
608 VkImageLayout dstImageLayout,
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600609 uint32_t regionCount,
610 const VkImageCopy *pRegions)
611{
612 VkBool32 skipCall = VK_FALSE;
Chia-I Wu1f851912015-10-27 18:04:07 +0800613 layer_data *device_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
Chia-I Wue420a332015-10-26 20:04:44 +0800614 auto srcImageEntry = device_data->imageMap.find(srcImage);
Chia-I Wu1f851912015-10-27 18:04:07 +0800615 auto dstImageEntry = device_data->imageMap.find(dstImage);
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600616
Jeremy Hayesac8ed0b2015-10-28 13:01:39 -0600617 // For each region, src and dst number of layers should not be zero
618 // For each region, src and dst number of layers must match
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600619 // For each region, src aspect mask must match dest aspect mask
620 // For each region, color aspects cannot be mixed with depth/stencil aspects
621 for (uint32_t i = 0; i < regionCount; i++) {
Chia-I Wu1f851912015-10-27 18:04:07 +0800622 if(pRegions[i].srcSubresource.layerCount == 0)
Jeremy Hayesac8ed0b2015-10-28 13:01:39 -0600623 {
624 char const str[] = "vkCmdCopyImage: number of layers in source subresource is zero";
Courtney Goeltzenleuchterf8fe1282015-11-25 10:30:56 -0700625 skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_WARN_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
Chia-I Wu1f851912015-10-27 18:04:07 +0800626 (uint64_t)commandBuffer, 0, IMAGE_MISMATCHED_IMAGE_ASPECT, "IMAGE", str);
Jeremy Hayesac8ed0b2015-10-28 13:01:39 -0600627 }
628
Chia-I Wu1f851912015-10-27 18:04:07 +0800629 if(pRegions[i].dstSubresource.layerCount == 0)
Jeremy Hayesac8ed0b2015-10-28 13:01:39 -0600630 {
631 char const str[] = "vkCmdCopyImage: number of layers in destination subresource is zero";
Courtney Goeltzenleuchterf8fe1282015-11-25 10:30:56 -0700632 skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_WARN_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
Chia-I Wu1f851912015-10-27 18:04:07 +0800633 (uint64_t)commandBuffer, 0, IMAGE_MISMATCHED_IMAGE_ASPECT, "IMAGE", str);
Jeremy Hayesac8ed0b2015-10-28 13:01:39 -0600634 }
635
Chia-I Wu1f851912015-10-27 18:04:07 +0800636 if(pRegions[i].srcSubresource.layerCount != pRegions[i].dstSubresource.layerCount)
Jeremy Hayesac8ed0b2015-10-28 13:01:39 -0600637 {
638 char const str[] = "vkCmdCopyImage: number of layers in source and destination subresources must match";
Courtney Goeltzenleuchterf8fe1282015-11-25 10:30:56 -0700639 skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
Chia-I Wu1f851912015-10-27 18:04:07 +0800640 (uint64_t)commandBuffer, 0, IMAGE_MISMATCHED_IMAGE_ASPECT, "IMAGE", str);
Jeremy Hayesac8ed0b2015-10-28 13:01:39 -0600641 }
642
Chia-I Wu4291d882015-10-27 19:00:15 +0800643 if (pRegions[i].srcSubresource.aspectMask != pRegions[i].dstSubresource.aspectMask) {
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600644 char const str[] = "vkCmdCopyImage: Src and dest aspectMasks for each region must match";
Courtney Goeltzenleuchterf8fe1282015-11-25 10:30:56 -0700645 skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
Chia-I Wu1f851912015-10-27 18:04:07 +0800646 (uint64_t)commandBuffer, 0, IMAGE_MISMATCHED_IMAGE_ASPECT, "IMAGE", str);
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600647 }
Chia-I Wu4291d882015-10-27 19:00:15 +0800648 if ((pRegions[i].srcSubresource.aspectMask & VK_IMAGE_ASPECT_COLOR_BIT) &&
649 (pRegions[i].srcSubresource.aspectMask & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT))) {
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600650 char const str[] = "vkCmdCopyImage aspectMask cannot specify both COLOR and DEPTH/STENCIL aspects";
Courtney Goeltzenleuchterf8fe1282015-11-25 10:30:56 -0700651 skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
Chia-I Wu1f851912015-10-27 18:04:07 +0800652 (uint64_t)commandBuffer, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", str);
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600653 }
654 }
655
Mike Stroyan43909d82015-09-25 13:39:21 -0600656 if ((srcImageEntry != device_data->imageMap.end())
Chia-I Wu1f851912015-10-27 18:04:07 +0800657 && (dstImageEntry != device_data->imageMap.end())) {
658 if (srcImageEntry->second.imageType != dstImageEntry->second.imageType) {
Mike Stroyan43909d82015-09-25 13:39:21 -0600659 char const str[] = "vkCmdCopyImage called with unmatched source and dest image types.";
Courtney Goeltzenleuchterf8fe1282015-11-25 10:30:56 -0700660 skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
Chia-I Wu1f851912015-10-27 18:04:07 +0800661 (uint64_t)commandBuffer, 0, IMAGE_MISMATCHED_IMAGE_TYPE, "IMAGE", str);
Mike Stroyan43909d82015-09-25 13:39:21 -0600662 }
663 // Check that format is same size or exact stencil/depth
Tobin Ehlis6fa437d2015-09-25 14:49:43 -0600664 if (is_depth_format(srcImageEntry->second.format)) {
Chia-I Wu1f851912015-10-27 18:04:07 +0800665 if (srcImageEntry->second.format != dstImageEntry->second.format) {
Mike Stroyan43909d82015-09-25 13:39:21 -0600666 char const str[] = "vkCmdCopyImage called with unmatched source and dest image depth/stencil formats.";
Courtney Goeltzenleuchterf8fe1282015-11-25 10:30:56 -0700667 skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
Chia-I Wu1f851912015-10-27 18:04:07 +0800668 (uint64_t)commandBuffer, 0, IMAGE_MISMATCHED_IMAGE_FORMAT, "IMAGE", str);
Mike Stroyan43909d82015-09-25 13:39:21 -0600669 }
670 } else {
Tobin Ehlis6fa437d2015-09-25 14:49:43 -0600671 size_t srcSize = vk_format_get_size(srcImageEntry->second.format);
Chia-I Wu1f851912015-10-27 18:04:07 +0800672 size_t destSize = vk_format_get_size(dstImageEntry->second.format);
Mike Stroyan43909d82015-09-25 13:39:21 -0600673 if (srcSize != destSize) {
674 char const str[] = "vkCmdCopyImage called with unmatched source and dest image format sizes.";
Courtney Goeltzenleuchterf8fe1282015-11-25 10:30:56 -0700675 skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
Chia-I Wu1f851912015-10-27 18:04:07 +0800676 (uint64_t)commandBuffer, 0, IMAGE_MISMATCHED_IMAGE_FORMAT, "IMAGE", str);
Mike Stroyan43909d82015-09-25 13:39:21 -0600677 }
678 }
679 }
680
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600681 if (VK_FALSE == skipCall) {
Chia-I Wu1f851912015-10-27 18:04:07 +0800682 device_data->device_dispatch_table->CmdCopyImage(commandBuffer, srcImage,
683 srcImageLayout, dstImage, dstImageLayout, regionCount, pRegions);
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600684 }
685}
686
Chia-I Wuaf9e4fd2015-11-06 06:42:02 +0800687VKAPI_ATTR void VKAPI_CALL vkCmdClearAttachments(
Chia-I Wu1f851912015-10-27 18:04:07 +0800688 VkCommandBuffer commandBuffer,
Courtney Goeltzenleuchter9feb0732015-10-15 16:51:05 -0600689 uint32_t attachmentCount,
690 const VkClearAttachment* pAttachments,
691 uint32_t rectCount,
Courtney Goeltzenleuchtera12e2912015-10-15 18:22:08 -0600692 const VkClearRect* pRects)
Courtney Goeltzenleuchter9feb0732015-10-15 16:51:05 -0600693{
694 VkBool32 skipCall = VK_FALSE;
695 VkImageAspectFlags aspectMask;
Chia-I Wu1f851912015-10-27 18:04:07 +0800696 layer_data *device_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
Courtney Goeltzenleuchter9feb0732015-10-15 16:51:05 -0600697 for (uint32_t i = 0; i < attachmentCount; i++) {
698 aspectMask = pAttachments[i].aspectMask;
699 if (aspectMask & VK_IMAGE_ASPECT_COLOR_BIT) {
700 if (aspectMask != VK_IMAGE_ASPECT_COLOR_BIT) {
701 // VK_IMAGE_ASPECT_COLOR_BIT is not the only bit set for this attachment
Courtney Goeltzenleuchter9feb0732015-10-15 16:51:05 -0600702 char const str[] = "vkCmdClearAttachments aspectMask [%d] must set only VK_IMAGE_ASPECT_COLOR_BIT of a color attachment.";
Courtney Goeltzenleuchterf8fe1282015-11-25 10:30:56 -0700703 skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
Chia-I Wu1f851912015-10-27 18:04:07 +0800704 (uint64_t)commandBuffer, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", str, i);
Courtney Goeltzenleuchter9feb0732015-10-15 16:51:05 -0600705 }
706 } else {
707 // Image aspect must be depth or stencil or both
708 if (((aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT) != VK_IMAGE_ASPECT_DEPTH_BIT) &&
709 ((aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT) != VK_IMAGE_ASPECT_STENCIL_BIT))
710 {
Courtney Goeltzenleuchter9feb0732015-10-15 16:51:05 -0600711 char const str[] = "vkCmdClearAttachments aspectMask [%d] must be set to VK_IMAGE_ASPECT_DEPTH_BIT and/or VK_IMAGE_ASPECT_STENCIL_BIT";
Courtney Goeltzenleuchterf8fe1282015-11-25 10:30:56 -0700712 skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
Chia-I Wu1f851912015-10-27 18:04:07 +0800713 (uint64_t)commandBuffer, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", str, i);
Courtney Goeltzenleuchter9feb0732015-10-15 16:51:05 -0600714 }
715 }
716 }
717
718 if (VK_FALSE == skipCall) {
Chia-I Wu1f851912015-10-27 18:04:07 +0800719 device_data->device_dispatch_table->CmdClearAttachments(commandBuffer,
Courtney Goeltzenleuchter9feb0732015-10-15 16:51:05 -0600720 attachmentCount, pAttachments, rectCount, pRects);
721 }
722}
723
Chia-I Wuaf9e4fd2015-11-06 06:42:02 +0800724VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdCopyImageToBuffer(
Chia-I Wu1f851912015-10-27 18:04:07 +0800725 VkCommandBuffer commandBuffer,
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600726 VkImage srcImage,
727 VkImageLayout srcImageLayout,
Chia-I Wu1f851912015-10-27 18:04:07 +0800728 VkBuffer dstBuffer,
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600729 uint32_t regionCount,
730 const VkBufferImageCopy *pRegions)
731{
732 VkBool32 skipCall = VK_FALSE;
Chia-I Wu1f851912015-10-27 18:04:07 +0800733 layer_data *device_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
Jeremy Hayesac8ed0b2015-10-28 13:01:39 -0600734 // For each region, the number of layers in the image subresource should not be zero
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600735 // Image aspect must be ONE OF color, depth, stencil
736 for (uint32_t i = 0; i < regionCount; i++) {
Chia-I Wu1f851912015-10-27 18:04:07 +0800737 if(pRegions[i].imageSubresource.layerCount == 0)
Jeremy Hayesac8ed0b2015-10-28 13:01:39 -0600738 {
Jeremy Hayesac8ed0b2015-10-28 13:01:39 -0600739 char const str[] = "vkCmdCopyImageToBuffer: number of layers in image subresource is zero";
Courtney Goeltzenleuchterf8fe1282015-11-25 10:30:56 -0700740 skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_WARN_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
Chia-I Wu1f851912015-10-27 18:04:07 +0800741 (uint64_t)commandBuffer, 0, IMAGE_MISMATCHED_IMAGE_ASPECT, "IMAGE", str);
Jeremy Hayesac8ed0b2015-10-28 13:01:39 -0600742 }
743
Chia-I Wu4291d882015-10-27 19:00:15 +0800744 VkImageAspectFlags aspectMask = pRegions[i].imageSubresource.aspectMask;
745 if ((aspectMask != VK_IMAGE_ASPECT_COLOR_BIT) &&
746 (aspectMask != VK_IMAGE_ASPECT_DEPTH_BIT) &&
747 (aspectMask != VK_IMAGE_ASPECT_STENCIL_BIT)) {
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600748 char const str[] = "vkCmdCopyImageToBuffer: aspectMasks for each region must specify only COLOR or DEPTH or STENCIL";
Courtney Goeltzenleuchterf8fe1282015-11-25 10:30:56 -0700749 skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
Chia-I Wu1f851912015-10-27 18:04:07 +0800750 (uint64_t)commandBuffer, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", str);
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600751 }
752 }
753
754 if (VK_FALSE == skipCall) {
Chia-I Wu1f851912015-10-27 18:04:07 +0800755 device_data->device_dispatch_table->CmdCopyImageToBuffer(commandBuffer,
756 srcImage, srcImageLayout, dstBuffer, regionCount, pRegions);
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600757 }
758}
759
Chia-I Wuaf9e4fd2015-11-06 06:42:02 +0800760VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdCopyBufferToImage(
Chia-I Wu1f851912015-10-27 18:04:07 +0800761 VkCommandBuffer commandBuffer,
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600762 VkBuffer srcBuffer,
Chia-I Wu1f851912015-10-27 18:04:07 +0800763 VkImage dstImage,
764 VkImageLayout dstImageLayout,
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600765 uint32_t regionCount,
766 const VkBufferImageCopy *pRegions)
767{
768 VkBool32 skipCall = VK_FALSE;
Chia-I Wu1f851912015-10-27 18:04:07 +0800769 layer_data *device_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
Jeremy Hayesac8ed0b2015-10-28 13:01:39 -0600770 // For each region, the number of layers in the image subresource should not be zero
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600771 // Image aspect must be ONE OF color, depth, stencil
772 for (uint32_t i = 0; i < regionCount; i++) {
Chia-I Wu1f851912015-10-27 18:04:07 +0800773 if(pRegions[i].imageSubresource.layerCount == 0)
Jeremy Hayesac8ed0b2015-10-28 13:01:39 -0600774 {
Jeremy Hayesac8ed0b2015-10-28 13:01:39 -0600775 char const str[] = "vkCmdCopyBufferToImage: number of layers in image subresource is zero";
Courtney Goeltzenleuchterf8fe1282015-11-25 10:30:56 -0700776 skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_WARN_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
Chia-I Wu1f851912015-10-27 18:04:07 +0800777 (uint64_t)commandBuffer, 0, IMAGE_MISMATCHED_IMAGE_ASPECT, "IMAGE", str);
Jeremy Hayesac8ed0b2015-10-28 13:01:39 -0600778 }
779
Chia-I Wu4291d882015-10-27 19:00:15 +0800780 VkImageAspectFlags aspectMask = pRegions[i].imageSubresource.aspectMask;
781 if ((aspectMask != VK_IMAGE_ASPECT_COLOR_BIT) &&
782 (aspectMask != VK_IMAGE_ASPECT_DEPTH_BIT) &&
783 (aspectMask != VK_IMAGE_ASPECT_STENCIL_BIT)) {
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600784 char const str[] = "vkCmdCopyBufferToImage: aspectMasks for each region must specify only COLOR or DEPTH or STENCIL";
Courtney Goeltzenleuchterf8fe1282015-11-25 10:30:56 -0700785 skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
Chia-I Wu1f851912015-10-27 18:04:07 +0800786 (uint64_t)commandBuffer, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", str);
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600787 }
788 }
789
790 if (VK_FALSE == skipCall) {
Chia-I Wu1f851912015-10-27 18:04:07 +0800791 device_data->device_dispatch_table->CmdCopyBufferToImage(commandBuffer,
792 srcBuffer, dstImage, dstImageLayout, regionCount, pRegions);
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600793 }
794}
795
Chia-I Wuaf9e4fd2015-11-06 06:42:02 +0800796VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdBlitImage(
Chia-I Wu1f851912015-10-27 18:04:07 +0800797 VkCommandBuffer commandBuffer,
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600798 VkImage srcImage,
799 VkImageLayout srcImageLayout,
Chia-I Wu1f851912015-10-27 18:04:07 +0800800 VkImage dstImage,
801 VkImageLayout dstImageLayout,
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600802 uint32_t regionCount,
803 const VkImageBlit *pRegions,
Chia-I Wu3603b082015-10-26 16:49:32 +0800804 VkFilter filter)
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600805{
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600806 VkBool32 skipCall = VK_FALSE;
Chia-I Wu1f851912015-10-27 18:04:07 +0800807 layer_data *device_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600808
Chia-I Wue420a332015-10-26 20:04:44 +0800809 auto srcImageEntry = device_data->imageMap.find(srcImage);
Chia-I Wu1f851912015-10-27 18:04:07 +0800810 auto dstImageEntry = device_data->imageMap.find(dstImage);
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600811
812 if ((srcImageEntry != device_data->imageMap.end()) &&
Chia-I Wu1f851912015-10-27 18:04:07 +0800813 (dstImageEntry != device_data->imageMap.end())) {
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600814
Tobin Ehlis6fa437d2015-09-25 14:49:43 -0600815 VkFormat srcFormat = srcImageEntry->second.format;
Chia-I Wu1f851912015-10-27 18:04:07 +0800816 VkFormat dstFormat = dstImageEntry->second.format;
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600817
818 // Validate consistency for signed and unsigned formats
819 if ((vk_format_is_sint(srcFormat) && !vk_format_is_sint(dstFormat)) ||
820 (vk_format_is_uint(srcFormat) && !vk_format_is_uint(dstFormat))) {
821 std::stringstream ss;
Chia-I Wu1f851912015-10-27 18:04:07 +0800822 ss << "vkCmdBlitImage: If one of srcImage and dstImage images has signed/unsigned integer format, "
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600823 << "the other one must also have signed/unsigned integer format. "
824 << "Source format is " << string_VkFormat(srcFormat) << " Destinatino format is " << string_VkFormat(dstFormat);
Courtney Goeltzenleuchterf8fe1282015-11-25 10:30:56 -0700825 skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
Michael Lentinecbc4a5e2015-11-03 16:19:46 -0800826 (uint64_t)commandBuffer, 0, IMAGE_INVALID_FORMAT, "IMAGE", "%s", ss.str().c_str());
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600827 }
828
829 // Validate aspect bits and formats for depth/stencil images
830 if (vk_format_is_depth_or_stencil(srcFormat) ||
831 vk_format_is_depth_or_stencil(dstFormat)) {
832 if (srcFormat != dstFormat) {
833 std::stringstream ss;
Chia-I Wu1f851912015-10-27 18:04:07 +0800834 ss << "vkCmdBlitImage: If one of srcImage and dstImage images has a format of depth, stencil or depth "
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600835 << "stencil, the other one must have exactly the same format. "
836 << "Source format is " << string_VkFormat(srcFormat) << " Destinatino format is " << string_VkFormat(dstFormat);
Courtney Goeltzenleuchterf8fe1282015-11-25 10:30:56 -0700837 skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
Michael Lentinecbc4a5e2015-11-03 16:19:46 -0800838 (uint64_t)commandBuffer, 0, IMAGE_INVALID_FORMAT, "IMAGE", "%s", ss.str().c_str());
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600839 }
840
841 for (uint32_t i = 0; i < regionCount; i++) {
Chia-I Wu1f851912015-10-27 18:04:07 +0800842 if(pRegions[i].srcSubresource.layerCount == 0)
Jeremy Hayesac8ed0b2015-10-28 13:01:39 -0600843 {
844 char const str[] = "vkCmdBlitImage: number of layers in source subresource is zero";
Courtney Goeltzenleuchterf8fe1282015-11-25 10:30:56 -0700845 skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_WARN_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
Chia-I Wu1f851912015-10-27 18:04:07 +0800846 (uint64_t)commandBuffer, 0, IMAGE_MISMATCHED_IMAGE_ASPECT, "IMAGE", str);
Jeremy Hayesac8ed0b2015-10-28 13:01:39 -0600847 }
848
Chia-I Wu1f851912015-10-27 18:04:07 +0800849 if(pRegions[i].dstSubresource.layerCount == 0)
Jeremy Hayesac8ed0b2015-10-28 13:01:39 -0600850 {
851 char const str[] = "vkCmdBlitImage: number of layers in destination subresource is zero";
Courtney Goeltzenleuchterf8fe1282015-11-25 10:30:56 -0700852 skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_WARN_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
Chia-I Wu1f851912015-10-27 18:04:07 +0800853 (uint64_t)commandBuffer, 0, IMAGE_MISMATCHED_IMAGE_ASPECT, "IMAGE", str);
Jeremy Hayesac8ed0b2015-10-28 13:01:39 -0600854 }
855
Chia-I Wu1f851912015-10-27 18:04:07 +0800856 if(pRegions[i].srcSubresource.layerCount != pRegions[i].dstSubresource.layerCount)
Jeremy Hayesac8ed0b2015-10-28 13:01:39 -0600857 {
858 char const str[] = "vkCmdBlitImage: number of layers in source and destination subresources must match";
Courtney Goeltzenleuchterf8fe1282015-11-25 10:30:56 -0700859 skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
Chia-I Wu1f851912015-10-27 18:04:07 +0800860 (uint64_t)commandBuffer, 0, IMAGE_MISMATCHED_IMAGE_ASPECT, "IMAGE", str);
Jeremy Hayesac8ed0b2015-10-28 13:01:39 -0600861 }
862
Chia-I Wu4291d882015-10-27 19:00:15 +0800863 VkImageAspectFlags srcAspect = pRegions[i].srcSubresource.aspectMask;
864 VkImageAspectFlags dstAspect = pRegions[i].dstSubresource.aspectMask;
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600865
866 if (srcAspect != dstAspect) {
867 std::stringstream ss;
868 ss << "vkCmdBlitImage: Image aspects of depth/stencil images should match";
Courtney Goeltzenleuchterf8fe1282015-11-25 10:30:56 -0700869 skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_WARN_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
Michael Lentinecbc4a5e2015-11-03 16:19:46 -0800870 (uint64_t)commandBuffer, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", "%s", ss.str().c_str());
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600871 }
872 if (vk_format_is_depth_and_stencil(srcFormat)) {
873 if (srcAspect != (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) {
874 std::stringstream ss;
875 ss << "vkCmdBlitImage: Combination depth/stencil image formats must have both VK_IMAGE_ASPECT_DEPTH_BIT "
Chia-I Wu1f851912015-10-27 18:04:07 +0800876 << "and VK_IMAGE_ASPECT_STENCIL_BIT set in both the srcImage and dstImage";
Courtney Goeltzenleuchterf8fe1282015-11-25 10:30:56 -0700877 skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
Michael Lentinecbc4a5e2015-11-03 16:19:46 -0800878 (uint64_t)commandBuffer, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", "%s", ss.str().c_str());
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600879 }
880 } else if (vk_format_is_stencil_only(srcFormat)) {
881 if (srcAspect != VK_IMAGE_ASPECT_STENCIL_BIT) {
882 std::stringstream ss;
883 ss << "vkCmdBlitImage: Stencil-only image formats must have only the VK_IMAGE_ASPECT_STENCIL_BIT "
Chia-I Wu1f851912015-10-27 18:04:07 +0800884 << "set in both the srcImage and dstImage";
Courtney Goeltzenleuchterf8fe1282015-11-25 10:30:56 -0700885 skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
Michael Lentinecbc4a5e2015-11-03 16:19:46 -0800886 (uint64_t)commandBuffer, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", "%s", ss.str().c_str());
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600887 }
888 } else if (vk_format_is_depth_only(srcFormat)) {
889 if (srcAspect != VK_IMAGE_ASPECT_DEPTH_BIT) {
890 std::stringstream ss;
891 ss << "vkCmdBlitImage: Depth-only image formats must have only the VK_IMAGE_ASPECT_DEPTH "
Chia-I Wu1f851912015-10-27 18:04:07 +0800892 << "set in both the srcImage and dstImage";
Courtney Goeltzenleuchterf8fe1282015-11-25 10:30:56 -0700893 skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
Michael Lentinecbc4a5e2015-11-03 16:19:46 -0800894 (uint64_t)commandBuffer, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", "%s", ss.str().c_str());
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600895 }
896 }
897 }
898 }
899
900 // Validate filter
901 if (vk_format_is_depth_or_stencil(srcFormat) ||
902 vk_format_is_int(srcFormat)) {
Chia-I Wu3603b082015-10-26 16:49:32 +0800903 if (filter != VK_FILTER_NEAREST) {
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600904 std::stringstream ss;
905 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 +0800906 << "then filter must be VK_FILTER_NEAREST.";
Courtney Goeltzenleuchterf8fe1282015-11-25 10:30:56 -0700907 skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
Michael Lentinecbc4a5e2015-11-03 16:19:46 -0800908 (uint64_t)commandBuffer, 0, IMAGE_INVALID_FILTER, "IMAGE", "%s", ss.str().c_str());
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600909 }
910 }
911 }
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600912
Chia-I Wu1f851912015-10-27 18:04:07 +0800913 device_data->device_dispatch_table->CmdBlitImage(commandBuffer, srcImage,
914 srcImageLayout, dstImage, dstImageLayout, regionCount, pRegions, filter);
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600915}
916
Jeremy Hayesa7d001a2015-11-17 18:19:55 -0700917VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdPipelineBarrier(
918 VkCommandBuffer commandBuffer,
919 VkPipelineStageFlags srcStageMask,
920 VkPipelineStageFlags dstStageMask,
921 VkDependencyFlags dependencyFlags,
922 uint32_t memoryBarrierCount,
923 const void* const* ppMemoryBarriers)
924{
925 VkBool32 skipCall = VK_FALSE;
926 layer_data *device_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
927
928 for (uint32_t i = 0; i < memoryBarrierCount; ++i)
929 {
930 VkImageMemoryBarrier const*const barrier = (VkImageMemoryBarrier const*const)ppMemoryBarriers[i];
931 if (barrier->sType == VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER)
932 {
933 if (barrier->subresourceRange.layerCount == 0)
934 {
935 std::stringstream ss;
936 ss << "vkCmdPipelineBarrier called with 0 in ppMemoryBarriers[" << i << "]->subresourceRange.layerCount.";
Courtney Goeltzenleuchter95e6dba2015-11-25 11:38:54 -0700937 skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT, (VkDebugReportObjectTypeLUNARG)0, 0, 0, 0, "IMAGE", "%s", ss.str().c_str());
Jeremy Hayesa7d001a2015-11-17 18:19:55 -0700938 }
939 }
940 }
941
942 if (skipCall)
943 {
944 return;
945 }
946
947 device_data->device_dispatch_table->CmdPipelineBarrier(commandBuffer, srcStageMask, dstStageMask, dependencyFlags,
948 memoryBarrierCount, ppMemoryBarriers);
949}
950
Chia-I Wuaf9e4fd2015-11-06 06:42:02 +0800951VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdResolveImage(
Chia-I Wu1f851912015-10-27 18:04:07 +0800952 VkCommandBuffer commandBuffer,
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600953 VkImage srcImage,
954 VkImageLayout srcImageLayout,
Chia-I Wu1f851912015-10-27 18:04:07 +0800955 VkImage dstImage,
956 VkImageLayout dstImageLayout,
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600957 uint32_t regionCount,
958 const VkImageResolve *pRegions)
959{
960 VkBool32 skipCall = VK_FALSE;
Chia-I Wu1f851912015-10-27 18:04:07 +0800961 layer_data *device_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
Chia-I Wue420a332015-10-26 20:04:44 +0800962 auto srcImageEntry = device_data->imageMap.find(srcImage);
Chia-I Wu1f851912015-10-27 18:04:07 +0800963 auto dstImageEntry = device_data->imageMap.find(dstImage);
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600964
Jeremy Hayesac8ed0b2015-10-28 13:01:39 -0600965 // For each region, the number of layers in the image subresource should not be zero
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600966 // For each region, src and dest image aspect must be color only
967 for (uint32_t i = 0; i < regionCount; i++) {
Chia-I Wu1f851912015-10-27 18:04:07 +0800968 if(pRegions[i].srcSubresource.layerCount == 0)
Jeremy Hayesac8ed0b2015-10-28 13:01:39 -0600969 {
970 char const str[] = "vkCmdResolveImage: number of layers in source subresource is zero";
Courtney Goeltzenleuchterf8fe1282015-11-25 10:30:56 -0700971 skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_WARN_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
Chia-I Wu1f851912015-10-27 18:04:07 +0800972 (uint64_t)commandBuffer, 0, IMAGE_MISMATCHED_IMAGE_ASPECT, "IMAGE", str);
Jeremy Hayesac8ed0b2015-10-28 13:01:39 -0600973 }
974
Chia-I Wu1f851912015-10-27 18:04:07 +0800975 if(pRegions[i].dstSubresource.layerCount == 0)
Jeremy Hayesac8ed0b2015-10-28 13:01:39 -0600976 {
977 char const str[] = "vkCmdResolveImage: number of layers in destination subresource is zero";
Courtney Goeltzenleuchterf8fe1282015-11-25 10:30:56 -0700978 skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_WARN_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
Chia-I Wu1f851912015-10-27 18:04:07 +0800979 (uint64_t)commandBuffer, 0, IMAGE_MISMATCHED_IMAGE_ASPECT, "IMAGE", str);
Jeremy Hayesac8ed0b2015-10-28 13:01:39 -0600980 }
981
Chia-I Wu4291d882015-10-27 19:00:15 +0800982 if ((pRegions[i].srcSubresource.aspectMask != VK_IMAGE_ASPECT_COLOR_BIT) ||
983 (pRegions[i].dstSubresource.aspectMask != VK_IMAGE_ASPECT_COLOR_BIT)) {
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600984 char const str[] = "vkCmdResolveImage: src and dest aspectMasks for each region must specify only VK_IMAGE_ASPECT_COLOR_BIT";
Courtney Goeltzenleuchterf8fe1282015-11-25 10:30:56 -0700985 skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
Chia-I Wu1f851912015-10-27 18:04:07 +0800986 (uint64_t)commandBuffer, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", str);
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -0600987 }
988 }
989
Mark Lobodzinskib4092de2015-10-23 14:20:31 -0600990 if ((srcImageEntry != device_data->imageMap.end()) &&
Chia-I Wu1f851912015-10-27 18:04:07 +0800991 (dstImageEntry != device_data->imageMap.end())) {
992 if (srcImageEntry->second.format != dstImageEntry->second.format) {
Mike Stroyan43909d82015-09-25 13:39:21 -0600993 char const str[] = "vkCmdResolveImage called with unmatched source and dest formats.";
Courtney Goeltzenleuchterf8fe1282015-11-25 10:30:56 -0700994 skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
Chia-I Wu1f851912015-10-27 18:04:07 +0800995 (uint64_t)commandBuffer, 0, IMAGE_MISMATCHED_IMAGE_FORMAT, "IMAGE", str);
Mike Stroyan43909d82015-09-25 13:39:21 -0600996 }
Chia-I Wu1f851912015-10-27 18:04:07 +0800997 if (srcImageEntry->second.imageType != dstImageEntry->second.imageType) {
Mike Stroyan43909d82015-09-25 13:39:21 -0600998 char const str[] = "vkCmdResolveImage called with unmatched source and dest image types.";
Courtney Goeltzenleuchterf8fe1282015-11-25 10:30:56 -0700999 skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
Chia-I Wu1f851912015-10-27 18:04:07 +08001000 (uint64_t)commandBuffer, 0, IMAGE_MISMATCHED_IMAGE_TYPE, "IMAGE", str);
Mike Stroyan43909d82015-09-25 13:39:21 -06001001 }
Chia-I Wu3138d6a2015-10-31 00:31:16 +08001002 if (srcImageEntry->second.samples == VK_SAMPLE_COUNT_1_BIT) {
Mike Stroyan43909d82015-09-25 13:39:21 -06001003 char const str[] = "vkCmdResolveImage called with source sample count less than 2.";
Courtney Goeltzenleuchterf8fe1282015-11-25 10:30:56 -07001004 skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
Chia-I Wu1f851912015-10-27 18:04:07 +08001005 (uint64_t)commandBuffer, 0, IMAGE_INVALID_RESOLVE_SAMPLES, "IMAGE", str);
Mike Stroyan43909d82015-09-25 13:39:21 -06001006 }
Chia-I Wu3138d6a2015-10-31 00:31:16 +08001007 if (dstImageEntry->second.samples != VK_SAMPLE_COUNT_1_BIT) {
Mike Stroyan43909d82015-09-25 13:39:21 -06001008 char const str[] = "vkCmdResolveImage called with dest sample count greater than 1.";
Courtney Goeltzenleuchterf8fe1282015-11-25 10:30:56 -07001009 skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
Chia-I Wu1f851912015-10-27 18:04:07 +08001010 (uint64_t)commandBuffer, 0, IMAGE_INVALID_RESOLVE_SAMPLES, "IMAGE", str);
Mike Stroyan43909d82015-09-25 13:39:21 -06001011 }
1012 }
1013
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -06001014 if (VK_FALSE == skipCall) {
Chia-I Wu1f851912015-10-27 18:04:07 +08001015 device_data->device_dispatch_table->CmdResolveImage(commandBuffer, srcImage,
1016 srcImageLayout, dstImage, dstImageLayout, regionCount, pRegions);
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -06001017 }
1018}
1019
Chia-I Wuaf9e4fd2015-11-06 06:42:02 +08001020VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL vkGetImageSubresourceLayout(
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -06001021 VkDevice device,
1022 VkImage image,
1023 const VkImageSubresource *pSubresource,
1024 VkSubresourceLayout *pLayout)
1025{
Mark Lobodzinskib4092de2015-10-23 14:20:31 -06001026 VkBool32 skipCall = VK_FALSE;
1027 layer_data *device_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
1028 VkFormat format;
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -06001029
Chia-I Wue420a332015-10-26 20:04:44 +08001030 auto imageEntry = device_data->imageMap.find(image);
Mark Lobodzinskib4092de2015-10-23 14:20:31 -06001031
1032 // Validate that image aspects match formats
1033 if (imageEntry != device_data->imageMap.end()) {
Tobin Ehlis6fa437d2015-09-25 14:49:43 -06001034 format = imageEntry->second.format;
Mark Lobodzinskib4092de2015-10-23 14:20:31 -06001035 if (vk_format_is_color(format)) {
Chia-I Wu195c9e12015-10-27 19:55:05 +08001036 if (pSubresource->aspectMask != VK_IMAGE_ASPECT_COLOR_BIT) {
Mark Lobodzinskib4092de2015-10-23 14:20:31 -06001037 std::stringstream ss;
Chia-I Wu195c9e12015-10-27 19:55:05 +08001038 ss << "vkGetImageSubresourceLayout: For color formats, the aspectMask field of VkImageSubresource must be VK_IMAGE_ASPECT_COLOR.";
Courtney Goeltzenleuchterf8fe1282015-11-25 10:30:56 -07001039 skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_IMAGE,
Michael Lentinecbc4a5e2015-11-03 16:19:46 -08001040 (uint64_t)image, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", "%s", ss.str().c_str());
Mark Lobodzinskib4092de2015-10-23 14:20:31 -06001041 }
1042 } else if (vk_format_is_depth_or_stencil(format)) {
Chia-I Wu195c9e12015-10-27 19:55:05 +08001043 if ((pSubresource->aspectMask != VK_IMAGE_ASPECT_DEPTH_BIT) &&
1044 (pSubresource->aspectMask != VK_IMAGE_ASPECT_STENCIL_BIT)) {
Mark Lobodzinskib4092de2015-10-23 14:20:31 -06001045 std::stringstream ss;
Chia-I Wu195c9e12015-10-27 19:55:05 +08001046 ss << "vkGetImageSubresourceLayout: For depth/stencil formats, the aspectMask selects either the depth or stencil image aspectMask.";
Courtney Goeltzenleuchterf8fe1282015-11-25 10:30:56 -07001047 skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_IMAGE,
Michael Lentinecbc4a5e2015-11-03 16:19:46 -08001048 (uint64_t)image, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", "%s", ss.str().c_str());
Mark Lobodzinskib4092de2015-10-23 14:20:31 -06001049 }
1050 }
1051 }
1052
1053 if (VK_FALSE == skipCall) {
Tobin Ehlis049f1782015-10-29 14:19:18 -06001054 device_data->device_dispatch_table->GetImageSubresourceLayout(device,
Mark Lobodzinskib4092de2015-10-23 14:20:31 -06001055 image, pSubresource, pLayout);
1056 }
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -06001057}
1058
Mark Lobodzinski69343212015-11-12 15:14:35 -07001059VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceProperties(VkPhysicalDevice physicalDevice, VkPhysicalDeviceProperties* pProperties)
1060{
1061 layer_data *phy_dev_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);
1062 phy_dev_data->instance_dispatch_table->GetPhysicalDeviceProperties(physicalDevice, pProperties);
1063}
1064
Chia-I Wuaf9e4fd2015-11-06 06:42:02 +08001065VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetDeviceProcAddr(VkDevice device, const char* funcName)
Jeremy Hayesb707aa52015-06-18 10:12:39 -06001066{
1067 if (device == NULL) {
1068 return NULL;
1069 }
1070
Tobin Ehlis049f1782015-10-29 14:19:18 -06001071 layer_data *my_data;
Mark Lobodzinskib4092de2015-10-23 14:20:31 -06001072 // loader uses this to force layer initialization; device object is wrapped
Jeremy Hayesb707aa52015-06-18 10:12:39 -06001073 if (!strcmp(funcName, "vkGetDeviceProcAddr")) {
Tobin Ehlis049f1782015-10-29 14:19:18 -06001074 VkBaseLayerObject* wrapped_dev = (VkBaseLayerObject*) device;
1075 my_data = get_my_data_ptr(get_dispatch_key(wrapped_dev->baseObject), layer_data_map);
1076 my_data->device_dispatch_table = new VkLayerDispatchTable;
1077 layer_initialize_dispatch_table(my_data->device_dispatch_table, wrapped_dev);
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06001078 return (PFN_vkVoidFunction) vkGetDeviceProcAddr;
Jeremy Hayesb707aa52015-06-18 10:12:39 -06001079 }
1080
Tobin Ehlis049f1782015-10-29 14:19:18 -06001081 my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
Courtney Goeltzenleuchterbe637992015-06-25 18:01:43 -06001082 if (!strcmp(funcName, "vkCreateDevice"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06001083 return (PFN_vkVoidFunction) vkCreateDevice;
Jeremy Hayesb707aa52015-06-18 10:12:39 -06001084 if (!strcmp(funcName, "vkDestroyDevice"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06001085 return (PFN_vkVoidFunction) vkDestroyDevice;
Jeremy Hayesb707aa52015-06-18 10:12:39 -06001086 if (!strcmp(funcName, "vkCreateImage"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06001087 return (PFN_vkVoidFunction) vkCreateImage;
Mark Lobodzinski9eb1ce42015-10-29 12:58:33 -06001088 if (!strcmp(funcName, "vkDestroyImage"))
1089 return (PFN_vkVoidFunction) vkDestroyImage;
Tobin Ehlis342b9bf2015-09-22 10:11:37 -06001090 if (!strcmp(funcName, "vkCreateImageView"))
1091 return (PFN_vkVoidFunction) vkCreateImageView;
Jeremy Hayesb707aa52015-06-18 10:12:39 -06001092 if (!strcmp(funcName, "vkCreateRenderPass"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06001093 return (PFN_vkVoidFunction) vkCreateRenderPass;
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -06001094 if (!strcmp(funcName, "vkCmdClearColorImage"))
1095 return (PFN_vkVoidFunction) vkCmdClearColorImage;
1096 if (!strcmp(funcName, "vkCmdClearDepthStencilImage"))
1097 return (PFN_vkVoidFunction) vkCmdClearDepthStencilImage;
Courtney Goeltzenleuchter9feb0732015-10-15 16:51:05 -06001098 if (!strcmp(funcName, "vkCmdClearAttachments"))
1099 return (PFN_vkVoidFunction) vkCmdClearAttachments;
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -06001100 if (!strcmp(funcName, "vkCmdCopyImage"))
1101 return (PFN_vkVoidFunction) vkCmdCopyImage;
1102 if (!strcmp(funcName, "vkCmdCopyImageToBuffer"))
1103 return (PFN_vkVoidFunction) vkCmdCopyImageToBuffer;
1104 if (!strcmp(funcName, "vkCmdCopyBufferToImage"))
1105 return (PFN_vkVoidFunction) vkCmdCopyBufferToImage;
1106 if (!strcmp(funcName, "vkCmdBlitImage"))
1107 return (PFN_vkVoidFunction) vkCmdBlitImage;
Jeremy Hayesa7d001a2015-11-17 18:19:55 -07001108 if (!strcmp(funcName, "vkCmdPipelineBarrier"))
1109 return (PFN_vkVoidFunction) vkCmdPipelineBarrier;
Mark Lobodzinski6f3403c2015-10-05 17:16:05 -06001110 if (!strcmp(funcName, "vkCmdResolveImage"))
1111 return (PFN_vkVoidFunction) vkCmdResolveImage;
1112 if (!strcmp(funcName, "vkGetImageSubresourceLayout"))
1113 return (PFN_vkVoidFunction) vkGetImageSubresourceLayout;
Tobin Ehlis049f1782015-10-29 14:19:18 -06001114
1115 VkLayerDispatchTable* pTable = my_data->device_dispatch_table;
Jeremy Hayesb707aa52015-06-18 10:12:39 -06001116 {
Tobin Ehlis049f1782015-10-29 14:19:18 -06001117 if (pTable->GetDeviceProcAddr == NULL)
Jeremy Hayesb707aa52015-06-18 10:12:39 -06001118 return NULL;
Tobin Ehlis049f1782015-10-29 14:19:18 -06001119 return pTable->GetDeviceProcAddr(device, funcName);
Jeremy Hayesb707aa52015-06-18 10:12:39 -06001120 }
1121}
1122
Chia-I Wuaf9e4fd2015-11-06 06:42:02 +08001123VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetInstanceProcAddr(VkInstance instance, const char* funcName)
Jeremy Hayesb707aa52015-06-18 10:12:39 -06001124{
1125 if (instance == NULL) {
1126 return NULL;
1127 }
1128
Tobin Ehlis049f1782015-10-29 14:19:18 -06001129 layer_data *my_data;
Mark Lobodzinskib4092de2015-10-23 14:20:31 -06001130 // loader uses this to force layer initialization; instance object is wrapped
Jeremy Hayesb707aa52015-06-18 10:12:39 -06001131 if (!strcmp(funcName, "vkGetInstanceProcAddr")) {
Tobin Ehlis049f1782015-10-29 14:19:18 -06001132 VkBaseLayerObject* wrapped_inst = (VkBaseLayerObject*) instance;
1133 my_data = get_my_data_ptr(get_dispatch_key(wrapped_inst->baseObject), layer_data_map);
1134 my_data->instance_dispatch_table = new VkLayerInstanceDispatchTable;
1135 layer_init_instance_dispatch_table(my_data->instance_dispatch_table, wrapped_inst);
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06001136 return (PFN_vkVoidFunction) vkGetInstanceProcAddr;
Jeremy Hayesb707aa52015-06-18 10:12:39 -06001137 }
1138
Tobin Ehlis049f1782015-10-29 14:19:18 -06001139 my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
Jeremy Hayesb707aa52015-06-18 10:12:39 -06001140 if (!strcmp(funcName, "vkCreateInstance"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06001141 return (PFN_vkVoidFunction) vkCreateInstance;
Jeremy Hayesb707aa52015-06-18 10:12:39 -06001142 if (!strcmp(funcName, "vkDestroyInstance"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06001143 return (PFN_vkVoidFunction) vkDestroyInstance;
Courtney Goeltzenleuchter74c4ce92015-09-14 17:22:16 -06001144 if (!strcmp(funcName, "vkEnumerateInstanceLayerProperties"))
1145 return (PFN_vkVoidFunction) vkEnumerateInstanceLayerProperties;
1146 if (!strcmp(funcName, "vkEnumerateInstanceExtensionProperties"))
1147 return (PFN_vkVoidFunction) vkEnumerateInstanceExtensionProperties;
1148 if (!strcmp(funcName, "vkEnumerateDeviceLayerProperties"))
1149 return (PFN_vkVoidFunction) vkEnumerateDeviceLayerProperties;
1150 if (!strcmp(funcName, "vkEnumerateDeviceExtensionProperties"))
1151 return (PFN_vkVoidFunction) vkEnumerateDeviceExtensionProperties;
Mark Lobodzinski69343212015-11-12 15:14:35 -07001152 if (!strcmp(funcName, "vkGetPhysicalDeviceProperties"))
1153 return (PFN_vkVoidFunction) vkGetPhysicalDeviceProperties;
Jeremy Hayesb707aa52015-06-18 10:12:39 -06001154
Tobin Ehlis049f1782015-10-29 14:19:18 -06001155 PFN_vkVoidFunction fptr = debug_report_get_instance_proc_addr(my_data->report_data, funcName);
Jeremy Hayesb707aa52015-06-18 10:12:39 -06001156 if(fptr)
1157 return fptr;
1158
1159 {
Tobin Ehlis049f1782015-10-29 14:19:18 -06001160 VkLayerInstanceDispatchTable* pTable = my_data->instance_dispatch_table;
1161 if (pTable->GetInstanceProcAddr == NULL)
Jeremy Hayesb707aa52015-06-18 10:12:39 -06001162 return NULL;
Tobin Ehlis049f1782015-10-29 14:19:18 -06001163 return pTable->GetInstanceProcAddr(instance, funcName);
Jeremy Hayesb707aa52015-06-18 10:12:39 -06001164 }
1165}