Vulkan支持两种主要的资源类型: 缓冲区 和 图像。 资源是带有关联格式、维度信息的内存视图。 缓冲区是未格式化字节数组,图像包含格式化信息,可以是多维的,也能有关联的元数据。
11.1. 缓冲区
缓冲区表示线性数组数据,通过描述符集合或特定命令或直接指定它们作为特定命令的参数 绑定到图形或者计算管线被用于各种目的。
缓冲区由 VkBuffer
类型handle表示:
VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkBuffer)
可调用如下命令来创建缓冲区:
VkResult vkCreateBuffer(
VkDevice device,
const VkBufferCreateInfo* pCreateInfo,
const VkAllocationCallbacks* pAllocator,
VkBuffer* pBuffer);
-
device
是创建缓冲区对象的逻辑设备。 -
pCreateInfo
是一个指向VkBufferCreateInfo
类型实例的指针,包含了影响创建缓冲区的参数。 -
pAllocator
控制主机端内存分配,如 内存分配章所讲。 -
pBuffer
指向一个VkBuffer
handle,生成的缓冲区对象以此被返回。
Valid Usage
-
若
pCreateInfo
的成员flags
包含VK_BUFFER_CREATE_SPARSE_BINDING_BIT
,创建这个VkBuffer
不能导致在设备上当前有效的稀疏资源总体需求的稀疏内存 超过VkPhysicalDeviceLimits
::sparseAddressSpaceSize
Valid Usage (Implicit)
-
device
must be a validVkDevice
handle -
pCreateInfo
must be a pointer to a validVkBufferCreateInfo
structure -
If
pAllocator
is notNULL
,pAllocator
must be a pointer to a validVkAllocationCallbacks
structure -
pBuffer
must be a pointer to aVkBuffer
handle
Return Codes
-
VK_SUCCESS
-
VK_ERROR_OUT_OF_HOST_MEMORY
-
VK_ERROR_OUT_OF_DEVICE_MEMORY
VkBufferCreateInfo
数据结构定义如下:
typedef struct VkBufferCreateInfo {
VkStructureType sType;
const void* pNext;
VkBufferCreateFlags flags;
VkDeviceSize size;
VkBufferUsageFlags usage;
VkSharingMode sharingMode;
uint32_t queueFamilyIndexCount;
const uint32_t* pQueueFamilyIndices;
} VkBufferCreateInfo;
-
sType
是这个数据结构的类型。 -
pNext
是NULL
或者一个 extension-specific 数据结构的指针。 -
flags
是一个位掩码,描述了缓冲区的附加参数。参看下方受支持的VkBufferCreateFlagBits
描述。 -
size
是将被创建的缓冲区的字节数。 -
usage
是一个 bitmask,描述了缓冲区被允许的使用方式。 参考 如下VkBufferUsageFlagBits
受支持的bit。 -
sharingMode
是缓冲区被多个队列族访问时的共享模式,参考 Resource Sharing 小节中VkSharingMode
给出的受支持的值。 -
queueFamilyIndexCount
是pQueueFamilyIndices
数组中的元素个数。 -
pQueueFamilyIndices
是一些队列族,它们将访问这个缓冲区 (ignored ifsharingMode
is notVK_SHARING_MODE_CONCURRENT
)。
usage
中可以设置的bit如下:
typedef enum VkBufferUsageFlagBits {
VK_BUFFER_USAGE_TRANSFER_SRC_BIT = 0x00000001,
VK_BUFFER_USAGE_TRANSFER_DST_BIT = 0x00000002,
VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT = 0x00000004,
VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT = 0x00000008,
VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT = 0x00000010,
VK_BUFFER_USAGE_STORAGE_BUFFER_BIT = 0x00000020,
VK_BUFFER_USAGE_INDEX_BUFFER_BIT = 0x00000040,
VK_BUFFER_USAGE_VERTEX_BUFFER_BIT = 0x00000080,
VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT = 0x00000100,
} VkBufferUsageFlagBits;
-
VK_BUFFER_USAGE_TRANSFER_SRC_BIT
表明缓冲区可以被用作 transfer command 的源 (参看VK_PIPELINE_STAGE_TRANSFER_BIT
的定义). -
VK_BUFFER_USAGE_TRANSFER_DST_BIT
表明缓冲区可以被用作 转移名利的目标。 -
VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT
表明缓冲区可以被用于创建一个VkBufferView
,其适于 占用一个VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER
类型的VkDescriptorSet
槽。 -
VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT
表明缓冲区可以被用于创建一个VkBufferView
,其适于 占用一个VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER
类型的VkDescriptorSet
槽。 -
VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT
表明缓冲区可以被用在一个VkDescriptorBufferInfo
中 ,其适于占用一个 类型为VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER
或者VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC
的VkDescriptorSet
槽 。 -
VK_BUFFER_USAGE_STORAGE_BUFFER_BIT
表明缓冲区可以被用于VkDescriptorBufferInfo
中,其适于占用一个类型为VK_DESCRIPTOR_TYPE_STORAGE_BUFFER
或者VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC
VkDescriptorSet
槽。 -
VK_BUFFER_USAGE_INDEX_BUFFER_BIT
表明此缓冲区适于被用作参数传递给vkCmdBindIndexBuffer
. -
VK_BUFFER_USAGE_VERTEX_BUFFER_BIT
表明此缓冲区适于被当作pBuffers
数组的一个元素 传递给vkCmdBindVertexBuffers
. -
VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT
表明此缓冲区适于被当作buffer
参数被传递给vkCmdDrawIndirect
,vkCmdDrawIndexedIndirect
, 或者vkCmdDispatchIndirect
.
任何bit的组合 可以: 指定 usage
,但是至少其中一个必须被设置用于创建一个有效的缓冲区。
pname:flags可以被设置的bit如下:
typedef enum VkBufferCreateFlagBits {
VK_BUFFER_CREATE_SPARSE_BINDING_BIT = 0x00000001,
VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT = 0x00000002,
VK_BUFFER_CREATE_SPARSE_ALIASED_BIT = 0x00000004,
} VkBufferCreateFlagBits;
这些bit的意义如下:
-
VK_BUFFER_CREATE_SPARSE_BINDING_BIT
表示缓冲区将使用稀疏内存绑定来实现。 -
VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT
表示缓冲区可以部分使用稀疏内存绑定实现。使用此flag创建的缓冲区也可以通过VK_BUFFER_CREATE_SPARSE_BINDING_BIT
flag来创建。 -
VK_BUFFER_CREATE_SPARSE_ALIASED_BIT
表示缓冲区将使用稀疏内存绑定来实现,内存区间可能也同时存储其他缓冲区的内容 或者同一个缓冲区的其他部分。使用此flag创建的缓冲区也可以使用VK_BUFFER_CREATE_SPARSE_BINDING_BIT
flag来创建。
参看 Sparse Resource Features 和 Physical Device Features 来 获取设备支持的稀疏内存特性的其他细节。
Valid Usage
-
size
必须: 比0
要大 -
若
sharingMode
是VK_SHARING_MODE_CONCURRENT
,pQueueFamilyIndices
必须: 是一个指针,指向一个类型为uint32_t
的queueFamilyIndexCount
值。 -
若
sharingMode
是VK_SHARING_MODE_CONCURRENT
,queueFamilyIndexCount
必须: 大于`1` -
若sparse bindings 特征没有被启用,
flags
不能: 包含VK_BUFFER_CREATE_SPARSE_BINDING_BIT
-
若 sparse buffer residency 特征没有被启用,
flags
不能: 包含VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT
-
若 sparse aliased residency 特征没有被启用,
flags
不能: 包含VK_BUFFER_CREATE_SPARSE_ALIASED_BIT
-
若
flags
包含VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT
或者VK_BUFFER_CREATE_SPARSE_ALIASED_BIT
,它 必须: 也包含VK_BUFFER_CREATE_SPARSE_BINDING_BIT
Valid Usage (Implicit)
-
sType
must beVK_STRUCTURE_TYPE_BUFFER_CREATE_INFO
-
pNext
must beNULL
-
flags
must be a valid combination ofVkBufferCreateFlagBits
values -
usage
must be a valid combination ofVkBufferUsageFlagBits
values -
usage
must not be0
-
sharingMode
must be a validVkSharingMode
value
可调用下面的命令来销毁缓冲区:
void vkDestroyBuffer(
VkDevice device,
VkBuffer buffer,
const VkAllocationCallbacks* pAllocator);
-
device
是销毁缓冲区的逻辑设备。 -
buffer
是需要被销毁的缓冲区。 -
pAllocator
控制CPU端内存分配,如 内存分配 一章详述。
Valid Usage
-
所有涉及到
buffer
的被提交的命令,要么直接,要么通过VkBufferView
,必须: 已经完成了执行。 -
若创建
buffer
时,提供了VkAllocationCallbacks
,那么此处必须提供兼容的 callbacks 。 -
若创建
buffer
时, 没有提供VkAllocationCallbacks
,那么pAllocator
必须: 为NULL
Valid Usage (Implicit)
-
device
must be a validVkDevice
handle -
If
buffer
is notVK_NULL_HANDLE
,buffer
must be a validVkBuffer
handle -
If
pAllocator
is notNULL
,pAllocator
must be a pointer to a validVkAllocationCallbacks
structure -
If
buffer
is a valid handle, it must have been created, allocated, or retrieved fromdevice
Host Synchronization
-
Host access to
buffer
must be externally synchronized