Skip to content

Instantly share code, notes, and snippets.

@gulafaran
Created March 23, 2025 13:57
Show Gist options
  • Save gulafaran/a33caf55e10b4d26083088ca8538ff33 to your computer and use it in GitHub Desktop.
Save gulafaran/a33caf55e10b4d26083088ca8538ff33 to your computer and use it in GitHub Desktop.
#include <vulkan/vulkan.h>
#include <unistd.h> // For close(fd)
#include <iostream>
// Function to create exportable Vulkan memory
VkDeviceMemory allocateExportableMemory(VkDevice device, VkDeviceSize size, uint32_t memoryTypeIndex, int* outFd) {
VkExportMemoryAllocateInfo exportAllocInfo{};
exportAllocInfo.sType = VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO;
exportAllocInfo.handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT;
VkMemoryAllocateInfo allocInfo{};
allocInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
allocInfo.allocationSize = size;
allocInfo.memoryTypeIndex = memoryTypeIndex;
allocInfo.pNext = &exportAllocInfo;
VkDeviceMemory memory;
if (vkAllocateMemory(device, &allocInfo, nullptr, &memory) != VK_SUCCESS) {
throw std::runtime_error("Failed to allocate exportable memory!");
}
// Retrieve the file descriptor for sharing memory
VkMemoryGetFdInfoKHR getFdInfo{};
getFdInfo.sType = VK_STRUCTURE_TYPE_MEMORY_GET_FD_INFO_KHR;
getFdInfo.memory = memory;
getFdInfo.handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT;
VkDeviceMemoryFdKHR vkGetMemoryFdKHR = (VkDeviceMemoryFdKHR) vkGetDeviceProcAddr(device, "vkGetMemoryFdKHR");
if (vkGetMemoryFdKHR(device, &getFdInfo, outFd) != VK_SUCCESS) {
throw std::runtime_error("Failed to get external memory FD!");
}
return memory;
}
// Function to import memory on a different GPU
VkDeviceMemory importExternalMemory(VkDevice device, int fd, VkDeviceSize size, uint32_t memoryTypeIndex) {
VkImportMemoryFdInfoKHR importInfo{};
importInfo.sType = VK_STRUCTURE_TYPE_IMPORT_MEMORY_FD_INFO_KHR;
importInfo.handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT;
importInfo.fd = fd;
VkMemoryAllocateInfo allocInfo{};
allocInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
allocInfo.allocationSize = size;
allocInfo.memoryTypeIndex = memoryTypeIndex;
allocInfo.pNext = &importInfo;
VkDeviceMemory memory;
if (vkAllocateMemory(device, &allocInfo, nullptr, &memory) != VK_SUCCESS) {
throw std::runtime_error("Failed to import external memory!");
}
return memory;
}
// Function to create an external semaphore
VkSemaphore createExternalSemaphore(VkDevice device, int* outFd) {
VkExportSemaphoreCreateInfo exportSemaphoreInfo{};
exportSemaphoreInfo.sType = VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_CREATE_INFO;
exportSemaphoreInfo.handleTypes = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT;
VkSemaphoreCreateInfo semaphoreInfo{};
semaphoreInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
semaphoreInfo.pNext = &exportSemaphoreInfo;
VkSemaphore semaphore;
if (vkCreateSemaphore(device, &semaphoreInfo, nullptr, &semaphore) != VK_SUCCESS) {
throw std::runtime_error("Failed to create external semaphore!");
}
// Get the FD for external synchronization
VkSemaphoreGetFdInfoKHR getFdInfo{};
getFdInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_GET_FD_INFO_KHR;
getFdInfo.semaphore = semaphore;
getFdInfo.handleType = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT;
VkDeviceSemaphoreFdKHR vkGetSemaphoreFdKHR = (VkDeviceSemaphoreFdKHR) vkGetDeviceProcAddr(device, "vkGetSemaphoreFdKHR");
if (vkGetSemaphoreFdKHR(device, &getFdInfo, outFd) != VK_SUCCESS) {
throw std::runtime_error("Failed to get external semaphore FD!");
}
return semaphore;
}
// Function to import an external semaphore on GPU 2
VkSemaphore importExternalSemaphore(VkDevice device, int fd) {
VkImportSemaphoreFdInfoKHR importInfo{};
importInfo.sType = VK_STRUCTURE_TYPE_IMPORT_SEMAPHORE_FD_INFO_KHR;
importInfo.handleType = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT;
importInfo.fd = fd;
VkSemaphoreCreateInfo semaphoreInfo{};
semaphoreInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
semaphoreInfo.pNext = &importInfo;
VkSemaphore semaphore;
if (vkCreateSemaphore(device, &semaphoreInfo, nullptr, &semaphore) != VK_SUCCESS) {
throw std::runtime_error("Failed to import external semaphore!");
}
return semaphore;
}
// Function to perform blitting
void blitTexture(VkCommandBuffer cmdBuffer, VkImage srcImage, VkImage dstImage, VkExtent2D srcSize, VkExtent2D dstSize) {
VkImageBlit blitRegion{};
blitRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
blitRegion.srcSubresource.mipLevel = 0;
blitRegion.srcSubresource.baseArrayLayer = 0;
blitRegion.srcSubresource.layerCount = 1;
blitRegion.srcOffsets[1] = { static_cast<int32_t>(srcSize.width), static_cast<int32_t>(srcSize.height), 1 };
blitRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
blitRegion.dstSubresource.mipLevel = 0;
blitRegion.dstSubresource.baseArrayLayer = 0;
blitRegion.dstSubresource.layerCount = 1;
blitRegion.dstOffsets[1] = { static_cast<int32_t>(dstSize.width), static_cast<int32_t>(dstSize.height), 1 };
vkCmdBlitImage(cmdBuffer,
srcImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
dstImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
1, &blitRegion,
VK_FILTER_LINEAR);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment