1 /* Copyright (c) 2015-2016 The Khronos Group Inc. 2 * Copyright (c) 2015-2016 Valve Corporation 3 * Copyright (c) 2015-2016 LunarG, Inc. 4 * Copyright (C) 2015-2016 Google Inc. 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a copy 7 * of this software and/or associated documentation files (the "Materials"), to 8 * deal in the Materials without restriction, including without limitation the 9 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 10 * sell copies of the Materials, and to permit persons to whom the Materials 11 * are furnished to do so, subject to the following conditions: 12 * 13 * The above copyright notice(s) and this permission notice shall be included 14 * in all copies or substantial portions of the Materials. 15 * 16 * THE MATERIALS ARE 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. 19 * 20 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 21 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 22 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE 23 * USE OR OTHER DEALINGS IN THE MATERIALS 24 * 25 * Author: Jeremy Hayes <jeremy (at) lunarg.com> 26 * Author: Mark Lobodzinski <mark (at) lunarg.com> 27 * Author: Mike Stroyan <mike (at) LunarG.com> 28 * Author: Tobin Ehlis <tobin (at) lunarg.com> 29 */ 30 31 #include <inttypes.h> 32 #include <stdio.h> 33 #include <stdlib.h> 34 #include <string.h> 35 #include <assert.h> 36 #include <vector> 37 #include <unordered_map> 38 #include <memory> 39 using namespace std; 40 41 #include "vk_loader_platform.h" 42 #include "vk_dispatch_table_helper.h" 43 #include "vk_struct_string_helper_cpp.h" 44 #include "vk_enum_validate_helper.h" 45 #include "image.h" 46 #include "vk_layer_config.h" 47 #include "vk_layer_extension_utils.h" 48 #include "vk_layer_table.h" 49 #include "vk_layer_data.h" 50 #include "vk_layer_extension_utils.h" 51 #include "vk_layer_utils.h" 52 #include "vk_layer_logging.h" 53 54 using namespace std; 55 56 struct layer_data { 57 debug_report_data *report_data; 58 vector<VkDebugReportCallbackEXT> logging_callback; 59 VkLayerDispatchTable *device_dispatch_table; 60 VkLayerInstanceDispatchTable *instance_dispatch_table; 61 VkPhysicalDevice physicalDevice; 62 VkPhysicalDeviceProperties physicalDeviceProperties; 63 64 unordered_map<VkImage, IMAGE_STATE> imageMap; 65 66 layer_data() 67 : report_data(nullptr), device_dispatch_table(nullptr), instance_dispatch_table(nullptr), physicalDevice(0), 68 physicalDeviceProperties(){}; 69 }; 70 71 static unordered_map<void *, layer_data *> layer_data_map; 72 static int globalLockInitialized = 0; 73 static loader_platform_thread_mutex globalLock; 74 75 static void init_image(layer_data *my_data, const VkAllocationCallbacks *pAllocator) { 76 77 layer_debug_actions(my_data->report_data, my_data->logging_callback, pAllocator, "lunarg_image"); 78 79 if (!globalLockInitialized) { 80 loader_platform_thread_create_mutex(&globalLock); 81 globalLockInitialized = 1; 82 } 83 } 84 85 VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL 86 vkCreateDebugReportCallbackEXT(VkInstance instance, const VkDebugReportCallbackCreateInfoEXT *pCreateInfo, 87 const VkAllocationCallbacks *pAllocator, VkDebugReportCallbackEXT *pMsgCallback) { 88 layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map); 89 VkResult res = my_data->instance_dispatch_table->CreateDebugReportCallbackEXT(instance, pCreateInfo, pAllocator, pMsgCallback); 90 if (res == VK_SUCCESS) { 91 res = layer_create_msg_callback(my_data->report_data, pCreateInfo, pAllocator, pMsgCallback); 92 } 93 return res; 94 } 95 96 VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL vkDestroyDebugReportCallbackEXT(VkInstance instance, 97 VkDebugReportCallbackEXT msgCallback, 98 const VkAllocationCallbacks *pAllocator) { 99 layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map); 100 my_data->instance_dispatch_table->DestroyDebugReportCallbackEXT(instance, msgCallback, pAllocator); 101 layer_destroy_msg_callback(my_data->report_data, msgCallback, pAllocator); 102 } 103 104 VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL 105 vkDebugReportMessageEXT(VkInstance instance, VkDebugReportFlagsEXT flags, VkDebugReportObjectTypeEXT objType, uint64_t object, 106 size_t location, int32_t msgCode, const char *pLayerPrefix, const char *pMsg) { 107 layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map); 108 my_data->instance_dispatch_table->DebugReportMessageEXT(instance, flags, objType, object, location, msgCode, pLayerPrefix, 109 pMsg); 110 } 111 112 VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL 113 vkCreateInstance(const VkInstanceCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkInstance *pInstance) { 114 VkLayerInstanceCreateInfo *chain_info = get_chain_info(pCreateInfo, VK_LAYER_LINK_INFO); 115 116 assert(chain_info->u.pLayerInfo); 117 PFN_vkGetInstanceProcAddr fpGetInstanceProcAddr = chain_info->u.pLayerInfo->pfnNextGetInstanceProcAddr; 118 PFN_vkCreateInstance fpCreateInstance = (PFN_vkCreateInstance)fpGetInstanceProcAddr(NULL, "vkCreateInstance"); 119 if (fpCreateInstance == NULL) { 120 return VK_ERROR_INITIALIZATION_FAILED; 121 } 122 123 // Advance the link info for the next element on the chain 124 chain_info->u.pLayerInfo = chain_info->u.pLayerInfo->pNext; 125 126 VkResult result = fpCreateInstance(pCreateInfo, pAllocator, pInstance); 127 if (result != VK_SUCCESS) 128 return result; 129 130 layer_data *my_data = get_my_data_ptr(get_dispatch_key(*pInstance), layer_data_map); 131 my_data->instance_dispatch_table = new VkLayerInstanceDispatchTable; 132 layer_init_instance_dispatch_table(*pInstance, my_data->instance_dispatch_table, fpGetInstanceProcAddr); 133 134 my_data->report_data = debug_report_create_instance(my_data->instance_dispatch_table, *pInstance, 135 pCreateInfo->enabledExtensionCount, pCreateInfo->ppEnabledExtensionNames); 136 137 init_image(my_data, pAllocator); 138 139 return result; 140 } 141 142 VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL vkDestroyInstance(VkInstance instance, const VkAllocationCallbacks *pAllocator) { 143 // Grab the key before the instance is destroyed. 144 dispatch_key key = get_dispatch_key(instance); 145 layer_data *my_data = get_my_data_ptr(key, layer_data_map); 146 VkLayerInstanceDispatchTable *pTable = my_data->instance_dispatch_table; 147 pTable->DestroyInstance(instance, pAllocator); 148 149 // Clean up logging callback, if any 150 while (my_data->logging_callback.size() > 0) { 151 VkDebugReportCallbackEXT callback = my_data->logging_callback.back(); 152 layer_destroy_msg_callback(my_data->report_data, callback, pAllocator); 153 my_data->logging_callback.pop_back(); 154 } 155 156 layer_debug_report_destroy_instance(my_data->report_data); 157 delete my_data->instance_dispatch_table; 158 layer_data_map.erase(key); 159 } 160 161 VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateDevice(VkPhysicalDevice physicalDevice, 162 const VkDeviceCreateInfo *pCreateInfo, 163 const VkAllocationCallbacks *pAllocator, VkDevice *pDevice) { 164 VkLayerDeviceCreateInfo *chain_info = get_chain_info(pCreateInfo, VK_LAYER_LINK_INFO); 165 166 assert(chain_info->u.pLayerInfo); 167 PFN_vkGetInstanceProcAddr fpGetInstanceProcAddr = chain_info->u.pLayerInfo->pfnNextGetInstanceProcAddr; 168 PFN_vkGetDeviceProcAddr fpGetDeviceProcAddr = chain_info->u.pLayerInfo->pfnNextGetDeviceProcAddr; 169 PFN_vkCreateDevice fpCreateDevice = (PFN_vkCreateDevice)fpGetInstanceProcAddr(NULL, "vkCreateDevice"); 170 if (fpCreateDevice == NULL) { 171 return VK_ERROR_INITIALIZATION_FAILED; 172 } 173 174 // Advance the link info for the next element on the chain 175 chain_info->u.pLayerInfo = chain_info->u.pLayerInfo->pNext; 176 177 VkResult result = fpCreateDevice(physicalDevice, pCreateInfo, pAllocator, pDevice); 178 if (result != VK_SUCCESS) { 179 return result; 180 } 181 182 layer_data *my_instance_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map); 183 layer_data *my_device_data = get_my_data_ptr(get_dispatch_key(*pDevice), layer_data_map); 184 185 // Setup device dispatch table 186 my_device_data->device_dispatch_table = new VkLayerDispatchTable; 187 layer_init_device_dispatch_table(*pDevice, my_device_data->device_dispatch_table, fpGetDeviceProcAddr); 188 189 my_device_data->report_data = layer_debug_report_create_device(my_instance_data->report_data, *pDevice); 190 my_device_data->physicalDevice = physicalDevice; 191 192 my_instance_data->instance_dispatch_table->GetPhysicalDeviceProperties(physicalDevice, 193 &(my_device_data->physicalDeviceProperties)); 194 195 return result; 196 } 197 198 VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL vkDestroyDevice(VkDevice device, const VkAllocationCallbacks *pAllocator) { 199 dispatch_key key = get_dispatch_key(device); 200 layer_data *my_data = get_my_data_ptr(key, layer_data_map); 201 my_data->device_dispatch_table->DestroyDevice(device, pAllocator); 202 delete my_data->device_dispatch_table; 203 layer_data_map.erase(key); 204 } 205 206 static const VkExtensionProperties instance_extensions[] = {{VK_EXT_DEBUG_REPORT_EXTENSION_NAME, VK_EXT_DEBUG_REPORT_SPEC_VERSION}}; 207 208 VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL 209 vkEnumerateInstanceExtensionProperties(const char *pLayerName, uint32_t *pCount, VkExtensionProperties *pProperties) { 210 return util_GetExtensionProperties(1, instance_extensions, pCount, pProperties); 211 } 212 213 static const VkLayerProperties pc_global_layers[] = {{ 214 "VK_LAYER_LUNARG_image", VK_LAYER_API_VERSION, 1, "LunarG Validation Layer", 215 }}; 216 217 VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL 218 vkEnumerateInstanceLayerProperties(uint32_t *pCount, VkLayerProperties *pProperties) { 219 return util_GetLayerProperties(ARRAY_SIZE(pc_global_layers), pc_global_layers, pCount, pProperties); 220 } 221 222 VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateDeviceExtensionProperties(VkPhysicalDevice physicalDevice, 223 const char *pLayerName, uint32_t *pCount, 224 VkExtensionProperties *pProperties) { 225 // Image does not have any physical device extensions 226 if (pLayerName == NULL) { 227 dispatch_key key = get_dispatch_key(physicalDevice); 228 layer_data *my_data = get_my_data_ptr(key, layer_data_map); 229 VkLayerInstanceDispatchTable *pTable = my_data->instance_dispatch_table; 230 return pTable->EnumerateDeviceExtensionProperties(physicalDevice, NULL, pCount, pProperties); 231 } else { 232 return util_GetExtensionProperties(0, NULL, pCount, pProperties); 233 } 234 } 235 236 VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL 237 vkEnumerateDeviceLayerProperties(VkPhysicalDevice physicalDevice, uint32_t *pCount, VkLayerProperties *pProperties) { 238 // ParamChecker's physical device layers are the same as global 239 return util_GetLayerProperties(ARRAY_SIZE(pc_global_layers), pc_global_layers, pCount, pProperties); 240 } 241 242 // Start of the Image layer proper 243 244 // Returns TRUE if a format is a depth-compatible format 245 bool is_depth_format(VkFormat format) { 246 bool result = VK_FALSE; 247 switch (format) { 248 case VK_FORMAT_D16_UNORM: 249 case VK_FORMAT_X8_D24_UNORM_PACK32: 250 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 263 static inline uint32_t validate_VkImageLayoutKHR(VkImageLayout input_value) { 264 return ((validate_VkImageLayout(input_value) == 1) || (input_value == VK_IMAGE_LAYOUT_PRESENT_SRC_KHR)); 265 } 266 267 VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL 268 vkCreateImage(VkDevice device, const VkImageCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkImage *pImage) { 269 VkBool32 skipCall = VK_FALSE; 270 VkResult result = VK_ERROR_VALIDATION_FAILED_EXT; 271 VkImageFormatProperties ImageFormatProperties; 272 273 layer_data *device_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map); 274 VkPhysicalDevice physicalDevice = device_data->physicalDevice; 275 layer_data *phy_dev_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map); 276 277 if (pCreateInfo->format != VK_FORMAT_UNDEFINED) { 278 VkFormatProperties properties; 279 phy_dev_data->instance_dispatch_table->GetPhysicalDeviceFormatProperties(device_data->physicalDevice, pCreateInfo->format, 280 &properties); 281 282 if ((properties.linearTilingFeatures) == 0 && (properties.optimalTilingFeatures == 0)) { 283 char const str[] = "vkCreateImage parameter, VkFormat pCreateInfo->format, contains unsupported format"; 284 // TODO: Verify against Valid Use section of spec. Generally if something yield an undefined result, it's invalid 285 skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__, 286 IMAGE_FORMAT_UNSUPPORTED, "IMAGE", str); 287 } 288 } 289 290 // Internal call to get format info. Still goes through layers, could potentially go directly to ICD. 291 phy_dev_data->instance_dispatch_table->GetPhysicalDeviceImageFormatProperties( 292 physicalDevice, pCreateInfo->format, pCreateInfo->imageType, pCreateInfo->tiling, pCreateInfo->usage, pCreateInfo->flags, 293 &ImageFormatProperties); 294 295 VkDeviceSize imageGranularity = device_data->physicalDeviceProperties.limits.bufferImageGranularity; 296 imageGranularity = imageGranularity == 1 ? 0 : imageGranularity; 297 298 if ((pCreateInfo->extent.depth > ImageFormatProperties.maxExtent.depth) || 299 (pCreateInfo->extent.width > ImageFormatProperties.maxExtent.width) || 300 (pCreateInfo->extent.height > ImageFormatProperties.maxExtent.height)) { 301 skipCall |= log_msg(phy_dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, 302 (uint64_t)pImage, __LINE__, IMAGE_INVALID_FORMAT_LIMITS_VIOLATION, "Image", 303 "CreateImage extents exceed allowable limits for format: " 304 "Width = %d Height = %d Depth = %d: Limits for Width = %d Height = %d Depth = %d for format %s.", 305 pCreateInfo->extent.width, pCreateInfo->extent.height, pCreateInfo->extent.depth, 306 ImageFormatProperties.maxExtent.width, ImageFormatProperties.maxExtent.height, 307 ImageFormatProperties.maxExtent.depth, string_VkFormat(pCreateInfo->format)); 308 } 309 310 uint64_t totalSize = ((uint64_t)pCreateInfo->extent.width * (uint64_t)pCreateInfo->extent.height * 311 (uint64_t)pCreateInfo->extent.depth * (uint64_t)pCreateInfo->arrayLayers * 312 (uint64_t)pCreateInfo->samples * (uint64_t)vk_format_get_size(pCreateInfo->format) + 313 (uint64_t)imageGranularity) & 314 ~(uint64_t)imageGranularity; 315 316 if (totalSize > ImageFormatProperties.maxResourceSize) { 317 skipCall |= log_msg(phy_dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, 318 (uint64_t)pImage, __LINE__, IMAGE_INVALID_FORMAT_LIMITS_VIOLATION, "Image", 319 "CreateImage resource size exceeds allowable maximum " 320 "Image resource size = %#" PRIxLEAST64 ", maximum resource size = %#" PRIxLEAST64 " ", 321 totalSize, ImageFormatProperties.maxResourceSize); 322 } 323 324 if (pCreateInfo->mipLevels > ImageFormatProperties.maxMipLevels) { 325 skipCall |= log_msg(phy_dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, 326 (uint64_t)pImage, __LINE__, IMAGE_INVALID_FORMAT_LIMITS_VIOLATION, "Image", 327 "CreateImage mipLevels=%d exceeds allowable maximum supported by format of %d", pCreateInfo->mipLevels, 328 ImageFormatProperties.maxMipLevels); 329 } 330 331 if (pCreateInfo->arrayLayers > ImageFormatProperties.maxArrayLayers) { 332 skipCall |= log_msg(phy_dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, 333 (uint64_t)pImage, __LINE__, IMAGE_INVALID_FORMAT_LIMITS_VIOLATION, "Image", 334 "CreateImage arrayLayers=%d exceeds allowable maximum supported by format of %d", 335 pCreateInfo->arrayLayers, ImageFormatProperties.maxArrayLayers); 336 } 337 338 if ((pCreateInfo->samples & ImageFormatProperties.sampleCounts) == 0) { 339 skipCall |= log_msg(phy_dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, 340 (uint64_t)pImage, __LINE__, IMAGE_INVALID_FORMAT_LIMITS_VIOLATION, "Image", 341 "CreateImage samples %s is not supported by format 0x%.8X", 342 string_VkSampleCountFlagBits(pCreateInfo->samples), ImageFormatProperties.sampleCounts); 343 } 344 345 if (pCreateInfo->initialLayout != VK_IMAGE_LAYOUT_UNDEFINED && pCreateInfo->initialLayout != VK_IMAGE_LAYOUT_PREINITIALIZED) { 346 skipCall |= log_msg(phy_dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, 347 (uint64_t)pImage, __LINE__, IMAGE_INVALID_LAYOUT, "Image", 348 "vkCreateImage parameter, pCreateInfo->initialLayout, must be VK_IMAGE_LAYOUT_UNDEFINED or " 349 "VK_IMAGE_LAYOUT_PREINITIALIZED"); 350 } 351 352 if (VK_FALSE == skipCall) { 353 result = device_data->device_dispatch_table->CreateImage(device, pCreateInfo, pAllocator, pImage); 354 } 355 if (result == VK_SUCCESS) { 356 loader_platform_thread_lock_mutex(&globalLock); 357 device_data->imageMap[*pImage] = IMAGE_STATE(pCreateInfo); 358 loader_platform_thread_unlock_mutex(&globalLock); 359 } 360 return result; 361 } 362 363 VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL vkDestroyImage(VkDevice device, VkImage image, const VkAllocationCallbacks *pAllocator) { 364 layer_data *device_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map); 365 loader_platform_thread_lock_mutex(&globalLock); 366 device_data->imageMap.erase(image); 367 loader_platform_thread_unlock_mutex(&globalLock); 368 device_data->device_dispatch_table->DestroyImage(device, image, pAllocator); 369 } 370 371 VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateRenderPass(VkDevice device, const VkRenderPassCreateInfo *pCreateInfo, 372 const VkAllocationCallbacks *pAllocator, 373 VkRenderPass *pRenderPass) { 374 layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map); 375 VkBool32 skipCall = VK_FALSE; 376 for (uint32_t i = 0; i < pCreateInfo->attachmentCount; ++i) { 377 if (pCreateInfo->pAttachments[i].format != VK_FORMAT_UNDEFINED) { 378 VkFormatProperties properties; 379 get_my_data_ptr(get_dispatch_key(my_data->physicalDevice), layer_data_map) 380 ->instance_dispatch_table->GetPhysicalDeviceFormatProperties(my_data->physicalDevice, 381 pCreateInfo->pAttachments[i].format, &properties); 382 383 if ((properties.linearTilingFeatures) == 0 && (properties.optimalTilingFeatures == 0)) { 384 std::stringstream ss; 385 ss << "vkCreateRenderPass parameter, VkFormat in pCreateInfo->pAttachments[" << i 386 << "], contains unsupported format"; 387 // TODO: Verify against Valid Use section of spec. Generally if something yield an undefined result, it's invalid 388 skipCall |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__, 389 IMAGE_FORMAT_UNSUPPORTED, "IMAGE", "%s", ss.str().c_str()); 390 } 391 } 392 } 393 394 for (uint32_t i = 0; i < pCreateInfo->attachmentCount; ++i) { 395 if (!validate_VkImageLayoutKHR(pCreateInfo->pAttachments[i].initialLayout) || 396 !validate_VkImageLayoutKHR(pCreateInfo->pAttachments[i].finalLayout)) { 397 std::stringstream ss; 398 ss << "vkCreateRenderPass parameter, VkImageLayout in pCreateInfo->pAttachments[" << i << "], is unrecognized"; 399 // TODO: Verify against Valid Use section of spec. Generally if something yield an undefined result, it's invalid 400 skipCall |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__, 401 IMAGE_RENDERPASS_INVALID_ATTACHMENT, "IMAGE", "%s", ss.str().c_str()); 402 } 403 } 404 405 for (uint32_t i = 0; i < pCreateInfo->attachmentCount; ++i) { 406 if (!validate_VkAttachmentLoadOp(pCreateInfo->pAttachments[i].loadOp)) { 407 std::stringstream ss; 408 ss << "vkCreateRenderPass parameter, VkAttachmentLoadOp in pCreateInfo->pAttachments[" << i << "], is unrecognized"; 409 // TODO: Verify against Valid Use section of spec. Generally if something yield an undefined result, it's invalid 410 skipCall |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__, 411 IMAGE_RENDERPASS_INVALID_ATTACHMENT, "IMAGE", "%s", ss.str().c_str()); 412 } 413 } 414 415 for (uint32_t i = 0; i < pCreateInfo->attachmentCount; ++i) { 416 if (!validate_VkAttachmentStoreOp(pCreateInfo->pAttachments[i].storeOp)) { 417 std::stringstream ss; 418 ss << "vkCreateRenderPass parameter, VkAttachmentStoreOp in pCreateInfo->pAttachments[" << i << "], is unrecognized"; 419 // TODO: Verify against Valid Use section of spec. Generally if something yield an undefined result, it's invalid 420 skipCall |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__, 421 IMAGE_RENDERPASS_INVALID_ATTACHMENT, "IMAGE", "%s", ss.str().c_str()); 422 } 423 } 424 425 // Any depth buffers specified as attachments? 426 bool depthFormatPresent = VK_FALSE; 427 for (uint32_t i = 0; i < pCreateInfo->attachmentCount; ++i) { 428 depthFormatPresent |= is_depth_format(pCreateInfo->pAttachments[i].format); 429 } 430 431 if (depthFormatPresent == VK_FALSE) { 432 // No depth attachment is present, validate that subpasses set depthStencilAttachment to VK_ATTACHMENT_UNUSED; 433 for (uint32_t i = 0; i < pCreateInfo->subpassCount; i++) { 434 if (pCreateInfo->pSubpasses[i].pDepthStencilAttachment && 435 pCreateInfo->pSubpasses[i].pDepthStencilAttachment->attachment != VK_ATTACHMENT_UNUSED) { 436 std::stringstream ss; 437 ss << "vkCreateRenderPass has no depth/stencil attachment, yet subpass[" << i 438 << "] has VkSubpassDescription::depthStencilAttachment value that is not VK_ATTACHMENT_UNUSED"; 439 skipCall |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__, 440 IMAGE_RENDERPASS_INVALID_DS_ATTACHMENT, "IMAGE", "%s", ss.str().c_str()); 441 } 442 } 443 } 444 if (skipCall) 445 return VK_ERROR_VALIDATION_FAILED_EXT; 446 447 VkResult result = my_data->device_dispatch_table->CreateRenderPass(device, pCreateInfo, pAllocator, pRenderPass); 448 449 return result; 450 } 451 452 VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateImageView(VkDevice device, const VkImageViewCreateInfo *pCreateInfo, 453 const VkAllocationCallbacks *pAllocator, VkImageView *pView) { 454 VkBool32 skipCall = VK_FALSE; 455 layer_data *device_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map); 456 auto imageEntry = device_data->imageMap.find(pCreateInfo->image); 457 if (imageEntry != device_data->imageMap.end()) { 458 if (pCreateInfo->subresourceRange.baseMipLevel >= imageEntry->second.mipLevels) { 459 std::stringstream ss; 460 ss << "vkCreateImageView called with baseMipLevel " << pCreateInfo->subresourceRange.baseMipLevel << " for image " 461 << pCreateInfo->image << " that only has " << imageEntry->second.mipLevels << " mip levels."; 462 skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__, 463 IMAGE_VIEW_CREATE_ERROR, "IMAGE", "%s", ss.str().c_str()); 464 } 465 if (pCreateInfo->subresourceRange.baseArrayLayer >= imageEntry->second.arraySize) { 466 std::stringstream ss; 467 ss << "vkCreateImageView called with baseArrayLayer " << pCreateInfo->subresourceRange.baseArrayLayer << " for image " 468 << pCreateInfo->image << " that only has " << imageEntry->second.arraySize << " array layers."; 469 skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__, 470 IMAGE_VIEW_CREATE_ERROR, "IMAGE", "%s", ss.str().c_str()); 471 } 472 if (!pCreateInfo->subresourceRange.levelCount) { 473 std::stringstream ss; 474 ss << "vkCreateImageView called with 0 in pCreateInfo->subresourceRange.levelCount."; 475 skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__, 476 IMAGE_VIEW_CREATE_ERROR, "IMAGE", "%s", ss.str().c_str()); 477 } 478 if (!pCreateInfo->subresourceRange.layerCount) { 479 std::stringstream ss; 480 ss << "vkCreateImageView called with 0 in pCreateInfo->subresourceRange.layerCount."; 481 skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__, 482 IMAGE_VIEW_CREATE_ERROR, "IMAGE", "%s", ss.str().c_str()); 483 } 484 485 VkImageCreateFlags imageFlags = imageEntry->second.flags; 486 VkFormat imageFormat = imageEntry->second.format; 487 VkFormat ivciFormat = pCreateInfo->format; 488 VkImageAspectFlags aspectMask = pCreateInfo->subresourceRange.aspectMask; 489 490 // Validate VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT state 491 if (imageFlags & VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT) { 492 // Format MUST be compatible (in the same format compatibility class) as the format the image was created with 493 if (vk_format_get_compatibility_class(imageFormat) != vk_format_get_compatibility_class(ivciFormat)) { 494 std::stringstream ss; 495 ss << "vkCreateImageView(): ImageView format " << string_VkFormat(ivciFormat) 496 << " is not in the same format compatibility class as image (" << (uint64_t)pCreateInfo->image << ") format " 497 << string_VkFormat(imageFormat) << ". Images created with the VK_IMAGE_CREATE_MUTABLE_FORMAT BIT " 498 << "can support ImageViews with differing formats but they must be in the same compatibility class."; 499 skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, 500 __LINE__, IMAGE_VIEW_CREATE_ERROR, "IMAGE", "%s", ss.str().c_str()); 501 } 502 } else { 503 // Format MUST be IDENTICAL to the format the image was created with 504 if (imageFormat != ivciFormat) { 505 std::stringstream ss; 506 ss << "vkCreateImageView() format " << string_VkFormat(ivciFormat) << " differs from image " 507 << (uint64_t)pCreateInfo->image << " format " << string_VkFormat(imageFormat) 508 << ". Formats MUST be IDENTICAL unless VK_IMAGE_CREATE_MUTABLE_FORMAT BIT was set on image creation."; 509 skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, 510 __LINE__, IMAGE_VIEW_CREATE_ERROR, "IMAGE", "%s", ss.str().c_str()); 511 } 512 } 513 514 // Validate correct image aspect bits for desired formats and format consistency 515 if (vk_format_is_color(imageFormat)) { 516 if ((aspectMask & VK_IMAGE_ASPECT_COLOR_BIT) != VK_IMAGE_ASPECT_COLOR_BIT) { 517 std::stringstream ss; 518 ss << "vkCreateImageView: Color image formats must have the VK_IMAGE_ASPECT_COLOR_BIT set"; 519 skipCall |= 520 log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, 521 (uint64_t)pCreateInfo->image, __LINE__, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", "%s", ss.str().c_str()); 522 } 523 if ((aspectMask & VK_IMAGE_ASPECT_COLOR_BIT) != aspectMask) { 524 std::stringstream ss; 525 ss << "vkCreateImageView: Color image formats must have ONLY the VK_IMAGE_ASPECT_COLOR_BIT set"; 526 skipCall |= 527 log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, 528 (uint64_t)pCreateInfo->image, __LINE__, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", "%s", ss.str().c_str()); 529 } 530 if (VK_FALSE == vk_format_is_color(ivciFormat)) { 531 std::stringstream ss; 532 ss << "vkCreateImageView: The image view's format can differ from the parent image's format, but both must be " 533 << "color formats. ImageFormat is " << string_VkFormat(imageFormat) << " ImageViewFormat is " 534 << string_VkFormat(ivciFormat); 535 skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, 536 (uint64_t)pCreateInfo->image, __LINE__, IMAGE_INVALID_FORMAT, "IMAGE", "%s", ss.str().c_str()); 537 } 538 // TODO: Uncompressed formats are compatible if they occupy they same number of bits per pixel. 539 // Compressed formats are compatible if the only difference between them is the numerical type of 540 // the uncompressed pixels (e.g. signed vs. unsigned, or sRGB vs. UNORM encoding). 541 } else if (vk_format_is_depth_and_stencil(imageFormat)) { 542 if ((aspectMask & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) == 0) { 543 std::stringstream ss; 544 ss << "vkCreateImageView: Depth/stencil image formats must have at least one of VK_IMAGE_ASPECT_DEPTH_BIT and " 545 "VK_IMAGE_ASPECT_STENCIL_BIT set"; 546 skipCall |= 547 log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, 548 (uint64_t)pCreateInfo->image, __LINE__, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", "%s", ss.str().c_str()); 549 } 550 if ((aspectMask & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) != aspectMask) { 551 std::stringstream ss; 552 ss << "vkCreateImageView: Combination depth/stencil image formats can have only the VK_IMAGE_ASPECT_DEPTH_BIT and " 553 "VK_IMAGE_ASPECT_STENCIL_BIT set"; 554 skipCall |= 555 log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, 556 (uint64_t)pCreateInfo->image, __LINE__, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", "%s", ss.str().c_str()); 557 } 558 } else if (vk_format_is_depth_only(imageFormat)) { 559 if ((aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT) != VK_IMAGE_ASPECT_DEPTH_BIT) { 560 std::stringstream ss; 561 ss << "vkCreateImageView: Depth-only image formats must have the VK_IMAGE_ASPECT_DEPTH_BIT set"; 562 skipCall |= 563 log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, 564 (uint64_t)pCreateInfo->image, __LINE__, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", "%s", ss.str().c_str()); 565 } 566 if ((aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT) != aspectMask) { 567 std::stringstream ss; 568 ss << "vkCreateImageView: Depth-only image formats can have only the VK_IMAGE_ASPECT_DEPTH_BIT set"; 569 skipCall |= 570 log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, 571 (uint64_t)pCreateInfo->image, __LINE__, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", "%s", ss.str().c_str()); 572 } 573 } else if (vk_format_is_stencil_only(imageFormat)) { 574 if ((aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT) != VK_IMAGE_ASPECT_STENCIL_BIT) { 575 std::stringstream ss; 576 ss << "vkCreateImageView: Stencil-only image formats must have the VK_IMAGE_ASPECT_STENCIL_BIT set"; 577 skipCall |= 578 log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, 579 (uint64_t)pCreateInfo->image, __LINE__, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", "%s", ss.str().c_str()); 580 } 581 if ((aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT) != aspectMask) { 582 std::stringstream ss; 583 ss << "vkCreateImageView: Stencil-only image formats can have only the VK_IMAGE_ASPECT_STENCIL_BIT set"; 584 skipCall |= 585 log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, 586 (uint64_t)pCreateInfo->image, __LINE__, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", "%s", ss.str().c_str()); 587 } 588 } 589 } 590 591 if (skipCall) { 592 return VK_ERROR_VALIDATION_FAILED_EXT; 593 } 594 595 VkResult result = device_data->device_dispatch_table->CreateImageView(device, pCreateInfo, pAllocator, pView); 596 return result; 597 } 598 599 VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdClearColorImage(VkCommandBuffer commandBuffer, VkImage image, 600 VkImageLayout imageLayout, const VkClearColorValue *pColor, 601 uint32_t rangeCount, const VkImageSubresourceRange *pRanges) { 602 VkBool32 skipCall = VK_FALSE; 603 layer_data *device_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map); 604 605 if (imageLayout != VK_IMAGE_LAYOUT_GENERAL && imageLayout != VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL) { 606 skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 607 (uint64_t)commandBuffer, __LINE__, IMAGE_INVALID_LAYOUT, "IMAGE", 608 "vkCmdClearColorImage parameter, imageLayout, must be VK_IMAGE_LAYOUT_GENERAL or " 609 "VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL"); 610 } 611 612 // For each range, image aspect must be color only 613 for (uint32_t i = 0; i < rangeCount; i++) { 614 if (pRanges[i].aspectMask != VK_IMAGE_ASPECT_COLOR_BIT) { 615 char const str[] = 616 "vkCmdClearColorImage aspectMasks for all subresource ranges must be set to VK_IMAGE_ASPECT_COLOR_BIT"; 617 skipCall |= 618 log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 619 (uint64_t)commandBuffer, __LINE__, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", str); 620 } 621 } 622 623 if (VK_FALSE == skipCall) { 624 device_data->device_dispatch_table->CmdClearColorImage(commandBuffer, image, imageLayout, pColor, rangeCount, pRanges); 625 } 626 } 627 628 VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL 629 vkCmdClearDepthStencilImage(VkCommandBuffer commandBuffer, VkImage image, VkImageLayout imageLayout, 630 const VkClearDepthStencilValue *pDepthStencil, uint32_t rangeCount, 631 const VkImageSubresourceRange *pRanges) { 632 VkBool32 skipCall = VK_FALSE; 633 layer_data *device_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map); 634 // For each range, Image aspect must be depth or stencil or both 635 for (uint32_t i = 0; i < rangeCount; i++) { 636 if (((pRanges[i].aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT) != VK_IMAGE_ASPECT_DEPTH_BIT) && 637 ((pRanges[i].aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT) != VK_IMAGE_ASPECT_STENCIL_BIT)) { 638 char const str[] = "vkCmdClearDepthStencilImage aspectMasks for all subresource ranges must be " 639 "set to VK_IMAGE_ASPECT_DEPTH_BIT and/or VK_IMAGE_ASPECT_STENCIL_BIT"; 640 skipCall |= 641 log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 642 (uint64_t)commandBuffer, __LINE__, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", str); 643 } 644 } 645 646 if (VK_FALSE == skipCall) { 647 device_data->device_dispatch_table->CmdClearDepthStencilImage(commandBuffer, image, imageLayout, pDepthStencil, rangeCount, 648 pRanges); 649 } 650 } 651 652 VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL 653 vkCmdCopyImage(VkCommandBuffer commandBuffer, VkImage srcImage, VkImageLayout srcImageLayout, VkImage dstImage, 654 VkImageLayout dstImageLayout, uint32_t regionCount, const VkImageCopy *pRegions) { 655 VkBool32 skipCall = VK_FALSE; 656 layer_data *device_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map); 657 auto srcImageEntry = device_data->imageMap.find(srcImage); 658 auto dstImageEntry = device_data->imageMap.find(dstImage); 659 660 // For each region, src and dst number of layers should not be zero 661 // For each region, src and dst number of layers must match 662 // For each region, src aspect mask must match dest aspect mask 663 // For each region, color aspects cannot be mixed with depth/stencil aspects 664 for (uint32_t i = 0; i < regionCount; i++) { 665 if (pRegions[i].srcSubresource.layerCount == 0) { 666 char const str[] = "vkCmdCopyImage: number of layers in source subresource is zero"; 667 // TODO: Verify against Valid Use section of spec 668 skipCall |= 669 log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 670 (uint64_t)commandBuffer, __LINE__, IMAGE_MISMATCHED_IMAGE_ASPECT, "IMAGE", str); 671 } 672 673 if (pRegions[i].dstSubresource.layerCount == 0) { 674 char const str[] = "vkCmdCopyImage: number of layers in destination subresource is zero"; 675 // TODO: Verify against Valid Use section of spec 676 skipCall |= 677 log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 678 (uint64_t)commandBuffer, __LINE__, IMAGE_MISMATCHED_IMAGE_ASPECT, "IMAGE", str); 679 } 680 681 if (pRegions[i].srcSubresource.layerCount != pRegions[i].dstSubresource.layerCount) { 682 char const str[] = "vkCmdCopyImage: number of layers in source and destination subresources must match"; 683 skipCall |= 684 log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 685 (uint64_t)commandBuffer, __LINE__, IMAGE_MISMATCHED_IMAGE_ASPECT, "IMAGE", str); 686 } 687 688 if (pRegions[i].srcSubresource.aspectMask != pRegions[i].dstSubresource.aspectMask) { 689 char const str[] = "vkCmdCopyImage: Src and dest aspectMasks for each region must match"; 690 skipCall |= 691 log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 692 (uint64_t)commandBuffer, __LINE__, IMAGE_MISMATCHED_IMAGE_ASPECT, "IMAGE", str); 693 } 694 if ((pRegions[i].srcSubresource.aspectMask & VK_IMAGE_ASPECT_COLOR_BIT) && 695 (pRegions[i].srcSubresource.aspectMask & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT))) { 696 char const str[] = "vkCmdCopyImage aspectMask cannot specify both COLOR and DEPTH/STENCIL aspects"; 697 skipCall |= 698 log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 699 (uint64_t)commandBuffer, __LINE__, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", str); 700 } 701 } 702 703 if ((srcImageEntry != device_data->imageMap.end()) && (dstImageEntry != device_data->imageMap.end())) { 704 if (srcImageEntry->second.imageType != dstImageEntry->second.imageType) { 705 char const str[] = "vkCmdCopyImage called with unmatched source and dest image types."; 706 skipCall |= 707 log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 708 (uint64_t)commandBuffer, __LINE__, IMAGE_MISMATCHED_IMAGE_TYPE, "IMAGE", str); 709 } 710 // Check that format is same size or exact stencil/depth 711 if (is_depth_format(srcImageEntry->second.format)) { 712 if (srcImageEntry->second.format != dstImageEntry->second.format) { 713 char const str[] = "vkCmdCopyImage called with unmatched source and dest image depth/stencil formats."; 714 skipCall |= 715 log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 716 (uint64_t)commandBuffer, __LINE__, IMAGE_MISMATCHED_IMAGE_FORMAT, "IMAGE", str); 717 } 718 } else { 719 size_t srcSize = vk_format_get_size(srcImageEntry->second.format); 720 size_t destSize = vk_format_get_size(dstImageEntry->second.format); 721 if (srcSize != destSize) { 722 char const str[] = "vkCmdCopyImage called with unmatched source and dest image format sizes."; 723 skipCall |= 724 log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 725 (uint64_t)commandBuffer, __LINE__, IMAGE_MISMATCHED_IMAGE_FORMAT, "IMAGE", str); 726 } 727 } 728 } 729 730 if (VK_FALSE == skipCall) { 731 device_data->device_dispatch_table->CmdCopyImage(commandBuffer, srcImage, srcImageLayout, dstImage, dstImageLayout, 732 regionCount, pRegions); 733 } 734 } 735 736 VKAPI_ATTR void VKAPI_CALL vkCmdClearAttachments(VkCommandBuffer commandBuffer, uint32_t attachmentCount, 737 const VkClearAttachment *pAttachments, uint32_t rectCount, 738 const VkClearRect *pRects) { 739 VkBool32 skipCall = VK_FALSE; 740 VkImageAspectFlags aspectMask; 741 layer_data *device_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map); 742 for (uint32_t i = 0; i < attachmentCount; i++) { 743 aspectMask = pAttachments[i].aspectMask; 744 if (aspectMask & VK_IMAGE_ASPECT_COLOR_BIT) { 745 if (aspectMask != VK_IMAGE_ASPECT_COLOR_BIT) { 746 // VK_IMAGE_ASPECT_COLOR_BIT is not the only bit set for this attachment 747 char const str[] = 748 "vkCmdClearAttachments aspectMask [%d] must set only VK_IMAGE_ASPECT_COLOR_BIT of a color attachment."; 749 skipCall |= 750 log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 751 (uint64_t)commandBuffer, __LINE__, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", str, i); 752 } 753 } else { 754 // Image aspect must be depth or stencil or both 755 if (((aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT) != VK_IMAGE_ASPECT_DEPTH_BIT) && 756 ((aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT) != VK_IMAGE_ASPECT_STENCIL_BIT)) { 757 char const str[] = "vkCmdClearAttachments aspectMask [%d] must be set to VK_IMAGE_ASPECT_DEPTH_BIT and/or " 758 "VK_IMAGE_ASPECT_STENCIL_BIT"; 759 skipCall |= 760 log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 761 (uint64_t)commandBuffer, __LINE__, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", str, i); 762 } 763 } 764 } 765 766 if (VK_FALSE == skipCall) { 767 device_data->device_dispatch_table->CmdClearAttachments(commandBuffer, attachmentCount, pAttachments, rectCount, pRects); 768 } 769 } 770 771 VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdCopyImageToBuffer(VkCommandBuffer commandBuffer, VkImage srcImage, 772 VkImageLayout srcImageLayout, VkBuffer dstBuffer, 773 uint32_t regionCount, const VkBufferImageCopy *pRegions) { 774 VkBool32 skipCall = VK_FALSE; 775 layer_data *device_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map); 776 // For each region, the number of layers in the image subresource should not be zero 777 // Image aspect must be ONE OF color, depth, stencil 778 for (uint32_t i = 0; i < regionCount; i++) { 779 if (pRegions[i].imageSubresource.layerCount == 0) { 780 char const str[] = "vkCmdCopyImageToBuffer: number of layers in image subresource is zero"; 781 // TODO: Verify against Valid Use section of spec, if this case yields undefined results, then it's an error 782 skipCall |= 783 log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 784 (uint64_t)commandBuffer, __LINE__, IMAGE_MISMATCHED_IMAGE_ASPECT, "IMAGE", str); 785 } 786 787 VkImageAspectFlags aspectMask = pRegions[i].imageSubresource.aspectMask; 788 if ((aspectMask != VK_IMAGE_ASPECT_COLOR_BIT) && (aspectMask != VK_IMAGE_ASPECT_DEPTH_BIT) && 789 (aspectMask != VK_IMAGE_ASPECT_STENCIL_BIT)) { 790 char const str[] = "vkCmdCopyImageToBuffer: aspectMasks for each region must specify only COLOR or DEPTH or STENCIL"; 791 skipCall |= 792 log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 793 (uint64_t)commandBuffer, __LINE__, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", str); 794 } 795 } 796 797 if (VK_FALSE == skipCall) { 798 device_data->device_dispatch_table->CmdCopyImageToBuffer(commandBuffer, srcImage, srcImageLayout, dstBuffer, regionCount, 799 pRegions); 800 } 801 } 802 803 VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdCopyBufferToImage(VkCommandBuffer commandBuffer, VkBuffer srcBuffer, 804 VkImage dstImage, VkImageLayout dstImageLayout, 805 uint32_t regionCount, const VkBufferImageCopy *pRegions) { 806 VkBool32 skipCall = VK_FALSE; 807 layer_data *device_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map); 808 // For each region, the number of layers in the image subresource should not be zero 809 // Image aspect must be ONE OF color, depth, stencil 810 for (uint32_t i = 0; i < regionCount; i++) { 811 if (pRegions[i].imageSubresource.layerCount == 0) { 812 char const str[] = "vkCmdCopyBufferToImage: number of layers in image subresource is zero"; 813 // TODO: Verify against Valid Use section of spec, if this case yields undefined results, then it's an error 814 skipCall |= 815 log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 816 (uint64_t)commandBuffer, __LINE__, IMAGE_MISMATCHED_IMAGE_ASPECT, "IMAGE", str); 817 } 818 819 VkImageAspectFlags aspectMask = pRegions[i].imageSubresource.aspectMask; 820 if ((aspectMask != VK_IMAGE_ASPECT_COLOR_BIT) && (aspectMask != VK_IMAGE_ASPECT_DEPTH_BIT) && 821 (aspectMask != VK_IMAGE_ASPECT_STENCIL_BIT)) { 822 char const str[] = "vkCmdCopyBufferToImage: aspectMasks for each region must specify only COLOR or DEPTH or STENCIL"; 823 skipCall |= 824 log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 825 (uint64_t)commandBuffer, __LINE__, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", str); 826 } 827 } 828 829 if (VK_FALSE == skipCall) { 830 device_data->device_dispatch_table->CmdCopyBufferToImage(commandBuffer, srcBuffer, dstImage, dstImageLayout, regionCount, 831 pRegions); 832 } 833 } 834 835 VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL 836 vkCmdBlitImage(VkCommandBuffer commandBuffer, VkImage srcImage, VkImageLayout srcImageLayout, VkImage dstImage, 837 VkImageLayout dstImageLayout, uint32_t regionCount, const VkImageBlit *pRegions, VkFilter filter) { 838 VkBool32 skipCall = VK_FALSE; 839 layer_data *device_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map); 840 841 auto srcImageEntry = device_data->imageMap.find(srcImage); 842 auto dstImageEntry = device_data->imageMap.find(dstImage); 843 844 if ((srcImageEntry != device_data->imageMap.end()) && (dstImageEntry != device_data->imageMap.end())) { 845 846 VkFormat srcFormat = srcImageEntry->second.format; 847 VkFormat dstFormat = dstImageEntry->second.format; 848 849 // Validate consistency for signed and unsigned formats 850 if ((vk_format_is_sint(srcFormat) && !vk_format_is_sint(dstFormat)) || 851 (vk_format_is_uint(srcFormat) && !vk_format_is_uint(dstFormat))) { 852 std::stringstream ss; 853 ss << "vkCmdBlitImage: If one of srcImage and dstImage images has signed/unsigned integer format, " 854 << "the other one must also have signed/unsigned integer format. " 855 << "Source format is " << string_VkFormat(srcFormat) << " Destination format is " << string_VkFormat(dstFormat); 856 skipCall |= 857 log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 858 (uint64_t)commandBuffer, __LINE__, IMAGE_INVALID_FORMAT, "IMAGE", "%s", ss.str().c_str()); 859 } 860 861 // Validate aspect bits and formats for depth/stencil images 862 if (vk_format_is_depth_or_stencil(srcFormat) || vk_format_is_depth_or_stencil(dstFormat)) { 863 if (srcFormat != dstFormat) { 864 std::stringstream ss; 865 ss << "vkCmdBlitImage: If one of srcImage and dstImage images has a format of depth, stencil or depth " 866 << "stencil, the other one must have exactly the same format. " 867 << "Source format is " << string_VkFormat(srcFormat) << " Destination format is " << string_VkFormat(dstFormat); 868 skipCall |= 869 log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 870 (uint64_t)commandBuffer, __LINE__, IMAGE_INVALID_FORMAT, "IMAGE", "%s", ss.str().c_str()); 871 } 872 873 for (uint32_t i = 0; i < regionCount; i++) { 874 if (pRegions[i].srcSubresource.layerCount == 0) { 875 char const str[] = "vkCmdBlitImage: number of layers in source subresource is zero"; 876 // TODO: Verify against Valid Use section of spec, if this case yields undefined results, then it's an error 877 skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, 878 VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, (uint64_t)commandBuffer, __LINE__, 879 IMAGE_MISMATCHED_IMAGE_ASPECT, "IMAGE", str); 880 } 881 882 if (pRegions[i].dstSubresource.layerCount == 0) { 883 char const str[] = "vkCmdBlitImage: number of layers in destination subresource is zero"; 884 // TODO: Verify against Valid Use section of spec, if this case yields undefined results, then it's an error 885 skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, 886 VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, (uint64_t)commandBuffer, __LINE__, 887 IMAGE_MISMATCHED_IMAGE_ASPECT, "IMAGE", str); 888 } 889 890 if (pRegions[i].srcSubresource.layerCount != pRegions[i].dstSubresource.layerCount) { 891 char const str[] = "vkCmdBlitImage: number of layers in source and destination subresources must match"; 892 skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, 893 VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, (uint64_t)commandBuffer, __LINE__, 894 IMAGE_MISMATCHED_IMAGE_ASPECT, "IMAGE", str); 895 } 896 897 VkImageAspectFlags srcAspect = pRegions[i].srcSubresource.aspectMask; 898 VkImageAspectFlags dstAspect = pRegions[i].dstSubresource.aspectMask; 899 900 if (srcAspect != dstAspect) { 901 std::stringstream ss; 902 ss << "vkCmdBlitImage: Image aspects of depth/stencil images should match"; 903 // TODO: Verify against Valid Use section of spec, if this case yields undefined results, then it's an error 904 skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, 905 VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, (uint64_t)commandBuffer, __LINE__, 906 IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", "%s", ss.str().c_str()); 907 } 908 if (vk_format_is_depth_and_stencil(srcFormat)) { 909 if ((srcAspect != VK_IMAGE_ASPECT_DEPTH_BIT) && (srcAspect != VK_IMAGE_ASPECT_STENCIL_BIT)) { 910 std::stringstream ss; 911 ss << "vkCmdBlitImage: Combination depth/stencil image formats must have only one of " 912 "VK_IMAGE_ASPECT_DEPTH_BIT " 913 << "and VK_IMAGE_ASPECT_STENCIL_BIT set in srcImage and dstImage"; 914 skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, 915 VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, (uint64_t)commandBuffer, __LINE__, 916 IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", "%s", ss.str().c_str()); 917 } 918 } else if (vk_format_is_stencil_only(srcFormat)) { 919 if (srcAspect != VK_IMAGE_ASPECT_STENCIL_BIT) { 920 std::stringstream ss; 921 ss << "vkCmdBlitImage: Stencil-only image formats must have only the VK_IMAGE_ASPECT_STENCIL_BIT " 922 << "set in both the srcImage and dstImage"; 923 skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, 924 VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, (uint64_t)commandBuffer, __LINE__, 925 IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", "%s", ss.str().c_str()); 926 } 927 } else if (vk_format_is_depth_only(srcFormat)) { 928 if (srcAspect != VK_IMAGE_ASPECT_DEPTH_BIT) { 929 std::stringstream ss; 930 ss << "vkCmdBlitImage: Depth-only image formats must have only the VK_IMAGE_ASPECT_DEPTH " 931 << "set in both the srcImage and dstImage"; 932 skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, 933 VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, (uint64_t)commandBuffer, __LINE__, 934 IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", "%s", ss.str().c_str()); 935 } 936 } 937 } 938 } 939 940 // Validate filter 941 if (vk_format_is_depth_or_stencil(srcFormat) || vk_format_is_int(srcFormat)) { 942 if (filter != VK_FILTER_NEAREST) { 943 std::stringstream ss; 944 ss << "vkCmdBlitImage: If the format of srcImage is a depth, stencil, depth stencil or integer-based format " 945 << "then filter must be VK_FILTER_NEAREST."; 946 skipCall |= 947 log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 948 (uint64_t)commandBuffer, __LINE__, IMAGE_INVALID_FILTER, "IMAGE", "%s", ss.str().c_str()); 949 } 950 } 951 } 952 953 device_data->device_dispatch_table->CmdBlitImage(commandBuffer, srcImage, srcImageLayout, dstImage, dstImageLayout, regionCount, 954 pRegions, filter); 955 } 956 957 VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL 958 vkCmdPipelineBarrier(VkCommandBuffer commandBuffer, VkPipelineStageFlags srcStageMask, VkPipelineStageFlags dstStageMask, 959 VkDependencyFlags dependencyFlags, uint32_t memoryBarrierCount, const VkMemoryBarrier *pMemoryBarriers, 960 uint32_t bufferMemoryBarrierCount, const VkBufferMemoryBarrier *pBufferMemoryBarriers, 961 uint32_t imageMemoryBarrierCount, const VkImageMemoryBarrier *pImageMemoryBarriers) { 962 VkBool32 skipCall = VK_FALSE; 963 layer_data *device_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map); 964 965 for (uint32_t i = 0; i < imageMemoryBarrierCount; ++i) { 966 VkImageMemoryBarrier const *const barrier = (VkImageMemoryBarrier const *const) & pImageMemoryBarriers[i]; 967 if (barrier->sType == VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER) { 968 if (barrier->subresourceRange.layerCount == 0) { 969 std::stringstream ss; 970 ss << "vkCmdPipelineBarrier called with 0 in ppMemoryBarriers[" << i << "]->subresourceRange.layerCount."; 971 skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, 972 __LINE__, IMAGE_INVALID_IMAGE_RESOURCE, "IMAGE", "%s", ss.str().c_str()); 973 } 974 } 975 } 976 977 if (skipCall) { 978 return; 979 } 980 981 device_data->device_dispatch_table->CmdPipelineBarrier(commandBuffer, srcStageMask, dstStageMask, dependencyFlags, 982 memoryBarrierCount, pMemoryBarriers, bufferMemoryBarrierCount, 983 pBufferMemoryBarriers, imageMemoryBarrierCount, pImageMemoryBarriers); 984 } 985 986 VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL 987 vkCmdResolveImage(VkCommandBuffer commandBuffer, VkImage srcImage, VkImageLayout srcImageLayout, VkImage dstImage, 988 VkImageLayout dstImageLayout, uint32_t regionCount, const VkImageResolve *pRegions) { 989 VkBool32 skipCall = VK_FALSE; 990 layer_data *device_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map); 991 auto srcImageEntry = device_data->imageMap.find(srcImage); 992 auto dstImageEntry = device_data->imageMap.find(dstImage); 993 994 // For each region, the number of layers in the image subresource should not be zero 995 // For each region, src and dest image aspect must be color only 996 for (uint32_t i = 0; i < regionCount; i++) { 997 if (pRegions[i].srcSubresource.layerCount == 0) { 998 char const str[] = "vkCmdResolveImage: number of layers in source subresource is zero"; 999 // TODO: Verify against Valid Use section of spec. Generally if something yield an undefined result, it's invalid/error 1000 skipCall |= 1001 log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 1002 (uint64_t)commandBuffer, __LINE__, IMAGE_MISMATCHED_IMAGE_ASPECT, "IMAGE", str); 1003 } 1004 1005 if (pRegions[i].dstSubresource.layerCount == 0) { 1006 char const str[] = "vkCmdResolveImage: number of layers in destination subresource is zero"; 1007 1008 // TODO: Verify against Valid Use section of spec. Generally if something yield an undefined result, it's invalid/error 1009 skipCall |= 1010 log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 1011 (uint64_t)commandBuffer, __LINE__, IMAGE_MISMATCHED_IMAGE_ASPECT, "IMAGE", str); 1012 } 1013 1014 if ((pRegions[i].srcSubresource.aspectMask != VK_IMAGE_ASPECT_COLOR_BIT) || 1015 (pRegions[i].dstSubresource.aspectMask != VK_IMAGE_ASPECT_COLOR_BIT)) { 1016 char const str[] = 1017 "vkCmdResolveImage: src and dest aspectMasks for each region must specify only VK_IMAGE_ASPECT_COLOR_BIT"; 1018 skipCall |= 1019 log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 1020 (uint64_t)commandBuffer, __LINE__, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", str); 1021 } 1022 } 1023 1024 if ((srcImageEntry != device_data->imageMap.end()) && (dstImageEntry != device_data->imageMap.end())) { 1025 if (srcImageEntry->second.format != dstImageEntry->second.format) { 1026 char const str[] = "vkCmdResolveImage called with unmatched source and dest formats."; 1027 skipCall |= 1028 log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 1029 (uint64_t)commandBuffer, __LINE__, IMAGE_MISMATCHED_IMAGE_FORMAT, "IMAGE", str); 1030 } 1031 if (srcImageEntry->second.imageType != dstImageEntry->second.imageType) { 1032 char const str[] = "vkCmdResolveImage called with unmatched source and dest image types."; 1033 skipCall |= 1034 log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 1035 (uint64_t)commandBuffer, __LINE__, IMAGE_MISMATCHED_IMAGE_TYPE, "IMAGE", str); 1036 } 1037 if (srcImageEntry->second.samples == VK_SAMPLE_COUNT_1_BIT) { 1038 char const str[] = "vkCmdResolveImage called with source sample count less than 2."; 1039 skipCall |= 1040 log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 1041 (uint64_t)commandBuffer, __LINE__, IMAGE_INVALID_RESOLVE_SAMPLES, "IMAGE", str); 1042 } 1043 if (dstImageEntry->second.samples != VK_SAMPLE_COUNT_1_BIT) { 1044 char const str[] = "vkCmdResolveImage called with dest sample count greater than 1."; 1045 skipCall |= 1046 log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 1047 (uint64_t)commandBuffer, __LINE__, IMAGE_INVALID_RESOLVE_SAMPLES, "IMAGE", str); 1048 } 1049 } 1050 1051 if (VK_FALSE == skipCall) { 1052 device_data->device_dispatch_table->CmdResolveImage(commandBuffer, srcImage, srcImageLayout, dstImage, dstImageLayout, 1053 regionCount, pRegions); 1054 } 1055 } 1056 1057 VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL 1058 vkGetImageSubresourceLayout(VkDevice device, VkImage image, const VkImageSubresource *pSubresource, VkSubresourceLayout *pLayout) { 1059 VkBool32 skipCall = VK_FALSE; 1060 layer_data *device_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map); 1061 VkFormat format; 1062 1063 auto imageEntry = device_data->imageMap.find(image); 1064 1065 // Validate that image aspects match formats 1066 if (imageEntry != device_data->imageMap.end()) { 1067 format = imageEntry->second.format; 1068 if (vk_format_is_color(format)) { 1069 if (pSubresource->aspectMask != VK_IMAGE_ASPECT_COLOR_BIT) { 1070 std::stringstream ss; 1071 ss << "vkGetImageSubresourceLayout: For color formats, the aspectMask field of VkImageSubresource must be " 1072 "VK_IMAGE_ASPECT_COLOR."; 1073 skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, 1074 (uint64_t)image, __LINE__, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", "%s", ss.str().c_str()); 1075 } 1076 } else if (vk_format_is_depth_or_stencil(format)) { 1077 if ((pSubresource->aspectMask != VK_IMAGE_ASPECT_DEPTH_BIT) && 1078 (pSubresource->aspectMask != VK_IMAGE_ASPECT_STENCIL_BIT)) { 1079 std::stringstream ss; 1080 ss << "vkGetImageSubresourceLayout: For depth/stencil formats, the aspectMask selects either the depth or stencil " 1081 "image aspectMask."; 1082 skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, 1083 (uint64_t)image, __LINE__, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", "%s", ss.str().c_str()); 1084 } 1085 } 1086 } 1087 1088 if (VK_FALSE == skipCall) { 1089 device_data->device_dispatch_table->GetImageSubresourceLayout(device, image, pSubresource, pLayout); 1090 } 1091 } 1092 1093 VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL 1094 vkGetPhysicalDeviceProperties(VkPhysicalDevice physicalDevice, VkPhysicalDeviceProperties *pProperties) { 1095 layer_data *phy_dev_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map); 1096 phy_dev_data->instance_dispatch_table->GetPhysicalDeviceProperties(physicalDevice, pProperties); 1097 } 1098 1099 VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetDeviceProcAddr(VkDevice device, const char *funcName) { 1100 if (!strcmp(funcName, "vkGetDeviceProcAddr")) 1101 return (PFN_vkVoidFunction)vkGetDeviceProcAddr; 1102 if (!strcmp(funcName, "vkDestroyDevice")) 1103 return (PFN_vkVoidFunction)vkDestroyDevice; 1104 if (!strcmp(funcName, "vkCreateImage")) 1105 return (PFN_vkVoidFunction)vkCreateImage; 1106 if (!strcmp(funcName, "vkDestroyImage")) 1107 return (PFN_vkVoidFunction)vkDestroyImage; 1108 if (!strcmp(funcName, "vkCreateImageView")) 1109 return (PFN_vkVoidFunction)vkCreateImageView; 1110 if (!strcmp(funcName, "vkCreateRenderPass")) 1111 return (PFN_vkVoidFunction)vkCreateRenderPass; 1112 if (!strcmp(funcName, "vkCmdClearColorImage")) 1113 return (PFN_vkVoidFunction)vkCmdClearColorImage; 1114 if (!strcmp(funcName, "vkCmdClearDepthStencilImage")) 1115 return (PFN_vkVoidFunction)vkCmdClearDepthStencilImage; 1116 if (!strcmp(funcName, "vkCmdClearAttachments")) 1117 return (PFN_vkVoidFunction)vkCmdClearAttachments; 1118 if (!strcmp(funcName, "vkCmdCopyImage")) 1119 return (PFN_vkVoidFunction)vkCmdCopyImage; 1120 if (!strcmp(funcName, "vkCmdCopyImageToBuffer")) 1121 return (PFN_vkVoidFunction)vkCmdCopyImageToBuffer; 1122 if (!strcmp(funcName, "vkCmdCopyBufferToImage")) 1123 return (PFN_vkVoidFunction)vkCmdCopyBufferToImage; 1124 if (!strcmp(funcName, "vkCmdBlitImage")) 1125 return (PFN_vkVoidFunction)vkCmdBlitImage; 1126 if (!strcmp(funcName, "vkCmdPipelineBarrier")) 1127 return (PFN_vkVoidFunction)vkCmdPipelineBarrier; 1128 if (!strcmp(funcName, "vkCmdResolveImage")) 1129 return (PFN_vkVoidFunction)vkCmdResolveImage; 1130 if (!strcmp(funcName, "vkGetImageSubresourceLayout")) 1131 return (PFN_vkVoidFunction)vkGetImageSubresourceLayout; 1132 1133 if (device == NULL) { 1134 return NULL; 1135 } 1136 1137 layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map); 1138 1139 VkLayerDispatchTable *pTable = my_data->device_dispatch_table; 1140 { 1141 if (pTable->GetDeviceProcAddr == NULL) 1142 return NULL; 1143 return pTable->GetDeviceProcAddr(device, funcName); 1144 } 1145 } 1146 1147 VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetInstanceProcAddr(VkInstance instance, const char *funcName) { 1148 if (!strcmp(funcName, "vkGetInstanceProcAddr")) 1149 return (PFN_vkVoidFunction)vkGetInstanceProcAddr; 1150 if (!strcmp(funcName, "vkCreateInstance")) 1151 return (PFN_vkVoidFunction)vkCreateInstance; 1152 if (!strcmp(funcName, "vkDestroyInstance")) 1153 return (PFN_vkVoidFunction)vkDestroyInstance; 1154 if (!strcmp(funcName, "vkCreateDevice")) 1155 return (PFN_vkVoidFunction)vkCreateDevice; 1156 if (!strcmp(funcName, "vkEnumerateInstanceLayerProperties")) 1157 return (PFN_vkVoidFunction)vkEnumerateInstanceLayerProperties; 1158 if (!strcmp(funcName, "vkEnumerateInstanceExtensionProperties")) 1159 return (PFN_vkVoidFunction)vkEnumerateInstanceExtensionProperties; 1160 if (!strcmp(funcName, "vkEnumerateDeviceLayerProperties")) 1161 return (PFN_vkVoidFunction)vkEnumerateDeviceLayerProperties; 1162 if (!strcmp(funcName, "vkEnumerateDeviceExtensionProperties")) 1163 return (PFN_vkVoidFunction)vkEnumerateDeviceExtensionProperties; 1164 if (!strcmp(funcName, "vkGetPhysicalDeviceProperties")) 1165 return (PFN_vkVoidFunction)vkGetPhysicalDeviceProperties; 1166 1167 if (instance == NULL) { 1168 return NULL; 1169 } 1170 1171 layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map); 1172 1173 PFN_vkVoidFunction fptr = debug_report_get_instance_proc_addr(my_data->report_data, funcName); 1174 if (fptr) 1175 return fptr; 1176 1177 VkLayerInstanceDispatchTable *pTable = my_data->instance_dispatch_table; 1178 if (pTable->GetInstanceProcAddr == NULL) 1179 return NULL; 1180 return pTable->GetInstanceProcAddr(instance, funcName); 1181 } 1182