1// Copyright 2016-2024 The Khronos Group Inc. 2// 3// SPDX-License-Identifier: CC-BY-4.0 4 5include::{generated}/meta/{refprefix}VK_KHR_external_memory.adoc[] 6 7=== Other Extension Metadata 8 9*Last Modified Date*:: 10 2016-10-20 11*IP Status*:: 12 No known IP claims. 13*Interactions and External Dependencies*:: 14 - Interacts with `apiext:VK_KHR_dedicated_allocation`. 15 - Interacts with `apiext:VK_NV_dedicated_allocation`. 16*Contributors*:: 17 - Faith Ekstrand, Intel 18 - Ian Elliott, Google 19 - Jesse Hall, Google 20 - Tobias Hector, Imagination Technologies 21 - James Jones, NVIDIA 22 - Jeff Juliano, NVIDIA 23 - Matthew Netsch, Qualcomm Technologies, Inc. 24 - Daniel Rakos, AMD 25 - Carsten Rohde, NVIDIA 26 - Ray Smith, ARM 27 - Lina Versace, Google 28 29=== Description 30 31An application may wish to reference device memory in multiple Vulkan 32logical devices or instances, in multiple processes, and/or in multiple 33APIs. 34This extension enables an application to export non-Vulkan handles from 35Vulkan memory objects such that the underlying resources can be referenced 36outside the scope of the Vulkan logical device that created them. 37 38=== Promotion to Vulkan 1.1 39 40All functionality in this extension is included in core Vulkan 1.1, with the 41KHR suffix omitted. 42The original type, enum and command names are still available as aliases of 43the core functionality. 44 45include::{generated}/interfaces/VK_KHR_external_memory.adoc[] 46 47=== Issues 48 491) How do applications correlate two physical devices across process or 50Vulkan instance boundaries? 51 52*RESOLVED*: New device ID fields have been introduced by 53`apiext:VK_KHR_external_memory_capabilities`. 54These fields, combined with the existing 55slink:VkPhysicalDeviceProperties::pname:driverVersion field can be used to 56identify compatible devices across processes, drivers, and APIs. 57slink:VkPhysicalDeviceProperties::pname:pipelineCacheUUID is not sufficient 58for this purpose because despite its description in the specification, it 59need only identify a unique pipeline cache format in practice. 60Multiple devices may be able to use the same pipeline cache data, and hence 61it would be desirable for all of them to have the same pipeline cache UUID. 62However, only the same concrete physical device can be used when sharing 63memory, so an actual unique device ID was introduced. 64Further, the pipeline cache UUID was specific to Vulkan, but correlation 65with other, non-extensible APIs is required to enable interoperation with 66those APIs. 67 682) If memory objects are shared between processes and APIs, is this 69considered aliasing according to the rules outlined in the 70<<resources-memory-aliasing,Memory Aliasing>> section? 71 72*RESOLVED*: Yes. 73Applications must take care to obey all restrictions imposed on aliased 74resources when using memory across multiple Vulkan instances or other APIs. 75 763) Are new image layouts or metadata required to specify image layouts and 77layout transitions compatible with non-Vulkan APIs, or with other instances 78of the same Vulkan driver? 79 80*RESOLVED*: Separate instances of the same Vulkan driver running on the same 81GPU should have identical internal layout semantics, so applications have 82the tools they need to ensure views of images are consistent between the two 83instances. 84Other APIs will fall into two categories: Those that are Vulkan- compatible, 85and those that are Vulkan-incompatible. 86Vulkan-incompatible APIs will require the image to be in the GENERAL layout 87whenever they are accessing them. 88 89Note this does not attempt to address cross-device transitions, nor 90transitions to engines on the same device which are not visible within the 91Vulkan API. 92Both of these are beyond the scope of this extension. 93 944) Is a new barrier flag or operation of some type needed to prepare 95external memory for handoff to another Vulkan instance or API and/or receive 96it from another instance or API? 97 98*RESOLVED*: Yes. 99Some implementations need to perform additional cache management when 100transitioning memory between address spaces and other APIs, instances, or 101processes which may operate in a separate address space. 102Options for defining this transition include: 103 104 * A new structure that can be added to the pname:pNext list in 105 slink:VkMemoryBarrier, slink:VkBufferMemoryBarrier, and 106 slink:VkImageMemoryBarrier. 107 * A new bit in tlink:VkAccessFlags that can be set to indicate an 108 "`external`" access. 109 * A new bit in tlink:VkDependencyFlags 110 * A new special queue family that represents an "`external`" queue. 111 112A new structure has the advantage that the type of external transition can 113be described in as much detail as necessary. 114However, there is not currently a known need for anything beyond 115differentiating between external and internal accesses, so this is likely an 116over-engineered solution. 117The access flag bit has the advantage that it can be applied at buffer, 118image, or global granularity, and semantically it maps pretty well to the 119operation being described. 120Additionally, the API already includes ename:VK_ACCESS_MEMORY_READ_BIT and 121ename:VK_ACCESS_MEMORY_WRITE_BIT which appear to be intended for this 122purpose. 123However, there is no obvious pipeline stage that would correspond to an 124external access, and therefore no clear way to use 125ename:VK_ACCESS_MEMORY_READ_BIT or ename:VK_ACCESS_MEMORY_WRITE_BIT. 126tlink:VkDependencyFlags and tlink:VkPipelineStageFlags operate at command 127granularity rather than image or buffer granularity, which would make an 128entire pipeline barrier an internal->external or external->internal barrier. 129This may not be a problem in practice, but seems like the wrong scope. 130Another downside of tlink:VkDependencyFlags is that it lacks inherent 131directionality: there are no ptext:src and ptext:dst variants of it in the 132barrier or dependency description semantics, so two bits might need to be 133added to describe both internal->external and external->internal 134transitions. 135Transitioning a resource to a special queue family corresponds well with the 136operation of transitioning to a separate Vulkan instance, in that both 137operations ideally include scheduling a barrier on both sides of the 138transition: Both the releasing and the acquiring queue or process. 139Using a special queue family requires adding an additional reserved queue 140family index. 141Re-using ename:VK_QUEUE_FAMILY_IGNORED would have left it unclear how to 142transition a concurrent usage resource from one process to another, since 143the semantics would have likely been equivalent to the currently-ignored 144transition of 145ename:VK_QUEUE_FAMILY_IGNORED{nbsp}->{nbsp}ename:VK_QUEUE_FAMILY_IGNORED. 146Fortunately, creating a new reserved queue family index is not invasive. 147 148Based on the above analysis, the approach of transitioning to a special 149"`external`" queue family was chosen. 150 1515) Do internal driver memory arrangements and/or other internal driver image 152properties need to be exported and imported when sharing images across 153processes or APIs. 154 155*RESOLVED*: Some vendors claim this is necessary on their implementations, 156but it was determined that the security risks of allowing opaque metadata to 157be passed from applications to the driver were too high. 158Therefore, implementations which require metadata will need to associate it 159with the objects represented by the external handles, and rely on the 160dedicated allocation mechanism to associate the exported and imported memory 161objects with a single image or buffer. 162 1636) Most prior interoperation and cross-process sharing APIs have been based 164on image-level sharing. 165Should Vulkan sharing be based on memory-object sharing or image sharing? 166 167*RESOLVED*: These extensions have assumed memory-level sharing is the 168correct granularity. 169Vulkan is a lower-level API than most prior APIs, and as such attempts to 170closely align with to the underlying primitives of the hardware and 171system-level drivers it abstracts. 172In general, the resource that holds the backing store for both images and 173buffers of various types is memory. 174Images and buffers are merely metadata containing brief descriptions of the 175layout of bits within that memory. 176 177Because memory object-based sharing is aligned with the overall Vulkan API 178design, it enables the full range of Vulkan capabilities with external 179objects. 180External memory can be used as backing for sparse images, for example, 181whereas such usage would be awkward at best with a sharing mechanism based 182on higher-level primitives such as images. 183Further, aligning the mechanism with the API in this way provides some hope 184of trivial compatibility with future API enhancements. 185If new objects backed by memory objects are added to the API, they too can 186be used across processes with minimal additions to the base external memory 187APIs. 188 189Earlier APIs implemented interop at a higher level, and this necessitated 190entirely separate sharing APIs for images and buffers. 191To co-exist and interoperate with those APIs, the Vulkan external sharing 192mechanism must accommodate their model. 193However, if it can be agreed that memory-based sharing is the more desirable 194and forward-looking design, legacy interoperation constraints can be 195considered another reason to favor memory-based sharing: while native and 196legacy driver primitives that may be used to implement sharing may not be as 197low-level as the API here suggests, raw memory is still the least common 198denominator among the types. 199Image-based sharing can be cleanly derived from a set of base memory- object 200sharing APIs with minimal effort, whereas image-based sharing does not 201generalize well to buffer or raw-memory sharing. 202Therefore, following the general Vulkan design principle of minimalism, it 203is better to expose interopability with image-based native and external 204primitives via the memory sharing API, and place sufficient limits on their 205usage to ensure they can be used only as backing for equivalent Vulkan 206images. 207This provides a consistent API for applications regardless of which platform 208or external API they are targeting, which makes development of multi-API and 209multi-platform applications simpler. 210 2117) Should Vulkan define a common external handle type and provide Vulkan 212functions to facilitate cross-process sharing of such handles rather than 213relying on native handles to define the external objects? 214 215*RESOLVED*: No. 216Cross-process sharing of resources is best left to native platforms. 217There are myriad security and extensibility issues with such a mechanism, 218and attempting to re-solve all those issues within Vulkan does not align 219with Vulkan's purpose as a graphics API. 220If desired, such a mechanism could be built as a layer or helper library on 221top of the opaque native handle defined in this family of extensions. 222 2238) Must implementations provide additional guarantees about state implicitly 224included in memory objects for those memory objects that may be exported? 225 226*RESOLVED*: Implementations must ensure that sharing memory objects does not 227transfer any information between the exporting and importing instances and 228APIs other than that required to share the data contained in the memory 229objects explicitly shared. 230As specific examples, data from previously freed memory objects that used 231the same underlying physical memory, and data from memory objects using 232adjacent physical memory must not be visible to applications importing an 233exported memory object. 234 2359) Must implementations validate external handles the application provides 236as inputs to memory import operations? 237 238*RESOLVED*: Implementations must return an error to the application if the 239provided memory handle cannot be used to complete the requested import 240operation. 241However, implementations need not validate handles are of the exact type 242specified by the application. 243 244=== Version History 245 246 * Revision 1, 2016-10-20 (James Jones) 247 ** Initial version 248