@@ -61,8 +61,11 @@ static VkCommandPool vk_transferCmdPool;
6161static VkCommandBuffer vk_computeCmdBuffer;
6262static VkCommandBuffer vk_transferCmdBuffers[2 ];
6363
64+ static bool supportsDedicatedAllocation = false ;
6465static bool requiresDedicatedAllocation = false ;
6566
67+ static bool supportsExternalSemaphore = false ;
68+
6669// A static debug callback function that relays messages from the Vulkan
6770// validation layer to the terminal.
6871static VKAPI_ATTR VkBool32 VKAPI_CALL
@@ -137,17 +140,35 @@ VkResult setupInstance() {
137140 std::vector<const char *> requiredInstanceExtensions = {
138141 VK_EXT_DEBUG_UTILS_EXTENSION_NAME,
139142 VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME,
140- VK_KHR_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME,
141- VK_KHR_EXTERNAL_SEMAPHORE_CAPABILITIES_EXTENSION_NAME};
143+ VK_KHR_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME};
144+
145+ std::vector<const char *> optionalInstanceExtensions = {
146+ VK_KHR_EXTERNAL_SEMAPHORE_CAPABILITIES_EXTENSION_NAME,
147+ VK_KHR_DEDICATED_ALLOCATION_EXTENSION_NAME};
142148
143149 // Make sure that our required instance extensions are supported by the
144150 // running Vulkan instance.
145151 for (int i = 0 ; i < requiredInstanceExtensions.size (); ++i) {
146152 std::string requiredExtension = requiredInstanceExtensions[i];
147153 if (std::find (supportedInstanceExtensions.begin (),
148154 supportedInstanceExtensions.end (),
149- requiredExtension) == supportedInstanceExtensions.end ())
155+ requiredExtension) == supportedInstanceExtensions.end ()) {
150156 return VK_ERROR_EXTENSION_NOT_PRESENT;
157+ }
158+ }
159+
160+ // Add any optional instance extensions that are supported by the
161+ // running Vulkan instance.
162+ for (int i = 0 ; i < optionalInstanceExtensions.size (); ++i) {
163+ std::string optionalExtension = optionalInstanceExtensions[i];
164+ if (std::find (supportedInstanceExtensions.begin (),
165+ supportedInstanceExtensions.end (),
166+ optionalExtension) != supportedInstanceExtensions.end ()) {
167+ requiredInstanceExtensions.push_back (optionalInstanceExtensions[i]);
168+ if (optionalExtension == VK_KHR_DEDICATED_ALLOCATION_EXTENSION_NAME) {
169+ supportsDedicatedAllocation = true ;
170+ }
171+ }
151172 }
152173
153174 // Create the vulkan instance with our required extensions and layers.
@@ -227,16 +248,25 @@ VkResult setupDevice(const sycl::device &dev) {
227248 static constexpr const char *requiredExtensions[] = {
228249 VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME,
229250 VK_KHR_EXTERNAL_MEMORY_EXTENSION_NAME,
230- VK_KHR_EXTERNAL_SEMAPHORE_EXTENSION_NAME,
231251#ifdef _WIN32
232252 VK_KHR_EXTERNAL_MEMORY_WIN32_EXTENSION_NAME,
253+ #else
254+ VK_KHR_EXTERNAL_MEMORY_FD_EXTENSION_NAME,
255+ #endif
256+ };
257+
258+ static constexpr const char *optionalExtensions[] = {
259+ VK_KHR_EXTERNAL_SEMAPHORE_EXTENSION_NAME,
260+ #ifdef _WIN32
233261 VK_KHR_EXTERNAL_SEMAPHORE_WIN32_EXTENSION_NAME,
234262#else
235263 VK_KHR_EXTERNAL_SEMAPHORE_FD_EXTENSION_NAME,
236- VK_KHR_EXTERNAL_MEMORY_FD_EXTENSION_NAME,
237264#endif
238265 };
239266
267+ std::vector<const char *> enabledDeviceExtensions (
268+ std::begin (requiredExtensions), std::end (requiredExtensions));
269+
240270 const auto UUID = dev.get_info <sycl::ext::intel::info::device::uuid>();
241271
242272 // From all physical devices, find the first one with a matching UUID
@@ -259,6 +289,7 @@ VkResult setupDevice(const sycl::device &dev) {
259289 continue ;
260290 }
261291
292+ // Check if the device supports the required extensions.
262293 std::vector<VkExtensionProperties> supportedDeviceExtensions;
263294 getSupportedDeviceExtensions (supportedDeviceExtensions, vk_physical_device);
264295 const bool hasRequiredExtensions = std::all_of (
@@ -271,10 +302,31 @@ VkResult setupDevice(const sycl::device &dev) {
271302 });
272303 return (it != std::end (supportedDeviceExtensions));
273304 });
305+ // Skip this device if it does not support all required extensions.
274306 if (!hasRequiredExtensions) {
275307 continue ;
276308 }
277309
310+ // Check if the device supports the optional extensions, if so add them to
311+ // the list of enabled device extensions.
312+ std::for_each (std::begin (optionalExtensions), std::end (optionalExtensions),
313+ [&](const char *optionalExt) -> void {
314+ auto it =
315+ std::find_if (std::begin (supportedDeviceExtensions),
316+ std::end (supportedDeviceExtensions),
317+ [&](const VkExtensionProperties &ext) {
318+ return (ext.extensionName ==
319+ std::string_view (optionalExt));
320+ });
321+ if (it != std::end (supportedDeviceExtensions)) {
322+ enabledDeviceExtensions.push_back (optionalExt);
323+ if (std::string_view (optionalExt) ==
324+ VK_KHR_EXTERNAL_SEMAPHORE_EXTENSION_NAME) {
325+ supportsExternalSemaphore = true ;
326+ }
327+ }
328+ });
329+
278330 foundDevice = true ;
279331 std::cout << " Found suitable Vulkan device: "
280332 << devProps2.properties .deviceName << std::endl;
@@ -348,9 +400,8 @@ VkResult setupDevice(const sycl::device &dev) {
348400 dci.pQueueCreateInfos = qcis.data ();
349401 dci.queueCreateInfoCount = qcis.size ();
350402 dci.pEnabledFeatures = &deviceFeatures;
351- dci.enabledExtensionCount =
352- sizeof (requiredExtensions) / sizeof (requiredExtensions[0 ]);
353- dci.ppEnabledExtensionNames = &requiredExtensions[0 ];
403+ dci.enabledExtensionCount = enabledDeviceExtensions.size ();
404+ dci.ppEnabledExtensionNames = enabledDeviceExtensions.data ();
354405
355406 VK_CHECK_CALL_RET (
356407 vkCreateDevice (vk_physical_device, &dci, nullptr , &vk_device));
@@ -371,13 +422,15 @@ VkResult setupDevice(const sycl::device &dev) {
371422 << " Could not get func pointer to \" vkGetMemoryWin32HandleKHR\" !\n " ;
372423 return VK_ERROR_UNKNOWN;
373424 }
374- vk_getSemaphoreWin32HandleKHR =
375- (PFN_vkGetSemaphoreWin32HandleKHR)vkGetDeviceProcAddr (
376- vk_device, " vkGetSemaphoreWin32HandleKHR" );
377- if (!vk_getSemaphoreWin32HandleKHR) {
378- std::cerr
379- << " Could not get func pointer to \" vkGetSemaphoreWin32HandleKHR\" !\n " ;
380- return VK_ERROR_UNKNOWN;
425+ if (supportsExternalSemaphore) {
426+ vk_getSemaphoreWin32HandleKHR =
427+ (PFN_vkGetSemaphoreWin32HandleKHR)vkGetDeviceProcAddr (
428+ vk_device, " vkGetSemaphoreWin32HandleKHR" );
429+ if (!vk_getSemaphoreWin32HandleKHR) {
430+ std::cerr << " Could not get func pointer to "
431+ " \" vkGetSemaphoreWin32HandleKHR\" !\n " ;
432+ return VK_ERROR_UNKNOWN;
433+ }
381434 }
382435#else
383436 vk_getMemoryFdKHR =
@@ -386,11 +439,13 @@ VkResult setupDevice(const sycl::device &dev) {
386439 std::cerr << " Could not get func pointer to \" vkGetMemoryFdKHR\" !\n " ;
387440 return VK_ERROR_UNKNOWN;
388441 }
389- vk_getSemaphoreFdKHR = (PFN_vkGetSemaphoreFdKHR)vkGetDeviceProcAddr (
390- vk_device, " vkGetSemaphoreFdKHR" );
391- if (!vk_getSemaphoreFdKHR) {
392- std::cerr << " Could not get func pointer to \" vkGetSemaphoreFdKHR\" !\n " ;
393- return VK_ERROR_UNKNOWN;
442+ if (supportsExternalSemaphore) {
443+ vk_getSemaphoreFdKHR = (PFN_vkGetSemaphoreFdKHR)vkGetDeviceProcAddr (
444+ vk_device, " vkGetSemaphoreFdKHR" );
445+ if (!vk_getSemaphoreFdKHR) {
446+ std::cerr << " Could not get func pointer to \" vkGetSemaphoreFdKHR\" !\n " ;
447+ return VK_ERROR_UNKNOWN;
448+ }
394449 }
395450#endif
396451
@@ -580,10 +635,11 @@ VkDeviceMemory allocateDeviceMemory(size_t size, uint32_t memoryTypeIndex,
580635#else
581636 emai.handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT;
582637#endif
583- if (requiresDedicatedAllocation)
638+ if (requiresDedicatedAllocation) {
584639 dedicatedInfo.pNext = &emai;
585- else
640+ } else {
586641 mai.pNext = &emai;
642+ }
587643 }
588644
589645 VkDeviceMemory memory;
@@ -601,12 +657,15 @@ property flags passed.
601657*/
602658uint32_t getImageMemoryTypeIndex (VkImage image, VkMemoryPropertyFlags flags,
603659 VkMemoryRequirements &memRequirements) {
604- VkMemoryDedicatedRequirements dedicatedRequirements{};
605- dedicatedRequirements.sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS;
606-
607660 VkMemoryRequirements2 memoryRequirements2{};
608661 memoryRequirements2.sType = VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2;
609- memoryRequirements2.pNext = &dedicatedRequirements;
662+
663+ VkMemoryDedicatedRequirements dedicatedRequirements{};
664+ if (supportsDedicatedAllocation) {
665+ dedicatedRequirements.sType =
666+ VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS;
667+ memoryRequirements2.pNext = &dedicatedRequirements;
668+ }
610669
611670 VkImageMemoryRequirementsInfo2 imageRequirementsInfo{};
612671 imageRequirementsInfo.sType =
@@ -616,8 +675,9 @@ uint32_t getImageMemoryTypeIndex(VkImage image, VkMemoryPropertyFlags flags,
616675 vk_getImageMemoryRequirements2 (vk_device, &imageRequirementsInfo,
617676 &memoryRequirements2);
618677
619- if (dedicatedRequirements.requiresDedicatedAllocation )
678+ if (dedicatedRequirements.requiresDedicatedAllocation ) {
620679 requiresDedicatedAllocation = true ;
680+ }
621681
622682 VkPhysicalDeviceMemoryProperties memProperties;
623683 vkGetPhysicalDeviceMemoryProperties (vk_physical_device, &memProperties);
@@ -715,6 +775,11 @@ HANDLE getSemaphoreWin32Handle(VkSemaphore semaphore) {
715775 sghwi.semaphore = semaphore;
716776 sghwi.handleType = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT;
717777
778+ if (!supportsExternalSemaphore) {
779+ std::cerr << " External semaphore support is not enabled!\n " ;
780+ return 0 ;
781+ }
782+
718783 if (vk_getSemaphoreWin32HandleKHR != nullptr ) {
719784 VK_CHECK_CALL (vk_getSemaphoreWin32HandleKHR (vk_device, &sghwi, &retHandle));
720785 } else {
@@ -757,6 +822,12 @@ int getSemaphoreOpaqueFD(VkSemaphore semaphore) {
757822 sgfi.handleType = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT;
758823
759824 int fd = 0 ;
825+
826+ if (!supportsExternalSemaphore) {
827+ std::cerr << " External semaphore support is not enabled!\n " ;
828+ return 0 ;
829+ }
830+
760831 if (vk_getSemaphoreFdKHR != nullptr ) {
761832 VK_CHECK_CALL (vk_getSemaphoreFdKHR (vk_device, &sgfi, &fd));
762833 } else {
@@ -805,11 +876,9 @@ struct vulkan_image_test_resources_t {
805876
806877 vulkan_image_test_resources_t (VkImageType imgType, VkFormat format,
807878 VkExtent3D ext, const size_t imageSizeBytes) {
808- vkImage = vkutil::createImage (imgType, format, ext,
809- VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
810- VK_IMAGE_USAGE_TRANSFER_DST_BIT |
811- VK_IMAGE_USAGE_STORAGE_BIT,
812- 1 );
879+ vkImage = vkutil::createImage (
880+ imgType, format, ext,
881+ VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT, 1 );
813882 VkMemoryRequirements memRequirements;
814883 auto inputImageMemoryTypeIndex = vkutil::getImageMemoryTypeIndex (
815884 vkImage, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, memRequirements);
0 commit comments