Reputation: 4663
This is a continuation of my previous post. In short - I have multiple VkDevice
's (and multiple everything - swapchains, command buffers etc) and I want to render the same geometry with these resources, i.e. I don't want to upload the data multiple times. As @Ekzuzy pointed out I could use VK_KHR_external_memory
. I tried and actually it works, but I have some questions remaining as well as debug layer complains.
This are the most important steps:
Include all required extensions:
instanceExtensions.push_back(VK_EXT_DEBUG_REPORT_EXTENSION_NAME);
instanceExtensions.push_back(VK_KHR_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME);
instanceExtensions.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
instanceExtensions.push_back(VK_KHR_EXTERNAL_SEMAPHORE_CAPABILITIES_EXTENSION_NAME);
deviceExtensions.push_back(VK_KHR_SWAPCHAIN_EXTENSION_NAME);
deviceExtensions.push_back(VK_KHR_EXTERNAL_MEMORY_EXTENSION_NAME);
deviceExtensions.push_back(VK_KHR_EXTERNAL_SEMAPHORE_EXTENSION_NAME);
deviceExtensions.push_back(VK_KHR_EXTERNAL_MEMORY_FD_EXTENSION_NAME);
deviceExtensions.push_back(VK_KHR_EXTERNAL_SEMAPHORE_FD_EXTENSION_NAME);
Create a device local memory with a data. It intended to be a shared memory:
a) create_staging_buffer_and_memory
b) copy_data_to_staging_buffer
c) create_device_local_buffer_and_memory
d) copy_staging_buffer_to_device_local_buffer
e) create_memory_handle
VkBuffer
objects here are temporary and are destroyed after the
copying is finished. Staging memory too. Device local memory created
with VkExportMemoryAllocateInfoKHR
structure in
VkMemoryAllocateInfo::pNext
field. Memory handle obtained with vkGetMemoryFdKHR
call. After that step I have a memory with a data in the device and a handle pointing to it.
Create VkBuffer
and VkDeviceMemory
which should participate
in actual rendering. Memory created with VkImportMemoryFdInfoKHR
structure in VkMemoryAllocateInfo::pNext
field, where I use the
handle which I got earlier.
Finally record a command buffer where bind a buffer from step 3
.
As I wrote before - I see the output, but the debug layer tells me:
layer MEM: vkCmdBindVertexBuffers(): Cannot read invalid region of memory allocation 0x17 for bound Buffer object 0x16, please fill the memory before using.
I'm not sure why. And how the layer knows that the memory is invalid. In any case it looks wrong to me and I should not worry about this warning. Or should?
Another question is about VkExternalMemoryBufferCreateInfoKHR
which is used in VkBufferCreateInfo::pNext
. The documentation is not clear to me what it does - all information it have is the type of some handle. Which handle? And the application works the same with and without this struct specified.
Update: it seems that the layer warning is a bug.
Upvotes: 3
Views: 4271
Reputation: 29240
VkExternalMemoryBufferCreateInfoKHR
is for creating memory that is shared across APIs, or potentially across Vulkan instances or devices where the underlying physical device is the same.
There is an example of using the external memory API to share texture image information between OpenGL and Vulkan in my examples repository here. This example uses the Win32 HANDLE versions of the API, but the functionality is equivalent to the FD versions, just with a different type for storing the identifier to be passed between different APIs.
Another question is about VkExternalMemoryBufferCreateInfoKHR which is used in VkBufferCreateInfo::pNext
This structure is used to inform the vulkan instance that the buffer in question may be shared, which may impact how the Vulkan driver manages it internally.
I think this structure is used when a Vulkan buffer is being created from external memory. During buffer (or image) creation, you'd use this structure to mark that the image would be backed by external memory, then instead of the normal allocation you'd set the pNext
of the MemoryAllocateInfo to a ImportMemoryHostPointerInfoEXT
instance containing the shared handle. I suspect it's not used in my example because there I use Vulkan only for exporting, and the GL side does the importing. If you're using Vulkan on both the export and import side, you may need it.
Upvotes: 3