/ appendices / VK_NV_win32_keyed_mutex.txt
VK_NV_win32_keyed_mutex.txt
  1  include::meta/VK_NV_win32_keyed_mutex.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 that wish to import Direct3D 11 memory objects into the Vulkan
 12  API may wish to use the native keyed mutex mechanism to synchronize access
 13  to the memory between Vulkan and Direct3D.
 14  This extension provides a way for an application to access the keyed mutex
 15  associated with an imported Vulkan memory object when submitting command
 16  buffers to a queue.
 17  
 18  === New Object Types
 19  
 20  None.
 21  
 22  === New Enum Constants
 23  
 24    * Extending elink:VkStructureType:
 25    ** ename:VK_STRUCTURE_TYPE_WIN32_KEYED_MUTEX_ACQUIRE_RELEASE_INFO_NV
 26  
 27  === New Enums
 28  
 29  None.
 30  
 31  === New Structures
 32  
 33    * Extending slink:VkSubmitInfo:
 34    ** slink:VkWin32KeyedMutexAcquireReleaseInfoNV
 35  
 36  === New Functions
 37  
 38  None.
 39  
 40  === Issues
 41  
 42  None.
 43  
 44  === Examples
 45  
 46  [source,c++]
 47  ----------------------------------------
 48  
 49      //
 50      // Import a memory object from Direct3D 11, and synchronize
 51      // access to it in Vulkan using keyed mutex objects.
 52      //
 53  
 54      extern VkPhysicalDevice physicalDevice;
 55      extern VkDevice device;
 56      extern HANDLE sharedNtHandle;
 57  
 58      static const VkFormat format = VK_FORMAT_R8G8B8A8_UNORM;
 59      static const VkExternalMemoryHandleTypeFlagsNV handleType =
 60          VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_IMAGE_BIT_NV;
 61  
 62      VkPhysicalDeviceMemoryProperties memoryProperties;
 63      VkExternalImageFormatPropertiesNV properties;
 64      VkExternalMemoryImageCreateInfoNV externalMemoryImageCreateInfo;
 65      VkImageCreateInfo imageCreateInfo;
 66      VkImage image;
 67      VkMemoryRequirements imageMemoryRequirements;
 68      uint32_t numMemoryTypes;
 69      uint32_t memoryType;
 70      VkImportMemoryWin32HandleInfoNV importMemoryInfo;
 71      VkMemoryAllocateInfo memoryAllocateInfo;
 72      VkDeviceMemory mem;
 73      VkResult result;
 74  
 75      // Figure out how many memory types the device supports
 76      vkGetPhysicalDeviceMemoryProperties(physicalDevice,
 77                                          &memoryProperties);
 78      numMemoryTypes = memoryProperties.memoryTypeCount;
 79  
 80      // Check the external handle type capabilities for the chosen format
 81      // Importable 2D image support with at least 1 mip level, 1 array
 82      // layer, and VK_SAMPLE_COUNT_1_BIT using optimal tiling and supporting
 83      // texturing and color rendering is required.
 84      result = vkGetPhysicalDeviceExternalImageFormatPropertiesNV(
 85          physicalDevice,
 86          format,
 87          VK_IMAGE_TYPE_2D,
 88          VK_IMAGE_TILING_OPTIMAL,
 89          VK_IMAGE_USAGE_SAMPLED_BIT |
 90          VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
 91          0,
 92          handleType,
 93          &properties);
 94  
 95      if ((result != VK_SUCCESS) ||
 96          !(properties.externalMemoryFeatures &
 97            VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT_NV)) {
 98          abort();
 99      }
