@@ -61,8 +61,11 @@ static VkCommandPool vk_transferCmdPool;
61
61
static VkCommandBuffer vk_computeCmdBuffer;
62
62
static VkCommandBuffer vk_transferCmdBuffers[2 ];
63
63
64
+ static bool supportsDedicatedAllocation = false ;
64
65
static bool requiresDedicatedAllocation = false ;
65
66
67
+ static bool supportsExternalSemaphore = false ;
68
+
66
69
// A static debug callback function that relays messages from the Vulkan
67
70
// validation layer to the terminal.
68
71
static VKAPI_ATTR VkBool32 VKAPI_CALL
@@ -137,17 +140,35 @@ VkResult setupInstance() {
137
140
std::vector<const char *> requiredInstanceExtensions = {
138
141
VK_EXT_DEBUG_UTILS_EXTENSION_NAME,
139
142
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};
142
148
143
149
// Make sure that our required instance extensions are supported by the
144
150
// running Vulkan instance.
145
151
for (int i = 0 ; i < requiredInstanceExtensions.size (); ++i) {
146
152
std::string requiredExtension = requiredInstanceExtensions[i];
147
153
if (std::find (supportedInstanceExtensions.begin (),
148
154
supportedInstanceExtensions.end (),
149
- requiredExtension) == supportedInstanceExtensions.end ())
155
+ requiredExtension) == supportedInstanceExtensions.end ()) {
150
156
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
+ }
151
172
}
152
173
153
174
// Create the vulkan instance with our required extensions and layers.
@@ -227,16 +248,25 @@ VkResult setupDevice(const sycl::device &dev) {
227
248
static constexpr const char *requiredExtensions[] = {
228
249
VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME,
229
250
VK_KHR_EXTERNAL_MEMORY_EXTENSION_NAME,
230
- VK_KHR_EXTERNAL_SEMAPHORE_EXTENSION_NAME,
231
251
#ifdef _WIN32
232
252
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
233
261
VK_KHR_EXTERNAL_SEMAPHORE_WIN32_EXTENSION_NAME,
234
262
#else
235
263
VK_KHR_EXTERNAL_SEMAPHORE_FD_EXTENSION_NAME,
236
- VK_KHR_EXTERNAL_MEMORY_FD_EXTENSION_NAME,
237
264
#endif
238
265
};
239
266
267
+ std::vector<const char *> enabledDeviceExtensions (
268
+ std::begin (requiredExtensions), std::end (requiredExtensions));
269
+
240
270
const auto UUID = dev.get_info <sycl::ext::intel::info::device::uuid>();
241
271
242
272
// From all physical devices, find the first one with a matching UUID
@@ -259,6 +289,7 @@ VkResult setupDevice(const sycl::device &dev) {
259
289
continue ;
260
290
}
261
291
292
+ // Check if the device supports the required extensions.
262
293
std::vector<VkExtensionProperties> supportedDeviceExtensions;
263
294
getSupportedDeviceExtensions (supportedDeviceExtensions, vk_physical_device);
264
295
const bool hasRequiredExtensions = std::all_of (
@@ -271,10 +302,29 @@ VkResult setupDevice(const sycl::device &dev) {
271
302
});
272
303
return (it != std::end (supportedDeviceExtensions));
273
304
});
305
+ // Skip this device if it does not support all required extensions.
274
306
if (!hasRequiredExtensions) {
275
307
continue ;
276
308
}
277
309
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
+
278
328
foundDevice = true ;
279
329
std::cout << " Found suitable Vulkan device: "
280
330
<< devProps2.properties .deviceName << std::endl;
@@ -348,9 +398,8 @@ VkResult setupDevice(const sycl::device &dev) {
348
398
dci.pQueueCreateInfos = qcis.data ();
349
399
dci.queueCreateInfoCount = qcis.size ();
350
400
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 ();
354
403
355
404
VK_CHECK_CALL_RET (
356
405
vkCreateDevice (vk_physical_device, &dci, nullptr , &vk_device));
@@ -371,13 +420,15 @@ VkResult setupDevice(const sycl::device &dev) {
371
420
<< " Could not get func pointer to \" vkGetMemoryWin32HandleKHR\" !\n " ;
372
421
return VK_ERROR_UNKNOWN;
373
422
}
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
+ }
381
432
}
382
433
#else
383
434
vk_getMemoryFdKHR =
@@ -386,11 +437,13 @@ VkResult setupDevice(const sycl::device &dev) {
386
437
std::cerr << " Could not get func pointer to \" vkGetMemoryFdKHR\" !\n " ;
387
438
return VK_ERROR_UNKNOWN;
388
439
}
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
+ }
394
447
}
395
448
#endif
396
449
@@ -580,10 +633,11 @@ VkDeviceMemory allocateDeviceMemory(size_t size, uint32_t memoryTypeIndex,
580
633
#else
581
634
emai.handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT;
582
635
#endif
583
- if (requiresDedicatedAllocation)
636
+ if (requiresDedicatedAllocation) {
584
637
dedicatedInfo.pNext = &emai;
585
- else
638
+ } else {
586
639
mai.pNext = &emai;
640
+ }
587
641
}
588
642
589
643
VkDeviceMemory memory;
@@ -601,12 +655,15 @@ property flags passed.
601
655
*/
602
656
uint32_t getImageMemoryTypeIndex (VkImage image, VkMemoryPropertyFlags flags,
603
657
VkMemoryRequirements &memRequirements) {
604
- VkMemoryDedicatedRequirements dedicatedRequirements{};
605
- dedicatedRequirements.sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS;
606
-
607
658
VkMemoryRequirements2 memoryRequirements2{};
608
659
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
+ }
610
667
611
668
VkImageMemoryRequirementsInfo2 imageRequirementsInfo{};
612
669
imageRequirementsInfo.sType =
@@ -616,8 +673,9 @@ uint32_t getImageMemoryTypeIndex(VkImage image, VkMemoryPropertyFlags flags,
616
673
vk_getImageMemoryRequirements2 (vk_device, &imageRequirementsInfo,
617
674
&memoryRequirements2);
618
675
619
- if (dedicatedRequirements.requiresDedicatedAllocation )
676
+ if (dedicatedRequirements.requiresDedicatedAllocation ) {
620
677
requiresDedicatedAllocation = true ;
678
+ }
621
679
622
680
VkPhysicalDeviceMemoryProperties memProperties;
623
681
vkGetPhysicalDeviceMemoryProperties (vk_physical_device, &memProperties);
@@ -715,6 +773,11 @@ HANDLE getSemaphoreWin32Handle(VkSemaphore semaphore) {
715
773
sghwi.semaphore = semaphore;
716
774
sghwi.handleType = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT;
717
775
776
+ if (!supportsExternalSemaphore) {
777
+ std::cerr << " External semaphore support is not enabled!\n " ;
778
+ return 0 ;
779
+ }
780
+
718
781
if (vk_getSemaphoreWin32HandleKHR != nullptr ) {
719
782
VK_CHECK_CALL (vk_getSemaphoreWin32HandleKHR (vk_device, &sghwi, &retHandle));
720
783
} else {
@@ -757,6 +820,12 @@ int getSemaphoreOpaqueFD(VkSemaphore semaphore) {
757
820
sgfi.handleType = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT;
758
821
759
822
int fd = 0 ;
823
+
824
+ if (!supportsExternalSemaphore) {
825
+ std::cerr << " External semaphore support is not enabled!\n " ;
826
+ return 0 ;
827
+ }
828
+
760
829
if (vk_getSemaphoreFdKHR != nullptr ) {
761
830
VK_CHECK_CALL (vk_getSemaphoreFdKHR (vk_device, &sgfi, &fd));
762
831
} else {
@@ -805,11 +874,9 @@ struct vulkan_image_test_resources_t {
805
874
806
875
vulkan_image_test_resources_t (VkImageType imgType, VkFormat format,
807
876
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 );
813
880
VkMemoryRequirements memRequirements;
814
881
auto inputImageMemoryTypeIndex = vkutil::getImageMemoryTypeIndex (
815
882
vkImage, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, memRequirements);
0 commit comments