/ appendices / VK_NV_external_memory_win32.txt
VK_NV_external_memory_win32.txt
1 include::meta/VK_NV_external_memory_win32.txt[] 2 3 *Last Modified Date*:: 4 2016-08-19 5 *IP Status*:: 6 No known IP claims. 7 *Contributors*:: 8 - James Jones, NVIDIA 9 - Carsten Rohde, NVIDIA 10 11 Applications may wish to export memory to other Vulkan instances or other 12 APIs, or import memory from other Vulkan instances or other APIs to enable 13 Vulkan workloads to be split up across application module, process, or API 14 boundaries. 15 This extension enables win32 applications to export win32 handles from 16 Vulkan memory objects such that the underlying resources can be referenced 17 outside the Vulkan instance that created them, and import win32 handles 18 created in the Direct3D API to Vulkan memory objects. 19 20 === New Object Types 21 22 None. 23 24 === New Enum Constants 25 26 * Extending elink:VkStructureType: 27 ** ename:VK_STRUCTURE_TYPE_IMPORT_MEMORY_WIN32_HANDLE_INFO_NV 28 ** ename:VK_STRUCTURE_TYPE_EXPORT_MEMORY_WIN32_HANDLE_INFO_NV 29 30 === New Enums 31 32 None. 33 34 === New Structures 35 36 * Extending slink:VkMemoryAllocateInfo 37 ** slink:VkImportMemoryWin32HandleInfoNV 38 * Extends slink:VkMemoryAllocateInfo 39 ** slink:VkExportMemoryWin32HandleInfoNV 40 41 === New Functions 42 43 * flink:vkGetMemoryWin32HandleNV 44 45 === Issues 46 47 1) If memory objects are shared between processes and APIs, is this 48 considered aliasing according to the rules outlined in the 49 <<resources-memory-aliasing,Memory Aliasing>> section? 50 51 *RESOLVED*: Yes, but strict exceptions to the rules are added to allow some 52 forms of aliasing in these cases. 53 Further, other extensions may build upon these new aliasing rules to define 54 specific support usage within Vulkan for imported native memory objects, or 55 memory objects from other APIs. 56 57 2) Are new image layouts or metadata required to specify image layouts and 58 layout transitions compatible with non-Vulkan APIs, or with other instances 59 of the same Vulkan driver? 60 61 *RESOLVED*: No. 62 Separate instances of the same Vulkan driver running on the same GPU should 63 have identical internal layout semantics, so applictions have the tools they 64 need to ensure views of images are consistent between the two instances. 65 Other APIs will fall into two categories: Those that are Vulkan compatible 66 (a term to be defined by subsequent interopability extensions), or Vulkan 67 incompatible. 68 When sharing images with Vulkan incompatible APIs, the Vulkan image must be 69 transitioned to the ename:VK_IMAGE_LAYOUT_GENERAL layout before handing it 70 off to the external API. 71 72 Note this does not attempt to address cross-device transitions, nor 73 transitions to engines on the same device which are not visible within the 74 Vulkan API. 75 Both of these are beyond the scope of this extension. 76 77 3) Do applications need to call code:CloseHandle() on the values returned 78 from flink:vkGetMemoryWin32HandleNV when pname:handleType is 79 ename:VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT_NV? 80 81 *RESOLVED*: Yes, unless it is passed back in to another driver instance to 82 import the object. 83 A successful get call transfers ownership of the handle to the application, 84 while an import transfers ownership to the associated driver. 85 Destroying the memory object will not destroy the handle or the handle's 86 reference to the underlying memory resource. 87 88 === Examples 89 90 [source,c++] 91 -------------------------------------- 92 93 // 94 // Create an exportable memory object and export an external 95 // handle from it. 96 // 97 98 // Pick an external format and handle type. 99 static const VkFormat format = VK_FORMAT_R8G8B8A8_UNORM; 100 static const VkExternalMemoryHandleTypeFlagsNV handleType = 101 VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT_NV; 102 103 extern VkPhysicalDevice physicalDevice; 104 extern VkDevice device; 105 106 VkPhysicalDeviceMemoryProperties memoryProperties; 107 VkExternalImageFormatPropertiesNV properties; 108 VkExternalMemoryImageCreateInfoNV externalMemoryImageCreateInfo; 109 VkDedicatedAllocationImageCreateInfoNV dedicatedImageCreateInfo; 110 VkImageCreateInfo imageCreateInfo; 111 VkImage image; 112 VkMemoryRequirements imageMemoryRequirements; 113 uint32_t numMemoryTypes; 114 uint32_t memoryType; 115 VkExportMemoryAllocateInfoNV exportMemoryAllocateInfo; 116 VkDedicatedAllocationMemoryAllocateInfoNV dedicatedAllocationInfo; 117 VkMemoryAllocateInfo memoryAllocateInfo; 118 VkDeviceMemory memory; 119 VkResult result; 120 HANDLE memoryHnd; 121 122 // Figure out how many memory types the device supports 123 vkGetPhysicalDeviceMemoryProperties(physicalDevice, 124 &memoryProperties); 125 numMemoryTypes = memoryProperties.memoryTypeCount; 126 127 // Check the external handle type capabilities for the chosen format 128 // Exportable 2D image support with at least 1 mip level, 1 array 129 // layer, and VK_SAMPLE_COUNT_1_BIT using optimal tiling and supporting 130 // texturing and color rendering is required. 131 result = vkGetPhysicalDeviceExternalImageFormatPropertiesNV( 132 physicalDevice, 133 format, 134 VK_IMAGE_TYPE_2D, 135 VK_IMAGE_TILING_OPTIMAL, 136 VK_IMAGE_USAGE_SAMPLED_BIT | 137 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, 138 0, 139 handleType, 140 &properties); 141 142 if ((result != VK_SUCCESS) || 143 !(properties.externalMemoryFeatures & 144 VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT_NV)) { 145 abort(); 146 } 147 148 // Set up the external memory image creation info 149 memset(&externalMemoryImageCreateInfo, 150 0, sizeof(externalMemoryImageCreateInfo)); 151 externalMemoryImageCreateInfo.sType = 152 VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO_NV; 153 externalMemoryImageCreateInfo.handleTypes = handleType; 154 if (properties.externalMemoryFeatures & 155 VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT_NV) { 156 memset(&dedicatedImageCreateInfo, 0, sizeof(dedicatedImageCreateInfo)); 157 dedicatedImageCreateInfo.sType = 158 VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_IMAGE_CREATE_INFO_NV; 159 dedicatedImageCreateInfo.dedicatedAllocation = VK_TRUE; 160 externalMemoryImageCreateInfo.pNext = &dedicatedImageCreateInfo; 161 } 162 // Set up the core image creation info 163 memset(&imageCreateInfo, 0, sizeof(imageCreateInfo)); 164 imageCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; 165 imageCreateInfo.pNext = &externalMemoryImageCreateInfo; 166 imageCreateInfo.format = format; 167 imageCreateInfo.extent.width = 64; 168 imageCreateInfo.extent.height = 64; 169 imageCreateInfo.extent.depth = 1; 170 imageCreateInfo.mipLevels = 1; 171 imageCreateInfo.arrayLayers = 1; 172 imageCreateInfo.samples = VK_SAMPLE_COUNT_1_BIT; 173 imageCreateInfo.tiling = VK_IMAGE_TILING_OPTIMAL; 174 imageCreateInfo.usage = VK_IMAGE_USAGE_SAMPLED_BIT | 175 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; 176 imageCreateInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE; 177 imageCreateInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; 178 179 vkCreateImage(device, &imageCreateInfo, NULL, &image); 180 181 vkGetImageMemoryRequirements(device, 182 image, 183 &imageMemoryRequirements); 184 185 // For simplicity, just pick the first compatible memory type. 186 for (memoryType = 0; memoryType < numMemoryTypes; memoryType++) { 187 if ((1 << memoryType) & imageMemoryRequirements.memoryTypeBits) { 188 break; 189 } 190 } 191 192 // At least one memory type must be supported given the prior external 193 // handle capability check. 194 assert(memoryType < numMemoryTypes); 195 196 // Allocate the external memory object. 197 memset(&exportMemoryAllocateInfo, 0, sizeof(exportMemoryAllocateInfo)); 198 exportMemoryAllocateInfo.sType = 199 VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO_NV; 200 exportMemoryAllocateInfo.handleTypes = handleType; 201 if (properties.externalMemoryFeatures & 202 VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT_NV) { 203 memset(&dedicatedAllocationInfo, 0, sizeof(dedicatedAllocationInfo)); 204 dedicatedAllocationInfo.sType = 205 VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_MEMORY_ALLOCATE_INFO_NV; 206 dedicatedAllocationInfo.image = image; 207 exportMemoryAllocateInfo.pNext = &dedicatedAllocationInfo; 208 } 209 memset(&memoryAllocateInfo, 0, sizeof(memoryAllocateInfo)); 210 memoryAllocateInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; 211 memoryAllocateInfo.pNext = &exportMemoryAllocateInfo; 212 memoryAllocateInfo.allocationSize = imageMemoryRequirements.size; 213 memoryAllocateInfo.memoryTypeIndex = memoryType; 214 215 vkAllocateMemory(device, &memoryAllocateInfo, NULL, &memory); 216 217 if (!(properties.externalMemoryFeatures & 218 VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT_NV)) { 219 vkBindImageMemory(device, image, memory, 0); 220 } 221 222 // Get the external memory opaque FD handle 223 vkGetMemoryWin32HandleNV(device, memory, &memoryHnd); 224 225 -------------------------------------- 226 227 === Version History 228 229 * Revision 1, 2016-08-11 (James Jones) 230 - Initial draft