100  
101      // Set up the external memory image creation info
102      memset(&externalMemoryImageCreateInfo,
103             0, sizeof(externalMemoryImageCreateInfo));
104      externalMemoryImageCreateInfo.sType =
105          VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO_NV;
106      externalMemoryImageCreateInfo.handleTypes = handleType;
107      // Set up the  core image creation info
108      memset(&imageCreateInfo, 0, sizeof(imageCreateInfo));
109      imageCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
110      imageCreateInfo.pNext = &externalMemoryImageCreateInfo;
111      imageCreateInfo.format = format;
112      imageCreateInfo.extent.width = 64;
113      imageCreateInfo.extent.height = 64;
114      imageCreateInfo.extent.depth = 1;
115      imageCreateInfo.mipLevels = 1;
116      imageCreateInfo.arrayLayers = 1;
117      imageCreateInfo.samples = VK_SAMPLE_COUNT_1_BIT;
118      imageCreateInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
119      imageCreateInfo.usage = VK_IMAGE_USAGE_SAMPLED_BIT |
120          VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
121      imageCreateInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
122      imageCreateInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
123  
124      vkCreateImage(device, &imageCreateInfo, NULL, &image);
125      vkGetImageMemoryRequirements(device,
126                                   image,
127                                   &imageMemoryRequirements);
128  
129      // For simplicity, just pick the first compatible memory type.
130      for (memoryType = 0; memoryType < numMemoryTypes; memoryType++) {
131          if ((1 << memoryType) & imageMemoryRequirements.memoryTypeBits) {
132              break;
133          }
134      }
135  
136      // At least one memory type must be supported given the prior external
137      // handle capability check.
138      assert(memoryType < numMemoryTypes);
139  
140      // Allocate the external memory object.
141      memset(&exportMemoryAllocateInfo, 0, sizeof(exportMemoryAllocateInfo));
142      exportMemoryAllocateInfo.sType =
143          VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO_NV;
144      importMemoryInfo.handleTypes = handleType;
145      importMemoryInfo.handle = sharedNtHandle;
146  
147      memset(&memoryAllocateInfo, 0, sizeof(memoryAllocateInfo));
148      memoryAllocateInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
149      memoryAllocateInfo.pNext = &exportMemoryAllocateInfo;
150      memoryAllocateInfo.allocationSize = imageMemoryRequirements.size;
151      memoryAllocateInfo.memoryTypeIndex = memoryType;
152  
153      vkAllocateMemory(device, &memoryAllocateInfo, NULL, &mem);
154  
155      vkBindImageMemory(device, image, mem, 0);
156  
157      ...
158  
159      const uint64_t acquireKey = 1;
160      const uint32_t timeout = INFINITE;
161      const uint64_t releaseKey = 2;
162  
163      VkWin32KeyedMutexAcquireReleaseInfoNV keyedMutex =
164          { VK_STRUCTURE_TYPE_WIN32_KEYED_MUTEX_ACQUIRE_RELEASE_INFO_NV };
165      keyedMutex.acquireCount = 1;
166      keyedMutex.pAcquireSyncs = &mem;
167      keyedMutex.pAcquireKeys = &acquireKey;
168      keyedMutex.pAcquireTimeoutMilliseconds = &timeout;
169      keyedMutex.releaseCount = 1;
170      keyedMutex.pReleaseSyncs = &mem;
171      keyedMutex.pReleaseKeys = &releaseKey;
172  
173      VkSubmitInfo submit_info = { VK_STRUCTURE_TYPE_SUBMIT_INFO, &keyedMutex };
174      submit_info.commandBufferCount = 1;
175      submit_info.pCommandBuffers = &cmd_buf;
176      vkQueueSubmit(queue, 1, &submit_info, VK_NULL_HANDLE);
177  
178  ----------------------------------------
179  
180  === Version History
181  
182    * Revision 2, 2016-08-11 (James Jones)
183      - Updated sample code based on the NV external memory extensions.
184      - Renamed from NVX to NV extension.
185      - Added Overview and Description sections.
186      - Updated sample code to use the NV external memory extensions.
187  
188    * Revision 1, 2016-06-14 (Carsten Rohde)
189      - Initial draft.