blob: 3dac75c6708fadea4a54830759cd7b149dc70374 [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.
*
* 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 "stateless/stateless_validation.h"
#include "generated/enum_flag_bits.h"
bool StatelessValidation::manual_PreCallValidateGetMemoryFdKHR(VkDevice device, const VkMemoryGetFdInfoKHR *pGetFdInfo, int *pFd,
const ErrorObject &error_obj) const {
constexpr auto allowed_types = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT | VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT;
bool skip = false;
if (0 == (pGetFdInfo->handleType & allowed_types)) {
skip |= LogError("VUID-VkMemoryGetFdInfoKHR-handleType-00672", pGetFdInfo->memory, error_obj.location,
"handle type %s is not one of the supported handle types.",
string_VkExternalMemoryHandleTypeFlagBits(pGetFdInfo->handleType));
}
return skip;
}
bool StatelessValidation::manual_PreCallValidateGetMemoryFdPropertiesKHR(VkDevice device,
VkExternalMemoryHandleTypeFlagBits handleType, int fd,
VkMemoryFdPropertiesKHR *pMemoryFdProperties,
const ErrorObject &error_obj) const {
bool skip = false;
if (fd < 0) {
skip |= LogError("VUID-vkGetMemoryFdPropertiesKHR-fd-00673", device, error_obj.location,
"fd handle (%d) is not a valid POSIX file descriptor.", fd);
}
if (handleType == VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT) {
skip |= LogError("VUID-vkGetMemoryFdPropertiesKHR-handleType-00674", device, error_obj.location,
"opaque handle type %s is not allowed.", string_VkExternalMemoryHandleTypeFlagBits(handleType));
}
return skip;
}
bool StatelessValidation::ValidateExternalSemaphoreHandleType(VkSemaphore semaphore, const char *vuid,
const Location &handle_type_loc,
VkExternalSemaphoreHandleTypeFlagBits handle_type,
VkExternalSemaphoreHandleTypeFlags allowed_types) const {
bool skip = false;
if (0 == (handle_type & allowed_types)) {
skip |= LogError(vuid, semaphore, handle_type_loc, "%s is not one of the supported handleTypes (%s).",
string_VkExternalSemaphoreHandleTypeFlagBits(handle_type),
string_VkExternalSemaphoreHandleTypeFlags(allowed_types).c_str());
}
return skip;
}
bool StatelessValidation::ValidateExternalFenceHandleType(VkFence fence, const char *vuid, const Location &handle_type_loc,
VkExternalFenceHandleTypeFlagBits handle_type,
VkExternalFenceHandleTypeFlags allowed_types) const {
bool skip = false;
if (0 == (handle_type & allowed_types)) {
skip |= LogError(vuid, fence, handle_type_loc, "%s is not one of the supported handleTypes (%s).",
string_VkExternalFenceHandleTypeFlagBits(handle_type),
string_VkExternalFenceHandleTypeFlags(allowed_types).c_str());
}
return skip;
}
static constexpr VkExternalSemaphoreHandleTypeFlags kSemFdHandleTypes =
VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT | VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT;
bool StatelessValidation::manual_PreCallValidateGetSemaphoreFdKHR(VkDevice device, const VkSemaphoreGetFdInfoKHR *info, int *pFd,
const ErrorObject &error_obj) const {
return ValidateExternalSemaphoreHandleType(info->semaphore, "VUID-VkSemaphoreGetFdInfoKHR-handleType-01136",
error_obj.location.dot(Field::info).dot(Field::handleType), info->handleType,
kSemFdHandleTypes);
}
bool StatelessValidation::manual_PreCallValidateImportSemaphoreFdKHR(VkDevice device, const VkImportSemaphoreFdInfoKHR *info,
const ErrorObject &error_obj) const {
bool skip = false;
skip |= ValidateExternalSemaphoreHandleType(info->semaphore, "VUID-VkImportSemaphoreFdInfoKHR-handleType-01143",
error_obj.location.dot(Field::info).dot(Field::handleType), info->handleType,
kSemFdHandleTypes);
if (info->handleType == VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT &&
(info->flags & VK_SEMAPHORE_IMPORT_TEMPORARY_BIT) == 0) {
skip |= LogError("VUID-VkImportSemaphoreFdInfoKHR-handleType-07307", info->semaphore, error_obj.location.dot(Field::info),
"handleType is VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT so"
" VK_SEMAPHORE_IMPORT_TEMPORARY_BIT must be set, but flags is 0x%x",
info->flags);
}
return skip;
}
static constexpr VkExternalFenceHandleTypeFlags kFenceFdHandleTypes =
VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_FD_BIT | VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT;
bool StatelessValidation::manual_PreCallValidateGetFenceFdKHR(VkDevice device, const VkFenceGetFdInfoKHR *info, int *pFd,
const ErrorObject &error_obj) const {
return ValidateExternalFenceHandleType(info->fence, "VUID-VkFenceGetFdInfoKHR-handleType-01456",
error_obj.location.dot(Field::info).dot(Field::handleType), info->handleType,
kFenceFdHandleTypes);
}
bool StatelessValidation::manual_PreCallValidateImportFenceFdKHR(VkDevice device, const VkImportFenceFdInfoKHR *info,
const ErrorObject &error_obj) const {
bool skip = false;
skip |= ValidateExternalFenceHandleType(info->fence, "VUID-VkImportFenceFdInfoKHR-handleType-01464",
error_obj.location.dot(Field::info).dot(Field::handleType), info->handleType,
kFenceFdHandleTypes);
if (info->handleType == VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT && (info->flags & VK_FENCE_IMPORT_TEMPORARY_BIT) == 0) {
skip |= LogError("VUID-VkImportFenceFdInfoKHR-handleType-07306", info->fence, error_obj.location.dot(Field::info),
"handleType is VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT so"
" VK_FENCE_IMPORT_TEMPORARY_BIT must be set, but flags is 0x%x",
info->flags);
}
return skip;
}
#ifdef VK_USE_PLATFORM_WIN32_KHR
bool StatelessValidation::manual_PreCallValidateGetMemoryWin32HandlePropertiesKHR(
VkDevice device, VkExternalMemoryHandleTypeFlagBits handleType, HANDLE handle,
VkMemoryWin32HandlePropertiesKHR *pMemoryWin32HandleProperties, const ErrorObject &error_obj) const {
bool skip = false;
if (handle == NULL || handle == INVALID_HANDLE_VALUE) {
static_assert(sizeof(HANDLE) == sizeof(uintptr_t)); // to use PRIxPTR for HANDLE formatting
skip |= LogError("VUID-vkGetMemoryWin32HandlePropertiesKHR-handle-00665", device, error_obj.location.dot(Field::handle),
"(0x%" PRIxPTR ") is not a valid Windows handle.", reinterpret_cast<std::uintptr_t>(handle));
}
if (handleType == VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT ||
handleType == VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT) {
skip |=
LogError("VUID-vkGetMemoryWin32HandlePropertiesKHR-handleType-00666", device, error_obj.location.dot(Field::handleType),
"%s is not allowed.", string_VkExternalMemoryHandleTypeFlagBits(handleType));
}
return skip;
}
static constexpr VkExternalSemaphoreHandleTypeFlags kSemWin32HandleTypes = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT |
VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT |
VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_D3D12_FENCE_BIT;
bool StatelessValidation::manual_PreCallValidateImportSemaphoreWin32HandleKHR(VkDevice device,
const VkImportSemaphoreWin32HandleInfoKHR *info,
const ErrorObject &error_obj) const {
bool skip = false;
skip |= ValidateExternalSemaphoreHandleType(info->semaphore, "VUID-VkImportSemaphoreWin32HandleInfoKHR-handleType-01140",
error_obj.location.dot(Field::info).dot(Field::handleType), info->handleType,
kSemWin32HandleTypes);
static constexpr auto kNameAllowedTypes =
VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT | VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_D3D12_FENCE_BIT;
if ((info->handleType & kNameAllowedTypes) == 0 && info->name) {
skip |=
LogError("VUID-VkImportSemaphoreWin32HandleInfoKHR-handleType-01466", info->semaphore,
error_obj.location.dot(Field::info).dot(Field::name), "(%p) must be NULL if handleType is %s",
reinterpret_cast<const void *>(info->name), string_VkExternalSemaphoreHandleTypeFlagBits(info->handleType));
}
if (info->handle && info->name) {
skip |=
LogError("VUID-VkImportSemaphoreWin32HandleInfoKHR-handle-01469", info->semaphore, error_obj.location.dot(Field::info),
"both handle (%p) and name (%p) are non-NULL", info->handle, reinterpret_cast<const void *>(info->name));
}
return skip;
}
bool StatelessValidation::manual_PreCallValidateGetSemaphoreWin32HandleKHR(VkDevice device,
const VkSemaphoreGetWin32HandleInfoKHR *info,
HANDLE *pHandle, const ErrorObject &error_obj) const {
return ValidateExternalSemaphoreHandleType(info->semaphore, "VUID-VkSemaphoreGetWin32HandleInfoKHR-handleType-01131",
error_obj.location.dot(Field::info).dot(Field::handleType), info->handleType,
kSemWin32HandleTypes);
}
static constexpr VkExternalFenceHandleTypeFlags kFenceWin32HandleTypes =
VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_BIT | VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT;
bool StatelessValidation::manual_PreCallValidateImportFenceWin32HandleKHR(VkDevice device,
const VkImportFenceWin32HandleInfoKHR *info,
const ErrorObject &error_obj) const {
bool skip = false;
skip |= ValidateExternalFenceHandleType(info->fence, "VUID-VkImportFenceWin32HandleInfoKHR-handleType-01457",
error_obj.location.dot(Field::info).dot(Field::handleType), info->handleType,
kFenceWin32HandleTypes);
static constexpr auto kNameAllowedTypes = VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_BIT;
if ((info->handleType & kNameAllowedTypes) == 0 && info->name) {
skip |= LogError("VUID-VkImportFenceWin32HandleInfoKHR-handleType-01459", info->fence,
error_obj.location.dot(Field::info).dot(Field::name), "(%p) must be NULL if handleType is %s",
reinterpret_cast<const void *>(info->name), string_VkExternalFenceHandleTypeFlagBits(info->handleType));
}
if (info->handle && info->name) {
skip |= LogError("VUID-VkImportFenceWin32HandleInfoKHR-handle-01462", info->fence, error_obj.location.dot(Field::info),
"both handle (%p) and name (%p) are non-NULL", info->handle, reinterpret_cast<const void *>(info->name));
}
return skip;
}
bool StatelessValidation::manual_PreCallValidateGetFenceWin32HandleKHR(VkDevice device, const VkFenceGetWin32HandleInfoKHR *info,
HANDLE *pHandle, const ErrorObject &error_obj) const {
return ValidateExternalFenceHandleType(info->fence, "VUID-VkFenceGetWin32HandleInfoKHR-handleType-01452",
error_obj.location.dot(Field::info).dot(Field::handleType), info->handleType,
kFenceWin32HandleTypes);
}
#endif
#ifdef VK_USE_PLATFORM_METAL_EXT
bool StatelessValidation::ExportMetalObjectsPNextUtil(VkExportMetalObjectTypeFlagBitsEXT bit, const char *vuid, const Location &loc,
const char *sType, const void *pNext) const {
bool skip = false;
auto export_metal_object_info = vku::FindStructInPNextChain<VkExportMetalObjectCreateInfoEXT>(pNext);
while (export_metal_object_info) {
if (export_metal_object_info->exportObjectType != bit) {
skip |= LogError(vuid, device, loc,
"The pNext chain contains a VkExportMetalObjectCreateInfoEXT whose exportObjectType = %s, but only "
"VkExportMetalObjectCreateInfoEXT structs with exportObjectType of %s are allowed.",
string_VkExportMetalObjectTypeFlagBitsEXT(export_metal_object_info->exportObjectType), sType);
}
export_metal_object_info = vku::FindStructInPNextChain<VkExportMetalObjectCreateInfoEXT>(export_metal_object_info->pNext);
}
return skip;
}
bool StatelessValidation::manual_PreCallValidateExportMetalObjectsEXT(VkDevice device,
VkExportMetalObjectsInfoEXT *pMetalObjectsInfo,
const ErrorObject &error_obj) const {
bool skip = false;
static_assert(AllVkExportMetalObjectTypeFlagBitsEXT == 0x3F, "Add new ExportMetalObjects support to VVL!");
constexpr std::array allowed_structs = {
VK_STRUCTURE_TYPE_EXPORT_METAL_BUFFER_INFO_EXT, VK_STRUCTURE_TYPE_EXPORT_METAL_COMMAND_QUEUE_INFO_EXT,
VK_STRUCTURE_TYPE_EXPORT_METAL_DEVICE_INFO_EXT, VK_STRUCTURE_TYPE_EXPORT_METAL_IO_SURFACE_INFO_EXT,
VK_STRUCTURE_TYPE_EXPORT_METAL_SHARED_EVENT_INFO_EXT, VK_STRUCTURE_TYPE_EXPORT_METAL_TEXTURE_INFO_EXT,
};
skip |=
ValidateStructPnext(error_obj.location.dot(Field::pMetalObjectsInfo), pMetalObjectsInfo->pNext, allowed_structs.size(),
allowed_structs.data(), GeneratedVulkanHeaderVersion, "VUID-VkExportMetalObjectsInfoEXT-pNext-pNext",
"VUID-VkExportMetalObjectsInfoEXT-sType-unique", false, true);
return skip;
}
#endif // VK_USE_PLATFORM_METAL_EXT