Skip to content

Commit 68d384d

Browse files
layers: Add new DMA checks
1 parent bbd836e commit 68d384d

4 files changed

Lines changed: 55 additions & 29 deletions

File tree

layers/core_checks/cc_device_memory.cpp

Lines changed: 45 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -572,33 +572,51 @@ bool CoreChecks::PreCallValidateAllocateMemory(VkDevice device, const VkMemoryAl
572572
}
573573
}
574574

575-
const auto import_memory_fd_info = vku::FindStructInPNextChain<VkImportMemoryFdInfoKHR>(pAllocateInfo->pNext);
576-
const bool imported_opaque_fd =
577-
import_memory_fd_info && import_memory_fd_info->handleType == VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT;
578-
if (imported_opaque_fd) {
579-
// There is no reasonable way to query all variations of Image/Buffer creation to see what is supported, but if the import
580-
// has dedicated Image/Buffer, we can at least validate that it has import support
581-
// https://gitlab.khronos.org/vulkan/vulkan/-/issues/3667
582-
if (dedicated_image != VK_NULL_HANDLE) {
583-
auto dedicated_image_state = Get<vvl::Image>(dedicated_image);
584-
if (dedicated_image_state &&
585-
!HasExternalMemoryImportSupport(*dedicated_image_state, VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT)) {
586-
skip |= LogError("VUID-VkImportMemoryFdInfoKHR-handleType-09862", dedicated_image,
587-
allocate_info_loc.pNext(Struct::VkMemoryDedicatedAllocateInfo, Field::image),
588-
"is %s but vkGetPhysicalDeviceImageFormatProperties2 shows no support for "
589-
"VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT.",
590-
FormatHandle(dedicated_image).c_str());
591-
}
592-
}
593-
if (dedicated_buffer != VK_NULL_HANDLE) {
594-
auto dedicated_buffer_state = Get<vvl::Buffer>(dedicated_buffer);
595-
if (dedicated_buffer_state &&
596-
!HasExternalMemoryImportSupport(*dedicated_buffer_state, VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT)) {
597-
skip |= LogError("VUID-VkImportMemoryFdInfoKHR-handleType-09862", dedicated_buffer,
598-
allocate_info_loc.pNext(Struct::VkMemoryDedicatedAllocateInfo, Field::buffer),
599-
"is %s but vkGetPhysicalDeviceExternalBufferProperties shows no support for "
600-
"VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT.",
601-
FormatHandle(dedicated_buffer).c_str());
575+
if (const auto import_memory_fd_info = vku::FindStructInPNextChain<VkImportMemoryFdInfoKHR>(pAllocateInfo->pNext)) {
576+
if (import_memory_fd_info->handleType == VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT &&
577+
pAllocateInfo->memoryTypeIndex < phys_dev_mem_props.memoryTypeCount) {
578+
const uint32_t heap_index = phys_dev_mem_props.memoryTypes[pAllocateInfo->memoryTypeIndex].heapIndex;
579+
const VkMemoryHeap& memory_heap = phys_dev_mem_props.memoryHeaps[heap_index];
580+
if (vvl::IsMultiInstance(*pAllocateInfo, memory_heap, device_state->physical_device_count)) {
581+
const char* reason =
582+
chained_flags_struct && (chained_flags_struct->flags & VK_MEMORY_ALLOCATE_DEVICE_MASK_BIT)
583+
? "VkMemoryAllocateFlagsInfo::deviceMask has more than one bit set"
584+
: "the heap has VK_MEMORY_HEAP_MULTI_INSTANCE_BIT and the logical device has more than one physical device";
585+
skip |=
586+
LogError("VUID-VkMemoryAllocateInfo-None-12523", device,
587+
allocate_info_loc.pNext(Struct::VkImportMemoryFdInfoKHR, Field::handleType),
588+
"is VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT, but more than one instance of the memory will be "
589+
"allocated (%s). (memoryTypeIndex %" PRIu32 " is from heap %" PRIu32
590+
" [flags = %s] and the logical device was created with %" PRIu32 " physical devices).",
591+
reason, pAllocateInfo->memoryTypeIndex, heap_index,
592+
string_VkMemoryHeapFlags(memory_heap.flags).c_str(), device_state->physical_device_count);
593+
}
594+
}
595+
if (import_memory_fd_info->handleType == VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT) {
596+
// There is no reasonable way to query all variations of Image/Buffer creation to see what is supported, but if the
597+
// import has dedicated Image/Buffer, we can at least validate that it has import support
598+
// https://gitlab.khronos.org/vulkan/vulkan/-/issues/3667
599+
if (dedicated_image != VK_NULL_HANDLE) {
600+
auto dedicated_image_state = Get<vvl::Image>(dedicated_image);
601+
if (dedicated_image_state &&
602+
!HasExternalMemoryImportSupport(*dedicated_image_state, VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT)) {
603+
skip |= LogError("VUID-VkImportMemoryFdInfoKHR-handleType-09862", dedicated_image,
604+
allocate_info_loc.pNext(Struct::VkMemoryDedicatedAllocateInfo, Field::image),
605+
"is %s but vkGetPhysicalDeviceImageFormatProperties2 shows no support for "
606+
"VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT.",
607+
FormatHandle(dedicated_image).c_str());
608+
}
609+
}
610+
if (dedicated_buffer != VK_NULL_HANDLE) {
611+
auto dedicated_buffer_state = Get<vvl::Buffer>(dedicated_buffer);
612+
if (dedicated_buffer_state &&
613+
!HasExternalMemoryImportSupport(*dedicated_buffer_state, VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT)) {
614+
skip |= LogError("VUID-VkImportMemoryFdInfoKHR-handleType-09862", dedicated_buffer,
615+
allocate_info_loc.pNext(Struct::VkMemoryDedicatedAllocateInfo, Field::buffer),
616+
"is %s but vkGetPhysicalDeviceExternalBufferProperties shows no support for "
617+
"VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT.",
618+
FormatHandle(dedicated_buffer).c_str());
619+
}
602620
}
603621
}
604622
}

layers/core_checks/cc_external_object.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,13 @@ bool CoreChecks::PreCallValidateGetMemoryFdKHR(VkDevice device, const VkMemoryGe
6464
string_VkExternalMemoryHandleTypeFlagBits(pGetFdInfo->handleType),
6565
string_VkExternalMemoryHandleTypeFlags(export_info->handleTypes).c_str());
6666
}
67+
68+
if (pGetFdInfo->handleType == VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT && memory_state->multi_instance) {
69+
skip |= LogError("VUID-VkMemoryGetFdInfoKHR-handleType-12524", pGetFdInfo->memory,
70+
error_obj.location.dot(Field::pGetFdInfo).dot(Field::handleType),
71+
"is VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT, but %s was allocated with multiple instances.",
72+
FormatHandle(pGetFdInfo->memory).c_str());
73+
}
6774
}
6875
return skip;
6976
}

