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