-
-
Save gulafaran/a33caf55e10b4d26083088ca8538ff33 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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