layers/state_tracker/device_memory_state.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,7 @@ std::optional<VkExternalMemoryHandleTypeFlagBits> GetImportHandleType(const VkMe
6464
return std::nullopt;
6565
}
6666

67-
static bool IsMultiInstance(const VkMemoryAllocateInfo& alloc_info, const VkMemoryHeap& memory_heap,
68-
uint32_t physical_device_count) {
67+
bool IsMultiInstance(const VkMemoryAllocateInfo& alloc_info, const VkMemoryHeap& memory_heap, uint32_t physical_device_count) {
6968
auto alloc_flags = vku::FindStructInPNextChain<VkMemoryAllocateFlagsInfo>(alloc_info.pNext);
7069
if (alloc_flags && (alloc_flags->flags & VK_MEMORY_ALLOCATE_DEVICE_MASK_BIT)) {
7170
auto dev_mask = alloc_flags->deviceMask;

layers/state_tracker/device_memory_state.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ namespace vvl {
2727

2828
std::optional<VkExternalMemoryHandleTypeFlagBits> GetImportHandleType(const VkMemoryAllocateInfo &alloc_info);
2929

30+
bool IsMultiInstance(const VkMemoryAllocateInfo& alloc_info, const VkMemoryHeap& memory_heap, uint32_t physical_device_count);
31+
3032
struct MemRange {
3133
VkDeviceSize offset = 0;
3234
VkDeviceSize size = 0;

0 commit comments

Comments
 (0)