@@ -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,29 @@ 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+ for (const char *optionalExt : optionalExtensions) {
313+ auto it = std::find_if (std::begin (supportedDeviceExtensions),
314+ std::end (supportedDeviceExtensions),
315+ [&](const VkExtensionProperties &ext) {
316+ return (ext.extensionName ==
317+ std::string_view (optionalExt));
318+ });
319+ if (it != std::end (supportedDeviceExtensions)) {
320+ enabledDeviceExtensions.push_back (optionalExt);
321+ if (std::string_view (optionalExt) ==
322+ VK_KHR_EXTERNAL_SEMAPHORE_EXTENSION_NAME ) {
323+ supportsExternalSemaphore = true ;
324+ }
325+ }
326+ }
327+
278328 foundDevice = true ;
279329 std::cout << " Found suitable Vulkan device: "
280330 << devProps2.properties .deviceName << std::endl;
@@ -348,9 +398,8 @@ VkResult setupDevice(const sycl::device &dev) {
348398 dci.pQueueCreateInfos = qcis.data ();
349399 dci.queueCreateInfoCount = qcis.size ();
350400 dci.pEnabledFeatures = &deviceFeatures;
351- dci.enabledExtensionCount =
352- sizeof (requiredExtensions) / sizeof (requiredExtensions[0 ]);
353- dci.ppEnabledExtensionNames = &requiredExtensions[0 ];
401+ dci.enabledExtensionCount = enabledDeviceExtensions.size ();
402+ dci.ppEnabledExtensionNames = enabledDeviceExtensions.data ();
354403
355404 VK_CHECK_CALL_RET (
356405 vkCreateDevice (vk_physical_device, &dci, nullptr , &vk_device));
@@ -371,13 +420,15 @@ VkResult setupDevice(const sycl::device &dev) {
371420 << " Could not get func pointer to \" vkGetMemoryWin32HandleKHR\" !\n " ;
372421 return VK_ERROR_UNKNOWN ;
373422 }
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 ;
423+ if (supportsExternalSemaphore) {
424+ vk_getSemaphoreWin32HandleKHR =
425+ (PFN_vkGetSemaphoreWin32HandleKHR)vkGetDeviceProcAddr (
426+ vk_device, " vkGetSemaphoreWin32HandleKHR" );
427+ if (!vk_getSemaphoreWin32HandleKHR) {
428+ std::cerr << " Could not get func pointer to "
429+ " \" vkGetSemaphoreWin32HandleKHR\" !\n " ;
430+ return VK_ERROR_UNKNOWN ;
431+ }
381432 }
382433#else
383434 vk_getMemoryFdKHR =
@@ -386,11 +437,13 @@ VkResult setupDevice(const sycl::device &dev) {
386437 std::cerr << " Could not get func pointer to \" vkGetMemoryFdKHR\" !\n " ;
387438 return VK_ERROR_UNKNOWN ;
388439 }
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 ;
440+ if (supportsExternalSemaphore) {
441+ vk_getSemaphoreFdKHR = (PFN_vkGetSemaphoreFdKHR)vkGetDeviceProcAddr (
442+ vk_device, " vkGetSemaphoreFdKHR" );
443+ if (!vk_getSemaphoreFdKHR) {
444+ std::cerr << " Could not get func pointer to \" vkGetSemaphoreFdKHR\" !\n " ;
445+ return VK_ERROR_UNKNOWN ;
446+ }
394447 }
395448#endif
396449
@@ -580,10 +633,11 @@ VkDeviceMemory allocateDeviceMemory(size_t size, uint32_t memoryTypeIndex,
580633#else
581634 emai.handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT ;
582635#endif
583- if (requiresDedicatedAllocation)
636+ if (requiresDedicatedAllocation) {
584637 dedicatedInfo.pNext = &emai;
585- else
638+ } else {
586639 mai.pNext = &emai;
640+ }
587641 }
588642
589643 VkDeviceMemory memory;
@@ -601,12 +655,15 @@ property flags passed.
601655*/
602656uint32_t getImageMemoryTypeIndex (VkImage image, VkMemoryPropertyFlags flags,
603657 VkMemoryRequirements &memRequirements) {
604- VkMemoryDedicatedRequirements dedicatedRequirements{};
605- dedicatedRequirements.sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS ;
606-
607658 VkMemoryRequirements2 memoryRequirements2{};
608659 memoryRequirements2.sType = VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2 ;
609- memoryRequirements2.pNext = &dedicatedRequirements;
660+
661+ VkMemoryDedicatedRequirements dedicatedRequirements{};
662+ if (supportsDedicatedAllocation) {
663+ dedicatedRequirements.sType =
664+ VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS ;
665+ memoryRequirements2.pNext = &dedicatedRequirements;
666+ }
610667
611668 VkImageMemoryRequirementsInfo2 imageRequirementsInfo{};
612669 imageRequirementsInfo.sType =
@@ -616,8 +673,9 @@ uint32_t getImageMemoryTypeIndex(VkImage image, VkMemoryPropertyFlags flags,
616673 vk_getImageMemoryRequirements2 (vk_device, &imageRequirementsInfo,
617674 &memoryRequirements2);
618675
619- if (dedicatedRequirements.requiresDedicatedAllocation )
676+ if (dedicatedRequirements.requiresDedicatedAllocation ) {
620677 requiresDedicatedAllocation = true ;
678+ }
621679
622680 VkPhysicalDeviceMemoryProperties memProperties;
623681 vkGetPhysicalDeviceMemoryProperties (vk_physical_device, &memProperties);
@@ -715,6 +773,11 @@ HANDLE getSemaphoreWin32Handle(VkSemaphore semaphore) {
715773 sghwi.semaphore = semaphore;
716774 sghwi.handleType = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT ;
717775
776+ if (!supportsExternalSemaphore) {
777+ std::cerr << " External semaphore support is not enabled!\n " ;
778+ return 0 ;
779+ }
780+
718781 if (vk_getSemaphoreWin32HandleKHR != nullptr ) {
719782 VK_CHECK_CALL (vk_getSemaphoreWin32HandleKHR (vk_device, &sghwi, &retHandle));
720783 } else {
@@ -757,6 +820,12 @@ int getSemaphoreOpaqueFD(VkSemaphore semaphore) {
757820 sgfi.handleType = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT ;
758821
759822 int fd = 0 ;
823+
824+ if (!supportsExternalSemaphore) {
825+ std::cerr << " External semaphore support is not enabled!\n " ;
826+ return 0 ;
827+ }
828+
760829 if (vk_getSemaphoreFdKHR != nullptr ) {
761830 VK_CHECK_CALL (vk_getSemaphoreFdKHR (vk_device, &sgfi, &fd));
762831 } else {
@@ -805,11 +874,9 @@ struct vulkan_image_test_resources_t {
805874
806875 vulkan_image_test_resources_t (VkImageType imgType, VkFormat format,
807876 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 );
877+ vkImage = vkutil::createImage (
878+ imgType, format, ext,
879+ VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT , 1 );
813880 VkMemoryRequirements memRequirements;
814881 auto inputImageMemoryTypeIndex = vkutil::getImageMemoryTypeIndex (
815882 vkImage, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT , memRequirements);
0 commit comments