// Copyright (c) 2021 Google Inc.
//
// SPDX-License-Identifier: CC-BY-4.0

[[fuchsia-external-memory]]
=== Fuchsia External Memory

On Fuchsia, when allocating memory that may: be imported from another
device, process or Vulkan instance, add a
slink:VkImportMemoryZirconHandleInfoFUCHSIA structure to the pname:pNext
chain of the slink:VkMemoryAllocateInfo structure.

External memory on Fuchsia is imported and exported using VMO handles of
type code:zx_handle_t.
VMO handles to external memory are canonically obtained from Fuchsia's
Sysmem service or from syscalls such as sname:zx_vmo_create().
VMO handles for import can also be obtained by exporting them from another
Vulkan instance as described in <<exporting-fuchsia-device-memory,exporting
fuchsia device memory>>.

Importing VMO handles to the Vulkan instance transfers ownership of the
handle to the instance from the application.
The application must: not perform any operations on the handle after
successful import.

Applications can: import the same underlying memory into multiple instances
of Vulkan, into the same instance from which it was exported, and multiple
times into a given Vulkan instance.
In all cases, each import operation must: create a distinct
sname:VkDeviceMemory object.


[[importing-fuchsia-external-memory]]
==== Importing Fuchsia External Memory

[open,refpage='VkImportMemoryZirconHandleInfoFUCHSIA',desc='Structure specifying import parameters for Zircon handle to external memory',type='structs']
--
The sname:VkImportMemoryZirconHandleInfoFUCHSIA structure is defined as:

include::{generated}/api/structs/VkImportMemoryZirconHandleInfoFUCHSIA.txt[]

  * pname:sType is the type of this structure.
  * pname:pNext is `NULL` or a pointer to a structure extending this
    structure.
  * pname:handleType is a elink:VkExternalMemoryHandleTypeFlagBits value
    specifying the type of pname:handle.
  * pname:handle is a code:zx_handle_t (Zircon) handle to the external
    memory.

.Valid Usage
****
  * [[VUID-VkImportMemoryZirconHandleInfoFUCHSIA-handleType-04771]]
    pname:handleType must: be
    ename:VK_EXTERNAL_MEMORY_HANDLE_TYPE_ZIRCON_VMO_BIT_FUCHSIA.
  * [[VUID-VkImportMemoryZirconHandleInfoFUCHSIA-handle-04772]]
    pname:handle must be a valid VMO handle.
****

include::{generated}/validity/structs/VkImportMemoryZirconHandleInfoFUCHSIA.txt[]
--

[open,refpage='vkGetMemoryZirconHandlePropertiesFUCHSIA',desc='Get a Zircon handle properties for an external memory object',type='protos']
--
To obtain the memoryTypeIndex for the slink:VkMemoryAllocateInfo structure,
call fname:vkGetMemoryZirconHandlePropertiesFUCHSIA:

include::{generated}/api/protos/vkGetMemoryZirconHandlePropertiesFUCHSIA.txt[]

  * pname:device is the slink:VkDevice.
  * pname:handleType is a elink:VkExternalMemoryHandleTypeFlagBits value
    specifying the type of pname:zirconHandle
  * pname:zirconHandle is a code:zx_handle_t (Zircon) handle to the external
    resource.
  * pname:pMemoryZirconHandleProperties is a pointer to a
    slink:VkMemoryZirconHandlePropertiesFUCHSIA structure in which the
    result will be stored.

.Valid Usage
****
  * [[VUID-vkGetMemoryZirconHandlePropertiesFUCHSIA-handleType-04773]]
    pname:handleType must: be
    ename:VK_EXTERNAL_MEMORY_HANDLE_TYPE_ZIRCON_VMO_BIT_FUCHSIA.
  * [[VUID-vkGetMemoryZirconHandlePropertiesFUCHSIA-zirconHandle-04774]]
    pname:zirconHandle must reference a valid VMO.
****

include::{generated}/validity/protos/vkGetMemoryZirconHandlePropertiesFUCHSIA.txt[]
--

