11.6. 资源内存关联
资源初始都是以_虚拟分配_ 的方式创建的,并不占内存。 设备内存被单独分配(参看设备内存),然后再和资源关联上。 这个关联操作对于稀疏、非稀疏资源来说是不同的。
任何以稀疏标志创建资源都被认为是稀疏资源。 以这些标志之外的标志创建的资源被认为是非稀疏资源。 关于稀疏资源的内存关联在 稀疏资源中有描述。
在资源被当作参数传递到以下任何一个操作之前,非稀疏资源必须完全并连续的绑定到一个
VkDeviceMemory
对象:
- 创建图像或者缓冲区视图
- 更新描述符集合
- 在命令缓冲区中记录命令
一旦绑定了,内存绑定在资源的生命周期内就是不变的。
想要知道一个缓冲区资源的内存限制条件,可调用:
void vkGetBufferMemoryRequirements(
VkDevice device,
VkBuffer buffer,
VkMemoryRequirements* pMemoryRequirements);
-
是持有缓冲区的逻辑设备。device
-
被查询的缓冲区。buffer
-
指向一个pMemoryRequirements
实例,装载了被返回的内存限制条件信息。VkMemoryRequirements
Valid Usage (Implicit)
-
must be a validdevice
handleVkDevice
-
must be a validbuffer
handleVkBuffer
-
must be a pointer to apMemoryRequirements
structureVkMemoryRequirements
-
must have been created, allocated, or retrieved frombuffer
device
想要知道图像资源内存限制条件,可调用:
void vkGetImageMemoryRequirements(
VkDevice device,
VkImage image,
VkMemoryRequirements* pMemoryRequirements);
-
是拥有该图像的逻辑设备。device
-
是被查询的图像。image
-
指向了一个pMemoryRequirements
是列,装载了该图像对象内存限制条件信息。VkMemoryRequirements
Valid Usage (Implicit)
-
must be a validdevice
handleVkDevice
-
must be a validimage
handleVkImage
-
must be a pointer to apMemoryRequirements
structureVkMemoryRequirements
-
must have been created, allocated, or retrieved fromimage
device
VkMemoryRequirements
类型数据结构定义如下:
typedef struct VkMemoryRequirements {
VkDeviceSize size;
VkDeviceSize alignment;
uint32_t memoryTypeBits;
} VkMemoryRequirements;
-
该资源所需的内存分配的大小,以字节为单位。size
-
是资源所要求的内存分配的对齐大小,以字节为单位。alignment
-
是一个标志位,每一bit表示每一个受支持的内存类型。但是, 只有当memoryTypeBits
在物理设备支持的内存类型i
中的时候,VkPhysicalDeviceMemoryProperties
才会被设置。i
Vulkan实现保证关于内存限制条件的某些属性通过
vkGetBufferMemoryRequirements
和
vkGetImageMemoryRequirements
返回:
-
成员总是至少包含一个被设置的bit位。memoryTypeBits
- 若
是一个在创建时没有带有buffer
的VK_BUFFER_CREATE_SPARSE_BINDING_BIT
,或者若VkBuffer
是在创建时image
的VkImageCreateInfo
成员带有tiling
的VK_IMAGE_TILING_LINEAR
,那么此VkImage
成员总是至少包含一个被设置的bit位,对应一个带有memoryTypeBits
的propertyFlags
,该VkMemoryType
的propertyFlags
bit 和VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT
bit 都被设置。 换言之,可映射的一致性内存可以总是被附着到这些对象上。VK_MEMORY_PROPERTY_HOST_COHERENT_BIT
-
成员总是至少包含一个被设置的bit位,对应着带有一个memoryTypeBits
的propertyFlags
, 该VkMemoryType
的propertyFlags
bit 被设置。VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT
-
成员和所有的 创建时传递给memoryTypeBits
的vkCreateBuffer
中 带有相同VkBufferCreateInfo
andflags
的usage
对象相同, Further, ifVkBuffer
andusage1
of typeusage2
are such that the bits set inVkBufferUsageFlags
are a subset of the bits set inusage2
, and they have the sameusage1
, then the bits set inflags
returned formemoryTypeBits
必须 be a subset of the bits set inusage1
returned formemoryTypeBits
, for all values ofusage2
.flags
-
成员值是2的幂。alignment
-
成员与 传递给name:vkCreateBuffer的alignment
数据结构的成员VkBufferCreateInfo
和usage
的相同bit组合 而创建的所有flags
对象 相同。VkBuffer
- 对于被创建时带有一个颜色格式的图像,
成员与 创建时传递给memoryTypeBits
的vkCreateImage
数据结构中的VkImageCreateInfo
成员,tiling
成员的flags
bit和 name:usage成员的VK_IMAGE_CREATE_SPARSE_BINDING_BIT
的组合相同 所有的VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT
对象完全一致。VkImage
- 对于被创建时带有一个depth/stencil 格式的图像,
成员与 创建时传递给memoryTypeBits
函数的vkCreateImage
数据结构的VkImageCreateInfo
成员、format
成员,tiling
成员的flags
bit、VK_IMAGE_CREATE_SPARSE_BINDING_BIT
成员的usage
的组合值相同的 所有VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT
对象。VkImage
- 若内存要求是为
准备的,VkImage
成员必须不能指代一个memoryTypeBits
的propertyFlags
bit 被设置的VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT
,若传递给VkMemoryType
的数据结构的vkCreateImage
的VkImageCreateInfo
::vkGetImageMemoryRequirements
的成员image
的usage
bit 没有被设置。VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT
- 若内存要求是为
准备的,VkBuffer
成员必须不能指代一个memoryTypeBits
中propertyFlags
bit被设置的VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_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)
-
must be a validdevice
handleVkDevice
-
must be a validbuffer
handleVkBuffer
-
must be a validmemory
handleVkDeviceMemory
-
must have been created, allocated, or retrieved frombuffer
device
-
must have been created, allocated, or retrieved frommemory
device
Host Synchronization
- Host access to
must be externally synchronizedbuffer
Return Codes
Success
-
VK_SUCCESS
Failure
-
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
-
被创建是不能带有稀疏内存绑定flags。image
-
必须小于memoryOffset
的大小。memory
-
必须在创建时使用 以memory
为参数调用image
而返回的vkGetImageMemoryRequirements
数据结构的VkMemoryRequirements
成员中被允许的内存类型之一。memoryTypeBits
-
必须是 以memoryOffset
为参数调用image
而返回的vkGetImageMemoryRequirements
数据结构的VkMemoryRequirements
成员的正整数倍。alignment
- 以
为参数调用image
而返回的vkGetImageMemoryRequirements
数据结构的VkMemoryRequirements
成员 必须 小于或 等于size
减去memory
之差。memoryOffset
Valid Usage (Implicit)
-
must be a validdevice
handleVkDevice
-
must be a validimage
handleVkImage
-
must be a validmemory
handleVkDeviceMemory
-
must have been created, allocated, or retrieved fromimage
device
-
must have been created, allocated, or retrieved frommemory
device
Host Synchronization
- Host access to
must be externally synchronizedimage
Return Codes
Success
-
VK_SUCCESS
Failure
-
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 with
VK_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.
注意 is really a granularity between "linear" resources, including buffers and images with linear tiling, vs. "optimal" resources, i.e. images with optimal tiling. It would have been better named "linearOptimalGranularity". |
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 the
bufferImageGranularity
.