11.4. 图像布局
图像被存储在依赖于Vulkan实现的不透明内存布局。Vulkan实现能能支持多种不透明布局,某个给定时刻使用的布局由 图像子资源的VkImageLayout
状态决定。 每一个布局都有限制条件,如使用该布局可对图像子资源做何种操作。 Applications have control over which layout each image subresource uses, and can transition an image subresource from one layout to another. Transitions可以 happen with an image memory barrier, included as part of avkCmdPipelineBarrier
或 a vkCmdWaitEvents
command buffer command (see 图像内存屏障),或 as part of a subpass dependency within a render pass (see VkSubpassDependency
). The image layout state is per-image subresource, and separate image subresources of the same image可以 be in different layouts at the same time with one exception - depth and stencil aspects of a given image subresource 必须 always be in the same layout.
注意 Each layout may offer optimal performance for a specific usage of image memory. For example, an image with a layout of |
创建完成后,一个图像的所有图像子资源初始状态都处于相同的布局,该布局由 VkImageCreateInfo
::initialLayout
成员选择。 initialLayout
必须 为 VK_IMAGE_LAYOUT_UNDEFINED
或 VK_IMAGE_LAYOUT_PREINITIALIZED
二者其一。 若为 VK_IMAGE_LAYOUT_PREINITIALIZED
, 那么该图像数据可以被host使用该布局预初始化,且布局转换可以保持数据。 若为 VK_IMAGE_LAYOUT_UNDEFINED
, 那么数据的内容被认为是未定义的,布局转换并不保证保持原有数据。 对于这任一初始布局,任何图像子资源 必须在device 访问它们之前转换到另一个布局。
Host access to image memory is only well-defined for images created with VK_IMAGE_TILING_LINEAR
tiling and for image subresources of those images which are currently in either the VK_IMAGE_LAYOUT_PREINITIALIZED
或 VK_IMAGE_LAYOUT_GENERAL
layout. Calling vkGetImageSubresourceLayout
for a linear image returns a subresource layout mapping that is valid for either of those image layouts.
The set of image layouts consists of:
typedef enum VkImageLayout {
VK_IMAGE_LAYOUT_UNDEFINED = 0,
VK_IMAGE_LAYOUT_GENERAL = 1,
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL = 2,
VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL = 3,
VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL = 4,
VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL = 5,
VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL = 6,
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL = 7,
VK_IMAGE_LAYOUT_PREINITIALIZED = 8,
} VkImageLayout;
The type(s) of device access supported by each layout are:
-
VK_IMAGE_LAYOUT_UNDEFINED
: 不支持设备访问。此布局 必须 仅被用作VkImageCreateInfo
或VkAttachmentDescription
的initialLayout
成员,或用于图像转换的oldLayout
。 当从此布局转换为其他布局时,内存的内容不被保证保留。 -
VK_IMAGE_LAYOUT_PREINITIALIZED
: 不支持设备访问。 此布局必须 仅被用于VkImageCreateInfo
或VkAttachmentDescription
的initialLayout
成员,或用于图像转换的oldLayout
。 当从此布局转换为其他布局时,内存的内容被保证保留。 此布局 专门被用于 host端写入的图像,其数据可以被立即写入内存,而不需要先执行布局转换。 当前,VK_IMAGE_LAYOUT_PREINITIALIZED
只对VK_IMAGE_TILING_LINEAR
图像有效,因为并没有为VK_IMAGE_TILING_OPTIMAL
图像定义的标准布局。 -
VK_IMAGE_LAYOUT_GENERAL
: 支持所有类型的设备访问。 -
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
: 必须 仅被用于VkFramebuffer
中的颜色或 resolve 附件。 此布局仅针对 以带有VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT
bit位被启用来创建的图像子资源来说有效。 -
VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL
: 必须 仅被用于VkFramebuffer
的 depth/stencil 附件。 此布局仅针对 以带有VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT
bit位被启用来创建的图像子资源来说有效。 -
VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL
: 必须 仅被用于VkFramebuffer
的只读 depth/stencil 附件, 且/或 被用于 着色器中只读的图像 (可以当作采样图像,combined image/sampler and/or 输入附件 被读取). 此布局仅针对 以带有VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT
bit位被启用来创建的图像子资源来说有效。 以VK_IMAGE_USAGE_SAMPLED_BIT
被创建的图像的图像子资源 可以在着色器中 被用作采样图像或combined image/sampler。 同样,, only image subresources of images created with 以VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT
被创建的图像的图像子资源 可以在着色器中被用作 输入附件。 -
VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
: 必须 仅被用作 着色器内只读图像 (可以被当作 采样图像、combined image/sampler 或 输入附件 只读采样)。 此布局仅针对 以带有VK_IMAGE_USAGE_SAMPLED_BIT
或VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT
bit位被启用来创建的图像子资源来说有效。 -
VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL
: 必须 仅被用作 转移命令的源图像 (参考VK_PIPELINE_STAGE_TRANSFER_BIT
的定义). 此布局仅针对 以带有VK_IMAGE_USAGE_TRANSFER_SRC_BIT
bit位被启用来创建的图像子资源来说有效。 -
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL
: 必须 仅被用作 转移命令的目标图像。 此布局仅针对 以带有VK_IMAGE_USAGE_TRANSFER_DST_BIT
bit位被启用来创建的图像子资源来说有效。
在API中每种方位图像的机制,都有一个参数 或 数据结构成员 来控制 访问该图像的布局。 对于转移命令,这是命令的一个参数 (参考 清除命令 和 复制命令)。 对于用作 帧缓冲区附件,这是 VkRenderPassCreateInfo
数据结构的一个成员 (参考 Render Pass)。 对于描述符集合中的使用,这是VkDescriptorImageInfo
数据结构的一个成员 (参考 描述符集合更新)。 在任何队列上 任何命令缓冲区命令访问图像的任何时刻,被访问该图像子资源的布局必须都匹配 API控制访问所指定的布局。
每个图像子资源的图像布局必须在该图像子资源的生命周期的每个时刻都是良好定义的。 这意味这在 该图像上操作 布局转换,老的布局值必须 等同于当前 图像子资源的布局 (在转换执行过程中), 或者是 VK_IMAGE_LAYOUT_UNDEFINED
( 意味着该图像子资源的内容不需要被保留)。 转移中使用的新布局 不能是 VK_IMAGE_LAYOUT_UNDEFINED
或 VK_IMAGE_LAYOUT_PREINITIALIZED
。