aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorspencer-lunarg <spencer@lunarg.com>2023-01-15 15:49:16 +0900
committerSpencer Fricke <115671160+spencer-lunarg@users.noreply.github.com>2023-01-17 07:48:35 +0900
commit5683b43bc6d73ea9d842bc948d656179d1689090 (patch)
treef3dd3bb002995b3330663fa63eba41a245ba0556
parent61314fb36166f07e4f903969721135cbb606a670 (diff)
downloadvulkan-validation-layers-5683b43bc6d73ea9d842bc948d656179d1689090.tar.gz
layers: Move External object CoreCheck into own file
-rw-r--r--BUILD.gn1
-rw-r--r--build-android/cmake/layerlib/CMakeLists.txt1
-rw-r--r--build-android/jni/Android.mk1
-rw-r--r--layers/CMakeLists.txt1
-rw-r--r--layers/core_validation.cpp409
-rw-r--r--layers/external_object_validation.cpp451
-rwxr-xr-xscripts/vk_validation_stats.py1
7 files changed, 456 insertions, 409 deletions
diff --git a/BUILD.gn b/BUILD.gn
index dc28dccf6..4afc85ca0 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -134,6 +134,7 @@ core_validation_sources = [
"layers/device_state.h",
"layers/device_validation.cpp",
"layers/drawdispatch.cpp",
+ "layers/external_object_validation.cpp",
"layers/generated/command_validation.cpp",
"layers/generated/command_validation.h",
"layers/generated/gpu_as_inspection_comp.h",
diff --git a/build-android/cmake/layerlib/CMakeLists.txt b/build-android/cmake/layerlib/CMakeLists.txt
index 36f8c1744..71f07425b 100644
--- a/build-android/cmake/layerlib/CMakeLists.txt
+++ b/build-android/cmake/layerlib/CMakeLists.txt
@@ -72,6 +72,7 @@ add_library(VkLayer_khronos_validation SHARED
${SRC_DIR}/layers/device_validation.cpp
${SRC_DIR}/layers/device_memory_state.cpp
${SRC_DIR}/layers/device_memory_validation.cpp
+ ${SRC_DIR}/layers/external_object_validation.cpp
${SRC_DIR}/layers/image_state.cpp
${SRC_DIR}/layers/pipeline_state.cpp
${SRC_DIR}/layers/pipeline_validation.cpp
diff --git a/build-android/jni/Android.mk b/build-android/jni/Android.mk
index 9f51d182a..7c1693139 100644
--- a/build-android/jni/Android.mk
+++ b/build-android/jni/Android.mk
@@ -42,6 +42,7 @@ LOCAL_SRC_FILES += $(SRC_DIR)/layers/android_validation.cpp
LOCAL_SRC_FILES += $(SRC_DIR)/layers/device_validation.cpp
LOCAL_SRC_FILES += $(SRC_DIR)/layers/device_memory_state.cpp
LOCAL_SRC_FILES += $(SRC_DIR)/layers/device_memory_validation.cpp
+LOCAL_SRC_FILES += $(SRC_DIR)/layers/external_object_validation.cpp
LOCAL_SRC_FILES += $(SRC_DIR)/layers/base_node.cpp
LOCAL_SRC_FILES += $(SRC_DIR)/layers/buffer_state.cpp
LOCAL_SRC_FILES += $(SRC_DIR)/layers/cmd_buffer_state.cpp
diff --git a/layers/CMakeLists.txt b/layers/CMakeLists.txt
index 5fd7280b2..7207a680e 100644
--- a/layers/CMakeLists.txt
+++ b/layers/CMakeLists.txt
@@ -209,6 +209,7 @@ target_sources(VkLayer_khronos_validation PRIVATE
device_memory_state.h
device_memory_validation.cpp
drawdispatch.cpp
+ external_object_validation.cpp
gpu_utils.cpp
gpu_utils.h
gpu_validation.cpp
diff --git a/layers/core_validation.cpp b/layers/core_validation.cpp
index 74df2e6d2..f4a1d0880 100644
--- a/layers/core_validation.cpp
+++ b/layers/core_validation.cpp
@@ -5915,174 +5915,6 @@ bool CoreChecks::PreCallValidateSignalSemaphoreKHR(VkDevice device, const VkSema
return ValidateSignalSemaphore(device, pSignalInfo, "vkSignalSemaphoreKHR");
}
-#ifdef VK_USE_PLATFORM_WIN32_KHR
-bool CoreChecks::PreCallValidateImportSemaphoreWin32HandleKHR(VkDevice device,
- const VkImportSemaphoreWin32HandleInfoKHR *info) const {
- bool skip = false;
- const char *func_name = "vkImportSemaphoreWin32HandleKHR";
- auto sem_state = Get<SEMAPHORE_STATE>(info->semaphore);
- if (sem_state) {
- skip |= ValidateObjectNotInUse(sem_state.get(), func_name, kVUIDUndefined);
-
- if ((info->flags & VK_SEMAPHORE_IMPORT_TEMPORARY_BIT) != 0 && sem_state->type == VK_SEMAPHORE_TYPE_TIMELINE) {
- skip |= LogError(
- sem_state->Handle(), "VUID-VkImportSemaphoreWin32HandleInfoKHR-flags-03322",
- "vkImportSemaphoreWin32HandleKHR(): VK_SEMAPHORE_IMPORT_TEMPORARY_BIT not allowed for timeline semaphores");
- }
- }
- return skip;
-}
-
-bool CoreChecks::PreCallValidateGetSemaphoreWin32HandleKHR(VkDevice device, const VkSemaphoreGetWin32HandleInfoKHR *info,
- HANDLE *pHandle) const {
- bool skip = false;
- const char *func_name = "vkGetSemaphoreWin32HandleKHR";
- auto sem_state = Get<SEMAPHORE_STATE>(info->semaphore);
- if (sem_state) {
- if ((info->handleType & sem_state->exportHandleTypes) == 0) {
- skip |= LogError(sem_state->Handle(), "VUID-VkSemaphoreGetWin32HandleInfoKHR-handleType-01126",
- "%s: handleType %s was not VkExportSemaphoreCreateInfo::handleTypes (%s)", func_name,
- string_VkExternalSemaphoreHandleTypeFlagBits(info->handleType),
- string_VkExternalSemaphoreHandleTypeFlags(sem_state->exportHandleTypes).c_str());
- }
- }
- return skip;
-}
-#endif // VK_USE_PLATFORM_WIN32_KHR
-
-bool CoreChecks::PreCallValidateImportSemaphoreFdKHR(VkDevice device, const VkImportSemaphoreFdInfoKHR *info) const {
- bool skip = false;
- const char *func_name = "vkImportSemaphoreFdKHR";
- auto sem_state = Get<SEMAPHORE_STATE>(info->semaphore);
- if (sem_state) {
- skip |= ValidateObjectNotInUse(sem_state.get(), func_name, kVUIDUndefined);
-
- if ((info->flags & VK_SEMAPHORE_IMPORT_TEMPORARY_BIT) != 0 && sem_state->type == VK_SEMAPHORE_TYPE_TIMELINE) {
- skip |= LogError(sem_state->Handle(), "VUID-VkImportSemaphoreFdInfoKHR-flags-03323",
- "%s(): VK_SEMAPHORE_IMPORT_TEMPORARY_BIT not allowed for timeline semaphores", func_name);
- }
- }
- return skip;
-}
-
-bool CoreChecks::PreCallValidateGetSemaphoreFdKHR(VkDevice device, const VkSemaphoreGetFdInfoKHR *info, int *pFd) const {
- bool skip = false;
- const char *func_name = "vkGetSemaphoreFdKHR";
- auto sem_state = Get<SEMAPHORE_STATE>(info->semaphore);
- if (sem_state) {
- if ((info->handleType & sem_state->exportHandleTypes) == 0) {
- skip |= LogError(sem_state->Handle(), "VUID-VkSemaphoreGetFdInfoKHR-handleType-01132",
- "%s(): handleType %s was not VkExportSemaphoreCreateInfo::handleTypes (%s)", func_name,
- string_VkExternalSemaphoreHandleTypeFlagBits(info->handleType),
- string_VkExternalSemaphoreHandleTypeFlags(sem_state->exportHandleTypes).c_str());
- }
-
- if (info->handleType == VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT) {
- if (sem_state->type != VK_SEMAPHORE_TYPE_BINARY) {
- skip |= LogError(sem_state->Handle(), "VUID-VkSemaphoreGetFdInfoKHR-handleType-03253",
- "%s(): can only export binary semaphores to %s", func_name,
- string_VkExternalSemaphoreHandleTypeFlagBits(info->handleType));
- }
- if (!sem_state->CanBeWaited()) {
- skip |= LogError(sem_state->Handle(), "VUID-VkSemaphoreGetFdInfoKHR-handleType-03254",
- "%s(): must be signaled or have a pending signal operation", func_name);
- }
- }
- }
- return skip;
-}
-
-#ifdef VK_USE_PLATFORM_FUCHSIA
-bool CoreChecks::PreCallValidateImportSemaphoreZirconHandleFUCHSIA(VkDevice device,
- const VkImportSemaphoreZirconHandleInfoFUCHSIA *info) const {
- bool skip = false;
- const char *func_name = "vkImportSemaphoreZirconHandleFUCHSIA";
- auto sem_state = Get<SEMAPHORE_STATE>(info->semaphore);
- if (sem_state) {
- skip |= ValidateObjectNotInUse(sem_state.get(), func_name, kVUIDUndefined);
-
- if (sem_state->type == VK_SEMAPHORE_TYPE_TIMELINE) {
- skip |=
- LogError(sem_state->Handle(), "VUID-VkImportSemaphoreZirconHandleInfoFUCHSIA-semaphoreType-04768",
- "%s(): VkSemaphoreTypeCreateInfo::semaphoreType field must not be VK_SEMAPHORE_TYPE_TIMELINE", func_name);
- }
- }
- return skip;
-}
-
-void CoreChecks::PostCallRecordImportSemaphoreZirconHandleFUCHSIA(
- VkDevice device, const VkImportSemaphoreZirconHandleInfoFUCHSIA *pImportSemaphoreZirconHandleInfo, VkResult result) {
- if (VK_SUCCESS != result) return;
- RecordImportSemaphoreState(pImportSemaphoreZirconHandleInfo->semaphore, pImportSemaphoreZirconHandleInfo->handleType,
- pImportSemaphoreZirconHandleInfo->flags);
-}
-
-void CoreChecks::PostCallRecordGetSemaphoreZirconHandleFUCHSIA(VkDevice device,
- const VkSemaphoreGetZirconHandleInfoFUCHSIA *pGetZirconHandleInfo,
- zx_handle_t *pZirconHandle, VkResult result) {
- if (VK_SUCCESS != result) return;
- RecordGetExternalSemaphoreState(pGetZirconHandleInfo->semaphore, pGetZirconHandleInfo->handleType);
-}
-#endif
-
-bool CoreChecks::ValidateImportFence(VkFence fence, const char *vuid, const char *caller_name) const {
- auto fence_node = Get<FENCE_STATE>(fence);
- bool skip = false;
- if (fence_node && fence_node->Scope() == kSyncScopeInternal && fence_node->State() == FENCE_INFLIGHT) {
- skip |=
- LogError(fence, vuid, "%s: Fence %s that is currently in use.", caller_name, report_data->FormatHandle(fence).c_str());
- }
- return skip;
-}
-
-#ifdef VK_USE_PLATFORM_WIN32_KHR
-bool CoreChecks::PreCallValidateImportFenceWin32HandleKHR(
- VkDevice device, const VkImportFenceWin32HandleInfoKHR *pImportFenceWin32HandleInfo) const {
- return ValidateImportFence(pImportFenceWin32HandleInfo->fence, "VUID-vkImportFenceWin32HandleKHR-fence-04448",
- "vkImportFenceWin32HandleKHR");
-}
-
-bool CoreChecks::PreCallValidateGetFenceWin32HandleKHR(VkDevice device, const VkFenceGetWin32HandleInfoKHR *info,
- HANDLE *pHandle) const {
- bool skip = false;
- const char *func_name = "vkGetFenceWin32HandleKHR";
- auto fence_state = Get<FENCE_STATE>(info->fence);
- if (fence_state) {
- if ((info->handleType & fence_state->exportHandleTypes) == 0) {
- skip |= LogError(fence_state->Handle(), "VUID-VkFenceGetWin32HandleInfoKHR-handleType-01448",
- "%s: handleType %s was not VkExportFenceCreateInfo::handleTypes (%s)", func_name,
- string_VkExternalFenceHandleTypeFlagBits(info->handleType),
- string_VkExternalFenceHandleTypeFlags(fence_state->exportHandleTypes).c_str());
- }
- }
- return skip;
-}
-#endif // VK_USE_PLATFORM_WIN32_KHR
-
-bool CoreChecks::PreCallValidateImportFenceFdKHR(VkDevice device, const VkImportFenceFdInfoKHR *pImportFenceFdInfo) const {
- return ValidateImportFence(pImportFenceFdInfo->fence, "VUID-vkImportFenceFdKHR-fence-01463", "vkImportFenceFdKHR");
-}
-
-bool CoreChecks::PreCallValidateGetFenceFdKHR(VkDevice device, const VkFenceGetFdInfoKHR *info, int *pFd) const {
- bool skip = false;
- const char *func_name = "vkGetFenceFdKHR";
- auto fence_state = Get<FENCE_STATE>(info->fence);
- if (fence_state) {
- if ((info->handleType & fence_state->exportHandleTypes) == 0) {
- skip |= LogError(fence_state->Handle(), "VUID-VkFenceGetFdInfoKHR-handleType-01453",
- "%s: handleType %s was not VkExportFenceCreateInfo::handleTypes (%s)", func_name,
- string_VkExternalFenceHandleTypeFlagBits(info->handleType),
- string_VkExternalFenceHandleTypeFlags(fence_state->exportHandleTypes).c_str());
- }
- if (info->handleType == VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT && fence_state->State() == FENCE_UNSIGNALED) {
- skip |= LogError(fence_state->Handle(), "VUID-VkFenceGetFdInfoKHR-handleType-01454",
- "%s(): cannot export to %s unless the fence has a pending signal operation or is already signaled",
- func_name, string_VkExternalFenceHandleTypeFlagBits(info->handleType));
- }
- }
- return skip;
-}
-
bool CoreChecks::PreCallValidateCmdDebugMarkerBeginEXT(VkCommandBuffer commandBuffer,
const VkDebugMarkerMarkerInfoEXT *pMarkerInfo) const {
auto cb_state = GetRead<CMD_BUFFER_STATE>(commandBuffer);
@@ -6784,244 +6616,3 @@ bool CoreChecks::PreCallValidateGetImageSubresourceLayout2EXT(VkDevice device, V
return skip;
}
-
-#ifdef VK_USE_PLATFORM_METAL_EXT
-bool CoreChecks::PreCallValidateExportMetalObjectsEXT(VkDevice device, VkExportMetalObjectsInfoEXT *pMetalObjectsInfo) const {
- bool skip = false;
- const VkBaseOutStructure *metal_objects_info_ptr = reinterpret_cast<const VkBaseOutStructure *>(pMetalObjectsInfo->pNext);
- while (metal_objects_info_ptr) {
- switch (metal_objects_info_ptr->sType) {
- case VK_STRUCTURE_TYPE_EXPORT_METAL_DEVICE_INFO_EXT:
- if (std::find(instance_state->export_metal_flags.begin(), instance_state->export_metal_flags.end(),
- VK_EXPORT_METAL_OBJECT_TYPE_METAL_DEVICE_BIT_EXT) == instance_state->export_metal_flags.end()) {
- skip |= LogError(
- device, "VUID-VkExportMetalObjectsInfoEXT-pNext-06791",
- "ExportMetalObjectsEXT: pNext chain contains a VkExportMetalDeviceInfoEXT structure "
- "but instance %s did not have a "
- "VkExportMetalObjectCreateInfoEXT struct with exportObjectType of "
- "VK_EXPORT_METAL_OBJECT_TYPE_METAL_DEVICE_BIT_EXT in the pNext chain of its VkInstanceCreateInfo structure",
- report_data->FormatHandle(instance_state->instance).c_str());
- }
- break;
-
- case VK_STRUCTURE_TYPE_EXPORT_METAL_COMMAND_QUEUE_INFO_EXT:
- if (std::find(instance_state->export_metal_flags.begin(), instance_state->export_metal_flags.end(),
- VK_EXPORT_METAL_OBJECT_TYPE_METAL_COMMAND_QUEUE_BIT_EXT) ==
- instance_state->export_metal_flags.end()) {
- skip |= LogError(device, "VUID-VkExportMetalObjectsInfoEXT-pNext-06792",
- "ExportMetalObjectsEXT: pNext chain contains a VkExportMetalCommandQueueInfoEXT structure "
- "but instance %s did not have a "
- "VkExportMetalObjectCreateInfoEXT struct with exportObjectType of "
- "VK_EXPORT_METAL_OBJECT_TYPE_METAL_COMMAND_QUEUE_BIT_EXT in the pNext chain of its "
- "VkInstanceCreateInfo structure",
- report_data->FormatHandle(instance_state->instance).c_str());
- }
- break;
-
- case VK_STRUCTURE_TYPE_EXPORT_METAL_BUFFER_INFO_EXT: {
- auto metal_buffer_ptr = reinterpret_cast<const VkExportMetalBufferInfoEXT *>(metal_objects_info_ptr);
- auto mem_info = Get<DEVICE_MEMORY_STATE>(metal_buffer_ptr->memory);
- if (mem_info) {
- if (!mem_info->metal_buffer_export) {
- skip |= LogError(
- device, "VUID-VkExportMetalObjectsInfoEXT-pNext-06793",
- "ExportMetalObjectsEXT: pNext chain contains a VkExportMetalBufferInfoEXT structure with memory = "
- "%s, but that memory was not allocated with a VkExportMetalObjectCreateInfoEXT whose exportObjectType "
- "member was set to VK_EXPORT_METAL_OBJECT_TYPE_METAL_BUFFER_BIT_EXT in the pNext chain of the "
- "VkMemoryAllocateInfo structure",
- report_data->FormatHandle(metal_buffer_ptr->memory).c_str());
- }
- }
- } break;
-
- case VK_STRUCTURE_TYPE_EXPORT_METAL_TEXTURE_INFO_EXT: {
- auto metal_texture_ptr = reinterpret_cast<const VkExportMetalTextureInfoEXT *>(metal_objects_info_ptr);
- if ((metal_texture_ptr->image == VK_NULL_HANDLE && metal_texture_ptr->imageView == VK_NULL_HANDLE &&
- metal_texture_ptr->bufferView == VK_NULL_HANDLE) ||
- (metal_texture_ptr->image &&
- ((metal_texture_ptr->imageView != VK_NULL_HANDLE) || (metal_texture_ptr->bufferView != VK_NULL_HANDLE))) ||
- (metal_texture_ptr->imageView &&
- ((metal_texture_ptr->image != VK_NULL_HANDLE) || (metal_texture_ptr->bufferView != VK_NULL_HANDLE))) ||
- (metal_texture_ptr->bufferView &&
- ((metal_texture_ptr->image != VK_NULL_HANDLE) || (metal_texture_ptr->imageView != VK_NULL_HANDLE)))) {
- skip |=
- LogError(device, "VUID-VkExportMetalObjectsInfoEXT-pNext-06794",
- "ExportMetalObjectsEXT: pNext chain contains a VkExportMetalTextureInfoEXT structure with image = "
- "%s, imageView = %s and bufferView = %s, but exactly one of those 3 must not be VK_NULL_HANDLE",
- report_data->FormatHandle(metal_texture_ptr->image).c_str(),
- report_data->FormatHandle(metal_texture_ptr->imageView).c_str(),
- report_data->FormatHandle(metal_texture_ptr->bufferView).c_str());
- }
- if (metal_texture_ptr->image) {
- auto image_info = Get<IMAGE_STATE>(metal_texture_ptr->image);
- if (image_info) {
- if (!image_info->metal_image_export) {
- skip |= LogError(
- device, "VUID-VkExportMetalObjectsInfoEXT-pNext-06795",
- "ExportMetalObjectsEXT: pNext chain contains a VkExportMetalTextureInfoEXT structure with image = "
- "%s, but that image was not created with a VkExportMetalObjectCreateInfoEXT whose exportObjectType "
- "member was set to VK_EXPORT_METAL_OBJECT_TYPE_METAL_TEXTURE_BIT_EXT in the pNext chain of the "
- "VkImageCreateInfo structure",
- report_data->FormatHandle(metal_texture_ptr->image).c_str());
- }
- auto format_plane_count = FormatPlaneCount(image_info->createInfo.format);
- auto image_plane = metal_texture_ptr->plane;
- if (!(format_plane_count > 1) && (image_plane != VK_IMAGE_ASPECT_PLANE_0_BIT)) {
- skip |= LogError(
- device, "VUID-VkExportMetalObjectsInfoEXT-pNext-06799",
- "ExportMetalObjectsEXT: pNext chain contains a VkExportMetalTextureInfoEXT structure with image = "
- "%s, and plane = %s, but image was created with format %s, which is not multiplaner and plane is "
- "required to be VK_IMAGE_ASPECT_PLANE_0_BIT",
- report_data->FormatHandle(metal_texture_ptr->image).c_str(),
- string_VkImageAspectFlags(image_plane).c_str(), string_VkFormat(image_info->createInfo.format));
- }
- if ((format_plane_count == 2) && (image_plane == VK_IMAGE_ASPECT_PLANE_2_BIT)) {
- skip |= LogError(
- device, "VUID-VkExportMetalObjectsInfoEXT-pNext-06800",
- "ExportMetalObjectsEXT: pNext chain contains a VkExportMetalTextureInfoEXT structure with image = "
- "%s, and plane = %s, but image was created with format %s, which has exactly 2 planes and plane "
- "cannot"
- "be VK_IMAGE_ASPECT_PLANE_2_BIT",
- report_data->FormatHandle(metal_texture_ptr->image).c_str(),
- string_VkImageAspectFlags(image_plane).c_str(), string_VkFormat(image_info->createInfo.format));
- }
- }
- }
- if (metal_texture_ptr->imageView) {
- auto image_view_info = Get<IMAGE_VIEW_STATE>(metal_texture_ptr->imageView);
- if (image_view_info) {
- if (!image_view_info->metal_imageview_export) {
- skip |= LogError(
- device, "VUID-VkExportMetalObjectsInfoEXT-pNext-06796",
- "ExportMetalObjectsEXT: pNext chain contains a VkExportMetalTextureInfoEXT structure with "
- "imageView = "
- "%s, but that image view was not created with a VkExportMetalObjectCreateInfoEXT whose "
- "exportObjectType "
- "member was set to VK_EXPORT_METAL_OBJECT_TYPE_METAL_TEXTURE_BIT_EXT in the pNext chain of the "
- "VkImageViewCreateInfo structure",
- report_data->FormatHandle(metal_texture_ptr->imageView).c_str());
- }
- auto format_plane_count = FormatPlaneCount(image_view_info->create_info.format);
- auto image_plane = metal_texture_ptr->plane;
- if (!(format_plane_count > 1) && (image_plane != VK_IMAGE_ASPECT_PLANE_0_BIT)) {
- skip |= LogError(
- device, "VUID-VkExportMetalObjectsInfoEXT-pNext-06801",
- "ExportMetalObjectsEXT: pNext chain contains a VkExportMetalTextureInfoEXT structure with "
- "imageView = "
- "%s, and plane = %s, but imageView was created with format %s, which is not multiplaner and "
- "plane is "
- "required to be VK_IMAGE_ASPECT_PLANE_0_BIT",
- report_data->FormatHandle(metal_texture_ptr->imageView).c_str(),
- string_VkImageAspectFlags(image_plane).c_str(),
- string_VkFormat(image_view_info->create_info.format));
- }
- if ((format_plane_count == 2) && (image_plane == VK_IMAGE_ASPECT_PLANE_2_BIT)) {
- skip |= LogError(device, "VUID-VkExportMetalObjectsInfoEXT-pNext-06802",
- "ExportMetalObjectsEXT: pNext chain contains a VkExportMetalTextureInfoEXT structure "
- "with imageView = "
- "%s, and plane = %s, but imageView was created with format %s, which has exactly 2 "
- "planes and plane "
- "cannot"
- "be VK_IMAGE_ASPECT_PLANE_2_BIT",
- report_data->FormatHandle(metal_texture_ptr->imageView).c_str(),
- string_VkImageAspectFlags(image_plane).c_str(),
- string_VkFormat(image_view_info->create_info.format));
- }
- }
- }
- if (metal_texture_ptr->bufferView) {
- auto buffer_view_info = Get<BUFFER_VIEW_STATE>(metal_texture_ptr->bufferView);
- if (buffer_view_info) {
- if (!buffer_view_info->metal_bufferview_export) {
- skip |= LogError(
- device, "VUID-VkExportMetalObjectsInfoEXT-pNext-06797",
- "ExportMetalObjectsEXT: pNext chain contains a VkExportMetalTextureInfoEXT structure with "
- "bufferView = "
- "%s, but that buffer view was not created with a VkExportMetalObjectCreateInfoEXT whose "
- "exportObjectType "
- "member was set to VK_EXPORT_METAL_OBJECT_TYPE_METAL_TEXTURE_BIT_EXT in the pNext chain of the "
- "VkBufferViewCreateInfo structure",
- report_data->FormatHandle(metal_texture_ptr->bufferView).c_str());
- }
- }
- }
- if (metal_texture_ptr->image || metal_texture_ptr->imageView) {
- if ((metal_texture_ptr->plane != VK_IMAGE_ASPECT_PLANE_0_BIT) &&
- (metal_texture_ptr->plane != VK_IMAGE_ASPECT_PLANE_1_BIT) &&
- (metal_texture_ptr->plane != VK_IMAGE_ASPECT_PLANE_2_BIT)) {
- skip |= LogError(
- device, "VUID-VkExportMetalObjectsInfoEXT-pNext-06798",
- "ExportMetalObjectsEXT: pNext chain contains a VkExportMetalTextureInfoEXT structure with "
- "image = %s and imageView = "
- "%s, but plane = %s which is not one of VK_IMAGE_ASPECT_PLANE_0_BIT, VK_IMAGE_ASPECT_PLANE_1_BIT, "
- "or VK_IMAGE_ASPECT_PLANE_2_BIT",
- report_data->FormatHandle(metal_texture_ptr->image).c_str(),
- report_data->FormatHandle(metal_texture_ptr->imageView).c_str(),
- string_VkImageAspectFlags(metal_texture_ptr->plane).c_str());
- }
- }
- } break;
-
- case VK_STRUCTURE_TYPE_EXPORT_METAL_IO_SURFACE_INFO_EXT: {
- auto metal_io_surface_ptr = reinterpret_cast<const VkExportMetalIOSurfaceInfoEXT *>(metal_objects_info_ptr);
- auto image_info = Get<IMAGE_STATE>(metal_io_surface_ptr->image);
- if (image_info) {
- if (!image_info->metal_io_surface_export) {
- skip |= LogError(
- device, "VUID-VkExportMetalObjectsInfoEXT-pNext-06803",
- "ExportMetalObjectsEXT: pNext chain contains a VkExportMetalIOSurfaceInfoEXT structure with image = "
- "%s, but that image was not created with a VkExportMetalObjectCreateInfoEXT whose exportObjectType "
- "member was set to VK_EXPORT_METAL_OBJECT_TYPE_METAL_IOSURFACE_BIT_EXT in the pNext chain of the "
- "VkImageCreateInfo structure",
- report_data->FormatHandle(metal_io_surface_ptr->image).c_str());
- }
- }
- } break;
-
- case VK_STRUCTURE_TYPE_EXPORT_METAL_SHARED_EVENT_INFO_EXT: {
- auto metal_shared_event_ptr = reinterpret_cast<const VkExportMetalSharedEventInfoEXT *>(metal_objects_info_ptr);
- if ((metal_shared_event_ptr->event == VK_NULL_HANDLE && metal_shared_event_ptr->semaphore == VK_NULL_HANDLE) ||
- (metal_shared_event_ptr->event != VK_NULL_HANDLE && metal_shared_event_ptr->semaphore != VK_NULL_HANDLE)) {
- skip |= LogError(
- device, "VUID-VkExportMetalObjectsInfoEXT-pNext-06804",
- "ExportMetalObjectsEXT: pNext chain contains a VkExportMetalSharedEventInfoEXT structure with semaphore = "
- "%s, and event = %s, but exactly one of them must not be VK_NULL_HANDLE",
- report_data->FormatHandle(metal_shared_event_ptr->semaphore).c_str(),
- report_data->FormatHandle(metal_shared_event_ptr->event).c_str());
- }
-
- if (metal_shared_event_ptr->semaphore) {
- auto semaphore_info = Get<SEMAPHORE_STATE>(metal_shared_event_ptr->semaphore);
- if (semaphore_info && !(semaphore_info->metal_semaphore_export)) {
- skip |= LogError(
- device, "VUID-VkExportMetalObjectsInfoEXT-pNext-06805",
- "ExportMetalObjectsEXT: pNext chain contains a VkExportMetalSharedEventInfoEXT structure "
- "with semaphore = "
- "%s, but that semaphore was not created with a VkExportMetalObjectCreateInfoEXT whose exportObjectType "
- "member was set to VK_EXPORT_METAL_OBJECT_TYPE_METAL_SHARED_EVENT_BIT_EXT in the pNext chain of the "
- "VkSemaphoreCreateInfo structure",
- report_data->FormatHandle(metal_shared_event_ptr->semaphore).c_str());
- }
- }
- if (metal_shared_event_ptr->event) {
- auto event_info = Get<EVENT_STATE>(metal_shared_event_ptr->event);
- if (event_info && !(event_info->metal_event_export)) {
- skip |= LogError(
- device, "VUID-VkExportMetalObjectsInfoEXT-pNext-06806",
- "ExportMetalObjectsEXT: pNext chain contains a VkExportMetalSharedEventInfoEXT structure "
- "with event = "
- "%s, but that event was not created with a VkExportMetalObjectCreateInfoEXT whose exportObjectType "
- "member was set to VK_EXPORT_METAL_OBJECT_TYPE_METAL_SHARED_EVENT_BIT_EXT in the pNext chain of the "
- "VkEventCreateInfo structure",
- report_data->FormatHandle(metal_shared_event_ptr->event).c_str());
- }
- }
- } break;
- default:
- break;
- }
- metal_objects_info_ptr = metal_objects_info_ptr->pNext;
- }
- return skip;
-}
-#endif // VK_USE_PLATFORM_METAL_EXT
diff --git a/layers/external_object_validation.cpp b/layers/external_object_validation.cpp
new file mode 100644
index 000000000..0600a04d4
--- /dev/null
+++ b/layers/external_object_validation.cpp
@@ -0,0 +1,451 @@
+/* Copyright (c) 2015-2023 The Khronos Group Inc.
+ * Copyright (c) 2015-2023 Valve Corporation
+ * Copyright (c) 2015-2023 LunarG, Inc.
+ * Copyright (C) 2015-2023 Google Inc.
+ * Modifications Copyright (C) 2020-2022 Advanced Micro Devices, Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Author: Cody Northrop <cnorthrop@google.com>
+ * Author: Michael Lentine <mlentine@google.com>
+ * Author: Tobin Ehlis <tobine@google.com>
+ * Author: Chia-I Wu <olv@google.com>
+ * Author: Chris Forbes <chrisf@ijw.co.nz>
+ * Author: Mark Lobodzinski <mark@lunarg.com>
+ * Author: Ian Elliott <ianelliott@google.com>
+ * Author: Dave Houlton <daveh@lunarg.com>
+ * Author: Dustin Graves <dustin@lunarg.com>
+ * Author: Jeremy Hayes <jeremy@lunarg.com>
+ * Author: Jon Ashburn <jon@lunarg.com>
+ * Author: Karl Schultz <karl@lunarg.com>
+ * Author: Mark Young <marky@lunarg.com>
+ * Author: Mike Schuchardt <mikes@lunarg.com>
+ * Author: Mike Weiblen <mikew@lunarg.com>
+ * Author: Tony Barbour <tony@LunarG.com>
+ * Author: John Zulauf <jzulauf@lunarg.com>
+ * Author: Shannon McPherson <shannon@lunarg.com>
+ * Author: Jeremy Kniager <jeremyk@lunarg.com>
+ * Author: Tobias Hector <tobias.hector@amd.com>
+ * Author: Jeremy Gebben <jeremyg@lunarg.com>
+ */
+
+#include "vk_enum_string_helper.h"
+#include "chassis.h"
+#include "core_validation.h"
+
+bool CoreChecks::PreCallValidateImportSemaphoreFdKHR(VkDevice device, const VkImportSemaphoreFdInfoKHR *info) const {
+ bool skip = false;
+ const char *func_name = "vkImportSemaphoreFdKHR";
+ auto sem_state = Get<SEMAPHORE_STATE>(info->semaphore);
+ if (sem_state) {
+ skip |= ValidateObjectNotInUse(sem_state.get(), func_name, kVUIDUndefined);
+
+ if ((info->flags & VK_SEMAPHORE_IMPORT_TEMPORARY_BIT) != 0 && sem_state->type == VK_SEMAPHORE_TYPE_TIMELINE) {
+ skip |= LogError(sem_state->Handle(), "VUID-VkImportSemaphoreFdInfoKHR-flags-03323",
+ "%s(): VK_SEMAPHORE_IMPORT_TEMPORARY_BIT not allowed for timeline semaphores", func_name);
+ }
+ }
+ return skip;
+}
+
+bool CoreChecks::PreCallValidateGetSemaphoreFdKHR(VkDevice device, const VkSemaphoreGetFdInfoKHR *info, int *pFd) const {
+ bool skip = false;
+ const char *func_name = "vkGetSemaphoreFdKHR";
+ auto sem_state = Get<SEMAPHORE_STATE>(info->semaphore);
+ if (sem_state) {
+ if ((info->handleType & sem_state->exportHandleTypes) == 0) {
+ skip |= LogError(sem_state->Handle(), "VUID-VkSemaphoreGetFdInfoKHR-handleType-01132",
+ "%s(): handleType %s was not VkExportSemaphoreCreateInfo::handleTypes (%s)", func_name,
+ string_VkExternalSemaphoreHandleTypeFlagBits(info->handleType),
+ string_VkExternalSemaphoreHandleTypeFlags(sem_state->exportHandleTypes).c_str());
+ }
+
+ if (info->handleType == VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT) {
+ if (sem_state->type != VK_SEMAPHORE_TYPE_BINARY) {
+ skip |= LogError(sem_state->Handle(), "VUID-VkSemaphoreGetFdInfoKHR-handleType-03253",
+ "%s(): can only export binary semaphores to %s", func_name,
+ string_VkExternalSemaphoreHandleTypeFlagBits(info->handleType));
+ }
+ if (!sem_state->CanBeWaited()) {
+ skip |= LogError(sem_state->Handle(), "VUID-VkSemaphoreGetFdInfoKHR-handleType-03254",
+ "%s(): must be signaled or have a pending signal operation", func_name);
+ }
+ }
+ }
+ return skip;
+}
+
+bool CoreChecks::ValidateImportFence(VkFence fence, const char *vuid, const char *caller_name) const {
+ auto fence_node = Get<FENCE_STATE>(fence);
+ bool skip = false;
+ if (fence_node && fence_node->Scope() == kSyncScopeInternal && fence_node->State() == FENCE_INFLIGHT) {
+ skip |=
+ LogError(fence, vuid, "%s: Fence %s that is currently in use.", caller_name, report_data->FormatHandle(fence).c_str());
+ }
+ return skip;
+}
+
+bool CoreChecks::PreCallValidateImportFenceFdKHR(VkDevice device, const VkImportFenceFdInfoKHR *pImportFenceFdInfo) const {
+ return ValidateImportFence(pImportFenceFdInfo->fence, "VUID-vkImportFenceFdKHR-fence-01463", "vkImportFenceFdKHR");
+}
+
+bool CoreChecks::PreCallValidateGetFenceFdKHR(VkDevice device, const VkFenceGetFdInfoKHR *info, int *pFd) const {
+ bool skip = false;
+ const char *func_name = "vkGetFenceFdKHR";
+ auto fence_state = Get<FENCE_STATE>(info->fence);
+ if (fence_state) {
+ if ((info->handleType & fence_state->exportHandleTypes) == 0) {
+ skip |= LogError(fence_state->Handle(), "VUID-VkFenceGetFdInfoKHR-handleType-01453",
+ "%s: handleType %s was not VkExportFenceCreateInfo::handleTypes (%s)", func_name,
+ string_VkExternalFenceHandleTypeFlagBits(info->handleType),
+ string_VkExternalFenceHandleTypeFlags(fence_state->exportHandleTypes).c_str());
+ }
+ if (info->handleType == VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT && fence_state->State() == FENCE_UNSIGNALED) {
+ skip |= LogError(fence_state->Handle(), "VUID-VkFenceGetFdInfoKHR-handleType-01454",
+ "%s(): cannot export to %s unless the fence has a pending signal operation or is already signaled",
+ func_name, string_VkExternalFenceHandleTypeFlagBits(info->handleType));
+ }
+ }
+ return skip;
+}
+
+#ifdef VK_USE_PLATFORM_WIN32_KHR
+bool CoreChecks::PreCallValidateImportSemaphoreWin32HandleKHR(VkDevice device,
+ const VkImportSemaphoreWin32HandleInfoKHR *info) const {
+ bool skip = false;
+ const char *func_name = "vkImportSemaphoreWin32HandleKHR";
+ auto sem_state = Get<SEMAPHORE_STATE>(info->semaphore);
+ if (sem_state) {
+ skip |= ValidateObjectNotInUse(sem_state.get(), func_name, kVUIDUndefined);
+
+ if ((info->flags & VK_SEMAPHORE_IMPORT_TEMPORARY_BIT) != 0 && sem_state->type == VK_SEMAPHORE_TYPE_TIMELINE) {
+ skip |= LogError(
+ sem_state->Handle(), "VUID-VkImportSemaphoreWin32HandleInfoKHR-flags-03322",
+ "vkImportSemaphoreWin32HandleKHR(): VK_SEMAPHORE_IMPORT_TEMPORARY_BIT not allowed for timeline semaphores");
+ }
+ }
+ return skip;
+}
+
+bool CoreChecks::PreCallValidateGetSemaphoreWin32HandleKHR(VkDevice device, const VkSemaphoreGetWin32HandleInfoKHR *info,
+ HANDLE *pHandle) const {
+ bool skip = false;
+ const char *func_name = "vkGetSemaphoreWin32HandleKHR";
+ auto sem_state = Get<SEMAPHORE_STATE>(info->semaphore);
+ if (sem_state) {
+ if ((info->handleType & sem_state->exportHandleTypes) == 0) {
+ skip |= LogError(sem_state->Handle(), "VUID-VkSemaphoreGetWin32HandleInfoKHR-handleType-01126",
+ "%s: handleType %s was not VkExportSemaphoreCreateInfo::handleTypes (%s)", func_name,
+ string_VkExternalSemaphoreHandleTypeFlagBits(info->handleType),
+ string_VkExternalSemaphoreHandleTypeFlags(sem_state->exportHandleTypes).c_str());
+ }
+ }
+ return skip;
+}
+
+bool CoreChecks::PreCallValidateImportFenceWin32HandleKHR(
+ VkDevice device, const VkImportFenceWin32HandleInfoKHR *pImportFenceWin32HandleInfo) const {
+ return ValidateImportFence(pImportFenceWin32HandleInfo->fence, "VUID-vkImportFenceWin32HandleKHR-fence-04448",
+ "vkImportFenceWin32HandleKHR");
+}
+
+bool CoreChecks::PreCallValidateGetFenceWin32HandleKHR(VkDevice device, const VkFenceGetWin32HandleInfoKHR *info,
+ HANDLE *pHandle) const {
+ bool skip = false;
+ const char *func_name = "vkGetFenceWin32HandleKHR";
+ auto fence_state = Get<FENCE_STATE>(info->fence);
+ if (fence_state) {
+ if ((info->handleType & fence_state->exportHandleTypes) == 0) {
+ skip |= LogError(fence_state->Handle(), "VUID-VkFenceGetWin32HandleInfoKHR-handleType-01448",
+ "%s: handleType %s was not VkExportFenceCreateInfo::handleTypes (%s)", func_name,
+ string_VkExternalFenceHandleTypeFlagBits(info->handleType),
+ string_VkExternalFenceHandleTypeFlags(fence_state->exportHandleTypes).c_str());
+ }
+ }
+ return skip;
+}
+#endif // VK_USE_PLATFORM_WIN32_KHR
+
+#ifdef VK_USE_PLATFORM_FUCHSIA
+bool CoreChecks::PreCallValidateImportSemaphoreZirconHandleFUCHSIA(VkDevice device,
+ const VkImportSemaphoreZirconHandleInfoFUCHSIA *info) const {
+ bool skip = false;
+ const char *func_name = "vkImportSemaphoreZirconHandleFUCHSIA";
+ auto sem_state = Get<SEMAPHORE_STATE>(info->semaphore);
+ if (sem_state) {
+ skip |= ValidateObjectNotInUse(sem_state.get(), func_name, kVUIDUndefined);
+
+ if (sem_state->type == VK_SEMAPHORE_TYPE_TIMELINE) {
+ skip |=
+ LogError(sem_state->Handle(), "VUID-VkImportSemaphoreZirconHandleInfoFUCHSIA-semaphoreType-04768",
+ "%s(): VkSemaphoreTypeCreateInfo::semaphoreType field must not be VK_SEMAPHORE_TYPE_TIMELINE", func_name);
+ }
+ }
+ return skip;
+}
+
+void CoreChecks::PostCallRecordImportSemaphoreZirconHandleFUCHSIA(
+ VkDevice device, const VkImportSemaphoreZirconHandleInfoFUCHSIA *pImportSemaphoreZirconHandleInfo, VkResult result) {
+ if (VK_SUCCESS != result) return;
+ RecordImportSemaphoreState(pImportSemaphoreZirconHandleInfo->semaphore, pImportSemaphoreZirconHandleInfo->handleType,
+ pImportSemaphoreZirconHandleInfo->flags);
+}
+
+void CoreChecks::PostCallRecordGetSemaphoreZirconHandleFUCHSIA(VkDevice device,
+ const VkSemaphoreGetZirconHandleInfoFUCHSIA *pGetZirconHandleInfo,
+ zx_handle_t *pZirconHandle, VkResult result) {
+ if (VK_SUCCESS != result) return;
+ RecordGetExternalSemaphoreState(pGetZirconHandleInfo->semaphore, pGetZirconHandleInfo->handleType);
+}
+#endif
+
+#ifdef VK_USE_PLATFORM_METAL_EXT
+bool CoreChecks::PreCallValidateExportMetalObjectsEXT(VkDevice device, VkExportMetalObjectsInfoEXT *pMetalObjectsInfo) const {
+ bool skip = false;
+ const VkBaseOutStructure *metal_objects_info_ptr = reinterpret_cast<const VkBaseOutStructure *>(pMetalObjectsInfo->pNext);
+ while (metal_objects_info_ptr) {
+ switch (metal_objects_info_ptr->sType) {
+ case VK_STRUCTURE_TYPE_EXPORT_METAL_DEVICE_INFO_EXT:
+ if (std::find(instance_state->export_metal_flags.begin(), instance_state->export_metal_flags.end(),
+ VK_EXPORT_METAL_OBJECT_TYPE_METAL_DEVICE_BIT_EXT) == instance_state->export_metal_flags.end()) {
+ skip |= LogError(
+ device, "VUID-VkExportMetalObjectsInfoEXT-pNext-06791",
+ "ExportMetalObjectsEXT: pNext chain contains a VkExportMetalDeviceInfoEXT structure "
+ "but instance %s did not have a "
+ "VkExportMetalObjectCreateInfoEXT struct with exportObjectType of "
+ "VK_EXPORT_METAL_OBJECT_TYPE_METAL_DEVICE_BIT_EXT in the pNext chain of its VkInstanceCreateInfo structure",
+ report_data->FormatHandle(instance_state->instance).c_str());
+ }
+ break;
+
+ case VK_STRUCTURE_TYPE_EXPORT_METAL_COMMAND_QUEUE_INFO_EXT:
+ if (std::find(instance_state->export_metal_flags.begin(), instance_state->export_metal_flags.end(),
+ VK_EXPORT_METAL_OBJECT_TYPE_METAL_COMMAND_QUEUE_BIT_EXT) ==
+ instance_state->export_metal_flags.end()) {
+ skip |= LogError(device, "VUID-VkExportMetalObjectsInfoEXT-pNext-06792",
+ "ExportMetalObjectsEXT: pNext chain contains a VkExportMetalCommandQueueInfoEXT structure "
+ "but instance %s did not have a "
+ "VkExportMetalObjectCreateInfoEXT struct with exportObjectType of "
+ "VK_EXPORT_METAL_OBJECT_TYPE_METAL_COMMAND_QUEUE_BIT_EXT in the pNext chain of its "
+ "VkInstanceCreateInfo structure",
+ report_data->FormatHandle(instance_state->instance).c_str());
+ }
+ break;
+
+ case VK_STRUCTURE_TYPE_EXPORT_METAL_BUFFER_INFO_EXT: {
+ auto metal_buffer_ptr = reinterpret_cast<const VkExportMetalBufferInfoEXT *>(metal_objects_info_ptr);
+ auto mem_info = Get<DEVICE_MEMORY_STATE>(metal_buffer_ptr->memory);
+ if (mem_info) {
+ if (!mem_info->metal_buffer_export) {
+ skip |= LogError(
+ device, "VUID-VkExportMetalObjectsInfoEXT-pNext-06793",
+ "ExportMetalObjectsEXT: pNext chain contains a VkExportMetalBufferInfoEXT structure with memory = "
+ "%s, but that memory was not allocated with a VkExportMetalObjectCreateInfoEXT whose exportObjectType "
+ "member was set to VK_EXPORT_METAL_OBJECT_TYPE_METAL_BUFFER_BIT_EXT in the pNext chain of the "
+ "VkMemoryAllocateInfo structure",
+ report_data->FormatHandle(metal_buffer_ptr->memory).c_str());
+ }
+ }
+ } break;
+
+ case VK_STRUCTURE_TYPE_EXPORT_METAL_TEXTURE_INFO_EXT: {
+ auto metal_texture_ptr = reinterpret_cast<const VkExportMetalTextureInfoEXT *>(metal_objects_info_ptr);
+ if ((metal_texture_ptr->image == VK_NULL_HANDLE && metal_texture_ptr->imageView == VK_NULL_HANDLE &&
+ metal_texture_ptr->bufferView == VK_NULL_HANDLE) ||
+ (metal_texture_ptr->image &&
+ ((metal_texture_ptr->imageView != VK_NULL_HANDLE) || (metal_texture_ptr->bufferView != VK_NULL_HANDLE))) ||
+ (metal_texture_ptr->imageView &&
+ ((metal_texture_ptr->image != VK_NULL_HANDLE) || (metal_texture_ptr->bufferView != VK_NULL_HANDLE))) ||
+ (metal_texture_ptr->bufferView &&
+ ((metal_texture_ptr->image != VK_NULL_HANDLE) || (metal_texture_ptr->imageView != VK_NULL_HANDLE)))) {
+ skip |=
+ LogError(device, "VUID-VkExportMetalObjectsInfoEXT-pNext-06794",
+ "ExportMetalObjectsEXT: pNext chain contains a VkExportMetalTextureInfoEXT structure with image = "
+ "%s, imageView = %s and bufferView = %s, but exactly one of those 3 must not be VK_NULL_HANDLE",
+ report_data->FormatHandle(metal_texture_ptr->image).c_str(),
+ report_data->FormatHandle(metal_texture_ptr->imageView).c_str(),
+ report_data->FormatHandle(metal_texture_ptr->bufferView).c_str());
+ }
+ if (metal_texture_ptr->image) {
+ auto image_info = Get<IMAGE_STATE>(metal_texture_ptr->image);
+ if (image_info) {
+ if (!image_info->metal_image_export) {
+ skip |= LogError(
+ device, "VUID-VkExportMetalObjectsInfoEXT-pNext-06795",
+ "ExportMetalObjectsEXT: pNext chain contains a VkExportMetalTextureInfoEXT structure with image = "
+ "%s, but that image was not created with a VkExportMetalObjectCreateInfoEXT whose exportObjectType "
+ "member was set to VK_EXPORT_METAL_OBJECT_TYPE_METAL_TEXTURE_BIT_EXT in the pNext chain of the "
+ "VkImageCreateInfo structure",
+ report_data->FormatHandle(metal_texture_ptr->image).c_str());
+ }
+ auto format_plane_count = FormatPlaneCount(image_info->createInfo.format);
+ auto image_plane = metal_texture_ptr->plane;
+ if (!(format_plane_count > 1) && (image_plane != VK_IMAGE_ASPECT_PLANE_0_BIT)) {
+ skip |= LogError(
+ device, "VUID-VkExportMetalObjectsInfoEXT-pNext-06799",
+ "ExportMetalObjectsEXT: pNext chain contains a VkExportMetalTextureInfoEXT structure with image = "
+ "%s, and plane = %s, but image was created with format %s, which is not multiplaner and plane is "
+ "required to be VK_IMAGE_ASPECT_PLANE_0_BIT",
+ report_data->FormatHandle(metal_texture_ptr->image).c_str(),
+ string_VkImageAspectFlags(image_plane).c_str(), string_VkFormat(image_info->createInfo.format));
+ }
+ if ((format_plane_count == 2) && (image_plane == VK_IMAGE_ASPECT_PLANE_2_BIT)) {
+ skip |= LogError(
+ device, "VUID-VkExportMetalObjectsInfoEXT-pNext-06800",
+ "ExportMetalObjectsEXT: pNext chain contains a VkExportMetalTextureInfoEXT structure with image = "
+ "%s, and plane = %s, but image was created with format %s, which has exactly 2 planes and plane "
+ "cannot"
+ "be VK_IMAGE_ASPECT_PLANE_2_BIT",
+ report_data->FormatHandle(metal_texture_ptr->image).c_str(),
+ string_VkImageAspectFlags(image_plane).c_str(), string_VkFormat(image_info->createInfo.format));
+ }
+ }
+ }
+ if (metal_texture_ptr->imageView) {
+ auto image_view_info = Get<IMAGE_VIEW_STATE>(metal_texture_ptr->imageView);
+ if (image_view_info) {
+ if (!image_view_info->metal_imageview_export) {
+ skip |= LogError(
+ device, "VUID-VkExportMetalObjectsInfoEXT-pNext-06796",
+ "ExportMetalObjectsEXT: pNext chain contains a VkExportMetalTextureInfoEXT structure with "
+ "imageView = "
+ "%s, but that image view was not created with a VkExportMetalObjectCreateInfoEXT whose "
+ "exportObjectType "
+ "member was set to VK_EXPORT_METAL_OBJECT_TYPE_METAL_TEXTURE_BIT_EXT in the pNext chain of the "
+ "VkImageViewCreateInfo structure",
+ report_data->FormatHandle(metal_texture_ptr->imageView).c_str());
+ }
+ auto format_plane_count = FormatPlaneCount(image_view_info->create_info.format);
+ auto image_plane = metal_texture_ptr->plane;
+ if (!(format_plane_count > 1) && (image_plane != VK_IMAGE_ASPECT_PLANE_0_BIT)) {
+ skip |= LogError(
+ device, "VUID-VkExportMetalObjectsInfoEXT-pNext-06801",
+ "ExportMetalObjectsEXT: pNext chain contains a VkExportMetalTextureInfoEXT structure with "
+ "imageView = "
+ "%s, and plane = %s, but imageView was created with format %s, which is not multiplaner and "
+ "plane is "
+ "required to be VK_IMAGE_ASPECT_PLANE_0_BIT",
+ report_data->FormatHandle(metal_texture_ptr->imageView).c_str(),
+ string_VkImageAspectFlags(image_plane).c_str(),
+ string_VkFormat(image_view_info->create_info.format));
+ }
+ if ((format_plane_count == 2) && (image_plane == VK_IMAGE_ASPECT_PLANE_2_BIT)) {
+ skip |= LogError(device, "VUID-VkExportMetalObjectsInfoEXT-pNext-06802",
+ "ExportMetalObjectsEXT: pNext chain contains a VkExportMetalTextureInfoEXT structure "
+ "with imageView = "
+ "%s, and plane = %s, but imageView was created with format %s, which has exactly 2 "
+ "planes and plane "
+ "cannot"
+ "be VK_IMAGE_ASPECT_PLANE_2_BIT",
+ report_data->FormatHandle(metal_texture_ptr->imageView).c_str(),
+ string_VkImageAspectFlags(image_plane).c_str(),
+ string_VkFormat(image_view_info->create_info.format));
+ }
+ }
+ }
+ if (metal_texture_ptr->bufferView) {
+ auto buffer_view_info = Get<BUFFER_VIEW_STATE>(metal_texture_ptr->bufferView);
+ if (buffer_view_info) {
+ if (!buffer_view_info->metal_bufferview_export) {
+ skip |= LogError(
+ device, "VUID-VkExportMetalObjectsInfoEXT-pNext-06797",
+ "ExportMetalObjectsEXT: pNext chain contains a VkExportMetalTextureInfoEXT structure with "
+ "bufferView = "
+ "%s, but that buffer view was not created with a VkExportMetalObjectCreateInfoEXT whose "
+ "exportObjectType "
+ "member was set to VK_EXPORT_METAL_OBJECT_TYPE_METAL_TEXTURE_BIT_EXT in the pNext chain of the "
+ "VkBufferViewCreateInfo structure",
+ report_data->FormatHandle(metal_texture_ptr->bufferView).c_str());
+ }
+ }
+ }
+ if (metal_texture_ptr->image || metal_texture_ptr->imageView) {
+ if ((metal_texture_ptr->plane != VK_IMAGE_ASPECT_PLANE_0_BIT) &&
+ (metal_texture_ptr->plane != VK_IMAGE_ASPECT_PLANE_1_BIT) &&
+ (metal_texture_ptr->plane != VK_IMAGE_ASPECT_PLANE_2_BIT)) {
+ skip |= LogError(
+ device, "VUID-VkExportMetalObjectsInfoEXT-pNext-06798",
+ "ExportMetalObjectsEXT: pNext chain contains a VkExportMetalTextureInfoEXT structure with "
+ "image = %s and imageView = "
+ "%s, but plane = %s which is not one of VK_IMAGE_ASPECT_PLANE_0_BIT, VK_IMAGE_ASPECT_PLANE_1_BIT, "
+ "or VK_IMAGE_ASPECT_PLANE_2_BIT",
+ report_data->FormatHandle(metal_texture_ptr->image).c_str(),
+ report_data->FormatHandle(metal_texture_ptr->imageView).c_str(),
+ string_VkImageAspectFlags(metal_texture_ptr->plane).c_str());
+ }
+ }
+ } break;
+
+ case VK_STRUCTURE_TYPE_EXPORT_METAL_IO_SURFACE_INFO_EXT: {
+ auto metal_io_surface_ptr = reinterpret_cast<const VkExportMetalIOSurfaceInfoEXT *>(metal_objects_info_ptr);
+ auto image_info = Get<IMAGE_STATE>(metal_io_surface_ptr->image);
+ if (image_info) {
+ if (!image_info->metal_io_surface_export) {
+ skip |= LogError(
+ device, "VUID-VkExportMetalObjectsInfoEXT-pNext-06803",
+ "ExportMetalObjectsEXT: pNext chain contains a VkExportMetalIOSurfaceInfoEXT structure with image = "
+ "%s, but that image was not created with a VkExportMetalObjectCreateInfoEXT whose exportObjectType "
+ "member was set to VK_EXPORT_METAL_OBJECT_TYPE_METAL_IOSURFACE_BIT_EXT in the pNext chain of the "
+ "VkImageCreateInfo structure",
+ report_data->FormatHandle(metal_io_surface_ptr->image).c_str());
+ }
+ }
+ } break;
+
+ case VK_STRUCTURE_TYPE_EXPORT_METAL_SHARED_EVENT_INFO_EXT: {
+ auto metal_shared_event_ptr = reinterpret_cast<const VkExportMetalSharedEventInfoEXT *>(metal_objects_info_ptr);
+ if ((metal_shared_event_ptr->event == VK_NULL_HANDLE && metal_shared_event_ptr->semaphore == VK_NULL_HANDLE) ||
+ (metal_shared_event_ptr->event != VK_NULL_HANDLE && metal_shared_event_ptr->semaphore != VK_NULL_HANDLE)) {
+ skip |= LogError(
+ device, "VUID-VkExportMetalObjectsInfoEXT-pNext-06804",
+ "ExportMetalObjectsEXT: pNext chain contains a VkExportMetalSharedEventInfoEXT structure with semaphore = "
+ "%s, and event = %s, but exactly one of them must not be VK_NULL_HANDLE",
+ report_data->FormatHandle(metal_shared_event_ptr->semaphore).c_str(),
+ report_data->FormatHandle(metal_shared_event_ptr->event).c_str());
+ }
+
+ if (metal_shared_event_ptr->semaphore) {
+ auto semaphore_info = Get<SEMAPHORE_STATE>(metal_shared_event_ptr->semaphore);
+ if (semaphore_info && !(semaphore_info->metal_semaphore_export)) {
+ skip |= LogError(
+ device, "VUID-VkExportMetalObjectsInfoEXT-pNext-06805",
+ "ExportMetalObjectsEXT: pNext chain contains a VkExportMetalSharedEventInfoEXT structure "
+ "with semaphore = "
+ "%s, but that semaphore was not created with a VkExportMetalObjectCreateInfoEXT whose exportObjectType "
+ "member was set to VK_EXPORT_METAL_OBJECT_TYPE_METAL_SHARED_EVENT_BIT_EXT in the pNext chain of the "
+ "VkSemaphoreCreateInfo structure",
+ report_data->FormatHandle(metal_shared_event_ptr->semaphore).c_str());
+ }
+ }
+ if (metal_shared_event_ptr->event) {
+ auto event_info = Get<EVENT_STATE>(metal_shared_event_ptr->event);
+ if (event_info && !(event_info->metal_event_export)) {
+ skip |= LogError(
+ device, "VUID-VkExportMetalObjectsInfoEXT-pNext-06806",
+ "ExportMetalObjectsEXT: pNext chain contains a VkExportMetalSharedEventInfoEXT structure "
+ "with event = "
+ "%s, but that event was not created with a VkExportMetalObjectCreateInfoEXT whose exportObjectType "
+ "member was set to VK_EXPORT_METAL_OBJECT_TYPE_METAL_SHARED_EVENT_BIT_EXT in the pNext chain of the "
+ "VkEventCreateInfo structure",
+ report_data->FormatHandle(metal_shared_event_ptr->event).c_str());
+ }
+ }
+ } break;
+ default:
+ break;
+ }
+ metal_objects_info_ptr = metal_objects_info_ptr->pNext;
+ }
+ return skip;
+}
+#endif // VK_USE_PLATFORM_METAL_EXT
diff --git a/scripts/vk_validation_stats.py b/scripts/vk_validation_stats.py
index 69dde4dd5..8abec30f9 100755
--- a/scripts/vk_validation_stats.py
+++ b/scripts/vk_validation_stats.py
@@ -53,6 +53,7 @@ layer_source_files = [common_codegen.repo_relative(path) for path in [
'layers/device_validation.cpp',
'layers/device_memory_validation.cpp',
'layers/drawdispatch.cpp',
+ 'layers/external_object_validation.cpp',
'layers/gpu_vuids.h',
'layers/parameter_validation_utils.cpp',
'layers/pipeline_validation.cpp',