/ 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