blob: d2f97908dd700e2efaa0d67772c7ba5c9016c467 [file] [log] [blame]
/* 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.
*/
#include <vulkan/vk_enum_string_helper.h>
#include "generated/chassis.h"
#include "core_validation.h"
bool CoreChecks::PreCallValidateGetMemoryFdKHR(VkDevice device, const VkMemoryGetFdInfoKHR *pGetFdInfo, int *pFd,
const ErrorObject &error_obj) const {
bool skip = false;
if (const auto memory_state = Get<DEVICE_MEMORY_STATE>(pGetFdInfo->memory)) {
const auto export_info = vku::FindStructInPNextChain<VkExportMemoryAllocateInfo>(memory_state->alloc_info.pNext);
if (!export_info) {
skip |= LogError("VUID-VkMemoryGetFdInfoKHR-handleType-00671", pGetFdInfo->memory,
error_obj.location.dot(Field::pGetFdInfo).dot(Field::memory),
"pNext chain does not include a VkExportMemoryAllocateInfo structure.");
} else if ((export_info->handleTypes & pGetFdInfo->handleType) == 0) {
skip |= LogError("VUID-VkMemoryGetFdInfoKHR-handleType-00671", pGetFdInfo->memory,
error_obj.location.dot(Field::pGetFdInfo).dot(Field::memory),
"the requested handle type (%s) is not included in the memory's "
"VkExportMemoryAllocateInfo::handleTypes (%s).",
string_VkExternalMemoryHandleTypeFlagBits(pGetFdInfo->handleType),
string_VkExternalMemoryHandleTypeFlags(export_info->handleTypes).c_str());
}
}
return skip;
}
bool CoreChecks::PreCallValidateImportSemaphoreFdKHR(VkDevice device, const VkImportSemaphoreFdInfoKHR *info,
const ErrorObject &error_obj) const {
bool skip = false;
auto sem_state = Get<SEMAPHORE_STATE>(info->semaphore);
if (sem_state) {
skip |= ValidateObjectNotInUse(sem_state.get(), error_obj.location, "VUID-vkImportSemaphoreFdKHR-semaphore-01142");
if ((info->flags & VK_SEMAPHORE_IMPORT_TEMPORARY_BIT) != 0 && sem_state->type == VK_SEMAPHORE_TYPE_TIMELINE) {
skip |= LogError("VUID-VkImportSemaphoreFdInfoKHR-flags-03323", sem_state->Handle(),
error_obj.location.dot(Field::info).dot(Field::flags),
"includes VK_SEMAPHORE_IMPORT_TEMPORARY_BIT and semaphore is VK_SEMAPHORE_TYPE_TIMELINE.");
}
}
return skip;
}
bool CoreChecks::PreCallValidateGetSemaphoreFdKHR(VkDevice device, const VkSemaphoreGetFdInfoKHR *info, int *pFd,
const ErrorObject &error_obj) const {
bool skip = false;
auto sem_state = Get<SEMAPHORE_STATE>(info->semaphore);
if (sem_state) {
if ((info->handleType & sem_state->exportHandleTypes) == 0) {
skip |= LogError("VUID-VkSemaphoreGetFdInfoKHR-handleType-01132", sem_state->Handle(),
error_obj.location.dot(Field::info).dot(Field::handleType),
"(%s) is different from VkExportSemaphoreCreateInfo::handleTypes (%s).",
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("VUID-VkSemaphoreGetFdInfoKHR-handleType-03253", sem_state->Handle(),
error_obj.location.dot(Field::info).dot(Field::handleType),
"is VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT, but semaphore type is %s.",
string_VkSemaphoreType(sem_state->type));
}
if (!sem_state->CanBeWaited()) {
skip |= LogError("VUID-VkSemaphoreGetFdInfoKHR-handleType-03254", sem_state->Handle(),
error_obj.location.dot(Field::info).dot(Field::semaphore),
"must be signaled or have a pending signal operation.");
}
}
}
return skip;
}
bool CoreChecks::ValidateImportFence(VkFence fence, const char *vuid, const Location &loc) 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(vuid, fence, loc.dot(Field::fence), "(%s) is currently in use.", FormatHandle(fence).c_str());
}
return skip;
}
bool CoreChecks::PreCallValidateImportFenceFdKHR(VkDevice device, const VkImportFenceFdInfoKHR *pImportFenceFdInfo,
const ErrorObject &error_obj) const {
return ValidateImportFence(pImportFenceFdInfo->fence, "VUID-vkImportFenceFdKHR-fence-01463",
error_obj.location.dot(Field::pImportFenceFdInfo));
}
bool CoreChecks::PreCallValidateGetFenceFdKHR(VkDevice device, const VkFenceGetFdInfoKHR *info, int *pFd,
const ErrorObject &error_obj) const {
bool skip = false;
auto fence_state = Get<FENCE_STATE>(info->fence);
if (fence_state) {
if ((info->handleType & fence_state->exportHandleTypes) == 0) {
skip |= LogError("VUID-VkFenceGetFdInfoKHR-handleType-01453", fence_state->Handle(),
error_obj.location.dot(Field::info).dot(Field::handleType),
"(%s) is different from VkExportFenceCreateInfo::handleTypes (%s). ",
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("VUID-VkFenceGetFdInfoKHR-handleType-01454", fence_state->Handle(),
error_obj.location.dot(Field::info).dot(Field::handleType),
"is VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT which cannot be exported unless the fence has a pending "
"signal operation or is already signaled.");
}
}
return skip;
}
#ifdef VK_USE_PLATFORM_WIN32_KHR
bool CoreChecks::PreCallValidateImportSemaphoreWin32HandleKHR(VkDevice device, const VkImportSemaphoreWin32HandleInfoKHR *info,
const ErrorObject &error_obj) const {
bool skip = false;
auto sem_state = Get<SEMAPHORE_STATE>(info->semaphore);
if (sem_state) {
// Waiting for: https://gitlab.khronos.org/vulkan/vulkan/-/issues/3507
skip |= ValidateObjectNotInUse(sem_state.get(), error_obj.location, kVUIDUndefined);
if ((info->flags & VK_SEMAPHORE_IMPORT_TEMPORARY_BIT) != 0 && sem_state->type == VK_SEMAPHORE_TYPE_TIMELINE) {
skip |= LogError("VUID-VkImportSemaphoreWin32HandleInfoKHR-flags-03322", sem_state->Handle(),
error_obj.location.dot(Field::info).dot(Field::semaphore),
"includes VK_SEMAPHORE_IMPORT_TEMPORARY_BIT and semaphore is VK_SEMAPHORE_TYPE_TIMELINE.");
}
}
return skip;
}
bool CoreChecks::PreCallValidateGetSemaphoreWin32HandleKHR(VkDevice device, const VkSemaphoreGetWin32HandleInfoKHR *info,
HANDLE *pHandle, const ErrorObject &error_obj) const {
bool skip = false;
auto sem_state = Get<SEMAPHORE_STATE>(info->semaphore);
if (sem_state) {
if ((info->handleType & sem_state->exportHandleTypes) == 0) {
skip |= LogError("VUID-VkSemaphoreGetWin32HandleInfoKHR-handleType-01126", sem_state->Handle(),
error_obj.location.dot(Field::info).dot(Field::handleType),
"(%s) is different from VkExportSemaphoreCreateInfo::handleTypes (%s)",
string_VkExternalSemaphoreHandleTypeFlagBits(info->handleType),
string_VkExternalSemaphoreHandleTypeFlags(sem_state->exportHandleTypes).c_str());
}
}
return skip;
}
bool CoreChecks::PreCallValidateImportFenceWin32HandleKHR(VkDevice device,
const VkImportFenceWin32HandleInfoKHR *pImportFenceWin32HandleInfo,
const ErrorObject &error_obj) const {
return ValidateImportFence(pImportFenceWin32HandleInfo->fence, "VUID-vkImportFenceWin32HandleKHR-fence-04448",
error_obj.location.dot(Field::pImportFenceWin32HandleInfo));
}
bool CoreChecks::PreCallValidateGetFenceWin32HandleKHR(VkDevice device, const VkFenceGetWin32HandleInfoKHR *info, HANDLE *pHandle,
const ErrorObject &error_obj) const {
bool skip = false;
auto fence_state = Get<FENCE_STATE>(info->fence);
if (fence_state) {
if ((info->handleType & fence_state->exportHandleTypes) == 0) {
skip |= LogError("VUID-VkFenceGetWin32HandleInfoKHR-handleType-01448", fence_state->Handle(),
error_obj.location.dot(Field::info).dot(Field::handleType),
"(%s) is different from VkExportFenceCreateInfo::handleTypes (%s)",
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 ErrorObject &error_obj) const {
bool skip = false;
auto sem_state = Get<SEMAPHORE_STATE>(info->semaphore);
if (sem_state) {
skip |= ValidateObjectNotInUse(sem_state.get(), error_obj.location,
"VUID-vkImportSemaphoreZirconHandleFUCHSIA-semaphore-04764");
if (sem_state->type == VK_SEMAPHORE_TYPE_TIMELINE) {
skip |=
LogError("VUID-VkImportSemaphoreZirconHandleInfoFUCHSIA-semaphoreType-04768", sem_state->Handle(),
error_obj.location.dot(Field::info).dot(Field::semaphore), "was created with VK_SEMAPHORE_TYPE_TIMELINE.");
}
}
return skip;
}
void CoreChecks::PostCallRecordImportSemaphoreZirconHandleFUCHSIA(
VkDevice device, const VkImportSemaphoreZirconHandleInfoFUCHSIA *pImportSemaphoreZirconHandleInfo,
const RecordObject &record_obj) {
if (VK_SUCCESS != record_obj.result) return;
RecordImportSemaphoreState(pImportSemaphoreZirconHandleInfo->semaphore, pImportSemaphoreZirconHandleInfo->handleType,
pImportSemaphoreZirconHandleInfo->flags);
}
void CoreChecks::PostCallRecordGetSemaphoreZirconHandleFUCHSIA(VkDevice device,
const VkSemaphoreGetZirconHandleInfoFUCHSIA *pGetZirconHandleInfo,
zx_handle_t *pZirconHandle, const RecordObject &record_obj) {
if (VK_SUCCESS != record_obj.result) return;
RecordGetExternalSemaphoreState(pGetZirconHandleInfo->semaphore, pGetZirconHandleInfo->handleType);
}
#endif
#ifdef VK_USE_PLATFORM_METAL_EXT
bool CoreChecks::PreCallValidateExportMetalObjectsEXT(VkDevice device, VkExportMetalObjectsInfoEXT *pMetalObjectsInfo,
const ErrorObject &error_obj) 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(
"VUID-VkExportMetalObjectsInfoEXT-pNext-06791", device, error_obj.location,
"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",
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("VUID-VkExportMetalObjectsInfoEXT-pNext-06792", device, error_obj.location,
"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",
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(
"VUID-VkExportMetalObjectsInfoEXT-pNext-06793", device, error_obj.location,
"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",
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("VUID-VkExportMetalObjectsInfoEXT-pNext-06794", device, error_obj.location,
"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",
FormatHandle(metal_texture_ptr->image).c_str(), FormatHandle(metal_texture_ptr->imageView).c_str(),
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(
"VUID-VkExportMetalObjectsInfoEXT-pNext-06795", device, error_obj.location,
"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",
FormatHandle(metal_texture_ptr->image).c_str());
}
auto format_plane_count = vkuFormatPlaneCount(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(
"VUID-VkExportMetalObjectsInfoEXT-pNext-06799", device, error_obj.location,
"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",
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(
"VUID-VkExportMetalObjectsInfoEXT-pNext-06800", device, error_obj.location,
"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",
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(
"VUID-VkExportMetalObjectsInfoEXT-pNext-06796", device, error_obj.location,
"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",
FormatHandle(metal_texture_ptr->imageView).c_str());
}
auto format_plane_count = vkuFormatPlaneCount(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(
"VUID-VkExportMetalObjectsInfoEXT-pNext-06801", device, error_obj.location,
"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",
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("VUID-VkExportMetalObjectsInfoEXT-pNext-06802", device, error_obj.location,
"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",
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(
"VUID-VkExportMetalObjectsInfoEXT-pNext-06797", device, error_obj.location,
"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",
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(
"VUID-VkExportMetalObjectsInfoEXT-pNext-06798", device, error_obj.location,
"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",
FormatHandle(metal_texture_ptr->image).c_str(), 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(
"VUID-VkExportMetalObjectsInfoEXT-pNext-06803", device, error_obj.location,
"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",
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("VUID-VkExportMetalObjectsInfoEXT-pNext-06804", device, error_obj.location,
"pNext chain contains a VkExportMetalSharedEventInfoEXT structure with semaphore = "
"%s, and event = %s, but exactly one of them must not be VK_NULL_HANDLE",
FormatHandle(metal_shared_event_ptr->semaphore).c_str(),
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(
"VUID-VkExportMetalObjectsInfoEXT-pNext-06805", device, error_obj.location,
"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",
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(
"VUID-VkExportMetalObjectsInfoEXT-pNext-06806", device, error_obj.location,
"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",
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