summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFaith Ekstrand <faith.ekstrand@collabora.com>2024-02-14 23:10:01 -0600
committerGitHub <noreply@github.com>2024-02-14 21:10:01 -0800
commit0c355559d6ca3d92edbaafb27347b0cbe34f3b2f (patch)
treedc72983811ef32b30b3454c4019f9a298c1291ef
parentd99193d3fcc4b2a0dacc0a9d7e4951ea611a3e96 (diff)
downloadgfxstream-protocols-0c355559d6ca3d92edbaafb27347b0cbe34f3b2f.tar.gz
Add a new extension: VK_EXT_map_memory_placed (#1906)
-rw-r--r--appendices/VK_EXT_map_memory_placed.adoc33
-rw-r--r--chapters/features.adoc31
-rw-r--r--chapters/limits.adoc27
-rw-r--r--chapters/memory.adoc158
-rw-r--r--proposals/VK_EXT_map_memory_placed.adoc180
-rwxr-xr-xxml/vk.xml45
6 files changed, 460 insertions, 14 deletions
diff --git a/appendices/VK_EXT_map_memory_placed.adoc b/appendices/VK_EXT_map_memory_placed.adoc
new file mode 100644
index 00000000..5108d732
--- /dev/null
+++ b/appendices/VK_EXT_map_memory_placed.adoc
@@ -0,0 +1,33 @@
+// Copyright 2022-2023 The Khronos Group Inc.
+//
+// SPDX-License-Identifier: CC-BY-4.0
+
+include::{generated}/meta/{refprefix}VK_EXT_map_memory_placed.adoc[]
+
+=== Other Extension Metadata
+
+*Last Modified Date*::
+ 2023-03-21
+*IP Status*::
+ No known IP claims.
+*Interactions and External Dependencies*::
+ - Depends on apitext:VK_KHR_map_memory2
+ - Interacts with apitext:VK_EXT_external_memory_host
+*Contributors*::
+ - Faith Ekstrand, Collabora
+ - Tobias Hector, AMD
+ - James Jones, NVIDIA
+ - Georg Lehmann, Valve
+ - Derek Lesho, Codeweavers
+
+=== Description
+
+This extension allows a client to request that flink:vkMapMemory2KHR
+attempt to place the memory map at a particular virtual address.
+
+include::{generated}/interfaces/VK_EXT_map_memory_placed.adoc[]
+
+=== Version History
+
+ * Revision 0, 2024-01-14 (Faith Ekstrand)
+ ** Internal revisions
diff --git a/chapters/features.adoc b/chapters/features.adoc
index be87d683..9f23f084 100644
--- a/chapters/features.adoc
+++ b/chapters/features.adoc
@@ -7529,6 +7529,33 @@ include::{generated}/validity/structs/VkPhysicalDeviceShaderQuadControlFeaturesK
--
endif::VK_KHR_shader_quad_control[]
+ifdef::VK_EXT_map_memory_placed[]
+[open,refpage='VkPhysicalDeviceMapMemoryPlacedFeaturesEXT',desc='Structure describing placed memory map features that can be supported by an implementation',type='structs']
+--
+The sname:VkPhysicalDeviceMapMemoryPlacedFeaturesEXT structure is defined
+as:
+
+include::{generated}/api/structs/VkPhysicalDeviceMapMemoryPlacedFeaturesEXT.adoc[]
+
+This structure describes the following features:
+
+ * [[features-memoryMapPlaced]] pname:memoryMapPlaced indicates that
+ the implementation supports placing memory maps at client-specified
+ virtual addresses.
+ * [[features-memoryMapRangePlaced]] pname:memoryMapRangePlaced indicates
+ that the implementation supports placing memory maps of a subrange of a
+ memory object at client-specified virtual addresses.
+ * [[features-memoryUnmapReserve]] pname:memoryUnmapReserve
+ indicates that the implementation supports leaving the memory range
+ reserved when unmapping a memory object.
+
+:refpage: VkPhysicalDeviceMapMemoryPlacedFeaturesEXT
+include::{chapters}/features.adoc[tag=features]
+
+include::{generated}/validity/structs/VkPhysicalDeviceMapMemoryPlacedFeaturesEXT.adoc[]
+--
+endif::VK_EXT_map_memory_placed[]
+
[[features-requirements]]
== Feature Requirements
@@ -8439,6 +8466,10 @@ ifdef::VK_KHR_shader_quad_control[]
* <<features-shaderQuadControl, pname:shaderQuadControl>>, if the
`apiext:VK_KHR_shader_quad_control` extension is supported.
endif::VK_KHR_shader_quad_control[]
+ifdef::VK_EXT_map_memory_placed[]
+ * <<features-memoryMapPlaced, pname:memoryMapPlaced>> if the
+ `apiext:VK_EXT_map_memory_placed` extension is supported.
+endif::VK_EXT_map_memory_placed[]
All other features defined in the Specification are optional:.
diff --git a/chapters/limits.adoc b/chapters/limits.adoc
index c893507b..99319d5c 100644
--- a/chapters/limits.adoc
+++ b/chapters/limits.adoc
@@ -4566,6 +4566,30 @@ include::{generated}/validity/structs/VkPhysicalDeviceRenderPassStripedPropertie
endif::VK_ARM_render_pass_striped[]
+ifdef::VK_EXT_map_memory_placed[]
+[open,refpage='VkPhysicalDeviceMapMemoryPlacedPropertiesEXT',desc='Structure describing the alignment requirements of placed memory maps for a physical device',type='structs']
+--
+The sname:VkPhysicalDeviceMapMemoryPlacedPropertiesEXT structure is
+defined as:
+
+include::{generated}/api/structs/VkPhysicalDeviceMapMemoryPlacedPropertiesEXT.adoc[]
+
+The members of the sname:VkPhysicalDeviceMapMemoryPlacedPropertiesEXT
+structure describe the following:
+
+ * [[limits-minPlacedMemoryMapAlignment]]
+ pname:minPlacedMemoryMapAlignment is the minimum alignment required for
+ memory object offsets and virtual address ranges when using placed
+ memory mapping.
+
+:refpage: VkPhysicalDeviceMapMemoryPlacedPropertiesEXT
+include::{chapters}/limits.adoc[tag=limits_desc]
+
+include::{generated}/validity/structs/VkPhysicalDeviceMapMemoryPlacedPropertiesEXT.adoc[]
+--
+endif::VK_EXT_map_memory_placed[]
+
+
[[limits-minmax]]
== Limit Requirements
@@ -5472,6 +5496,9 @@ ifdef::VK_ARM_render_pass_striped[]
| pname:renderPassStripeGranularity | - | (64,64) | max
| pname:maxRenderPassStripes | - | 32 | min
endif::VK_ARM_render_pass_striped[]
+ifdef::VK_EXT_map_memory_placed[]
+| pname:minPlacedMemoryMapAlignment | - | 65536 | max
+endif::VK_EXT_map_memory_placed[]
|====
1::
diff --git a/chapters/memory.adoc b/chapters/memory.adoc
index a1ed2238..8cf9f876 100644
--- a/chapters/memory.adoc
+++ b/chapters/memory.adoc
@@ -3490,7 +3490,13 @@ include::{generated}/api/protos/vkMapMemory.adoc[]
* pname:size is the size of the memory range to map, or
ename:VK_WHOLE_SIZE to map from pname:offset to the end of the
allocation.
+ifndef::VK_EXT_map_memory_placed[]
* pname:flags is reserved for future use.
+endif::VK_EXT_map_memory_placed[]
+ifdef::VK_EXT_map_memory_placed[]
+ * pname:flags is a bitmask of elink:VkMemoryMapFlagBits specifying
+ additional parameters of the memory map operation.
+endif::VK_EXT_map_memory_placed[]
* pname:ppData is a pointer to a code:void* variable in which a
host-accessible pointer to the beginning of the mapped range is
returned.
@@ -3576,17 +3582,38 @@ ifdef::VK_KHR_device_group[]
* [[VUID-vkMapMemory-memory-00683]]
pname:memory must: not have been allocated with multiple instances
endif::VK_KHR_device_group[]
+ifdef::VK_EXT_map_memory_placed[]
+ * ename:VK_MEMORY_MAP_PLACED_BIT_EXT must: not be set in pname:flags
+endif::VK_EXT_map_memory_placed[]
****
include::{generated}/validity/protos/vkMapMemory.adoc[]
--
-[open,refpage='VkMemoryMapFlags',desc='Reserved for future use',type='flags']
+ifdef::VK_EXT_map_memory_placed[]
+[open,refpage='VkMemoryMapFlagBits',desc='Bitmask specifying additional parameters of a memory map',type='enums']
+--
+Bits which can: be set in flink:vkMapMemory::pname:flags and
+slink:VkMemoryMapInfoKHR::pname:flags, specifying additional properties of
+a memory map, are:
+
+include::{generated}/api/enums/VkMemoryMapFlagBits.adoc[]
+
+ * ename:VK_MEMORY_MAP_PLACED_BIT_EXT requests that the implementation
+ place the memory map at the virtual address specified by the client via
+ slink:VkMemoryMapPlacedInfoEXT::pname:pPlacedAddress, replacing any
+ existing mapping at that address.
+ This flag must: not be used with flink:vkMapMemory as there is no way
+ to specify the placement address.
+--
+endif::VK_EXT_map_memory_placed[]
+
+[open,refpage='VkMemoryMapFlags',desc='Bitmask of VkMemoryMapFlagBits',type='flags']
--
include::{generated}/api/flags/VkMemoryMapFlags.adoc[]
-tname:VkMemoryMapFlags is a bitmask type for setting a mask, but is
-currently reserved for future use.
+tname:VkMemoryMapFlags is a bitmask type for setting a mask of zero or more
+elink:VkMemoryMapFlagBits.
--
ifdef::VK_KHR_map_memory2[]
@@ -3622,7 +3649,8 @@ include::{generated}/api/structs/VkMemoryMapInfoKHR.adoc[]
* pname:sType is a elink:VkStructureType value identifying this structure.
* pname:pNext is `NULL` or a pointer to a structure extending this
structure.
- * pname:flags is reserved for future use.
+ * pname:flags is a bitmask of elink:VkMemoryMapFlagBits specifying
+ additional parameters of the memory map operation.
* pname:memory is the slink:VkDeviceMemory object to be mapped.
* pname:offset is a zero-based byte offset from the beginning of the
memory object.
@@ -3649,12 +3677,90 @@ ifdef::VK_KHR_device_group[]
* [[VUID-VkMemoryMapInfoKHR-memory-07963]]
pname:memory must: not have been allocated with multiple instances
endif::VK_KHR_device_group[]
+ifdef::VK_EXT_map_memory_placed[]
+ * If ename:VK_MEMORY_MAP_PLACED_BIT_EXT is set in pname:flags, the
+ <<features-memoryMapPlaced, pname:memoryMapPlaced>> feature must: be
+ enabled
+ * If ename:VK_MEMORY_MAP_PLACED_BIT_EXT is set in pname:flags, the
+ pname:pNext chain must: include a slink:VkMemoryMapPlacedInfoEXT
+ structure and sname:VkMemoryMapPlacedInfoEXT::pname:pPlacedAddress
+ must: not be `NULL`
+ * If ename:VK_MEMORY_MAP_PLACED_BIT_EXT is set in pname:flags and the
+ <<features-memoryMapRangePlaced, pname:memoryMapRangePlaced>> feature
+ is not enabled, pname:offset must: be zero
+ * If ename:VK_MEMORY_MAP_PLACED_BIT_EXT is set in pname:flags and the
+ <<features-memoryMapRangePlaced, pname:memoryMapRangePlaced>> feature
+ is not enabled, pname:size must: be ename:VK_WHOLE_SIZE
+ * If ename:VK_MEMORY_MAP_PLACED_BIT_EXT is set in pname:flags and the
+ <<features-memoryMapRangePlaced, pname:memoryMapRangePlaced>> feature
+ is enabled, pname:offset must: be aligned to an integer multiple of
+ sname:VkPhysicalDeviceMapMemoryPlacedPropertiesEXT::pname:minPlacedMemoryMapAlignment
+ * If ename:VK_MEMORY_MAP_PLACED_BIT_EXT is set in pname:flags and the
+ <<features-memoryMapRangePlaced, pname:memoryMapRangePlaced>> feature
+ is enabled, pname:size must: be ename:VK_WHOLE_SIZE or be aligned to an
+ integer multiple of
+ sname:VkPhysicalDeviceMapMemoryPlacedPropertiesEXT::pname:minPlacedMemoryMapAlignment
+ifdef::VK_EXT_external_memory_host[]
+ * If ename:VK_MEMORY_MAP_PLACED_BIT_EXT is set in pname:flags, the memory
+ object must: not have been imported from a handle type of
+ ename:VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT or
+ ename:VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_MAPPED_FOREIGN_MEMORY_BIT_EXT
+endif::VK_EXT_external_memory_host[]
+endif::VK_EXT_map_memory_placed[]
****
include::{generated}/validity/structs/VkMemoryMapInfoKHR.adoc[]
--
endif::VK_KHR_map_memory2[]
+ifdef::VK_EXT_map_memory_placed[]
+[open,refpage='VkMemoryMapPlacedInfoEXT',desc='Structure containing memory map placement parameters',type='structs']
+--
+If ename:VK_MEMORY_MAP_PLACED_BIT_EXT is set in
+sname:VkMemoryMapInfoKHR::pname:flags and the pname:pNext chain of
+slink:VkMemoryMapInfoKHR includes a sname:VkMemoryMapPlacedInfoEXT
+structure, then that structure specifies the placement address of the
+memory map.
+The implementation will place the memory map at the specified address,
+replacing any existing maps in the specified memory range.
+Replacing memory maps in this way does not implicitly unmap Vulkan memory
+objects.
+Instead, the client must: ensure no other Vulkan memory objects are mapped
+anywhere in the specified virtual address range.
+If successful, pname:ppData will be set to the same value as
+sname:VkMemoryMapPlacedInfoEXT::pname:pPlacedAddress and
+fname:vkMapMemory2KHR will return ename:VK_SUCCESS.
+If it cannot place the map at the requested address for any
+reason, the memory object is left unmapped and fname:vkMapMemory2KHR will
+return ename:VK_ERROR_MEMORY_MAP_FAILED.
+
+The sname:VkMemoryMapPlacedInfoEXT structure is defined as:
+
+include::{generated}/api/structs/VkMemoryMapPlacedInfoEXT.adoc[]
+
+ * pname:sType is the type of this structure.
+ * pname:pNext is `NULL` or a pointer to a structure extending this
+ structure.
+ * pname:pPlacedAddress is the virtual address at which to place the
+ address. If sname:VkMemoryMapInfoKHR::pname:flags does not contain
+ ename:VK_MEMORY_MAP_PLACED_BIT_EXT, this value is ignored.
+
+.Valid Usage
+****
+ * If sname:VkMemoryMapInfoKHR::pname:flags contains
+ ename:VK_MEMORY_MAP_PLACED_BIT_EXT, pname:pPlacedAddress must: not be
+ `NULL`
+ * pname:pPlacedAddress must: be aligned to an integer multiple of
+ sname:VkPhysicalDeviceMapMemoryPlacedPropertiesEXT::pname:minPlacedMemoryMapAlignment
+ * The address range specified by pname:pPlacedAddress and
+ sname:VkMemoryMapInfoKHR::pname:size must: not overlap any existing
+ Vulkan memory object mapping.
+****
+
+include::{generated}/validity/structs/VkMemoryMapPlacedInfoEXT.adoc[]
+--
+endif::VK_EXT_map_memory_placed[]
+
Two commands are provided to enable applications to work with non-coherent
memory allocations: fname:vkFlushMappedMemoryRanges and
fname:vkInvalidateMappedMemoryRanges.
@@ -3889,24 +3995,60 @@ include::{generated}/api/structs/VkMemoryUnmapInfoKHR.adoc[]
* pname:sType is a elink:VkStructureType value identifying this structure.
* pname:pNext is `NULL` or a pointer to a structure extending this
structure.
- * pname:flags is reserved for future use.
+ * pname:flags is a bitmask of elink:VkMemoryUnmapFlagBitsKHR specifying
+ additional parameters of the memory map operation.
* pname:memory is the slink:VkDeviceMemory object to be unmapped.
.Valid Usage
****
* [[VUID-VkMemoryUnmapInfoKHR-memory-07964]]
pname:memory must: be currently host mapped
+ifdef::VK_EXT_map_memory_placed[]
+ * If ename:VK_MEMORY_UNMAP_RESERVE_BIT_EXT is set in pname:flags,
+ the <<features-memoryUnmapReserve, pname:memoryUnmapReserve>>
+ must: be enabled
+ifdef::VK_EXT_external_memory_host[]
+ * If ename:VK_MEMORY_UNMAP_RESERVE_BIT_EXT is set in pname:flags, the
+ memory object must: not have been imported from a handle type of
+ ename:VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT or
+ ename:VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_MAPPED_FOREIGN_MEMORY_BIT_EXT
+endif::VK_EXT_external_memory_host[]
+endif::VK_EXT_map_memory_placed[]
****
include::{generated}/validity/structs/VkMemoryUnmapInfoKHR.adoc[]
--
-[open,refpage='VkMemoryUnmapFlagsKHR',desc='Reserved for future use',type='flags']
+ifdef::VK_EXT_map_memory_placed[]
+[open,refpage='VkMemoryUnmapFlagBitsKHR',desc='Bitmask specifying additional parameters of a memory unmap',type='enums']
+--
+Bits which can: be set in slink:VkMemoryUnmapInfoKHR::pname:flags, specifying
+additional properties of a memory unmap, are:
+
+include::{generated}/api/enums/VkMemoryUnmapFlagBitsKHR.adoc[]
+
+ * ename:VK_MEMORY_UNMAP_RESERVE_BIT_EXT requests that virtual address
+ range currently occupied by the memory map remain reserved after the
+ flink:vkUnmapMemory2KHR call completes.
+ Future system memory map operations or calls to flink:vkMapMemory or
+ flink:vkMapMemory2KHR will not return addresses in that range unless
+ the range has since been unreserved by the client or the mapping is
+ explicitly placed in that range by calling flink:vkMapMemory2KHR with
+ ename:VK_MEMORY_MAP_PLACED_BIT_EXT, or doing the system memory map
+ equivalent.
+ When ename:VK_MEMORY_UNMAP_RESERVE_BIT_EXT is set, the memory unmap
+ operation may: fail, in which case the memory object will remain host
+ mapped and flink:vkUnmapMemory2KHR will return
+ ename:VK_ERROR_MEMORY_MAP_FAILED.
+--
+endif::VK_EXT_map_memory_placed[]
+
+[open,refpage='VkMemoryUnmapFlagsKHR',desc='Bitmask of VkMemoryUnmapFlagBitsKHR',type='flags']
--
include::{generated}/api/flags/VkMemoryUnmapFlagsKHR.adoc[]
-tname:VkMemoryMapFlagsKHR is a bitmask type for setting a mask, but is
-currently reserved for future use.
+tname:VkMemoryUnmapFlagsKHR is a bitmask type for setting a mask of zero or
+more elink:VkMemoryUnmapFlagBitsKHR.
--
endif::VK_KHR_map_memory2[]
diff --git a/proposals/VK_EXT_map_memory_placed.adoc b/proposals/VK_EXT_map_memory_placed.adoc
new file mode 100644
index 00000000..91037207
--- /dev/null
+++ b/proposals/VK_EXT_map_memory_placed.adoc
@@ -0,0 +1,180 @@
+// Copyright 2022-2023 The Khronos Group, Inc.
+//
+// SPDX-License-Identifier: CC-BY-4.0
+
+# VK_EXT_map_memory_placed
+:toc: left
+:refpage: https://www.khronos.org/registry/vulkan/specs/1.2-extensions/man/html/
+:sectnums:
+
+This document proposes adding support client-controlled virtual address
+placement of `VkDeviceMemory` maps.
+
+## Problem Statement
+
+There are certain cases in which it can be useful to directly control the
+address used by a memory map operation.
+One example of this is in emulation environments when the application under
+emulation is 32-bit but the host userspace is 64-bit.
+In order to avoid additional copies or address translation, the emulator
+can choose an address in the lower 32 bits of the address space and request
+that the map be placed there.
+
+This functionality is already supported by the standard UNIX `mmap()`
+system call which provides an address hint flag as its first parameter as
+well as a `MAP_FIXED` flag which causes the `mmap()` to fail if it cannot
+place the map in exactly that location.
+This extension proposes to add similar functionality to `vkMapMemory()`.
+
+
+## Solution Space
+
+It is possible to emulate this functionality using
+VK_EXT_external_memory_host by creating a placed memory mapping in some
+other way (such as a Linux memfd combined with conventional `mmap()`) and
+then importing the resulting map via VK_EXT_external_memory_host.
+However, this requires every mappable Vulkan memory allocation to be a host
+pointer import which places restrictions available memory types and heaps
+and may have significant performance costs.
+
+One alternative approach to the emulation use-case would be to add a
+`VK_MEMORY_MAP_32BIT_ADDRESS_BIT_EXT` which does exactly what emulation
+wants and places the map in the lower 32 bits.
+This is equivalent to the Linux `MAP_32BIT` flag.
+However, this is less flexible and may be difficult to implement on Arm
+platforms where Linux `mmap()` does not support `MAP_32BIT` since drivers
+are likely relying on `mmap()` to implement `vkMapMemory()`.
+
+## Proposal
+
+### Dependencies
+
+ - VK_EXT_map_memory2
+
+### API Features
+
+The following features are exposed by this extension:
+
+[source,c]
+----
+typedef struct VkPhysicalDeviceMapMemoryPlacedFeaturesEXT {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 memoryMapPlaced;
+ VkBool32 memoryMapRangePlaced;
+ VkBool32 memoryUnmapReserve;
+} VkPhysicalDeviceMapMemoryPlacedFeaturesEXT;
+
+typedef struct VkPhysicalDeviceMapMemoryPlacedPropertiesEXT {
+ VkStructureType sType;
+ void* pNext;
+ VkDeviceSize minPlacedMemoryMapAlignment;
+} VkPhysicalDeviceMapMemoryPlacedPropertiesEXT;
+
+typedef enum VkMemoryMapFlagBits {
+ VK_MEMORY_MAP_PLACED_BIT_EXT = 0x00000001,
+} VkMemoryMapFlagBits;
+
+typedef struct VkMemoryMapPlacedInfoEXT {
+ VkStructureType sType;
+ const void* pNext;
+ void* pPlacedAddress;
+} VkMemoryMapPlacedInfoEXT;
+
+typedef enum VkMemoryUnmapFlagBitsKHR {
+ VK_MEMORY_UNMAP_RESERVE_BIT_EXT = 0x00000001,
+} VkMemoryMapFlagBitsKHR;
+----
+
+ . `memoryMapPlaced` indicates support for placed memory maps
+ . `memoryMapRangePlaced` indicates support for placed memory maps of
+ subranges of the `VkDeviceMemory` object.
+ . `memoryUnmapReserve` indicates support for
+ `VK_MEMORY_UNMAP_RESERVE_BIT_EXT`.
+
+When `VK_MEMORY_MAP_PLACED_BIT_EXT` is set in the `flags` member of
+`VkMemoryMapInfoKHR` and a `VkMapMemoryPlacedInfoEXT` structure is included
+in the `pNext` chain of `VkMemoryMapInfoKHR`, the implementation attempts
+to place the map at the address specified by
+`VkMapMemoryPlacedInfoEXT::pPlacedAddress`.
+If the map cannot be placed exactly at the specified virtual address,
+`vkMapMemory2KHR()` returns `VK_ERROR_MEMORY_MAP_FAILED`.
+
+When `VK_MEMORY_UNMAP_RESERVE_BIT_EXT` is set in the `flags` member of
+`VkMemoryUnmapInfoEXT`, the memory object will be unmapped but the
+address range will remain reserved so that another call to `mmap()` or
+`vkMapMemory()` will not re-use that address range without an address hint
+or `VK_MEMORY_MAP_PLACED_BIT_EXT`, respectively.
+
+## Examples
+
+The following example allocates a memory object and maps it in the lower 32
+bit address space, using `mmap()` to select the address.
+
+[source,c]
+----
+VkDeviceMemory mem;
+const VkMemoryAllocateInfo allocInfo = {
+ .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
+ .allocationSize = /* compute size */,
+ .memoryTypeIndex = /* compute memory type */,
+};
+VK_CHECK(vkAllocateMemory(device, &allocInfo, NULL, &mem));
+
+void *reserved = mmap(NULL, allocInfo.allocationSize, PROT_NONE,
+ MAP_ANONYMOUS | MAP_PRIVATE | MAP_32BIT, -1, 0);
+CHECK(reserved != MAP_FAILED);
+
+const VkMemoryMapPlacedInfoEXT mapPlacedInfo = {
+ .sType = VK_STRUCTURE_TYPE_MEMORY_MAP_PLACED_INFO_EXT,
+ .pPlacedAddress = reserved,
+};
+const VkMemoryMapInfoKHR mapInfo = {
+ .sType = VK_STRUCTURE_TYPE_MEMORY_MAP_INFO_KHR,
+ .pNext = &mapPlacedInfo,
+ .memory = mem,
+ .offset = 0,
+ .size = VK_WHOLE_SIZE,
+ .flags = VK_MEMORY_MAP_PLACED_BIT_EXT,
+};
+void *map;
+VK_CHECK(vkMapMemory2KHR(device, &mapInfo, &map));
+CHECK(map == reserved);
+----
+
+## Issues
+
+1) How should the requested address be passed to `vkMapMemory2KHR()`?
+
+*RESOLVED*: When `VK_MEMORY_MAP_PLACED_BIT_EXT` is passed to
+`vkMapMemory2KHR()` and a `VkMemoryMapPlacedInfoEXT` structure is present
+in the `pNext` chain, the implementation attempts to map to whatever
+address is provided by `VkMemoryMapPlacedInfoEXT::pPlacedAddress`.
+
+2) What should happen if the implementation cannot place the memory map at
+the requested address?
+
+*RESOLVED*: The memory object should be left unmapped and
+flink:vkMapMemory2KHR should return ename:VK_ERROR_MEMORY_MAP_FAILED.
+
+3) How can a client atomically re-reserve the address range on unmap?
+
+*RESOLVED*: When `VK_MEMORY_UNMAP_RESERVE_BIT_EXT` is passed to
+`vkUnmapMemory2KHR()`, the implementation unmaps the memory range in such a
+way that the range is automatically re-reserved.
+With `mmap()`, this is accomplished by simply mapping over the range with
+another anonymous mapping.
+However, allowing this with `vkMapMemory()` would break Vulkan's concept of
+when a memory object is or is not mapped.
+
+4) Should a placed memory map replace existing maps in the specified
+range or fail if a map exists?
+
+*RESOLVED*: It should replace existing maps.
+If a client wants try-map behavior, it can get that by using mmap with
+`MAP_ANONYMOUS` and an address and only call `vkMapMemory2KHR()` to do a
+placed map if that succeeds.
+Without replacement, there is no way for the application to atomically
+exchange maps and prevent races between reservation and the final map.
+Also, any attempt at a middle ground in which it might replace would make
+the spec less well-defined.
diff --git a/xml/vk.xml b/xml/vk.xml
index fb92b7c2..2dbad9ba 100755
--- a/xml/vk.xml
+++ b/xml/vk.xml
@@ -338,8 +338,8 @@ typedef void* <name>MTLSharedEvent_id</name>;
<type requires="VkCommandBufferResetFlagBits" category="bitmask">typedef <type>VkFlags</type> <name>VkCommandBufferResetFlags</name>;</type>
<type requires="VkCommandBufferUsageFlagBits" category="bitmask">typedef <type>VkFlags</type> <name>VkCommandBufferUsageFlags</name>;</type>
<type requires="VkQueryPipelineStatisticFlagBits" category="bitmask">typedef <type>VkFlags</type> <name>VkQueryPipelineStatisticFlags</name>;</type>
- <type category="bitmask">typedef <type>VkFlags</type> <name>VkMemoryMapFlags</name>;</type>
- <type category="bitmask">typedef <type>VkFlags</type> <name>VkMemoryUnmapFlagsKHR</name>;</type>
+ <type requires="VkMemoryMapFlagBits" category="bitmask">typedef <type>VkFlags</type> <name>VkMemoryMapFlags</name>;</type>
+ <type requires="VkMemoryUnmapFlagBitsKHR" category="bitmask">typedef <type>VkFlags</type> <name>VkMemoryUnmapFlagsKHR</name>;</type>
<type requires="VkImageAspectFlagBits" category="bitmask">typedef <type>VkFlags</type> <name>VkImageAspectFlags</name>;</type>
<type requires="VkSparseMemoryBindFlagBits" category="bitmask">typedef <type>VkFlags</type> <name>VkSparseMemoryBindFlags</name>;</type>
<type requires="VkSparseImageFormatFlagBits" category="bitmask">typedef <type>VkFlags</type> <name>VkSparseImageFormatFlags</name>;</type>
@@ -619,6 +619,7 @@ typedef void* <name>MTLSharedEvent_id</name>;
<type name="VkFormat" category="enum"/>
<type name="VkFormatFeatureFlagBits" category="enum"/>
<type name="VkFrontFace" category="enum"/>
+ <type name="VkMemoryMapFlagBits" category="enum"/>
<type name="VkImageAspectFlagBits" category="enum"/>
<type name="VkImageCreateFlagBits" category="enum"/>
<type name="VkImageLayout" category="enum"/>
@@ -872,6 +873,7 @@ typedef void* <name>MTLSharedEvent_id</name>;
<type name="VkLatencyMarkerNV" category="enum"/>
<type name="VkOutOfBandQueueTypeNV" category="enum"/>
<type name="VkPhysicalDeviceSchedulingControlsFlagBitsARM" category="enum"/>
+ <type name="VkMemoryUnmapFlagBitsKHR" category="enum"/>
<comment>Enumerated types in the header, but not used by the API</comment>
<type name="VkVendorId" category="enum"/>
@@ -9078,6 +9080,23 @@ typedef void* <name>MTLSharedEvent_id</name>;
<member optional="true" noautovalidity="true"><type>void</type>* <name>pNext</name></member>
<member><type>VkBool32</type> <name>shaderQuadControl</name></member>
</type>
+ <type category="struct" name="VkPhysicalDeviceMapMemoryPlacedFeaturesEXT" structextends="VkPhysicalDeviceFeatures2,VkDeviceCreateInfo">
+ <member values="VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAP_MEMORY_PLACED_FEATURES_EXT"><type>VkStructureType</type> <name>sType</name></member>
+ <member optional="true"><type>void</type>* <name>pNext</name></member>
+ <member><type>VkBool32</type> <name>memoryMapPlaced</name></member>
+ <member><type>VkBool32</type> <name>memoryMapRangePlaced</name></member>
+ <member><type>VkBool32</type> <name>memoryUnmapReserve</name></member>
+ </type>
+ <type category="struct" name="VkPhysicalDeviceMapMemoryPlacedPropertiesEXT" returnedonly="true" structextends="VkPhysicalDeviceProperties2">
+ <member values="VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAP_MEMORY_PLACED_PROPERTIES_EXT"><type>VkStructureType</type> <name>sType</name></member>
+ <member optional="true"><type>void</type>* <name>pNext</name></member>
+ <member limittype="min,pot"><type>VkDeviceSize</type> <name>minPlacedMemoryMapAlignment</name></member>
+ </type>
+ <type category="struct" name="VkMemoryMapPlacedInfoEXT" structextends="VkMemoryMapInfoKHR">
+ <member values="VK_STRUCTURE_TYPE_MEMORY_MAP_PLACED_INFO_EXT"><type>VkStructureType</type> <name>sType</name></member>
+ <member optional="true">const <type>void</type>* <name>pNext</name></member>
+ <member noautovalidity="true"><type>void</type>* <name>pPlacedAddress</name></member>
+ </type>
</types>
@@ -9837,6 +9856,8 @@ typedef void* <name>MTLSharedEvent_id</name>;
<enum bitpos="9" name="VK_QUERY_PIPELINE_STATISTIC_TESSELLATION_EVALUATION_SHADER_INVOCATIONS_BIT" comment="Optional"/>
<enum bitpos="10" name="VK_QUERY_PIPELINE_STATISTIC_COMPUTE_SHADER_INVOCATIONS_BIT" comment="Optional"/>
</enums>
+ <enums name="VkMemoryMapFlagBits" type="bitmask">
+ </enums>
<enums name="VkImageAspectFlagBits" type="bitmask">
<enum bitpos="0" name="VK_IMAGE_ASPECT_COLOR_BIT"/>
<enum bitpos="1" name="VK_IMAGE_ASPECT_DEPTH_BIT"/>
@@ -11211,6 +11232,8 @@ typedef void* <name>MTLSharedEvent_id</name>;
<enum value="0" name="VK_OUT_OF_BAND_QUEUE_TYPE_RENDER_NV"/>
<enum value="1" name="VK_OUT_OF_BAND_QUEUE_TYPE_PRESENT_NV"/>
</enums>
+ <enums name="VkMemoryUnmapFlagBitsKHR" type="bitmask">
+ </enums>
<commands comment="Vulkan command definitions">
<command successcodes="VK_SUCCESS" errorcodes="VK_ERROR_OUT_OF_HOST_MEMORY,VK_ERROR_OUT_OF_DEVICE_MEMORY,VK_ERROR_INITIALIZATION_FAILED,VK_ERROR_LAYER_NOT_PRESENT,VK_ERROR_EXTENSION_NOT_PRESENT,VK_ERROR_INCOMPATIBLE_DRIVER">
@@ -15175,7 +15198,7 @@ typedef void* <name>MTLSharedEvent_id</name>;
<param>const <type>VkMemoryMapInfoKHR</type>* <name>pMemoryMapInfo</name></param>
<param optional="false,true"><type>void</type>** <name>ppData</name></param>
</command>
- <command successcodes="VK_SUCCESS">
+ <command successcodes="VK_SUCCESS" errorcodes="VK_ERROR_MEMORY_MAP_FAILED">
<proto><type>VkResult</type> <name>vkUnmapMemory2KHR</name></proto>
<param><type>VkDevice</type> <name>device</name></param>
<param>const <type>VkMemoryUnmapInfoKHR</type>* <name>pMemoryUnmapInfo</name></param>
@@ -15491,6 +15514,7 @@ typedef void* <name>MTLSharedEvent_id</name>;
<require comment="Memory commands">
<type name="VkMappedMemoryRange"/>
<type name="VkMemoryAllocateInfo"/>
+ <type name="VkMemoryMapFlagBits"/>
<type name="VkMemoryMapFlags"/>
<command name="vkAllocateMemory"/>
<command name="vkFreeMemory"/>
@@ -20638,15 +20662,24 @@ typedef void* <name>MTLSharedEvent_id</name>;
<enum offset="1" extends="VkStructureType" name="VK_STRUCTURE_TYPE_MEMORY_UNMAP_INFO_KHR"/>
<type name="VkMemoryMapInfoKHR"/>
<type name="VkMemoryUnmapInfoKHR"/>
+ <type name="VkMemoryUnmapFlagBitsKHR"/>
<type name="VkMemoryUnmapFlagsKHR"/>
<command name="vkMapMemory2KHR"/>
<command name="vkUnmapMemory2KHR"/>
</require>
</extension>
- <extension name="VK_INTEL_extension_273" number="273" type="device" author="INTEL" contact="Faith Ekstrand @gfxstrand" supported="disabled">
+ <extension name="VK_EXT_map_memory_placed" number="273" type="device" depends="VK_KHR_map_memory2" author="EXT" contact="Faith Ekstrand @gfxstrand" supported="vulkan">
<require>
- <enum value="0" name="VK_INTEL_EXTENSION_273_SPEC_VERSION"/>
- <enum value="&quot;VK_INTEL_extension_273&quot;" name="VK_INTEL_EXTENSION_273_EXTENSION_NAME"/>
+ <enum value="1" name="VK_EXT_MAP_MEMORY_PLACED_SPEC_VERSION"/>
+ <enum value="&quot;VK_EXT_map_memory_placed&quot;" name="VK_EXT_MAP_MEMORY_PLACED_EXTENSION_NAME"/>
+ <enum offset="0" extends="VkStructureType" name="VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAP_MEMORY_PLACED_FEATURES_EXT"/>
+ <enum offset="1" extends="VkStructureType" name="VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAP_MEMORY_PLACED_PROPERTIES_EXT"/>
+ <enum offset="2" extends="VkStructureType" name="VK_STRUCTURE_TYPE_MEMORY_MAP_PLACED_INFO_EXT"/>
+ <enum bitpos="0" extends="VkMemoryMapFlagBits" name="VK_MEMORY_MAP_PLACED_BIT_EXT"/>
+ <enum bitpos="0" extends="VkMemoryUnmapFlagBitsKHR" name="VK_MEMORY_UNMAP_RESERVE_BIT_EXT"/>
+ <type name="VkPhysicalDeviceMapMemoryPlacedFeaturesEXT"/>
+ <type name="VkPhysicalDeviceMapMemoryPlacedPropertiesEXT"/>
+ <type name="VkMemoryMapPlacedInfoEXT"/>
</require>
</extension>
<extension name="VK_EXT_shader_atomic_float2" number="274" type="device" depends="VK_EXT_shader_atomic_float" author="EXT" contact="Faith Ekstrand @gfxstrand" supported="vulkan">