Skip to content

Commit 3647352

Browse files
authored
[SYCL][E2E][Bindless] Check and use DedicatedAllocation in vulkan interop test for L0 (#14967)
Vulkan interop in L0 backend currently has an issue that image sizes are not correctly passed to graphics memory management (GMM). Using dedicated allocation is an approach to solve the issue. In this case, image and device memory has 1:1 mapping and GMM is aware of the image info. This PR enables VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME extension and checks if VkMemoryDedicatedRequirements.requiresDedicatedAllocation is true. The value is false by default in CUDA and L0 backends.
1 parent 4093207 commit 3647352

File tree

4 files changed

+67
-35
lines changed

4 files changed

+67
-35
lines changed

sycl/test-e2e/bindless_images/vulkan_interop/mipmaps.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -272,8 +272,8 @@ bool run_test(sycl::range<NDims> dims, sycl::range<NDims> localSize,
272272
VkMemoryRequirements memRequirements;
273273
auto inputImageMemoryTypeIndex = vkutil::getImageMemoryTypeIndex(
274274
inputImage, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, memRequirements);
275-
auto inputMemory = vkutil::allocateDeviceMemory(memRequirements.size,
276-
inputImageMemoryTypeIndex);
275+
auto inputMemory = vkutil::allocateDeviceMemory(
276+
memRequirements.size, inputImageMemoryTypeIndex, inputImage);
277277
VK_CHECK_CALL(vkBindImageMemory(vk_device, inputImage, inputMemory,
278278
0 /*memoryOffset*/));
279279

@@ -286,7 +286,8 @@ bool run_test(sycl::range<NDims> dims, sycl::range<NDims> localSize,
286286
inputStagingBuffer, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
287287
VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
288288
auto inputStagingMemory = vkutil::allocateDeviceMemory(
289-
memRequirements.size, inputStagingMemoryTypeIndex, false /*exportable*/);
289+
memRequirements.size, inputStagingMemoryTypeIndex, nullptr /*image*/,
290+
false /*exportable*/);
290291
VK_CHECK_CALL(vkBindBufferMemory(vk_device, inputStagingBuffer,
291292
inputStagingMemory, 0 /*memoryOffset*/));
292293

sycl/test-e2e/bindless_images/vulkan_interop/sampled_images.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -213,8 +213,8 @@ bool run_test(sycl::range<NDims> dims, sycl::range<NDims> localSize,
213213
VkMemoryRequirements memRequirements;
214214
auto inputImageMemoryTypeIndex = vkutil::getImageMemoryTypeIndex(
215215
inputImage, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, memRequirements);
216-
auto inputMemory =
217-
vkutil::allocateDeviceMemory(imageSizeBytes, inputImageMemoryTypeIndex);
216+
auto inputMemory = vkutil::allocateDeviceMemory(
217+
imageSizeBytes, inputImageMemoryTypeIndex, inputImage);
218218
VK_CHECK_CALL(vkBindImageMemory(vk_device, inputImage, inputMemory,
219219
0 /*memoryOffset*/));
220220

@@ -226,8 +226,9 @@ bool run_test(sycl::range<NDims> dims, sycl::range<NDims> localSize,
226226
auto inputStagingMemoryTypeIndex = vkutil::getBufferMemoryTypeIndex(
227227
inputStagingBuffer, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
228228
VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
229-
auto inputStagingMemory = vkutil::allocateDeviceMemory(
230-
imageSizeBytes, inputStagingMemoryTypeIndex, false /*exportable*/);
229+
auto inputStagingMemory =
230+
vkutil::allocateDeviceMemory(imageSizeBytes, inputStagingMemoryTypeIndex,
231+
nullptr /*image*/, false /*exportable*/);
231232
VK_CHECK_CALL(vkBindBufferMemory(vk_device, inputStagingBuffer,
232233
inputStagingMemory, 0 /*memoryOffset*/));
233234

sycl/test-e2e/bindless_images/vulkan_interop/sampled_images_USM.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -192,8 +192,8 @@ bool run_test(sycl::range<NDims> dims, sycl::range<NDims> localSize,
192192
memRequirements.size = imageSizeBytes;
193193
auto inputImageMemoryTypeIndex = vkutil::getImageMemoryTypeIndex(
194194
inputImage, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, memRequirements);
195-
auto inputMemory =
196-
vkutil::allocateDeviceMemory(imageSizeBytes, inputImageMemoryTypeIndex);
195+
auto inputMemory = vkutil::allocateDeviceMemory(
196+
imageSizeBytes, inputImageMemoryTypeIndex, inputImage);
197197
VK_CHECK_CALL(vkBindImageMemory(vk_device, inputImage, inputMemory,
198198
0 /*memoryOffset*/));
199199

@@ -206,7 +206,7 @@ bool run_test(sycl::range<NDims> dims, sycl::range<NDims> localSize,
206206
inputStagingBuffer, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
207207
VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
208208
auto inputStagingMemory = vkutil::allocateDeviceMemory(
209-
stagingBufferSizeBytes, inputStagingMemoryTypeIndex,
209+
stagingBufferSizeBytes, inputStagingMemoryTypeIndex, nullptr /*image*/,
210210
false /*exportable*/);
211211
VK_CHECK_CALL(vkBindBufferMemory(vk_device, inputStagingBuffer,
212212
inputStagingMemory, 0 /*memoryOffset*/));

sycl/test-e2e/bindless_images/vulkan_interop/vulkan_common.hpp

Lines changed: 55 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@ static PFN_vkGetMemoryFdKHR vk_getMemoryFdKHR;
5050
static PFN_vkGetSemaphoreFdKHR vk_getSemaphoreFdKHR;
5151
#endif
5252

53+
static PFN_vkGetImageMemoryRequirements2 vk_getImageMemoryRequirements2;
54+
5355
static uint32_t vk_computeQueueFamilyIndex;
5456
static uint32_t vk_transferQueueFamilyIndex;
5557

@@ -59,6 +61,8 @@ static VkCommandPool vk_transferCmdPool;
5961
static VkCommandBuffer vk_computeCmdBuffer;
6062
static VkCommandBuffer vk_transferCmdBuffers[2];
6163

64+
static bool requiresDedicatedAllocation = false;
65+
6266
// A static debug callback function that relays messages from the Vulkan
6367
// validation layer to the terminal.
6468
static VKAPI_ATTR VkBool32 VKAPI_CALL
@@ -220,7 +224,8 @@ VkResult setupDevice(std::string device) {
220224
bool foundDevice = false;
221225

222226
// Define the required device extensions to run the tests.
223-
static constexpr std::string_view requiredExtensions[] = {
227+
static constexpr const char *requiredExtensions[] = {
228+
VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME,
224229
VK_KHR_EXTERNAL_MEMORY_EXTENSION_NAME,
225230
VK_KHR_EXTERNAL_SEMAPHORE_EXTENSION_NAME,
226231
#ifdef _WIN32
@@ -325,28 +330,15 @@ VkResult setupDevice(std::string device) {
325330

326331
VkPhysicalDeviceFeatures deviceFeatures = {};
327332

328-
// Store our required device extensions. To be passed to the Vulkan device
329-
// creation function.
330-
std::vector<const char *> extensions = {
331-
VK_KHR_EXTERNAL_MEMORY_EXTENSION_NAME,
332-
VK_KHR_EXTERNAL_SEMAPHORE_EXTENSION_NAME,
333-
#ifdef _WIN32
334-
VK_KHR_EXTERNAL_MEMORY_WIN32_EXTENSION_NAME,
335-
VK_KHR_EXTERNAL_SEMAPHORE_WIN32_EXTENSION_NAME,
336-
#else
337-
VK_KHR_EXTERNAL_SEMAPHORE_FD_EXTENSION_NAME,
338-
VK_KHR_EXTERNAL_MEMORY_FD_EXTENSION_NAME,
339-
#endif
340-
};
341-
342333
// Create the Vulkan device with the above queues, extensions, and layers.
343334
VkDeviceCreateInfo dci = {};
344335
dci.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
345336
dci.pQueueCreateInfos = qcis.data();
346337
dci.queueCreateInfoCount = qcis.size();
347338
dci.pEnabledFeatures = &deviceFeatures;
348-
dci.enabledExtensionCount = extensions.size();
349-
dci.ppEnabledExtensionNames = extensions.data();
339+
dci.enabledExtensionCount =
340+
sizeof(requiredExtensions) / sizeof(requiredExtensions[0]);
341+
dci.ppEnabledExtensionNames = &requiredExtensions[0];
350342

351343
VK_CHECK_CALL_RET(
352344
vkCreateDevice(vk_physical_device, &dci, nullptr, &vk_device));
@@ -390,6 +382,15 @@ VkResult setupDevice(std::string device) {
390382
}
391383
#endif
392384

385+
vk_getImageMemoryRequirements2 =
386+
reinterpret_cast<PFN_vkGetImageMemoryRequirements2>(
387+
vkGetDeviceProcAddr(vk_device, "vkGetImageMemoryRequirements2KHR"));
388+
if (!vk_getImageMemoryRequirements2) {
389+
std::cerr << "Could not get func pointer to "
390+
"\"vkGetImageMemoryRequirements2KHR\"!\n";
391+
return VK_ERROR_UNKNOWN;
392+
}
393+
393394
return VK_SUCCESS;
394395
}
395396

@@ -533,21 +534,32 @@ exportable, in which case the appropriate extension struct is populated based on
533534
the OS the program is compiled for.
534535
*/
535536
VkDeviceMemory allocateDeviceMemory(size_t size, uint32_t memoryTypeIndex,
536-
bool exportable = true) {
537-
VkMemoryAllocateInfo mai = {};
537+
VkImage image, bool exportable = true) {
538+
VkMemoryAllocateInfo mai{};
538539
mai.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
539540
mai.allocationSize = size;
540541
mai.memoryTypeIndex = memoryTypeIndex;
541542

542-
VkExportMemoryAllocateInfo emai = {};
543+
VkMemoryDedicatedAllocateInfoKHR dedicatedInfo{};
544+
if (requiresDedicatedAllocation) {
545+
dedicatedInfo.sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO_KHR;
546+
dedicatedInfo.image = image;
547+
dedicatedInfo.buffer = VK_NULL_HANDLE;
548+
mai.pNext = &dedicatedInfo;
549+
}
550+
551+
VkExportMemoryAllocateInfo emai{};
543552
if (exportable) {
544553
emai.sType = VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO;
545554
#ifdef _WIN32
546555
emai.handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT;
547556
#else
548557
emai.handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT;
549558
#endif
550-
mai.pNext = &emai;
559+
if (requiresDedicatedAllocation)
560+
dedicatedInfo.pNext = &emai;
561+
else
562+
mai.pNext = &emai;
551563
}
552564

553565
VkDeviceMemory memory;
@@ -565,11 +577,28 @@ property flags passed.
565577
*/
566578
uint32_t getImageMemoryTypeIndex(VkImage image, VkMemoryPropertyFlags flags,
567579
VkMemoryRequirements &memRequirements) {
568-
vkGetImageMemoryRequirements(vk_device, image, &memRequirements);
580+
VkMemoryDedicatedRequirements dedicatedRequirements{};
581+
dedicatedRequirements.sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS;
582+
583+
VkMemoryRequirements2 memoryRequirements2{};
584+
memoryRequirements2.sType = VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2;
585+
memoryRequirements2.pNext = &dedicatedRequirements;
586+
587+
VkImageMemoryRequirementsInfo2 imageRequirementsInfo{};
588+
imageRequirementsInfo.sType =
589+
VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2;
590+
imageRequirementsInfo.image = image;
591+
592+
vk_getImageMemoryRequirements2(vk_device, &imageRequirementsInfo,
593+
&memoryRequirements2);
594+
595+
if (dedicatedRequirements.requiresDedicatedAllocation)
596+
requiresDedicatedAllocation = true;
569597

570598
VkPhysicalDeviceMemoryProperties memProperties;
571599
vkGetPhysicalDeviceMemoryProperties(vk_physical_device, &memProperties);
572600

601+
memRequirements = memoryRequirements2.memoryRequirements;
573602
for (uint32_t i = 0; i < memProperties.memoryTypeCount; i++) {
574603
if ((memRequirements.memoryTypeBits & (1 << i)) &&
575604
(memProperties.memoryTypes[i].propertyFlags & flags) == flags) {
@@ -760,8 +789,8 @@ struct vulkan_image_test_resources_t {
760789
VkMemoryRequirements memRequirements;
761790
auto inputImageMemoryTypeIndex = vkutil::getImageMemoryTypeIndex(
762791
vkImage, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, memRequirements);
763-
imageMemory =
764-
vkutil::allocateDeviceMemory(imageSizeBytes, inputImageMemoryTypeIndex);
792+
imageMemory = vkutil::allocateDeviceMemory(
793+
imageSizeBytes, inputImageMemoryTypeIndex, vkImage);
765794
VK_CHECK_CALL(
766795
vkBindImageMemory(vk_device, vkImage, imageMemory, 0 /*memoryOffset*/));
767796

@@ -772,7 +801,8 @@ struct vulkan_image_test_resources_t {
772801
stagingBuffer, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
773802
VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
774803
stagingMemory = vkutil::allocateDeviceMemory(
775-
imageSizeBytes, inputStagingMemoryTypeIndex, false /*exportable*/);
804+
imageSizeBytes, inputStagingMemoryTypeIndex, nullptr /*image*/,
805+
false /*exportable*/);
776806
VK_CHECK_CALL(vkBindBufferMemory(vk_device, stagingBuffer, stagingMemory,
777807
0 /*memoryOffset*/));
778808
}

0 commit comments

Comments
 (0)