[open,refpage='VkMemoryZirconHandlePropertiesFUCHSIA',desc='Structure specifying Zircon handle compatible external memory',type='structs']
--
The sname:VkMemoryZirconHandlePropertiesFUCHSIA structure is defined as:

include::{generated}/api/structs/VkMemoryZirconHandlePropertiesFUCHSIA.txt[]

  * pname:sType is the type of this structure.
  * pname:pNext is `NULL` or a pointer to a structure extending this
    structure.
  * pname:memoryTypeBits a bitmask containing one bit set for every memory
    type which the specified handle can be imported as.

include::{generated}/validity/structs/VkMemoryZirconHandlePropertiesFUCHSIA.txt[]
--

With pname:pMemoryZirconHandleProperties now successfully populated by
flink:vkGetMemoryZirconHandlePropertiesFUCHSIA, assign the
slink:VkMemoryAllocateInfo memoryTypeIndex field to a memory type which has
a bit set in the slink:VkMemoryZirconHandlePropertiesFUCHSIA memoryTypeBits
field.


[[exporting-fuchsia-device-memory]]
==== Exporting Fuchsia Device Memory
Similar to importing, exporting a VMO handle from Vulkan transfers ownership
of the handle from the Vulkan instance to the application.
The application is responsible for closing the handle with
code:zx_handle_close() when it is no longer in use.


[open,refpage='vkGetMemoryZirconHandleFUCHSIA',desc='Get a Zircon handle for an external memory object',type='protos']
--
To export device memory as a Zircon handle that can be used by another
instance, device, or process, the handle to the slink:VkDeviceMemory must be
retrieved using flink:vkGetMemoryZirconHandleFUCHSIA:

include::{generated}/api/protos/vkGetMemoryZirconHandleFUCHSIA.txt[]

  * pname:device is the slink:VkDevice.
  * pname:pGetZirconHandleInfo is a pointer to a
    slink:VkMemoryGetZirconHandleInfoFUCHSIA structure.
  * pname:pZirconHandle is a pointer to a code:zx_handle_t which holds the
    resulting Zircon handle.

include::{generated}/validity/protos/vkGetMemoryZirconHandleFUCHSIA.txt[]
--

[open,refpage='VkMemoryGetZirconHandleInfoFUCHSIA',desc='Structure specifying export parameters for Zircon handle to device memory',type='structs']
--
sname:VkMemoryGetZirconHandleInfoFUCHSIA is defined as:

include::{generated}/api/structs/VkMemoryGetZirconHandleInfoFUCHSIA.txt[]

  * pname:sType is the type of this structure.
  * pname:pNext is `NULL` or a pointer to a structure extending this
    structure.
  * pname:memory the slink:VkDeviceMemory being exported.
  * pname:handleType is a elink:VkExternalMemoryHandleTypeFlagBits value
    specifying the type of the handle pointed to by
    flink:vkGetMemoryZirconHandleFUCHSIA::pname:pZirconHandle.

.Valid Usage
****
  * [[VUID-VkMemoryGetZirconHandleInfoFUCHSIA-handleType-04775]]
    pname:handleType must: be
    ename:VK_EXTERNAL_MEMORY_HANDLE_TYPE_ZIRCON_VMO_BIT_FUCHSIA.
  * [[VUID-VkMemoryGetZirconHandleInfoFUCHSIA-handleType-04776]]
    pname:handleType must: have been included in the sname:handleTypes field
    of the sname:VkExportMemoryAllocateInfo structure when the external
    memory was allocated.
****

include::{generated}/validity/structs/VkMemoryGetZirconHandleInfoFUCHSIA.txt[]
--

With the result pname:pZirconHandle now obtained, the memory properties for
the handle can be retrieved using
flink:vkGetMemoryZirconHandlePropertiesFUCHSIA as documented above
substituting the dereferenced, retrieved pname:pZirconHandle in for the
pname:zirconHandle argument.
