Merge pull request #194 from krOoze/improve-ch10.2.0

Suggestions for ch10.2.0 Device Memory
This commit is contained in:
Jon Leech 2017-10-26 16:14:21 -07:00 committed by GitHub
commit 38d4064bb4
1 changed files with 129 additions and 116 deletions

View File

@ -446,9 +446,9 @@ endif::VK_EXT_validation_cache[]
[[memory-device]]
== Device Memory
Device memory is memory that is visible to the device, for example the
contents of opaque images that can: be natively used by the device, or
uniform buffer objects that reside in on-device memory.
_Device memory_ is memory that is visible to the device -- for example
the contents of the image or buffer objects, which can: be natively used by
the device.
Memory properties of a physical device describe the memory heaps and memory
types available.
@ -500,48 +500,48 @@ different properties.
The number of memory heaps is given by pname:memoryHeapCount and is less
than or equal to ename:VK_MAX_MEMORY_HEAPS.
Each heap is described by an element of the pname:memoryHeaps array, as a
sname:VkMemoryHeap structure.
Each heap is described by an element of the pname:memoryHeaps array as a
slink:VkMemoryHeap structure.
The number of memory types available across all memory heaps is given by
pname:memoryTypeCount and is less than or equal to
ename:VK_MAX_MEMORY_TYPES.
Each memory type is described by an element of the pname:memoryTypes array,
as a sname:VkMemoryType structure.
Each memory type is described by an element of the pname:memoryTypes array
as a slink:VkMemoryType structure.
At least one heap must: include ename:VK_MEMORY_HEAP_DEVICE_LOCAL_BIT in
slink:VkMemoryHeap::pname:flags.
If there are multiple heaps that all have similar performance
characteristics, they may: all include
ename:VK_MEMORY_HEAP_DEVICE_LOCAL_BIT.
In a unified memory architecture (UMA) system, there is often only a single
In a unified memory architecture (UMA) system there is often only a single
memory heap which is considered to be equally "`local`" to the host and to
the device, and such an implementation must: advertise the heap as
device-local.
[[memory-device-bitmask-list]]
Each memory type returned by flink:vkGetPhysicalDeviceMemoryProperties must:
have its pname:propertyFlags set to one of the following values:
* 0
* ename:VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
* ename:VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | +
ename:VK_MEMORY_PROPERTY_HOST_COHERENT_BIT
* ename:VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
* ename:VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | +
ename:VK_MEMORY_PROPERTY_HOST_CACHED_BIT
* ename:VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
ename:VK_MEMORY_PROPERTY_HOST_CACHED_BIT |
* ename:VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | +
ename:VK_MEMORY_PROPERTY_HOST_CACHED_BIT | +
ename:VK_MEMORY_PROPERTY_HOST_COHERENT_BIT
* ename:VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT
* ename:VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT |
ename:VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
* ename:VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT | +
ename:VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | +
ename:VK_MEMORY_PROPERTY_HOST_COHERENT_BIT
* ename:VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT |
ename:VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
* ename:VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT | +
ename:VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | +
ename:VK_MEMORY_PROPERTY_HOST_CACHED_BIT
* ename:VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT |
ename:VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
ename:VK_MEMORY_PROPERTY_HOST_CACHED_BIT |
* ename:VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT | +
ename:VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | +
ename:VK_MEMORY_PROPERTY_HOST_CACHED_BIT | +
ename:VK_MEMORY_PROPERTY_HOST_COHERENT_BIT
* ename:VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT |
* ename:VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT | +
ename:VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT
There must: be at least one memory type with both the
@ -552,57 +552,75 @@ There must: be at least one memory type with the
ename:VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT bit set in its
pname:propertyFlags.
The memory types are sorted according to a preorder which serves to aid in
easily selecting an appropriate memory type.
Given two memory types X and Y, the preorder defines [eq]#X {leq} Y# if:
For each pair of elements *X* and *Y* returned in pname:memoryTypes, *X*
must: be placed at a lower index position than *Y* if:
* the memory property bits set for X are a strict subset of the memory
property bits set for Y. Or,
* the memory property bits set for X are the same as the memory property
bits set for Y, and X uses a memory heap with greater or equal
performance (as determined in an implementation-specific manner).
* either the set of bit flags returned in the pname:propertyFlags member
of *X* is a strict subset of the set of bit flags returned in the
pname:propertyFlags member of *Y*.
* or the pname:propertyFlags members of *X* and *Y* are equal, and *X*
belongs to a memory heap with greater performance (as determined in an
implementation-specific manner).
Memory types are ordered in the list such that X is assigned a lesser
pname:memoryTypeIndex than Y if [eq]#(X {leq} Y) {land} {lnot} (Y {leq} X)#
according to the preorder.
Note that the list of all allowed memory property flag combinations above
satisfies this preorder, but other orders would as well.
The goal of this ordering is to enable applications to use a simple search
loop in selecting the proper memory type, along the lines of:
[NOTE]
.Note
====
There is no ordering requirement between *X* and *Y* elements for the case
their pname:propertyFlags members are not in a subset relation.
That potentially allows more than one possible way to order the same set of
memory types.
Notice that the
<<memory-device-bitmask-list,list of all allowed memory property flag combinations>>
is written in the required order.
But if instead
ename:VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT was before
ename:VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
ename:VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
the list would still be in the required order.
====
This ordering requirement enables applications to use a simple search loop
to select the desired memory type along the lines of:
[source,c++]
---------------------------------------------------
// Find a memory type in "memoryTypeBits" that includes all of "properties"
int32_t FindProperties(uint32_t memoryTypeBits, VkMemoryPropertyFlags properties)
{
for (int32_t i = 0; i < memoryTypeCount; ++i)
{
if ((memoryTypeBits & (1 << i)) &&
((memoryTypes[i].propertyFlags & properties) == properties))
return i;
// Find a memory in `memoryTypeBitsRequirement` that includes all of `requiredProperties`
int32_t findProperties(const VkPhysicalDeviceMemoryProperties* pMemoryProperties,
uint32_t memoryTypeBitsRequirement,
VkMemoryPropertyFlags requiredProperties) {
const uint32_t memoryCount = pMemoryProperties->memoryTypeCount;
for (uint32_t memoryIndex = 0; memoryIndex < memoryCount; ++memoryIndex) {
const uint32_t memoryTypeBits = (1 << memoryIndex);
const bool isRequiredMemoryType = memoryTypeBitsRequirement & memoryTypeBits;
const VkMemoryPropertyFlags properties =
pMemoryProperties->memoryTypes[memoryIndex].propertyFlags;
const bool hasRequiredProperties =
(properties & requiredProperties) == requiredProperties;
if (isRequiredMemoryType && hasRequiredProperties)
return static_cast<int32_t>(memoryIndex);
}
// failed to find memory type
return -1;
}
// Try to find an optimal memory type, or if it does not exist
// find any compatible memory type
// Try to find an optimal memory type, or if it does not exist try fallback memory type
// `device` is the VkDevice
// `image` is the VkImage that requires memory to be bound
// `memoryProperties` properties as returned by vkGetPhysicalDeviceMemoryProperties
// `requiredProperties` are the property flags that must be present
// `optimalProperties` are the property flags that are preferred by the application
VkMemoryRequirements memoryRequirements;
vkGetImageMemoryRequirements(device, image, &memoryRequirements);
int32_t memoryType = FindProperties(memoryRequirements.memoryTypeBits, optimalProperties);
if (memoryType == -1)
memoryType = FindProperties(memoryRequirements.memoryTypeBits, requiredProperties);
int32_t memoryType =
findProperties(&memoryProperties, memoryRequirements.memoryTypeBits, optimalProperties);
if (memoryType == -1) // not found; try fallback properties
memoryType =
findProperties(&memoryProperties, memoryRequirements.memoryTypeBits, requiredProperties);
---------------------------------------------------
The loop will find the first supported memory type that has all bits
requested in code:properties set.
If there is no exact match, it will find a closest match (i.e. a memory type
with the fewest additional bits set), which has some additional bits set but
which are not detrimental to the behaviors requested by code:properties.
The application can: first search for the optimal properties, e.g. a memory
type that is device-local or supports coherent cached accesses, as
appropriate for the intended usage, and if such a memory type is not present
can: fallback to searching for a less optimal but guaranteed set of
properties such as "0" or "host-visible and coherent".
include::../validity/structs/VkPhysicalDeviceMemoryProperties.txt[]
--
@ -691,7 +709,7 @@ include::../api/structs/VkMemoryType.txt[]
* pname:heapIndex describes which memory heap this memory type corresponds
to, and must: be less than pname:memoryHeapCount from the
sname:VkPhysicalDeviceMemoryProperties structure.
slink:VkPhysicalDeviceMemoryProperties structure.
* pname:propertyFlags is a bitmask of elink:VkMemoryPropertyFlagBits of
properties for this memory type.
@ -708,8 +726,8 @@ include::../api/enums/VkMemoryPropertyFlagBits.txt[]
* ename:VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT bit indicates that memory
allocated with this type is the most efficient for device access.
This property will only be set for memory types belonging to heaps with
the ename:VK_MEMORY_HEAP_DEVICE_LOCAL_BIT set.
This property will be set if and only if the memory type belongs to a
heap with the ename:VK_MEMORY_HEAP_DEVICE_LOCAL_BIT set.
* ename:VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT bit indicates that memory
allocated with this type can: be mapped for host access using
flink:vkMapMemory.
@ -736,9 +754,7 @@ include::../api/enums/VkMemoryPropertyFlagBits.txt[]
--
A Vulkan device operates on data in device memory via memory objects that
are represented in the API by a sname:VkDeviceMemory handle.
Memory objects are represented by sname:VkDeviceMemory handles:
are represented in the API by a sname:VkDeviceMemory handle:
include::../api/handles/VkDeviceMemory.txt[]
@ -763,7 +779,7 @@ include::../api/protos/vkAllocateMemory.txt[]
information about the allocated memory is returned.
Allocations returned by fname:vkAllocateMemory are guaranteed to meet any
alignment requirement by the implementation.
alignment requirement of the implementation.
For example, if an implementation requires 128 byte alignment for images and
64 byte alignment for buffers, the device memory returned through this
mechanism would be 128-byte aligned.
@ -774,29 +790,30 @@ same memory object.
When memory is allocated, its contents are undefined.
There is an implementation-dependent maximum number of memory allocations
which can: be simultaneously created on a device.
that can: be simultaneously created on a device.
This is specified by the
<<features-limits-maxMemoryAllocationCount,pname:maxMemoryAllocationCount>>
member of the sname:VkPhysicalDeviceLimits structure.
member of the slink:VkPhysicalDeviceLimits structure.
If pname:maxMemoryAllocationCount is exceeded, fname:vkAllocateMemory will
return ename:VK_ERROR_TOO_MANY_OBJECTS.
[NOTE]
.Note
====
Some platforms may: have a limit on the maximum size of a single allocation.
For example, certain systems may: fail to create allocations with a size
greater than or equal to 4GB.
Such a limit is implementation-dependent, and if such a failure occurs then
the error ename:VK_ERROR_OUT_OF_DEVICE_MEMORY should: be returned.
====
the error ename:VK_ERROR_OUT_OF_DEVICE_MEMORY must: be returned.
.Valid Usage
****
* [[VUID-vkAllocateMemory-device-00636]]
The number of currently valid memory objects, allocated from
pname:device, must: be less than
sname:VkPhysicalDeviceLimits::pname:maxMemoryAllocationCount
* pname:pAllocateInfo\->pname:allocationSize must: be less than or equal
to
slink:VkPhysicalDeviceMemoryProperties::pname:memoryHeaps[pname:pAllocateInfo\->pname:memoryTypeIndex].pname:size
as returned by flink:vkGetPhysicalDeviceMemoryProperties for the
slink:VkPhysicalDevice that pname:device was created from.
* pname:pAllocateInfo\->pname:memoryTypeIndex must: be less than
slink:VkPhysicalDeviceMemoryProperties::pname:memoryTypeCount as
returned by flink:vkGetPhysicalDeviceMemoryProperties for the
slink:VkPhysicalDevice that pname:device was created from.
****
include::../validity/protos/vkAllocateMemory.txt[]
@ -812,9 +829,9 @@ include::../api/structs/VkMemoryAllocateInfo.txt[]
* pname:sType is the type of this structure.
* pname:pNext is `NULL` or a pointer to an extension-specific structure.
* pname:allocationSize is the size of the allocation in bytes
* pname:memoryTypeIndex is the memory type index, which selects the
properties of the memory to be allocated, as well as the heap the memory
will come from.
* pname:memoryTypeIndex is an index identifying a memory type from the
pname:memoryTypes array of the slink:VkPhysicalDeviceMemoryProperties
structure
ifdef::VK_KHR_external_memory_win32,VK_KHR_external_memory_fd[]
If the pname:pNext chain contains an instance of
@ -865,10 +882,6 @@ endif::VK_KHR_external_memory_win32,VK_KHR_external_memory_fd[]
.Valid Usage
****
* [[VUID-VkMemoryAllocateInfo-allocationSize-00637]]
pname:allocationSize must: be less than or equal to the amount of memory
available to the sname:VkMemoryHeap specified by pname:memoryTypeIndex
and the calling command's sname:VkDevice
* [[VUID-VkMemoryAllocateInfo-allocationSize-00638]]
pname:allocationSize must: be greater than `0`
ifdef::VK_KHR_external_memory[]
@ -971,41 +984,41 @@ include::../api/structs/VkMemoryDedicatedAllocateInfoKHR.txt[]
* pname:sType is the type of this structure.
* pname:pNext is `NULL` or a pointer to an extension-specific structure.
* pname:image is sname:VK_NULL_HANDLE or a handle of an image which this
* pname:image is dlink:VK_NULL_HANDLE or a handle of an image which this
memory will be bound to.
* pname:buffer is sname:VK_NULL_HANDLE or a handle of a buffer which this
* pname:buffer is dlink:VK_NULL_HANDLE or a handle of a buffer which this
memory will be bound to.
.Valid Usage
****
* [[VUID-VkMemoryDedicatedAllocateInfoKHR-image-01432]]
At least one of pname:image and pname:buffer must: be
sname:VK_NULL_HANDLE
dlink:VK_NULL_HANDLE
* [[VUID-VkMemoryDedicatedAllocateInfoKHR-image-01433]]
If pname:image is not sname:VK_NULL_HANDLE,
If pname:image is not dlink:VK_NULL_HANDLE,
sname:VkMemoryAllocateInfo::pname:allocationSize must: equal the
sname:VkMemoryRequirements::pname:size of the image
* [[VUID-VkMemoryDedicatedAllocateInfoKHR-image-01434]]
If pname:image is not sname:VK_NULL_HANDLE, pname:image must: have been
If pname:image is not dlink:VK_NULL_HANDLE, pname:image must: have been
created without ename:VK_IMAGE_CREATE_SPARSE_BINDING_BIT set in
sname:VkImageCreateInfo::pname:flags
slink:VkImageCreateInfo::pname:flags
* [[VUID-VkMemoryDedicatedAllocateInfoKHR-buffer-01435]]
If pname:buffer is not sname:VK_NULL_HANDLE,
If pname:buffer is not dlink:VK_NULL_HANDLE,
sname:VkMemoryAllocateInfo::pname:allocationSize must: equal the
sname:VkMemoryRequirements::pname:size of the buffer
* [[VUID-VkMemoryDedicatedAllocateInfoKHR-buffer-01436]]
If pname:buffer is not sname:VK_NULL_HANDLE, pname:buffer must: have
If pname:buffer is not dlink:VK_NULL_HANDLE, pname:buffer must: have
been created without ename:VK_BUFFER_CREATE_SPARSE_BINDING_BIT set in
sname:VkBufferCreateInfo::pname:flags
slink:VkBufferCreateInfo::pname:flags
ifdef::VK_KHR_external_memory_win32,VK_KHR_external_memory_fd[]
* [[VUID-VkMemoryDedicatedAllocateInfoKHR-image-01437]]
If pname:image is not sname:VK_NULL_HANDLE and
If pname:image is not dlink:VK_NULL_HANDLE and
slink:VkMemoryAllocateInfo defines a memory import operation, the memory
being imported must: also be a dedicated image allocation and
pname:image must be identical to the image associated with the imported
memory.
* [[VUID-VkMemoryDedicatedAllocateInfoKHR-buffer-01438]]
If pname:buffer is not sname:VK_NULL_HANDLE and
If pname:buffer is not dlink:VK_NULL_HANDLE and
slink:VkMemoryAllocateInfo defines a memory import operation, the memory
being imported must: also be a dedicated buffer allocation and
pname:buffer must be identical to the buffer associated with the
@ -1034,43 +1047,43 @@ include::../api/structs/VkDedicatedAllocationMemoryAllocateInfoNV.txt[]
* pname:sType is the type of this structure.
* pname:pNext is `NULL` or a pointer to an extension-specific structure.
* pname:image is sname:VK_NULL_HANDLE or a handle of an image which this
* pname:image is dlink:VK_NULL_HANDLE or a handle of an image which this
memory will be bound to.
* pname:buffer is sname:VK_NULL_HANDLE or a handle of a buffer which this
* pname:buffer is dlink:VK_NULL_HANDLE or a handle of a buffer which this
memory will be bound to.
.Valid Usage
****
* [[VUID-VkDedicatedAllocationMemoryAllocateInfoNV-image-00649]]
At least one of pname:image and pname:buffer must: be
sname:VK_NULL_HANDLE
dlink:VK_NULL_HANDLE
* [[VUID-VkDedicatedAllocationMemoryAllocateInfoNV-image-00650]]
If pname:image is not sname:VK_NULL_HANDLE, the image must: have been
If pname:image is not dlink:VK_NULL_HANDLE, the image must: have been
created with
sname:VkDedicatedAllocationImageCreateInfoNV::pname:dedicatedAllocation
equal to ename:VK_TRUE
* [[VUID-VkDedicatedAllocationMemoryAllocateInfoNV-buffer-00651]]
If pname:buffer is not sname:VK_NULL_HANDLE, the buffer must: have been
If pname:buffer is not dlink:VK_NULL_HANDLE, the buffer must: have been
created with
sname:VkDedicatedAllocationBufferCreateInfoNV::pname:dedicatedAllocation
equal to ename:VK_TRUE
* [[VUID-VkDedicatedAllocationMemoryAllocateInfoNV-image-00652]]
If pname:image is not sname:VK_NULL_HANDLE,
If pname:image is not dlink:VK_NULL_HANDLE,
sname:VkMemoryAllocateInfo::pname:allocationSize must: equal the
sname:VkMemoryRequirements::pname:size of the image
* [[VUID-VkDedicatedAllocationMemoryAllocateInfoNV-buffer-00653]]
If pname:buffer is not sname:VK_NULL_HANDLE,
If pname:buffer is not dlink:VK_NULL_HANDLE,
sname:VkMemoryAllocateInfo::pname:allocationSize must: equal the
sname:VkMemoryRequirements::pname:size of the buffer
ifdef::VK_KHR_external_memory_win32,VK_KHR_external_memory_fd[]
* [[VUID-VkDedicatedAllocationMemoryAllocateInfoNV-image-00654]]
If pname:image is not sname:VK_NULL_HANDLE and
If pname:image is not dlink:VK_NULL_HANDLE and
slink:VkMemoryAllocateInfo defines a memory import operation, the memory
being imported must: also be a dedicated image allocation and
pname:image must: be identical to the image associated with the imported
memory.
* [[VUID-VkDedicatedAllocationMemoryAllocateInfoNV-buffer-00655]]
If pname:buffer is not sname:VK_NULL_HANDLE and
If pname:buffer is not dlink:VK_NULL_HANDLE and
slink:VkMemoryAllocateInfo defines a memory import operation, the memory
being imported must: also be a dedicated buffer allocation and
pname:buffer must: be identical to the buffer associated with the
@ -1201,7 +1214,7 @@ include::../api/structs/VkImportMemoryWin32HandleInfoKHR.txt[]
Importing memory objects from Windows handles does not transfer ownership of
the handle to the Vulkan implementation.
For handle types defined as NT handles, the application must: release
ownership using the fname:CloseHandle system call when the handle is no
ownership using the code:CloseHandle system call when the handle is no
longer needed.
Applications can: import the same underlying memory into multiple instances
@ -1273,7 +1286,7 @@ include::../api/protos/vkGetMemoryWin32HandleKHR.txt[]
For handle types defined as NT handles, the handles returned by
fname:vkGetMemoryWin32HandleKHR are owned by the application.
To avoid leaking resources, the application must: release ownership of them
using the fname:CloseHandle system call when they are no longer needed.
using the code:CloseHandle system call when they are no longer needed.
include::../validity/protos/vkGetMemoryWin32HandleKHR.txt[]
--
@ -1430,10 +1443,10 @@ include::../api/protos/vkGetMemoryFdKHR.txt[]
Each call to fname:vkGetMemoryFdKHR must: create a new file descriptor and
transfer ownership of it to the application.
To avoid leaking resources, the application must: release ownership of the
file descriptor using the fname:close system call when it is no longer
file descriptor using the code:close system call when it is no longer
needed, or by importing a Vulkan memory object from it.
Where supported by the operating system, the implementation must: set the
file descriptor to be closed automatically when an fname:execve system call
file descriptor to be closed automatically when an code:execve system call
is made.
include::../validity/protos/vkGetMemoryFdKHR.txt[]
@ -1619,7 +1632,7 @@ include::../api/protos/vkFreeMemory.txt[]
Before freeing a memory object, an application must: ensure the memory
object is no longer in use by the device--for example by command buffers
queued for execution.
in the _pending state_.
The memory can: remain bound to images or buffers at the time the memory
object is freed, but any further use of them (on host or device) for
anything other than destroying those objects will result in undefined
@ -1659,7 +1672,7 @@ include::../validity/protos/vkFreeMemory.txt[]
[[memory-device-hostaccess]]
=== Host Access to Device Memory Objects
Memory objects created with fname:vkAllocateMemory are not directly host
Memory objects created with flink:vkAllocateMemory are not directly host
accessible.
Memory objects created with the memory property
@ -1686,7 +1699,7 @@ include::../api/protos/vkMapMemory.txt[]
* pname:ppData points to a pointer in which is returned a host-accessible
pointer to the beginning of the mapped range.
This pointer minus pname:offset must: be aligned to at least
sname:VkPhysicalDeviceLimits::pname:minMemoryMapAlignment.
slink:VkPhysicalDeviceLimits::pname:minMemoryMapAlignment.
It is an application error to call fname:vkMapMemory on a memory object that
is already mapped.
@ -1717,9 +1730,9 @@ If the device memory was allocated without the
ename:VK_MEMORY_PROPERTY_HOST_COHERENT_BIT set, these guarantees must: be
made for an extended range: the application must: round down the start of
the range to the nearest multiple of
sname:VkPhysicalDeviceLimits::pname:nonCoherentAtomSize, and round the end
slink:VkPhysicalDeviceLimits::pname:nonCoherentAtomSize, and round the end
of the range up to the nearest multiple of
sname:VkPhysicalDeviceLimits::pname:nonCoherentAtomSize.
slink:VkPhysicalDeviceLimits::pname:nonCoherentAtomSize.
While a range of device memory is mapped for host access, the application is
responsible for synchronizing both device and host access to that memory
@ -1875,15 +1888,15 @@ include::../api/structs/VkMappedMemoryRange.txt[]
* [[VUID-VkMappedMemoryRange-size-01389]]
If pname:size is equal to ename:VK_WHOLE_SIZE, the end of the current
mapping of pname:memory must: be a multiple of
sname:VkPhysicalDeviceLimits::pname:nonCoherentAtomSize bytes from the
slink:VkPhysicalDeviceLimits::pname:nonCoherentAtomSize bytes from the
beginning of the memory object.
* [[VUID-VkMappedMemoryRange-offset-00687]]
pname:offset must: be a multiple of
sname:VkPhysicalDeviceLimits::pname:nonCoherentAtomSize
slink:VkPhysicalDeviceLimits::pname:nonCoherentAtomSize
* [[VUID-VkMappedMemoryRange-size-01390]]
If pname:size is not equal to ename:VK_WHOLE_SIZE, pname:size must:
either be a multiple of
sname:VkPhysicalDeviceLimits::pname:nonCoherentAtomSize, or pname:offset
slink:VkPhysicalDeviceLimits::pname:nonCoherentAtomSize, or pname:offset
plus pname:size must: equal the size of pname:memory.
****