11.6. 资源内存关联
资源初始都是以_虚拟分配_ 的方式创建的,并不占内存。 设备内存被单独分配(参看设备内存),然后再和资源关联上。 这个关联操作对于稀疏、非稀疏资源来说是不同的。
任何以稀疏标志创建资源都被认为是稀疏资源。 以这些标志之外的标志创建的资源被认为是非稀疏资源。 关于稀疏资源的内存关联在 稀疏资源中有描述。
在资源被当作参数传递到以下任何一个操作之前,非稀疏资源必须完全并连续的绑定到一个VkDeviceMemory
对象:
-
创建图像或者缓冲区视图
-
更新描述符集合
-
在命令缓冲区中记录命令
一旦绑定了,内存绑定在资源的生命周期内就是不变的。
想要知道一个缓冲区资源的内存限制条件,可调用:
void vkGetBufferMemoryRequirements(
VkDevice device,
VkBuffer buffer,
VkMemoryRequirements* pMemoryRequirements);
-
device
是持有缓冲区的逻辑设备。 -
buffer
被查询的缓冲区。 -
pMemoryRequirements
指向一个VkMemoryRequirements
实例,装载了被返回的内存限制条件信息。
Valid Usage (Implicit)
-
device
must be a validVkDevice
handle -
buffer
must be a validVkBuffer
handle -
pMemoryRequirements
must be a pointer to aVkMemoryRequirements
structure -
buffer
must have been created, allocated, or retrieved fromdevice
想要知道图像资源内存限制条件,可调用:
void vkGetImageMemoryRequirements(
VkDevice device,
VkImage image,
VkMemoryRequirements* pMemoryRequirements);
-
device
是拥有该图像的逻辑设备。 -
image
是被查询的图像。 -
pMemoryRequirements
指向了一个VkMemoryRequirements
是列,装载了该图像对象内存限制条件信息。
Valid Usage (Implicit)
-
device
must be a validVkDevice
handle -
image
must be a validVkImage
handle -
pMemoryRequirements
must be a pointer to aVkMemoryRequirements
structure -
image
must have been created, allocated, or retrieved fromdevice
VkMemoryRequirements
类型数据结构定义如下:
typedef struct VkMemoryRequirements {
VkDeviceSize size;
VkDeviceSize alignment;
uint32_t memoryTypeBits;
} VkMemoryRequirements;
-
size
该资源所需的内存分配的大小,以字节为单位。 -
alignment
是资源所要求的内存分配的对齐大小,以字节为单位。 -
memoryTypeBits
是一个标志位,每一bit表示每一个受支持的内存类型。但是, 只有当i
在物理设备支持的内存类型VkPhysicalDeviceMemoryProperties
中的时候,i
才会被设置。
Vulkan实现保证关于内存限制条件的某些属性通过vkGetBufferMemoryRequirements
和vkGetImageMemoryRequirements
返回:
-
memoryTypeBits
成员总是至少包含一个被设置的bit位。 -
若
buffer
是一个在创建时没有带有VK_BUFFER_CREATE_SPARSE_BINDING_BIT
的VkBuffer
,或者若image
是在创建时VkImageCreateInfo
的tiling
成员带有VK_IMAGE_TILING_LINEAR
的VkImage
,那么此memoryTypeBits
成员总是至少包含一个被设置的bit位,对应一个带有propertyFlags
的VkMemoryType
,该propertyFlags
的VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT
bit 和VK_MEMORY_PROPERTY_HOST_COHERENT_BIT
bit 都被设置。 换言之,可映射的一致性内存可以总是被附着到这些对象上。 -
memoryTypeBits
成员总是至少包含一个被设置的bit位,对应着带有一个propertyFlags
的VkMemoryType
, 该propertyFlags
的VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT
bit 被设置。 -
memoryTypeBits
成员和所有的 创建时传递给vkCreateBuffer
的VkBufferCreateInfo
中 带有相同flags
andusage
的VkBuffer
对象相同, Further, ifusage1
andusage2
of typeVkBufferUsageFlags
are such that the bits set inusage2
are a subset of the bits set inusage1
, and they have the sameflags
, then the bits set inmemoryTypeBits
returned forusage1
必须 be a subset of the bits set inmemoryTypeBits
returned forusage2
, for all values offlags
. -
alignment
成员值是2的幂。 -
alignment
成员与 传递给name:vkCreateBuffer的VkBufferCreateInfo
数据结构的成员usage
和flags
的相同bit组合 而创建的所有VkBuffer
对象 相同。 -
对于被创建时带有一个颜色格式的图像,
memoryTypeBits
成员与 创建时传递给vkCreateImage
的VkImageCreateInfo
数据结构中的tiling
成员,flags
成员的VK_IMAGE_CREATE_SPARSE_BINDING_BIT
bit和 name:usage成员的VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT
的组合相同 所有的VkImage
对象完全一致。 -
对于被创建时带有一个depth/stencil 格式的图像,
memoryTypeBits
成员与 创建时传递给vkCreateImage
函数的VkImageCreateInfo
数据结构的format
成员、tiling
成员,flags
成员的VK_IMAGE_CREATE_SPARSE_BINDING_BIT
bit、usage
成员的VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT
的组合值相同的 所有VkImage
对象。 -
若内存要求是为
VkImage
准备的,memoryTypeBits
成员必须不能指代一个propertyFlags
的VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT
bit 被设置的VkMemoryType
,若传递给vkCreateImage
的数据结构的VkImageCreateInfo
的vkGetImageMemoryRequirements
::image
的成员usage
的VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT
bit 没有被设置。 -
若内存要求是为
VkBuffer
准备的,memoryTypeBits
成员必须不能指代一个propertyFlags
中VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT
bit被设置的VkMemoryType
。注意
此要求的隐藏含义是 该惰性分配的内存不适用于所有情形的缓冲区。
把内存附着在一个缓冲区对象,可调用:
VkResult vkBindBufferMemory(
VkDevice device,
VkBuffer buffer,
VkDeviceMemory memory,
VkDeviceSize memoryOffset);
-
device
是拥有该缓冲区和内存的逻辑设备。 -
buffer
是缓冲区。 -
memory
是一个VkDeviceMemory
类型对象,描述了需附着的设备内存。 -
memoryOffset
是memory
区域的起始偏移,该内存被绑定到缓冲区上。 被返回的memory
的成员VkMemoryRequirements
::size
带有的字节数,从memoryOffset
开始的字节数, 将被绑定到特定的缓冲区。
Valid Usage
-
buffer
本身不能是内存对象。 -
buffer
被创建时不能带有稀疏内存绑定标识位。 -
memoryOffset
必须小于memory
的大小。 -
若创建
buffer
时带有VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT
或VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT
,memoryOffset
必须是VkPhysicalDeviceLimits
::minTexelBufferOffsetAlignment
的倍数。 -
若创建
buffer
时带有VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT
,memoryOffset
必须是VkPhysicalDeviceLimits
::minUniformBufferOffsetAlignment
的倍数。 -
若创建
buffer
时带有VK_BUFFER_USAGE_STORAGE_BUFFER_BIT
,memoryOffset
必须是VkPhysicalDeviceLimits
::minStorageBufferOffsetAlignment
的倍数。 -
memory
被分配时必须使用 以buffer
为参数调用vkGetBufferMemoryRequirements
而返回的VkMemoryRequirements
数据结构的memoryTypeBits
成员中被允许的内存类型。 -
memoryOffset
必须是一个 以buffer
为参数调用vkGetBufferMemoryRequirements
而返回的VkMemoryRequirements
数据结构alignment
成员 的倍数的正整数。 -
以
buffer
为参数调用vkGetBufferMemoryRequirements
而返回的VkMemoryRequirements
数据结构的size
成员 必须 小于或 等于memory
减去memoryOffset
之差。
Valid Usage (Implicit)
-
device
must be a validVkDevice
handle -
buffer
must be a validVkBuffer
handle -
memory
must be a validVkDeviceMemory
handle -
buffer
must have been created, allocated, or retrieved fromdevice
-
memory
must have been created, allocated, or retrieved fromdevice
Host Synchronization
-
Host access to
buffer
must be externally synchronized
Return Codes
-
VK_SUCCESS
-
VK_ERROR_OUT_OF_HOST_MEMORY
-
VK_ERROR_OUT_OF_DEVICE_MEMORY
把内存附着到一个图像对象上,可调用:
VkResult vkBindImageMemory(
VkDevice device,
VkImage image,
VkDeviceMemory memory,
VkDeviceSize memoryOffset);
-
device
是拥有该图像和内存的逻辑设备。 -
image
是图像。 -
memory
是一个VkDeviceMemory
对象,描述了需被附着的设备内存。 -
memoryOffset
绑定到该图像的内存的区域的起始偏移。memory
的VkMemoryRequirements
::size
成员里被返回的字节数量,从memoryOffset
字节开始, 将被绑定到特定的图像。
Valid Usage
-
image
实际内存不能是内存对象。 -
image
被创建是不能带有稀疏内存绑定flags。 -
memoryOffset
必须小于memory
的大小。 -
memory
必须在创建时使用 以image
为参数调用vkGetImageMemoryRequirements
而返回的VkMemoryRequirements
数据结构的memoryTypeBits
成员中被允许的内存类型之一。 -
memoryOffset
必须是 以image
为参数调用vkGetImageMemoryRequirements
而返回的VkMemoryRequirements
数据结构的alignment
成员的正整数倍。 -
以
image
为参数调用vkGetImageMemoryRequirements
而返回的VkMemoryRequirements
数据结构的size
成员 必须 小于或 等于memory
减去memoryOffset
之差。
Valid Usage (Implicit)
-
device
must be a validVkDevice
handle -
image
must be a validVkImage
handle -
memory
must be a validVkDeviceMemory
handle -
image
must have been created, allocated, or retrieved fromdevice
-
memory
must have been created, allocated, or retrieved fromdevice
Host Synchronization
-
Host access to
image
must be externally synchronized
Return Codes
-
VK_SUCCESS
-
VK_ERROR_OUT_OF_HOST_MEMORY
-
VK_ERROR_OUT_OF_DEVICE_MEMORY
Buffer-Image Granularity
There is an implementation-dependent limit, bufferImageGranularity
, which specifies a page-like granularity at which buffer, linear image and optimal image resources 必须 be placed in adjacent memory locations to avoid aliasing. Two resources which do not satisfy this granularity requirement are said to alias. Linear image resource are images created with VK_IMAGE_TILING_LINEAR
and optimal image resources are those created withVK_IMAGE_TILING_OPTIMAL
. bufferImageGranularity
is specified in bytes, and 必须 be a power of two. Implementations which do not require such an additional granularity may report a value of one.
注意
|
Given resourceA at the lower memory offset and resourceB at the higher memory offset in the same VkDeviceMemory
object, where one of the resources is a buffer或 a linear image and the other is an optimal image, and the following:
resourceA.end = resourceA.memoryOffset + resourceA.size - 1
resourceA.endPage = resourceA.end & ~(bufferImageGranularity-1)
resourceB.start = resourceB.memoryOffset
resourceB.startPage = resourceB.start & ~(bufferImageGranularity-1)
The following property 必须 hold:
resourceA.endPage < resourceB.startPage
That is, the end of the first resource (A) and the beginning of the second resource (B) 必须 be on separate “pages” of size bufferImageGranularity
. bufferImageGranularity
may be different than the physical page size of the memory heap. This restriction is only needed when a buffer或 a linear image is at adjacent memory location with an optimal image and both will被用于 simultaneously. Adjacent buffers’或 adjacent images' memory ranges可以 be closer than bufferImageGranularity
, provided they meet the alignment
requirement for the objects in question.
Sparse block size in bytes and sparse image and buffer memory alignments 必须 all be multiples of the bufferImageGranularity
. Therefore, memory bound to sparse resources naturally satisfies thebufferImageGranularity
.