渲染通道
绘制命令必须在渲染通道实例中记录。每个渲染通道实例定义一组在渲染期间使用的图像资源,称为附件。
要开始渲染通道实例,请调用
// Provided by VK_VERSION_1_3
void vkCmdBeginRendering(
VkCommandBuffer commandBuffer,
const VkRenderingInfo* pRenderingInfo);
或等效命令
// Provided by VK_KHR_dynamic_rendering
void vkCmdBeginRenderingKHR(
VkCommandBuffer commandBuffer,
const VkRenderingInfo* pRenderingInfo);
-
commandBuffer
是在其中记录命令的命令缓冲区。 -
pRenderingInfo
是指向 VkRenderingInfo 结构的指针,该结构指定要开始的渲染通道实例的详细信息。
开始渲染通道实例后,命令缓冲区即可记录绘制命令。
如果 pRenderingInfo->flags
包含 VK_RENDERING_RESUMING_BIT
,则此渲染通道是从先前在提交顺序中挂起的渲染通道实例恢复的。
VkRenderingInfo
结构定义如下
// Provided by VK_VERSION_1_3
typedef struct VkRenderingInfo {
VkStructureType sType;
const void* pNext;
VkRenderingFlags flags;
VkRect2D renderArea;
uint32_t layerCount;
uint32_t viewMask;
uint32_t colorAttachmentCount;
const VkRenderingAttachmentInfo* pColorAttachments;
const VkRenderingAttachmentInfo* pDepthAttachment;
const VkRenderingAttachmentInfo* pStencilAttachment;
} VkRenderingInfo;
或等效的
// Provided by VK_KHR_dynamic_rendering, VK_QCOM_tile_properties with VK_KHR_dynamic_rendering or VK_VERSION_1_3
typedef VkRenderingInfo VkRenderingInfoKHR;
-
sType
是一个 VkStructureType 值,用于标识此结构。 -
pNext
为NULL
或指向扩展此结构的结构的指针。 -
flags
是 VkRenderingFlagBits 的位掩码。 -
renderArea
是受渲染过程实例影响的渲染区域。 -
layerCount
是当viewMask
为0
时,每个附件中渲染的层数。 -
viewMask
是视图掩码,指示当它不为0
时将渲染的附件层的索引。 -
colorAttachmentCount
是pColorAttachments
中的元素数量。 -
pColorAttachments
是指向colorAttachmentCount
个 VkRenderingAttachmentInfo 结构的数组的指针,这些结构描述了使用的任何颜色附件。 -
pDepthAttachment
是指向描述深度附件的 VkRenderingAttachmentInfo 结构的指针。 -
pStencilAttachment
是指向描述模板附件的 VkRenderingAttachmentInfo 结构的指针。
如果 viewMask
不为 0
,则启用多视图。
如果 pNext
链中包含 VkDeviceGroupRenderPassBeginInfo 的实例,并且其 deviceRenderAreaCount
成员不为 0
,则将忽略 renderArea
,并且渲染区域由该结构按设备定义。
如果启用了多视图,并且启用了 multiviewPerViewRenderAreas
功能,并且 pNext
链中包含 VkMultiviewPerViewRenderAreasRenderPassBeginInfoQCOM 的实例,且 perViewRenderAreaCount
不等于 0
,则 VkMultiviewPerViewRenderAreasRenderPassBeginInfoQCOM::pPerViewRenderAreas
的元素将覆盖 renderArea
并为每个视图定义一个渲染区域。 在这种情况下,renderArea
必须 是至少与所有按视图渲染区域的联合一样大的区域。
pColorAttachments
数组的每个元素都对应于着色器中的一个输出位置,即如果着色器声明了一个使用 Location
值为 X 修饰的输出变量,则它将使用 pColorAttachments
[X] 中提供的附件。 如果 pColorAttachments
的任何元素的 imageView
成员是 VK_NULL_HANDLE,并且 resolveMode
不是 VK_RESOLVE_MODE_EXTERNAL_FORMAT_DOWNSAMPLE_ANDROID
,则会丢弃片段对相应位置的写入。
在 VkRenderingInfo::flags
中可以设置的,描述渲染通道附加属性的位是:
// Provided by VK_VERSION_1_3
typedef enum VkRenderingFlagBits {
VK_RENDERING_CONTENTS_SECONDARY_COMMAND_BUFFERS_BIT = 0x00000001,
VK_RENDERING_SUSPENDING_BIT = 0x00000002,
VK_RENDERING_RESUMING_BIT = 0x00000004,
// Provided by VK_EXT_legacy_dithering with (VK_KHR_dynamic_rendering or VK_VERSION_1_3) and (VK_KHR_maintenance5 or VK_VERSION_1_4)
VK_RENDERING_ENABLE_LEGACY_DITHERING_BIT_EXT = 0x00000008,
// Provided by VK_KHR_maintenance7
VK_RENDERING_CONTENTS_INLINE_BIT_KHR = 0x00000010,
// Provided by VK_KHR_dynamic_rendering
VK_RENDERING_CONTENTS_SECONDARY_COMMAND_BUFFERS_BIT_KHR = VK_RENDERING_CONTENTS_SECONDARY_COMMAND_BUFFERS_BIT,
// Provided by VK_KHR_dynamic_rendering
VK_RENDERING_SUSPENDING_BIT_KHR = VK_RENDERING_SUSPENDING_BIT,
// Provided by VK_KHR_dynamic_rendering
VK_RENDERING_RESUMING_BIT_KHR = VK_RENDERING_RESUMING_BIT,
// Provided by VK_EXT_nested_command_buffer
VK_RENDERING_CONTENTS_INLINE_BIT_EXT = VK_RENDERING_CONTENTS_INLINE_BIT_KHR,
} VkRenderingFlagBits;
或等效的
// Provided by VK_KHR_dynamic_rendering
typedef VkRenderingFlagBits VkRenderingFlagBitsKHR;
-
VK_RENDERING_CONTENTS_SECONDARY_COMMAND_BUFFERS_BIT
指定渲染通道实例的绘制调用将记录在辅助命令缓冲区中。如果启用了nestedCommandBuffer
特性,则绘制调用可以来自内联和 vkCmdExecuteCommands。 -
VK_RENDERING_RESUMING_BIT
指定渲染通道实例正在恢复之前暂停的渲染通道实例。 -
VK_RENDERING_SUSPENDING_BIT
指定渲染通道实例将被暂停。 -
VK_RENDERING_ENABLE_LEGACY_DITHERING_BIT_EXT
指定渲染通道实例启用了旧式抖动。 -
VK_RENDERING_CONTENTS_INLINE_BIT_KHR
指定渲染通道实例的绘制调用可以在当前命令缓冲区内内联记录。 这可以与VK_RENDERING_CONTENTS_SECONDARY_COMMAND_BUFFERS_BIT
位组合使用,以允许绘制调用同时在内联和辅助命令缓冲区中记录。
在暂停的渲染通道实例和恢复它们的渲染通道实例之间,pRenderingInfo
的内容必须匹配,除了 VK_RENDERING_RESUMING_BIT
、VK_RENDERING_SUSPENDING_BIT
和 VK_RENDERING_CONTENTS_SECONDARY_COMMAND_BUFFERS_BIT
标志的存在或缺失。在暂停和恢复渲染通道实例之间,不允许执行任何操作或同步命令,也不允许执行其他渲染通道实例。
// Provided by VK_VERSION_1_3
typedef VkFlags VkRenderingFlags;
或等效的
// Provided by VK_KHR_dynamic_rendering
typedef VkRenderingFlags VkRenderingFlagsKHR;
VkRenderingFlags
是一个位掩码类型,用于设置零个或多个 VkRenderingFlagBits 的掩码。
VkRenderingAttachmentInfo
结构体定义如下:
// Provided by VK_VERSION_1_3
typedef struct VkRenderingAttachmentInfo {
VkStructureType sType;
const void* pNext;
VkImageView imageView;
VkImageLayout imageLayout;
VkResolveModeFlagBits resolveMode;
VkImageView resolveImageView;
VkImageLayout resolveImageLayout;
VkAttachmentLoadOp loadOp;
VkAttachmentStoreOp storeOp;
VkClearValue clearValue;
} VkRenderingAttachmentInfo;
或等效的
// Provided by VK_KHR_dynamic_rendering
typedef VkRenderingAttachmentInfo VkRenderingAttachmentInfoKHR;
-
sType
是一个 VkStructureType 值,用于标识此结构。 -
pNext
为NULL
或指向扩展此结构的结构的指针。 -
imageView
是将用于渲染的图像视图。 -
imageLayout
是渲染期间imageView
将处于的布局。 -
resolveMode
是一个 VkResolveModeFlagBits 值,定义写入imageView
的数据将如何解析到resolveImageView
中。 -
resolveImageView
是一个图像视图,用于在渲染结束时写入解析后的数据。 -
resolveImageLayout
是渲染期间resolveImageView
将处于的布局。 -
loadOp
是一个 VkAttachmentLoadOp 值,定义附件的加载操作。 -
storeOp
是一个 VkAttachmentStoreOp 值,定义附件的存储操作。 -
clearValue
是一个 VkClearValue 结构体,定义当loadOp
为VK_ATTACHMENT_LOAD_OP_CLEAR
时用于清除imageView
的值。
imageView
中的值会根据 loadOp
和 storeOp
的值,在 VkRenderingInfo 中指定的每个设备的渲染区域内加载和存储。 如果 imageView
为 VK_NULL_HANDLE,并且 resolveMode
不是 VK_RESOLVE_MODE_EXTERNAL_FORMAT_DOWNSAMPLE_ANDROID
,则此结构体的其他成员将被忽略;对该附件的写入将被丢弃,并且不会执行加载、存储或多重采样解析操作。
如果 resolveMode
为 VK_RESOLVE_MODE_NONE
,则 resolveImageView
将被忽略。如果 resolveMode
不是 VK_RESOLVE_MODE_NONE
,且 resolveImageView
不为 VK_NULL_HANDLE,则为附件子资源定义渲染通道多重采样解析操作。如果 resolveMode
为 VK_RESOLVE_MODE_EXTERNAL_FORMAT_DOWNSAMPLE_ANDROID
,并且 nullColorAttachmentWithExternalFormatResolve
限制为 VK_TRUE
,则只有在 加载操作完成后,值才为未定义。
解析模式和存储操作是独立的;写入解析值和未解析值都是有效的,并且在写入解析值时丢弃未解析值也是同样有效的。 |
存储和解析操作仅在不指定 VK_RENDERING_SUSPENDING_BIT_KHR
标志的渲染通道实例结束时执行。
加载操作仅在不指定 VK_RENDERING_RESUMING_BIT_KHR
标志的渲染通道实例开始时执行。
暂停的渲染通道实例末尾的图像内容保持定义,以便恢复的渲染通道实例访问。
如果 nullColorAttachmentWithExternalFormatResolve
限制为 VK_TRUE
,并且 resolveMode
为 VK_RESOLVE_MODE_EXTERNAL_FORMAT_DOWNSAMPLE_ANDROID
,则在渲染开始时将从解析附件加载颜色附件中的值,并且在解析发生后或写入解析附件后,可能也会重新加载;如果发生这种情况,它必须在任何对颜色附件的写入之前发生,而这些写入发生在触发此操作的解析之后。如果外部格式中的任何颜色分量被二次采样,则当加载它们时,将从图像中最接近的采样中读取值。
VkRenderingFragmentShadingRateAttachmentInfoKHR
结构的定义如下:
// Provided by VK_KHR_fragment_shading_rate with VK_VERSION_1_3 or VK_KHR_dynamic_rendering
typedef struct VkRenderingFragmentShadingRateAttachmentInfoKHR {
VkStructureType sType;
const void* pNext;
VkImageView imageView;
VkImageLayout imageLayout;
VkExtent2D shadingRateAttachmentTexelSize;
} VkRenderingFragmentShadingRateAttachmentInfoKHR;
-
sType
是一个 VkStructureType 值,用于标识此结构。 -
pNext
为NULL
或指向扩展此结构的结构的指针。 -
imageView
是将用作片段着色率附件的图像视图。 -
imageLayout
是渲染期间imageView
将处于的布局。 -
shadingRateAttachmentTexelSize
指定imageView
中每个纹素对应的像素数。
此结构可以包含在 VkRenderingInfo 的 pNext
链中,以定义片段着色率附件。如果 imageView
为 VK_NULL_HANDLE,或者未指定此结构,则实现的行为就好像指定了一个有效的着色率附件,其中所有纹素都指定每个片段一个像素。
VkRenderingFragmentDensityMapAttachmentInfoEXT
结构定义如下
// Provided by VK_EXT_fragment_density_map with VK_VERSION_1_3 or VK_KHR_dynamic_rendering
typedef struct VkRenderingFragmentDensityMapAttachmentInfoEXT {
VkStructureType sType;
const void* pNext;
VkImageView imageView;
VkImageLayout imageLayout;
} VkRenderingFragmentDensityMapAttachmentInfoEXT;
-
sType
是一个 VkStructureType 值,用于标识此结构。 -
pNext
为NULL
或指向扩展此结构的结构的指针。 -
imageView
是将用作片段密度图附件的图像视图。 -
imageLayout
是渲染期间imageView
将处于的布局。
此结构可以包含在 VkRenderingInfo 的 pNext
链中,以定义片段密度图。如果此结构未包含在 pNext
链中,则 imageView
被视为 VK_NULL_HANDLE。
要查询渲染过程实例的渲染区域粒度,请调用
// Provided by VK_VERSION_1_4
void vkGetRenderingAreaGranularity(
VkDevice device,
const VkRenderingAreaInfo* pRenderingAreaInfo,
VkExtent2D* pGranularity);
或等效命令
// Provided by VK_KHR_maintenance5
void vkGetRenderingAreaGranularityKHR(
VkDevice device,
const VkRenderingAreaInfo* pRenderingAreaInfo,
VkExtent2D* pGranularity);
-
device
是拥有渲染过程实例的逻辑设备。 -
pRenderingAreaInfo
是指向 VkRenderingAreaInfo 结构的指针,该结构指定要查询渲染区域粒度的渲染过程实例的详细信息。 -
pGranularity
是指向 VkExtent2D 结构的指针,其中返回粒度。
导致最佳 renderArea
的条件是
-
renderArea
中的offset.x
成员是返回的 VkExtent2D 的width
成员(水平粒度)的倍数。 -
renderArea
中的offset.y
成员是返回的 VkExtent2D 的height
成员(垂直粒度)的倍数。 -
renderArea
中的extent.width
成员是水平粒度的倍数,或者offset.x
+extent.width
等于渲染过程实例中使用的每个附件的width
。 -
renderArea
中的extent.height
成员是垂直粒度的倍数,或者offset.y
+extent.height
等于渲染过程实例中使用的每个附件的height
。
VkRenderingAreaInfo
结构定义如下
// Provided by VK_VERSION_1_4
typedef struct VkRenderingAreaInfo {
VkStructureType sType;
const void* pNext;
uint32_t viewMask;
uint32_t colorAttachmentCount;
const VkFormat* pColorAttachmentFormats;
VkFormat depthAttachmentFormat;
VkFormat stencilAttachmentFormat;
} VkRenderingAreaInfo;
或等效的
// Provided by VK_KHR_maintenance5
typedef VkRenderingAreaInfo VkRenderingAreaInfoKHR;
-
sType
是一个 VkStructureType 值,用于标识此结构。 -
pNext
为NULL
或指向扩展此结构的结构的指针。 -
viewMask
是用于渲染的 viewMask。 -
colorAttachmentCount
是pColorAttachmentFormats
中的条目数 -
pColorAttachmentFormats
是指向 VkFormat 值数组的指针,这些值定义了渲染过程实例中使用的颜色附件的格式。 -
depthAttachmentFormat
是一个 VkFormat 值,定义了渲染过程实例中使用的深度附件的格式。 -
stencilAttachmentFormat
是一个 VkFormat 值,定义了渲染过程实例中使用的模板附件的格式。
VkRenderPassStripeBeginInfoARM
结构的定义如下:
// Provided by VK_ARM_render_pass_striped
typedef struct VkRenderPassStripeBeginInfoARM {
VkStructureType sType;
const void* pNext;
uint32_t stripeInfoCount;
const VkRenderPassStripeInfoARM* pStripeInfos;
} VkRenderPassStripeBeginInfoARM;
-
sType
是一个 VkStructureType 值,用于标识此结构。 -
pNext
为NULL
或指向扩展此结构的结构的指针。 -
stripeInfoCount
是此渲染过程实例中的条带数量。 -
pStripeInfos
是指向stripeInfoCount
个 VkRenderPassStripeInfoARM 结构数组的指针,这些结构描述了渲染过程实例使用的条带。
此结构可以包含在 VkRenderPassBeginInfo 或 VkRenderingInfo 的 pNext
链中,以定义渲染过程实例如何分割为条带。
VkRenderPassStripeInfoARM
结构的定义如下:
// Provided by VK_ARM_render_pass_striped
typedef struct VkRenderPassStripeInfoARM {
VkStructureType sType;
const void* pNext;
VkRect2D stripeArea;
} VkRenderPassStripeInfoARM;
-
sType
是一个 VkStructureType 值,用于标识此结构。 -
pNext
为NULL
或指向扩展此结构的结构的指针。 -
stripeArea
是条带区域,下面将详细介绍。
stripeArea
是渲染过程实例中此条带影响的渲染区域。它必须是渲染过程实例的 renderArea
的子区域。
要结束渲染过程实例,请调用
// Provided by VK_VERSION_1_3
void vkCmdEndRendering(
VkCommandBuffer commandBuffer);
或等效命令
// Provided by VK_KHR_dynamic_rendering
void vkCmdEndRenderingKHR(
VkCommandBuffer commandBuffer);
-
commandBuffer
是在其中记录命令的命令缓冲区。
如果用于开始此渲染过程实例的 pRenderingInfo->flags
的值包含 VK_RENDERING_SUSPENDING_BIT
,则此渲染过程将被挂起,并在 提交顺序 中稍后恢复。
对于更复杂的渲染图,可以预定义一个静态的渲染过程对象,该对象除了允许绘制命令外,还允许定义多个子过程之间的帧缓冲本地依赖关系。与 vkCmdBeginRendering 相比,这些对象的设置成本很高,但在某些设备上使用子过程依赖关系可以带来重要的性能优势。 |
VkTilePropertiesQCOM
结构的定义如下:
// Provided by VK_QCOM_tile_properties
typedef struct VkTilePropertiesQCOM {
VkStructureType sType;
void* pNext;
VkExtent3D tileSize;
VkExtent2D apronSize;
VkOffset2D origin;
} VkTilePropertiesQCOM;
-
sType
是一个 VkStructureType 值,用于标识此结构。 -
pNext
为NULL
或指向扩展此结构的结构的指针。 -
tileSize
是图块的尺寸,其中宽度和高度描述了图块的像素宽度和高度,深度对应于图块跨越的切片数。 -
apronSize
是围裙的尺寸。 -
origin
是附件空间中第一个图块的左上角。
所有图块都将紧密地围绕第一个图块排列,边缘与原点的距离是图块宽度和/或高度的倍数。
|
要在使用动态渲染时查询图块属性,请调用
// Provided by VK_QCOM_tile_properties
VkResult vkGetDynamicRenderingTilePropertiesQCOM(
VkDevice device,
const VkRenderingInfo* pRenderingInfo,
VkTilePropertiesQCOM* pProperties);
-
device
是与渲染通道关联的逻辑设备。 -
pRenderingInfo
是指向 VkRenderingInfo 结构的指针,该结构指定动态渲染中渲染通道实例的详细信息。 -
pProperties
是指向 VkTilePropertiesQCOM 结构的指针,该结构将返回属性。
渲染通道对象
渲染通道对象表示附件、子通道以及子通道之间依赖关系的集合,并描述附件在子通道过程中如何被使用。
渲染通道由 VkRenderPass
句柄表示
// Provided by VK_VERSION_1_0
VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkRenderPass)
附件描述描述附件的属性,包括其格式、采样计数,以及在每个渲染通道实例的开始和结束时如何处理其内容。
子通道表示渲染的一个阶段,该阶段读取和写入渲染通道中附件的子集。渲染命令被记录到渲染通道实例的特定子通道中。
子通道描述描述参与子通道执行的附件子集。每个子通道可以从一些附件读取数据作为输入附件,写入一些附件作为颜色附件或深度/模板附件,对颜色附件或深度/模板附件执行着色器解析操作,并对解析附件执行多重采样解析操作。子通道描述也可以包括一组保留附件,这些附件不会被子通道读取或写入,但其内容必须在整个子通道中保留。
如果附件是该子通道的颜色、深度/模板、解析、深度/模板解析、片段着色率或输入附件,则子通道使用附件(由VkSubpassDescription的pColorAttachments
、pDepthStencilAttachment
、pResolveAttachments
、VkSubpassDescriptionDepthStencilResolve::pDepthStencilResolveAttachment
、VkFragmentShadingRateAttachmentInfoKHR::pFragmentShadingRateAttachment->attachment
和pInputAttachments
成员确定)。如果子通道保留附件,则子通道不使用该附件。附件的首次使用是在使用该附件的编号最小的子通道中。类似地,附件的最后一次使用是在使用该附件的编号最大的子通道中。
渲染通道中的子通道都渲染到相同的尺寸,并且一个子通道中像素(x,y,layer)的片段只能读取先前子通道在相同(x,y,layer)位置写入的附件内容。对于多像素片段,从输入附件读取的像素是从实现相关的方式中选择的,该方式涵盖了该片段的像素。但是,对于VkDevice的生命周期内,任何具有相同着色率的片段,都必须一致地进行此选择。
通过预先描述完整的子通道集合,渲染通道为实现提供了优化子通道之间附件数据的存储和传输的机会。 实际上,这意味着具有简单帧缓冲区空间依赖性的子通道可能被合并为单个平铺渲染通道,从而在渲染通道实例期间将附件数据保留在芯片上。但是,渲染通道也只包含一个子通道的情况也很常见。 |
子通道依赖关系描述子通道之间的执行和内存依赖关系。
子通道依赖关系链是渲染通道中子通道依赖关系的一个序列,其中每个子通道依赖关系(在第一个之后)的源子通道等于前一个依赖关系的目标子通道。
子通道的执行可能与其它子通道重叠或乱序执行,除非执行依赖强制要求。每个子通道仅尊重在同一子通道中记录的命令以及分隔渲染通道的vkCmdBeginRenderPass和vkCmdEndRenderPass命令的提交顺序 - 不包括其他子通道内的命令。这会影响大多数其他隐式排序保证。
渲染通道描述了独立于附件的任何特定图像视图的子通道和附件的结构。将用于附件的特定图像视图及其尺寸在 VkFramebuffer
对象中指定。帧缓冲区是根据帧缓冲区与之兼容的特定渲染通道创建的(请参阅渲染通道兼容性)。总体而言,渲染通道和帧缓冲区定义了一个或多个子通道的完整渲染目标状态以及子通道之间的算法依赖关系。
给定子通道的绘制命令的各个管线阶段可以在绘制命令内部和跨绘制命令同时和/或乱序执行,同时仍然尊重管线顺序。但是,对于给定的(x,y,layer,sample)采样位置,某些每采样操作以光栅化顺序执行。
VK_ATTACHMENT_UNUSED
是一个常量,指示渲染通道附件未使用。
#define VK_ATTACHMENT_UNUSED (~0U)
渲染通道创建
要创建渲染通道,请调用
// Provided by VK_VERSION_1_0
VkResult vkCreateRenderPass(
VkDevice device,
const VkRenderPassCreateInfo* pCreateInfo,
const VkAllocationCallbacks* pAllocator,
VkRenderPass* pRenderPass);
-
device
是创建渲染通道的逻辑设备。 -
pCreateInfo
是指向 VkRenderPassCreateInfo 结构的指针,该结构描述渲染通道的参数。 -
pAllocator
控制主机内存分配,如内存分配章节所述。 -
pRenderPass
是指向 VkRenderPass 句柄的指针,其中返回生成的渲染通道对象。
VkRenderPassCreateInfo
结构定义如下:
// Provided by VK_VERSION_1_0
typedef struct VkRenderPassCreateInfo {
VkStructureType sType;
const void* pNext;
VkRenderPassCreateFlags flags;
uint32_t attachmentCount;
const VkAttachmentDescription* pAttachments;
uint32_t subpassCount;
const VkSubpassDescription* pSubpasses;
uint32_t dependencyCount;
const VkSubpassDependency* pDependencies;
} VkRenderPassCreateInfo;
-
sType
是一个 VkStructureType 值,用于标识此结构。 -
pNext
为NULL
或指向扩展此结构的结构的指针。 -
flags
是 VkRenderPassCreateFlagBits 的位掩码。 -
attachmentCount
是此渲染通道使用的附件数量。 -
pAttachments
是指向attachmentCount
个 VkAttachmentDescription 结构数组的指针,这些结构描述了渲染通道使用的附件。 -
subpassCount
是要创建的子通道数量。 -
pSubpasses
是指向subpassCount
个 VkSubpassDescription 结构数组的指针,这些结构描述了每个子通道。 -
dependencyCount
是子通道对之间内存依赖的数量。 -
pDependencies
是指向dependencyCount
个 VkSubpassDependency 结构数组的指针,这些结构描述了子通道对之间的依赖关系。
应注意避免此处的数据竞争;如果任何子通道访问具有重叠内存位置的附件,并且其中一个访问是写入,则需要在它们之间包含子通道依赖关系。 |
可以在 VkRenderPassCreateInfo::flags
中设置的位,用于描述渲染通道的附加属性,如下所示:
// Provided by VK_VERSION_1_0
typedef enum VkRenderPassCreateFlagBits {
// Provided by VK_QCOM_render_pass_transform
VK_RENDER_PASS_CREATE_TRANSFORM_BIT_QCOM = 0x00000002,
} VkRenderPassCreateFlagBits;
-
VK_RENDER_PASS_CREATE_TRANSFORM_BIT_QCOM
指定创建的渲染通道与渲染通道变换兼容。
// Provided by VK_VERSION_1_0
typedef VkFlags VkRenderPassCreateFlags;
VkRenderPassCreateFlags
是一个位掩码类型,用于设置零个或多个 VkRenderPassCreateFlagBits 的掩码。
如果 VkRenderPassCreateInfo::pNext
链包含 VkRenderPassMultiviewCreateInfo
结构,则该结构包含渲染通道的视图掩码、视图偏移量和相关掩码的数组。
VkRenderPassMultiviewCreateInfo
结构定义如下:
// Provided by VK_VERSION_1_1
typedef struct VkRenderPassMultiviewCreateInfo {
VkStructureType sType;
const void* pNext;
uint32_t subpassCount;
const uint32_t* pViewMasks;
uint32_t dependencyCount;
const int32_t* pViewOffsets;
uint32_t correlationMaskCount;
const uint32_t* pCorrelationMasks;
} VkRenderPassMultiviewCreateInfo;
或等效的
// Provided by VK_KHR_multiview
typedef VkRenderPassMultiviewCreateInfo VkRenderPassMultiviewCreateInfoKHR;
-
sType
是一个 VkStructureType 值,用于标识此结构。 -
pNext
为NULL
或指向扩展此结构的结构的指针。 -
subpassCount
为零或渲染通道中子通道的数量。 -
pViewMasks
是指向subpassCount
个视图掩码的数组的指针,其中每个掩码都是视图索引的位域,描述在启用多视图时,每个子通道中的渲染被广播到哪些视图。如果subpassCount
为零,则每个视图掩码都被视为零。 -
dependencyCount
为零或渲染通道中依赖项的数量。 -
pViewOffsets
是指向dependencyCount
个视图偏移量的数组的指针,每个依赖项一个。如果dependencyCount
为零,则每个依赖项的视图偏移量都被视为零。每个视图偏移量控制目标子通道中的视图依赖于源子通道中的哪些视图。 -
correlationMaskCount
为零或相关掩码的数量。 -
pCorrelationMasks
是指向correlationMaskCount
个视图掩码的数组的指针,指示可能更高效地同时渲染的视图集。
当子通道使用非零视图掩码时,将认为启用了多视图功能。多视图对于渲染通道来说是完全的 - 也就是说,要么所有子通道 必须 具有非零视图掩码(尽管某些子通道 可能 只有一个视图),要么所有子通道 必须 为零。多视图使子通道中的所有绘制和清除命令的行为就像它们被广播到每个视图一样,其中视图由帧缓冲附件的一个层表示。所有绘制和清除操作都将广播到视图掩码中设置了位的每个视图索引。视图索引在 ViewIndex
着色器输入变量中提供,颜色、深度/模板和输入附件都读取/写入与视图索引相对应的帧缓冲层。
如果所有子通道的视图掩码都为零,则认为多视图已禁用,并且所有绘制命令都正常执行,而没有此额外的广播。
启用多视图时,依赖项中的 VK_DEPENDENCY_VIEW_LOCAL_BIT
位 可以 用于表示视图局部依赖项,这意味着目标子通道中的每个视图都依赖于源子通道中的单个视图。与管线屏障不同,子通道依赖项 可以 在源子通道和目标子通道中具有不同的视图掩码。如果依赖项是视图局部的,则目标子通道中的每个视图(dstView)都依赖于源子通道中的视图 dstView + pViewOffsets
[dependency]。如果源子通道中不存在这样的视图,则此依赖项不会影响目标子通道中的该视图。如果依赖项不是视图局部的,则目标子通道中的所有视图都依赖于源子通道中的所有视图,并且视图偏移量将被忽略。在自依赖项中不允许使用非零视图偏移量。
pCorrelationMasks
的元素是一组视图掩码,指示同一掩码中的视图之间可能存在空间一致性,从而使同时渲染它们更有效率。相关掩码 必须 不会对多视图渲染的结果产生功能性影响。
启用多视图时,在每个子通道的开头,所有非渲染通道状态都是未定义的。特别是,每次调用 vkCmdBeginRenderPass 或 vkCmdNextSubpass 时,必须绑定图形管线,必须绑定任何相关的描述符集或顶点/索引缓冲区,并且必须在使用之前设置任何相关的动态状态或推送常量。
多视图子通道可以声明其着色器将为单个调用中的所有视图写入每个视图的属性,方法是在子通道描述中设置 VK_SUBPASS_DESCRIPTION_PER_VIEW_ATTRIBUTES_BIT_NVX
位。唯一支持的每个视图属性是位置和视口掩码,并且每个视图的位置和视口掩码分别写入用 PositionPerViewNV
和 ViewportMaskPerViewNV
修饰的输出数组变量。如果不支持且未启用 VK_NV_viewport_array2
扩展,则必须不使用 ViewportMaskPerViewNV
。写入到 PositionPerViewNV
和 ViewportMaskPerViewNV
元素的数值必须不依赖于 ViewIndex
。着色器必须还写入到用 Position
修饰的输出变量,并且写入到 Position
的数值必须等于写入到 PositionPerViewNV
[ViewIndex
] 的数值。类似地,如果写入了 ViewportMaskPerViewNV
,则着色器必须还写入到用 ViewportMaskNV
修饰的输出变量,并且写入到 ViewportMaskNV
的数值必须等于写入到 ViewportMaskPerViewNV
[ViewIndex
] 的数值。实现将使用从 Position
和 ViewportMaskNV
获取的值并为每个视图调用着色器一次,或者将使用从 PositionPerViewNV
和 ViewportMaskPerViewNV
获取的值并较少地调用着色器。写入到 Position
和 ViewportMaskNV
的数值必须不依赖于写入到 PositionPerViewNV
和 ViewportMaskPerViewNV
的数值,反之亦然(以允许编译器消除未使用的输出)。所有没有 *PerViewNV
对应项的属性必须不依赖于 ViewIndex
。
对于一个子通道,每个视图的属性是全有或全无的。也就是说,针对包含 VK_SUBPASS_DESCRIPTION_PER_VIEW_ATTRIBUTES_BIT_NVX
位的子通道编译的所有管线,必须将每个视图的属性写入到 *PerViewNV[]
着色器输出,此外还包括非每个视图(例如 Position
)的输出。针对不包含此位的子通道编译的管线,必须不在其接口中包含 *PerViewNV[]
输出。
VkMultiviewPerViewAttributesInfoNVX
结构定义为
// Provided by VK_NVX_multiview_per_view_attributes with VK_VERSION_1_3 or VK_KHR_dynamic_rendering
typedef struct VkMultiviewPerViewAttributesInfoNVX {
VkStructureType sType;
const void* pNext;
VkBool32 perViewAttributes;
VkBool32 perViewAttributesPositionXOnly;
} VkMultiviewPerViewAttributesInfoNVX;
-
sType
是一个 VkStructureType 值,用于标识此结构。 -
pNext
为NULL
或指向扩展此结构的结构的指针。 -
perViewAttributes
指定为此管线编译的着色器在每个顶点处理阶段的单个调用中写入所有视图的属性。在包含此位的渲染通道实例中执行的所有管线,必须将每个视图的属性写入到*PerViewNV[]
着色器输出,此外还包括非每个视图(例如Position
)的输出。 -
perViewAttributesPositionXOnly
指定为此管线编译的着色器使用仅在 x 分量中值不同的每个视图位置。每个视图的视口掩码可以也使用。
当使用动态渲染通道实例时,不是在子通道描述标志中指定 VK_SUBPASS_DESCRIPTION_PER_VIEW_ATTRIBUTES_BIT_NVX
或 VK_SUBPASS_DESCRIPTION_PER_VIEW_POSITION_X_ONLY_BIT_NVX
,而是必须通过 VkMultiviewPerViewAttributesInfoNVX
结构指定渲染通道实例的每个属性属性。在为动态渲染创建图形管线时,将 VkMultiviewPerViewAttributesInfoNVX
结构包含在 VkGraphicsPipelineCreateInfo 的 pNext
链中;在启动动态渲染通道实例时,将其包含在 VkRenderingInfo 中;并在为二级命令缓冲区指定动态渲染通道实例参数时,将其包含在 VkCommandBufferInheritanceInfo 中。
如果 VkRenderPassCreateInfo::pNext
链包含一个 VkRenderPassFragmentDensityMapCreateInfoEXT
结构,则该结构包括渲染通道的片段密度映射附件。
VkRenderPassFragmentDensityMapCreateInfoEXT
结构定义为
// Provided by VK_EXT_fragment_density_map
typedef struct VkRenderPassFragmentDensityMapCreateInfoEXT {
VkStructureType sType;
const void* pNext;
VkAttachmentReference fragmentDensityMapAttachment;
} VkRenderPassFragmentDensityMapCreateInfoEXT;
-
sType
是一个 VkStructureType 值,用于标识此结构。 -
pNext
为NULL
或指向扩展此结构的结构的指针。 -
fragmentDensityMapAttachment
是用于渲染通道的片段密度映射。
片段密度映射在与附件的图像视图 flags
确定的以下约束相关的实现定义的时间读取
-
VK_IMAGE_VIEW_CREATE_FRAGMENT_DENSITY_MAP_DYNAMIC_BIT_EXT
指定设备将在VK_PIPELINE_STAGE_FRAGMENT_DENSITY_PROCESS_BIT_EXT
期间读取片段密度映射。 -
VK_IMAGE_VIEW_CREATE_FRAGMENT_DENSITY_MAP_DEFERRED_BIT_EXT
指定主机将在渲染通道记录到的主命令缓冲区的 vkEndCommandBuffer 期间读取片段密度映射。 -
否则,主机将在 vkCmdBeginRenderPass 期间读取片段密度映射。
对于任何模式,设备可以在 VK_PIPELINE_STAGE_FRAGMENT_DENSITY_PROCESS_BIT_EXT
期间额外读取片段密度映射。
如果不存在此结构,则如同将 fragmentDensityMapAttachment
指定为 VK_ATTACHMENT_UNUSED
。
VkAttachmentDescription
结构体的定义如下:
// Provided by VK_VERSION_1_0
typedef struct VkAttachmentDescription {
VkAttachmentDescriptionFlags flags;
VkFormat format;
VkSampleCountFlagBits samples;
VkAttachmentLoadOp loadOp;
VkAttachmentStoreOp storeOp;
VkAttachmentLoadOp stencilLoadOp;
VkAttachmentStoreOp stencilStoreOp;
VkImageLayout initialLayout;
VkImageLayout finalLayout;
} VkAttachmentDescription;
-
flags
是一个 VkAttachmentDescriptionFlagBits 的位掩码,用于指定附件的附加属性。 -
format
是一个 VkFormat 值,用于指定将用于附件的图像视图的格式。 -
samples
是一个 VkSampleCountFlagBits 值,用于指定图像的样本数量。 -
loadOp
是一个 VkAttachmentLoadOp 值,用于指定在第一次使用附件的子通道开始时,如何处理附件的颜色和深度分量的内容。 -
storeOp
是一个 VkAttachmentStoreOp 值,用于指定在最后一次使用附件的子通道结束时,如何处理附件的颜色和深度分量的内容。 -
stencilLoadOp
是一个 VkAttachmentLoadOp 值,用于指定在第一次使用附件的子通道开始时,如何处理附件的模板分量的内容。 -
stencilStoreOp
是一个 VkAttachmentStoreOp 值,用于指定在最后一次使用附件的子通道结束时,如何处理附件的模板分量的内容。 -
initialLayout
是渲染通道实例开始时,附件图像子资源的布局。 -
finalLayout
是渲染通道实例结束时,附件图像子资源将转换到的布局。
如果附件使用颜色格式,则使用 loadOp
和 storeOp
,而 stencilLoadOp
和 stencilStoreOp
将被忽略。如果格式具有深度和/或模板分量,则 loadOp
和 storeOp
仅适用于深度数据,而 stencilLoadOp
和 stencilStoreOp
定义如何处理模板数据。loadOp
和 stencilLoadOp
定义附件的加载操作。storeOp
和 stencilStoreOp
定义附件的存储操作。如果任何子通道都不使用附件,则该附件的 loadOp
、storeOp
、stencilStoreOp
和 stencilLoadOp
将被忽略,并且不会执行加载或存储操作。但是,由 initialLayout
和 finalLayout
指定的任何转换仍将执行。
如果 flags
包括 VK_ATTACHMENT_DESCRIPTION_MAY_ALIAS_BIT
,则该附件将被视为与同一渲染通道中的另一个附件共享物理内存。此信息限制了实现重新排序某些操作(如布局转换和 loadOp
)的能力,从而避免与其他通过不同附件对同一物理内存的使用进行错误地重新排序。这将在下面更详细地描述。
如果渲染通道使用多个别名同一设备内存的附件,则这些附件的附件描述标志中必须包含 VK_ATTACHMENT_DESCRIPTION_MAY_ALIAS_BIT
位。别名同一内存的附件以多种方式出现:
-
多个附件被分配相同的图像视图作为帧缓冲创建的一部分。
-
附件使用与图像的同一图像子资源对应的不同图像视图。
-
附件使用与绑定到重叠内存范围的不同图像子资源的视图。
渲染通道必须在任何两个操作相同附件或别名附件的子通道之间包含子通道依赖项(直接或通过子通道依赖项链),并且这些子通道依赖项必须包含分隔别名使用的执行和内存依赖项,如果至少有一个子通道写入其中一个别名。如果别名是内存中重叠的不同图像子资源的视图,则这些依赖项不能包括 |
别名相同内存的多个附件不能在单个子通道中使用。给定的附件索引不能在单个子通道中多次使用,但有一个例外:如果至少有一个用作输入附件并且两个都没有用作解析或保留附件,则两个子通道附件可以使用相同的附件索引。换句话说,同一视图可以同时用作输入和颜色或深度/模板附件,但不能用作多个颜色或深度/模板附件,也不能用作解析或保留附件。
如果一组附件相互别名,则所有除渲染通道中第一个使用的附件之外的附件必须使用 VK_IMAGE_LAYOUT_UNDEFINED
的 initialLayout
,因为较早使用其他别名会使其内容未定义。一旦使用了一个别名,并且在此之后使用了另一个不同的别名,则第一个别名不得在任何后续的子通道中使用。但是,应用程序可以将相同的图像视图分配给多个别名附件索引,这允许即使在使用了其他别名之间,也可以多次使用该图像视图。
一旦附件需要 |
在 VkAttachmentDescription::flags
中可以设置的位,描述了附件的附加属性,是
// Provided by VK_VERSION_1_0
typedef enum VkAttachmentDescriptionFlagBits {
VK_ATTACHMENT_DESCRIPTION_MAY_ALIAS_BIT = 0x00000001,
} VkAttachmentDescriptionFlagBits;
-
VK_ATTACHMENT_DESCRIPTION_MAY_ALIAS_BIT
指定附件与其它附件使用相同的设备内存别名。
// Provided by VK_VERSION_1_0
typedef VkFlags VkAttachmentDescriptionFlags;
VkAttachmentDescriptionFlags
是一个位掩码类型,用于设置零个或多个 VkAttachmentDescriptionFlagBits 的掩码。
VkRenderPassInputAttachmentAspectCreateInfo
结构定义如下
// Provided by VK_VERSION_1_1
typedef struct VkRenderPassInputAttachmentAspectCreateInfo {
VkStructureType sType;
const void* pNext;
uint32_t aspectReferenceCount;
const VkInputAttachmentAspectReference* pAspectReferences;
} VkRenderPassInputAttachmentAspectCreateInfo;
或等效的
// Provided by VK_KHR_maintenance2
typedef VkRenderPassInputAttachmentAspectCreateInfo VkRenderPassInputAttachmentAspectCreateInfoKHR;
-
sType
是一个 VkStructureType 值,用于标识此结构。 -
pNext
为NULL
或指向扩展此结构的结构的指针。 -
aspectReferenceCount
是pAspectReferences
数组中的元素数量。 -
pAspectReferences
是一个指向aspectReferenceCount
个 VkInputAttachmentAspectReference 结构的数组的指针,该结构包含一个掩码,用于描述在给定的子通道中,可以访问给定输入附件的哪个或哪些方面。
要指定输入附件的哪些方面可以被读取,请将 VkRenderPassInputAttachmentAspectCreateInfo 结构添加到 VkRenderPassCreateInfo 结构的 pNext
链中
应用程序可以访问在 pAspectReferences
数组中没有指定方面掩码的输入附件的任何方面。否则,应用程序必须不访问输入附件的方面,除非该方面位于其指定的方面掩码中。
VkInputAttachmentAspectReference
结构定义如下
// Provided by VK_VERSION_1_1
typedef struct VkInputAttachmentAspectReference {
uint32_t subpass;
uint32_t inputAttachmentIndex;
VkImageAspectFlags aspectMask;
} VkInputAttachmentAspectReference;
或等效的
// Provided by VK_KHR_maintenance2
typedef VkInputAttachmentAspectReference VkInputAttachmentAspectReferenceKHR;
-
subpass
是父VkRenderPassCreateInfo
结构的pSubpasses
数组中的索引。 -
inputAttachmentIndex
是指定子通道的pInputAttachments
中的索引。 -
aspectMask
是一个掩码,指示在指定子通道中可以访问的方面。
此结构指定渲染通道中特定子通道的特定输入附件的方面掩码。
subpass
和 inputAttachmentIndex
索引到渲染通道的方式如下:
pCreateInfo->pSubpasses[subpass].pInputAttachments[inputAttachmentIndex]
VkSubpassDescription
结构定义如下:
// Provided by VK_VERSION_1_0
typedef struct VkSubpassDescription {
VkSubpassDescriptionFlags flags;
VkPipelineBindPoint pipelineBindPoint;
uint32_t inputAttachmentCount;
const VkAttachmentReference* pInputAttachments;
uint32_t colorAttachmentCount;
const VkAttachmentReference* pColorAttachments;
const VkAttachmentReference* pResolveAttachments;
const VkAttachmentReference* pDepthStencilAttachment;
uint32_t preserveAttachmentCount;
const uint32_t* pPreserveAttachments;
} VkSubpassDescription;
-
flags
是一个 VkSubpassDescriptionFlagBits 的位掩码,指定子通道的用法。 -
pipelineBindPoint
是一个 VkPipelineBindPoint 值,指定此子通道支持的管线类型。 -
inputAttachmentCount
是输入附件的数量。 -
pInputAttachments
是指向 VkAttachmentReference 结构数组的指针,这些结构定义了此子通道的输入附件及其布局。 -
colorAttachmentCount
是颜色附件的数量。 -
pColorAttachments
是指向colorAttachmentCount
个 VkAttachmentReference 结构数组的指针,这些结构定义了此子通道的颜色附件及其布局。 -
pResolveAttachments
是NULL
或指向colorAttachmentCount
个 VkAttachmentReference 结构数组的指针,这些结构定义了此子通道的解析附件及其布局。 -
pDepthStencilAttachment
是指向 VkAttachmentReference 结构的指针,该结构指定此子通道的深度/模板附件及其布局。 -
preserveAttachmentCount
是保留附件的数量。 -
pPreserveAttachments
是指向一个preserveAttachmentCount
个渲染通道附件索引数组的指针,这些索引标识了此子通道未使用的附件,但其内容必须在整个子通道中保留。
pInputAttachments
数组的每个元素对应于片段着色器中的输入附件索引,例如,如果着色器声明了一个使用 InputAttachmentIndex
值 X 修饰的图像变量,那么它将使用 pInputAttachments
[X] 中提供的附件。输入附件必须也绑定到描述符集中的管线。如果 pInputAttachments
的任何元素的 attachment
成员为 VK_ATTACHMENT_UNUSED
,则应用程序必须不从相应的输入附件索引读取。片段着色器可以使用子通道输入变量来访问片段的 (xf,yf) 帧缓冲区坐标和层处的输入附件内容。在启用渲染通道变换的渲染通道内的任何子通道中,不能使用输入附件。
pColorAttachments
数组的每个元素对应于着色器中的一个输出位置,例如,如果着色器声明了一个使用 Location
值 X 修饰的输出变量,那么它将使用 pColorAttachments
[X] 中提供的附件。如果 pColorAttachments
的任何元素的 attachment
成员为 VK_ATTACHMENT_UNUSED
,或者如果颜色写入启用已针对相应的附件索引禁用,则片段着色器对相应位置的写入将被丢弃。
如果 flags
不包含 VK_SUBPASS_DESCRIPTION_SHADER_RESOLVE_BIT_QCOM
,并且如果 pResolveAttachments
不为 NULL
,则其每个元素都对应于一个颜色附件(pColorAttachments
中相同索引处的元素),并且为每个附件定义了多重采样解析操作,除非解析附件索引为 VK_ATTACHMENT_UNUSED
。
类似地,如果 flags
不包含 VK_SUBPASS_DESCRIPTION_SHADER_RESOLVE_BIT_QCOM
,并且 VkSubpassDescriptionDepthStencilResolve::pDepthStencilResolveAttachment
不为 NULL
且不具有值 VK_ATTACHMENT_UNUSED
,则它对应于 pDepthStencilAttachment
中的深度/模板附件,并且深度和模板的多重采样解析操作分别由 VkSubpassDescriptionDepthStencilResolve::depthResolveMode
和 VkSubpassDescriptionDepthStencilResolve::stencilResolveMode
定义。如果 VkSubpassDescriptionDepthStencilResolve::depthResolveMode
为 VK_RESOLVE_MODE_NONE
或 pDepthStencilResolveAttachment
不具有深度方面,则不为深度附件执行解析操作。如果 VkSubpassDescriptionDepthStencilResolve::stencilResolveMode
为 VK_RESOLVE_MODE_NONE
或 pDepthStencilResolveAttachment
不具有模板方面,则不为模板附件执行解析操作。
如果由深度/模板附件引用的图像子资源范围是使用 VK_IMAGE_CREATE_SAMPLE_LOCATIONS_COMPATIBLE_DEPTH_BIT_EXT
创建的,则多重采样解析操作将使用 VkRenderPassSampleLocationsBeginInfoEXT
::pPostSubpassSampleLocations
的元素中为子通道指定的 sampleLocationsInfo
成员中的采样位置状态。
如果 pDepthStencilAttachment
为 NULL
,或者其附件索引为 VK_ATTACHMENT_UNUSED
,则表示子通道中将不使用深度/模板附件。
如果满足以下所有条件,则附件在渲染区域内的内容在子通道 S 的开始时变为未定义
-
附件在渲染通道中的任何子通道中用作颜色、深度/模板或解析附件。
-
存在一个子通道 S1 使用或保留该附件,以及从 S1 到 S 的子通道依赖关系。
-
附件在子通道 S 中未使用或保留。
此外,如果满足以下所有条件,则附件在渲染区域内的内容在子通道 S 的开始时变为未定义
-
设置了
VK_SUBPASS_DESCRIPTION_SHADER_RESOLVE_BIT_QCOM
。 -
附件在子通道中用作颜色或深度/模板。
一旦附件的内容在子通道 S 中变为未定义,它们将在以子通道 S 开头的子通道依赖链中的子通道中保持未定义,直到再次写入它们为止。但是,如果其他子通道依赖链(从子通道 S1 开始)中的子通道使用或保留该附件,则它们对于这些子通道仍然有效。
可以在 VkSubpassDescription::flags
中设置的位,用于指定子通道的用法,如下:
// Provided by VK_VERSION_1_0
typedef enum VkSubpassDescriptionFlagBits {
// Provided by VK_NVX_multiview_per_view_attributes
VK_SUBPASS_DESCRIPTION_PER_VIEW_ATTRIBUTES_BIT_NVX = 0x00000001,
// Provided by VK_NVX_multiview_per_view_attributes
VK_SUBPASS_DESCRIPTION_PER_VIEW_POSITION_X_ONLY_BIT_NVX = 0x00000002,
// Provided by VK_QCOM_render_pass_shader_resolve
VK_SUBPASS_DESCRIPTION_FRAGMENT_REGION_BIT_QCOM = 0x00000004,
// Provided by VK_QCOM_render_pass_shader_resolve
VK_SUBPASS_DESCRIPTION_SHADER_RESOLVE_BIT_QCOM = 0x00000008,
// Provided by VK_EXT_rasterization_order_attachment_access
VK_SUBPASS_DESCRIPTION_RASTERIZATION_ORDER_ATTACHMENT_COLOR_ACCESS_BIT_EXT = 0x00000010,
// Provided by VK_EXT_rasterization_order_attachment_access
VK_SUBPASS_DESCRIPTION_RASTERIZATION_ORDER_ATTACHMENT_DEPTH_ACCESS_BIT_EXT = 0x00000020,
// Provided by VK_EXT_rasterization_order_attachment_access
VK_SUBPASS_DESCRIPTION_RASTERIZATION_ORDER_ATTACHMENT_STENCIL_ACCESS_BIT_EXT = 0x00000040,
// Provided by VK_EXT_legacy_dithering
VK_SUBPASS_DESCRIPTION_ENABLE_LEGACY_DITHERING_BIT_EXT = 0x00000080,
// Provided by VK_ARM_rasterization_order_attachment_access
VK_SUBPASS_DESCRIPTION_RASTERIZATION_ORDER_ATTACHMENT_COLOR_ACCESS_BIT_ARM = VK_SUBPASS_DESCRIPTION_RASTERIZATION_ORDER_ATTACHMENT_COLOR_ACCESS_BIT_EXT,
// Provided by VK_ARM_rasterization_order_attachment_access
VK_SUBPASS_DESCRIPTION_RASTERIZATION_ORDER_ATTACHMENT_DEPTH_ACCESS_BIT_ARM = VK_SUBPASS_DESCRIPTION_RASTERIZATION_ORDER_ATTACHMENT_DEPTH_ACCESS_BIT_EXT,
// Provided by VK_ARM_rasterization_order_attachment_access
VK_SUBPASS_DESCRIPTION_RASTERIZATION_ORDER_ATTACHMENT_STENCIL_ACCESS_BIT_ARM = VK_SUBPASS_DESCRIPTION_RASTERIZATION_ORDER_ATTACHMENT_STENCIL_ACCESS_BIT_EXT,
} VkSubpassDescriptionFlagBits;
-
VK_SUBPASS_DESCRIPTION_PER_VIEW_ATTRIBUTES_BIT_NVX
指定为此子通道编译的着色器在每次调用预光栅化着色器阶段时写入所有视图的属性。所有针对包含此位的子通道编译的管线必须将每个视图的属性写入*PerViewNV[]
着色器输出,以及非每个视图(例如,Position
)的输出。 -
VK_SUBPASS_DESCRIPTION_PER_VIEW_POSITION_X_ONLY_BIT_NVX
指定为此子通道编译的着色器使用仅在 x 分量的值上不同的每个视图位置。也可以使用每个视图的视口遮罩。 -
VK_SUBPASS_DESCRIPTION_FRAGMENT_REGION_BIT_QCOM
指定帧缓冲区区域是片段区域,也就是说,最小区域依赖关系是按像素而不是按采样,因此任何片段着色器调用可以访问与该片段着色器调用关联的任何采样。 -
VK_SUBPASS_DESCRIPTION_SHADER_RESOLVE_BIT_QCOM
指定子通道执行着色器解析操作。 -
VK_SUBPASS_DESCRIPTION_RASTERIZATION_ORDER_ATTACHMENT_COLOR_ACCESS_BIT_EXT
指定此子通道支持使用VK_PIPELINE_COLOR_BLEND_STATE_CREATE_RASTERIZATION_ORDER_ATTACHMENT_ACCESS_BIT_EXT
创建的管线。 -
VK_SUBPASS_DESCRIPTION_RASTERIZATION_ORDER_ATTACHMENT_DEPTH_ACCESS_BIT_EXT
指定此子通道支持使用VK_PIPELINE_DEPTH_STENCIL_STATE_CREATE_RASTERIZATION_ORDER_ATTACHMENT_DEPTH_ACCESS_BIT_EXT
创建的管线。 -
VK_SUBPASS_DESCRIPTION_RASTERIZATION_ORDER_ATTACHMENT_STENCIL_ACCESS_BIT_EXT
指定此子通道支持使用VK_PIPELINE_DEPTH_STENCIL_STATE_CREATE_RASTERIZATION_ORDER_ATTACHMENT_STENCIL_ACCESS_BIT_EXT
创建的管线。 -
VK_SUBPASS_DESCRIPTION_ENABLE_LEGACY_DITHERING_BIT_EXT
指定此子通道启用了传统抖动。
着色器解析操作允许自定义解析操作,但过度绘制像素可能会产生性能和/或功耗成本。此外,由于任何深度模板附件或颜色附件的内容在着色器解析子通道的开始处是未定义的,因此任何源自这些未定义值的深度测试、模板测试或混合操作也具有未定义的结果值。 |
// Provided by VK_VERSION_1_0
typedef VkFlags VkSubpassDescriptionFlags;
VkSubpassDescriptionFlags
是一个位掩码类型,用于设置零个或多个 VkSubpassDescriptionFlagBits 的掩码。
VkAttachmentReference
结构定义如下:
// Provided by VK_VERSION_1_0
typedef struct VkAttachmentReference {
uint32_t attachment;
VkImageLayout layout;
} VkAttachmentReference;
-
attachment
是一个整数值,用于标识 VkRenderPassCreateInfo::pAttachments
中相应索引处的附件,或者VK_ATTACHMENT_UNUSED
,表示不使用此附件。 -
layout
是一个 VkImageLayout 值,用于指定附件在子通道期间使用的布局。
VK_SUBPASS_EXTERNAL
是一个特殊的子通道索引值,它将同步范围扩展到子通道之外。有关详细信息,请参阅 VkSubpassDependency。
#define VK_SUBPASS_EXTERNAL (~0U)
VkSubpassDependency
结构定义如下:
// Provided by VK_VERSION_1_0
typedef struct VkSubpassDependency {
uint32_t srcSubpass;
uint32_t dstSubpass;
VkPipelineStageFlags srcStageMask;
VkPipelineStageFlags dstStageMask;
VkAccessFlags srcAccessMask;
VkAccessFlags dstAccessMask;
VkDependencyFlags dependencyFlags;
} VkSubpassDependency;
-
srcSubpass
是依赖关系中第一个子通道的索引,或VK_SUBPASS_EXTERNAL
。 -
dstSubpass
是依赖关系中第二个子通道的索引,或VK_SUBPASS_EXTERNAL
。 -
srcStageMask
是一个 VkPipelineStageFlagBits 的位掩码,指定 源阶段掩码。 -
dstStageMask
是一个 VkPipelineStageFlagBits 的位掩码,指定 目标阶段掩码。 -
srcAccessMask
是一个 VkAccessFlagBits 的位掩码,指定 源访问掩码。 -
dstAccessMask
是一个 VkAccessFlagBits 的位掩码,指定 目标访问掩码。 -
dependencyFlags
是一个 VkDependencyFlagBits 的位掩码。
如果 srcSubpass
等于 dstSubpass
,则 VkSubpassDependency 不直接定义 依赖关系。相反,它允许在标识的子通道内的渲染通道实例中使用管线屏障,其中一个管线屏障的范围必须是由一个子通道依赖关系描述的范围的子集。以这种方式指定的子通道依赖关系在 srcStageMask
中包含 帧缓冲区空间阶段,必须仅在 dstStageMask
中包含 帧缓冲区空间阶段,并且必须包含 VK_DEPENDENCY_BY_REGION_BIT
。当以这种方式为视图掩码中具有多个视图的子通道指定子通道依赖关系时,其 dependencyFlags
必须包含 VK_DEPENDENCY_VIEW_LOCAL_BIT
。
如果 srcSubpass
和 dstSubpass
不相等,则当包含子通道依赖关系的渲染通道实例提交到队列时,它会在由 srcSubpass
和 dstSubpass
标识的子通道之间定义 依赖关系。
如果 srcSubpass
等于 VK_SUBPASS_EXTERNAL
,则第一个 同步范围 包括在 提交顺序 中早于用于开始渲染通道实例的 vkCmdBeginRenderPass 的命令。否则,第一组命令包括作为由 srcSubpass
标识的子通道实例的一部分提交的所有命令,以及在 srcSubpass
中使用的附件上的任何 加载、存储 或 多重采样解析 操作。在任何情况下,第一个同步范围都限制为由 srcStageMask
指定的 源阶段掩码 确定的管线阶段上的操作。
如果 dstSubpass
等于 VK_SUBPASS_EXTERNAL
,则第二个 同步范围 包括在 提交顺序 中晚于用于结束渲染通道实例的 vkCmdEndRenderPass 的命令。否则,第二组命令包括作为由 dstSubpass
标识的子通道实例的一部分提交的所有命令,以及在 dstSubpass
中使用的附件上的任何 加载、存储 和 多重采样解析 操作。在任何情况下,第二个同步范围都限制为由 dstStageMask
指定的 目标阶段掩码 确定的管线阶段上的操作。
对于非附件资源,子通道依赖关系表达的内存依赖关系与作为 vkCmdPipelineBarrier 的一部分提交的 VkMemoryBarrier(具有匹配的 然而,对于附件来说,子通道依赖关系更像是 VkImageMemoryBarrier,其定义方式类似于上面的 VkMemoryBarrier,队列族索引设置为
|
当启用多视图时,一个子通道的多个视图的执行可能不会同时或甚至背靠背发生,而是可能与其他子通道的执行交错进行。加载和存储操作以每个视图为基础应用于附件。例如,使用 VK_ATTACHMENT_LOAD_OP_CLEAR
的附件将在首次使用时清除每个视图,但一个视图的首次使用在时间上可能与另一个视图的首次使用相距很远。
多视图的一个好的心理模型是将多视图子通道视为一组单独的(每个视图)子通道,它们在逻辑上分组在一起,并在 API 中描述为单个多视图子通道。类似地,多视图附件可以被认为是单个图像中的多个层。两个多视图子通道之间的视图本地依赖关系就像对应的一对一对每个视图的子通道的依赖关系集。两个多视图子通道之间的视图全局依赖关系就像源和目标中所有成对的每个视图子通道之间的 N × M 个依赖关系集。因此,它是一种更紧凑的表示,也清楚地表明了子通道中视图之间存在的共性和重用。这种解释激发了诸如“加载操作何时应用”之类的问题的答案 - 它是在首次使用附件的每个视图时,就好像每个视图都是一个单独的附件一样。 每个视图的内容遵循附件内容行为中的描述。特别是,如果保留了附件,则保留附件中的所有视图。 |
如果渲染通道的任何两个子通道将变换反馈激活到相同的绑定变换反馈缓冲区,则它们之间必须包含一个子通道依赖关系(直接或通过一些中间子通道)。
如果没有从 VK_SUBPASS_EXTERNAL
到使用附件的第一个子通道的子通道依赖关系,则存在从 VK_SUBPASS_EXTERNAL
到首次使用它的子通道的隐式子通道依赖关系。仅当存在从 initialLayout
自动布局转换时,才存在隐式子通道依赖关系。子通道依赖关系的操作方式就像使用以下参数定义的一样:
VkSubpassDependency implicitDependency = {
.srcSubpass = VK_SUBPASS_EXTERNAL,
.dstSubpass = firstSubpass, // First subpass attachment is used in
.srcStageMask = VK_PIPELINE_STAGE_NONE,
.dstStageMask = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
.srcAccessMask = 0,
.dstAccessMask = VK_ACCESS_INPUT_ATTACHMENT_READ_BIT |
VK_ACCESS_COLOR_ATTACHMENT_READ_BIT |
VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT |
VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT |
VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
.dependencyFlags = 0
};
同样,如果没有从使用附件的最后一个子通道到 VK_SUBPASS_EXTERNAL
的子通道依赖关系,则存在从使用它的最后一个子通道到 VK_SUBPASS_EXTERNAL
的隐式子通道依赖关系。仅当存在到 finalLayout
的自动布局转换时,才存在隐式子通道依赖关系。子通道依赖关系的操作方式就像使用以下参数定义的一样:
VkSubpassDependency implicitDependency = {
.srcSubpass = lastSubpass, // Last subpass attachment is used in
.dstSubpass = VK_SUBPASS_EXTERNAL,
.srcStageMask = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
.dstStageMask = VK_PIPELINE_STAGE_NONE,
.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT |
VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
.dstAccessMask = 0,
.dependencyFlags = 0
};
由于子通道可能会与其他子通道重叠或乱序执行,除非子通道依赖关系链另有说明,否则应用程序无法知道子通道之间所需的布局转换。相反,应用程序提供每个附件在渲染通道开始和结束时必须处于的布局,以及在其使用的每个子通道期间必须处于的布局。然后,实现必须执行子通道之间的布局转换,以确保图像处于每个子通道所需的布局中,并且在渲染通道结束时处于最终布局中。
自动布局转换应用于附加到帧缓冲区的整个图像子资源。如果未启用多视图,并且附件是 1D 或 2D 图像的视图,则自动布局转换将应用于 VkFramebufferCreateInfo::layers
指定的层数。如果启用多视图,并且附件是 1D 或 2D 图像的视图,则自动布局转换将应用于与渲染通道中某个子通道使用的视图相对应的层,即使该子通道不引用给定的附件也是如此。如果附件视图是 3D 图像的 2D 或 2D 数组视图,即使附件视图仅引用 3D 图像所选 mip 级别的切片子集,自动布局转换也适用于引用的整个子资源,即本例中的整个 mip 级别。
离开子通道中使用的布局的自动布局转换发生在以该子通道为 srcSubpass
的所有依赖项的可用性操作之后。
自动布局转换到子通道中使用的布局,发生在以该子通道为dstSubpass
的所有依赖项的可见性操作之前。
自动布局从 initialLayout
转换离开,发生在 srcSubpass
等于 VK_SUBPASS_EXTERNAL
的所有依赖项的可用性操作之后,其中 dstSubpass
使用将要转换的附件。对于使用 VK_ATTACHMENT_DESCRIPTION_MAY_ALIAS_BIT
创建的附件,自动布局从 initialLayout
转换离开,发生在 srcSubpass
等于 VK_SUBPASS_EXTERNAL
的所有依赖项的可用性操作之后,其中 dstSubpass
使用任何别名附件。
自动布局转换到 finalLayout
,发生在 dstSubpass
等于 VK_SUBPASS_EXTERNAL
的所有依赖项的可见性操作之前,其中 srcSubpass
使用将要转换的附件。对于使用 VK_ATTACHMENT_DESCRIPTION_MAY_ALIAS_BIT
创建的附件,自动布局转换到 finalLayout
,发生在 dstSubpass
等于 VK_SUBPASS_EXTERNAL
的所有依赖项的可见性操作之前,其中 srcSubpass
使用任何别名附件。
引用使用 VK_IMAGE_CREATE_SAMPLE_LOCATIONS_COMPATIBLE_DEPTH_BIT_EXT
创建的图像的深度/模板附件的深度方面的图像布局,取决于最后一次用于渲染到该附件的采样位置,因此自动布局转换使用 VkRenderPassSampleLocationsBeginInfoEXT 中指定的采样位置状态。
引用使用 VK_IMAGE_CREATE_SAMPLE_LOCATIONS_COMPATIBLE_DEPTH_BIT_EXT
创建的深度/模板图像的附件的自动布局转换,使用附件引用的图像子资源范围最后一次渲染时使用的采样位置。如果当前渲染通道在之前的任何子通道中都没有将该附件用作深度/模板附件,则自动布局转换使用 VkRenderPassSampleLocationsBeginInfoEXT
::pAttachmentInitialSampleLocations
数组元素的 sampleLocationsInfo
成员中指定的采样位置状态,该元素的 attachmentIndex
成员等于附件的附件索引(如果指定)。否则,自动布局转换使用 VkRenderPassSampleLocationsBeginInfoEXT
::pPostSubpassSampleLocations
数组元素的 sampleLocationsInfo
成员中指定的采样位置状态,该元素的 subpassIndex
成员等于最后一次将该附件用作深度/模板附件的子通道的索引(如果指定)。
如果对于引用使用 VK_IMAGE_CREATE_SAMPLE_LOCATIONS_COMPATIBLE_DEPTH_BIT_EXT
创建的深度/模板图像的附件执行的自动布局转换没有指定采样位置状态,则深度/模板附件的深度方面的内容将变为未定义,就像附件的布局是从 VK_IMAGE_LAYOUT_UNDEFINED
布局转换而来一样。
如果两个子通道使用相同的附件,并且两个子通道都以只读布局使用该附件,则不需要在这两个子通道之间指定子通道依赖项。如果实现将这些布局分开处理,则必须在这两个子通道之间插入一个隐式的子通道依赖项,以分隔每个布局中的使用。子通道依赖项的操作方式就像使用以下参数定义一样
// Used for input attachments
VkPipelineStageFlags inputAttachmentStages = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
VkAccessFlags inputAttachmentDstAccess = VK_ACCESS_INPUT_ATTACHMENT_READ_BIT;
// Used for depth/stencil attachments
VkPipelineStageFlags depthStencilAttachmentStages = VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT;
VkAccessFlags depthStencilAttachmentDstAccess = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT;
VkSubpassDependency implicitDependency = {
.srcSubpass = firstSubpass;
.dstSubpass = secondSubpass;
.srcStageMask = inputAttachmentStages | depthStencilAttachmentStages;
.dstStageMask = inputAttachmentStages | depthStencilAttachmentStages;
.srcAccessMask = 0;
.dstAccessMask = inputAttachmentDstAccess | depthStencilAttachmentDstAccess;
.dependencyFlags = 0;
};
当使用着色器对象进行绘制时,或者当使用在VkPipelineDynamicStateCreateInfo::pDynamicStates
中设置的 VK_DYNAMIC_STATE_ATTACHMENT_FEEDBACK_LOOP_ENABLE_EXT
创建图形管线时,应用程序必须指定在渲染通道期间写入的附件类型,这些附件类型也将在渲染通道中作为非附件访问。
要动态设置管线是否可以在作为被写入的附件的同时,也作为非附件访问资源,请调用
// Provided by VK_EXT_attachment_feedback_loop_dynamic_state
void vkCmdSetAttachmentFeedbackLoopEnableEXT(
VkCommandBuffer commandBuffer,
VkImageAspectFlags aspectMask);
-
commandBuffer
是将要记录命令的命令缓冲区。 -
aspectMask
指定将启用反馈循环的附件类型。 其方面未包含在aspectMask
中的附件类型将禁用反馈循环。
对于在渲染通道中写入的附件,只有具有在 aspectMask
中指定的方面的附件,才能被后续的绘图命令作为非附件访问。
下面还定义了渲染通道创建的更可扩展版本。
要创建渲染通道,请调用
// Provided by VK_VERSION_1_2
VkResult vkCreateRenderPass2(
VkDevice device,
const VkRenderPassCreateInfo2* pCreateInfo,
const VkAllocationCallbacks* pAllocator,
VkRenderPass* pRenderPass);
或等效命令
// Provided by VK_KHR_create_renderpass2
VkResult vkCreateRenderPass2KHR(
VkDevice device,
const VkRenderPassCreateInfo2* pCreateInfo,
const VkAllocationCallbacks* pAllocator,
VkRenderPass* pRenderPass);
-
device
是创建渲染通道的逻辑设备。 -
pCreateInfo
是指向一个 VkRenderPassCreateInfo2 结构的指针,该结构描述了渲染通道的参数。 -
pAllocator
控制主机内存分配,如内存分配章节所述。 -
pRenderPass
是指向 VkRenderPass 句柄的指针,其中返回生成的渲染通道对象。
此命令在功能上与 vkCreateRenderPass 相同,但包括可扩展的子结构,其中包括 sType
和 pNext
参数,使其更容易扩展。
VkRenderPassCreateInfo2
结构定义为
// Provided by VK_VERSION_1_2
typedef struct VkRenderPassCreateInfo2 {
VkStructureType sType;
const void* pNext;
VkRenderPassCreateFlags flags;
uint32_t attachmentCount;
const VkAttachmentDescription2* pAttachments;
uint32_t subpassCount;
const VkSubpassDescription2* pSubpasses;
uint32_t dependencyCount;
const VkSubpassDependency2* pDependencies;
uint32_t correlatedViewMaskCount;
const uint32_t* pCorrelatedViewMasks;
} VkRenderPassCreateInfo2;
或等效的
// Provided by VK_KHR_create_renderpass2
typedef VkRenderPassCreateInfo2 VkRenderPassCreateInfo2KHR;
-
sType
是一个 VkStructureType 值,用于标识此结构。 -
pNext
为NULL
或指向扩展此结构的结构的指针。 -
flags
保留供将来使用。 -
attachmentCount
是此渲染通道使用的附件数量。 -
pAttachments
是一个指向attachmentCount
个 VkAttachmentDescription2 结构的数组的指针,这些结构描述了渲染通道使用的附件。 -
subpassCount
是要创建的子通道数量。 -
pSubpasses
是一个指向subpassCount
个 VkSubpassDescription2 结构的数组的指针,这些结构描述了每个子通道。 -
dependencyCount
是子通道对之间依赖关系的数量。 -
pDependencies
是一个指向dependencyCount
个 VkSubpassDependency2 结构的数组的指针,这些结构描述了子通道对之间的依赖关系。 -
correlatedViewMaskCount
是相关掩码的数量。 -
pCorrelatedViewMasks
是一个指向视图掩码数组的指针,该数组指示可能更有效地并发渲染的视图集。
此结构定义的参数与 VkRenderPassCreateInfo 中同名的参数具有相同的效果;子结构是 VkRenderPassCreateInfo 中使用的变体,它们添加了 sType
和 pNext
参数,从而允许对其进行扩展。
如果 pSubpasses
的任何元素的 VkSubpassDescription2::viewMask
成员不为零,则认为此渲染通道启用了多视图功能。
correlatedViewMaskCount
和 pCorrelatedViewMasks
的效果分别与 VkRenderPassMultiviewCreateInfo::correlationMaskCount
和 VkRenderPassMultiviewCreateInfo::pCorrelationMasks
相同。
VkAttachmentDescription2
结构定义为
// Provided by VK_VERSION_1_2
typedef struct VkAttachmentDescription2 {
VkStructureType sType;
const void* pNext;
VkAttachmentDescriptionFlags flags;
VkFormat format;
VkSampleCountFlagBits samples;
VkAttachmentLoadOp loadOp;
VkAttachmentStoreOp storeOp;
VkAttachmentLoadOp stencilLoadOp;
VkAttachmentStoreOp stencilStoreOp;
VkImageLayout initialLayout;
VkImageLayout finalLayout;
} VkAttachmentDescription2;
或等效的
// Provided by VK_KHR_create_renderpass2
typedef VkAttachmentDescription2 VkAttachmentDescription2KHR;
-
sType
是一个 VkStructureType 值,用于标识此结构。 -
pNext
为NULL
或指向扩展此结构的结构的指针。 -
flags
是一个 VkAttachmentDescriptionFlagBits 的位掩码,用于指定附件的附加属性。 -
format
是一个 VkFormat 值,指定将用于附件的图像的格式。 -
samples
是一个 VkSampleCountFlagBits 值,用于指定图像的样本数量。 -
loadOp
是一个 VkAttachmentLoadOp 值,用于指定在第一次使用附件的子通道开始时,如何处理附件的颜色和深度分量的内容。 -
storeOp
是一个 VkAttachmentStoreOp 值,用于指定在最后一次使用附件的子通道结束时,如何处理附件的颜色和深度分量的内容。 -
stencilLoadOp
是一个 VkAttachmentLoadOp 值,用于指定在第一次使用附件的子通道开始时,如何处理附件的模板分量的内容。 -
stencilStoreOp
是一个 VkAttachmentStoreOp 值,用于指定在最后一次使用附件的子通道结束时,如何处理附件的模板分量的内容。 -
initialLayout
是渲染通道实例开始时,附件图像子资源的布局。 -
finalLayout
是渲染通道实例结束时,附件图像子资源将转换到的布局。
此结构中定义的与 VkAttachmentDescription 中同名的参数具有与这些参数相同的效果。
如果启用了 separateDepthStencilLayouts
特性,并且 format
是深度/模板格式,则 initialLayout
和 finalLayout
可以设置为仅指定深度方面布局的布局。
如果 pNext
链包含一个 VkAttachmentDescriptionStencilLayout 结构体,那么 stencilInitialLayout
和 stencilFinalLayout
成员指定深度/模板格式的模板方面的初始和最终布局,而 initialLayout
和 finalLayout
仅适用于深度方面。对于仅深度格式,VkAttachmentDescriptionStencilLayout 结构体将被忽略。对于仅模板格式,如果存在 VkAttachmentDescriptionStencilLayout 结构体,则从该结构体获取模板方面的初始和最终布局;否则,从 initialLayout
和 finalLayout
获取。
如果 format
是深度/模板格式,并且 initialLayout
或 finalLayout
没有指定模板方面的布局,那么应用程序**必须**通过在 pNext
链中包含一个 VkAttachmentDescriptionStencilLayout 结构体来指定模板方面的初始和最终布局。
对于片段着色率附件,loadOp
和 storeOp
将被忽略。loadOp
和 storeOp
中不会执行对着色率附件的访问。相反,当栅格化片段时,会执行对 VK_ACCESS_FRAGMENT_SHADING_RATE_ATTACHMENT_READ_BIT_KHR
的访问。
VkAttachmentDescriptionStencilLayout
结构定义如下:
// Provided by VK_VERSION_1_2
typedef struct VkAttachmentDescriptionStencilLayout {
VkStructureType sType;
void* pNext;
VkImageLayout stencilInitialLayout;
VkImageLayout stencilFinalLayout;
} VkAttachmentDescriptionStencilLayout;
或等效的
// Provided by VK_KHR_separate_depth_stencil_layouts
typedef VkAttachmentDescriptionStencilLayout VkAttachmentDescriptionStencilLayoutKHR;
-
sType
是一个 VkStructureType 值,用于标识此结构。 -
pNext
为NULL
或指向扩展此结构的结构的指针。 -
stencilInitialLayout
是渲染通道实例开始时附件图像子资源的模板方面将处于的布局。 -
stencilFinalLayout
是渲染通道实例结束时附件图像子资源的模板方面将转换到的布局。
VkSubpassDescription2
结构定义如下:
// Provided by VK_VERSION_1_2
typedef struct VkSubpassDescription2 {
VkStructureType sType;
const void* pNext;
VkSubpassDescriptionFlags flags;
VkPipelineBindPoint pipelineBindPoint;
uint32_t viewMask;
uint32_t inputAttachmentCount;
const VkAttachmentReference2* pInputAttachments;
uint32_t colorAttachmentCount;
const VkAttachmentReference2* pColorAttachments;
const VkAttachmentReference2* pResolveAttachments;
const VkAttachmentReference2* pDepthStencilAttachment;
uint32_t preserveAttachmentCount;
const uint32_t* pPreserveAttachments;
} VkSubpassDescription2;
或等效的
// Provided by VK_KHR_create_renderpass2
typedef VkSubpassDescription2 VkSubpassDescription2KHR;
-
sType
是一个 VkStructureType 值,用于标识此结构。 -
pNext
为NULL
或指向扩展此结构的结构的指针。 -
flags
是一个 VkSubpassDescriptionFlagBits 的位掩码,指定子通道的用法。 -
pipelineBindPoint
是一个 VkPipelineBindPoint 值,指定此子通道支持的管线类型。 -
viewMask
是视图索引的位域,当启用多视图时,它描述了此子通道中渲染广播到的视图。 -
inputAttachmentCount
是输入附件的数量。 -
pInputAttachments
是指向 VkAttachmentReference2 结构数组的指针,该数组定义了此子通道的输入附件及其布局。 -
colorAttachmentCount
是颜色附件的数量。 -
pColorAttachments
是指向colorAttachmentCount
个 VkAttachmentReference2 结构数组的指针,该数组定义了此子通道的颜色附件及其布局。 -
pResolveAttachments
为NULL
或指向colorAttachmentCount
个 VkAttachmentReference2 结构数组的指针,该数组定义了此子通道的解析附件及其布局。 -
pDepthStencilAttachment
是指向 VkAttachmentReference2 结构的指针,该结构指定了此子通道的深度/模板附件及其布局。 -
preserveAttachmentCount
是保留附件的数量。 -
pPreserveAttachments
是指向一个preserveAttachmentCount
个渲染通道附件索引数组的指针,这些索引标识了此子通道未使用的附件,但其内容必须在整个子通道中保留。
此结构定义的参数与 VkSubpassDescription 中同名的参数具有相同的效果。
viewMask
对所描述的子通道具有与 VkRenderPassMultiviewCreateInfo::pViewMasks
对每个相应子通道的效果相同。
如果 pNext
链中包含 VkFragmentShadingRateAttachmentInfoKHR 结构,且 pFragmentShadingRateAttachment
不为 NULL
,并且其 attachment
成员不为 VK_ATTACHMENT_UNUSED
,则标识的附件定义了该子通道的片段着色率附件。
如果 pResolveAttachments
的任何元素是使用 VkExternalFormatANDROID 指定的图像,则相应颜色附件中的值将以与为 VK_RESOLVE_MODE_EXTERNAL_FORMAT_DOWNSAMPLE_ANDROID
指定的方式相同的方式解析到解析附件。
如果 nullColorAttachmentWithExternalFormatResolve
限制为 VK_TRUE
,则在渲染开始时,颜色附件中的值将从解析附件加载,并且可能在发生解析或写入解析附件之后的任何时间重新加载;如果发生这种情况,它必须在任何在触发此解析之后发生的对颜色附件的写入之前发生。如果外部格式中的任何颜色分量被二次采样,则在加载时将从图像中的最近样本读取值。如果颜色附件也用作输入附件,则适用相同的行为。
当使用外部解析附件且 nullColorAttachmentWithExternalFormatResolve
限制为 VK_TRUE
时,将颜色附件设置为 VK_ATTACHMENT_UNUSED
不会导致丢弃该附件的颜色附件写入。
当 nullColorAttachmentWithExternalFormatResolve
为 VK_TRUE
时,子通道的颜色输出仍然可以通过输入附件读取;但是应用程序无法为颜色附件绑定图像视图,因为没有绑定这样的图像视图。相反,为了将数据作为输入附件访问,应用程序可以使用解析附件代替 - 使用解析附件图像作为描述符,并将 pInputAttachments
的相应元素设置为解析附件的索引。
从解析附件进行的加载或输入附件读取操作,其执行方式如同使用以下参数的 VkSamplerYcbcrConversionCreateInfo
VkSamplerYcbcrConversionCreateInfo createInfo = {
.sType = VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_CREATE_INFO,
.pNext = NULL,
.format = VK_FORMAT_UNDEFINED,
.ycbcrModel = VK_SAMPLER_YCBCR_MODEL_CONVERSION_RGB_IDENTITY,
.ycbcrRange = VK_SAMPLER_YCBCR_RANGE_ITU_FULL,
.components = {
.r = VK_COMPONENT_SWIZZLE_B
.g = VK_COMPONENT_SWIZZLE_R
.b = VK_COMPONENT_SWIZZLE_G
.a = VK_COMPONENT_SWIZZLE_IDENTITY},
.xChromaOffset = properties.chromaOffsetX,
.yChromaOffset = properties.chromaOffsetY,
.chromaFilter = VK_FILTER_NEAREST,
.forceExplicitReconstruction = ... };
其中 properties
等于设备返回的 VkPhysicalDeviceExternalFormatResolvePropertiesANDROID,并且 forceExplicitReconstruction
被有效忽略,因为使用了 VK_SAMPLER_YCBCR_MODEL_CONVERSION_RGB_IDENTITY
模型。应用的 swizzle 与 VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_IDENTITY
模型应用的有效 swizzle 相同,但不会应用范围扩展。
VkSubpassDescriptionDepthStencilResolve
结构定义如下:
// Provided by VK_VERSION_1_2
typedef struct VkSubpassDescriptionDepthStencilResolve {
VkStructureType sType;
const void* pNext;
VkResolveModeFlagBits depthResolveMode;
VkResolveModeFlagBits stencilResolveMode;
const VkAttachmentReference2* pDepthStencilResolveAttachment;
} VkSubpassDescriptionDepthStencilResolve;
或等效的
// Provided by VK_KHR_depth_stencil_resolve
typedef VkSubpassDescriptionDepthStencilResolve VkSubpassDescriptionDepthStencilResolveKHR;
-
sType
是一个 VkStructureType 值,用于标识此结构。 -
pNext
为NULL
或指向扩展此结构的结构的指针。 -
depthResolveMode
是一个 VkResolveModeFlagBits 值,描述深度解析模式。 -
stencilResolveMode
是一个 VkResolveModeFlagBits 值,描述模板解析模式。 -
pDepthStencilResolveAttachment
是NULL
或指向 VkAttachmentReference2 结构的指针,该结构定义此子通道的深度/模板解析附件及其布局。
如果 VkSubpassDescription2 的 pNext
链包含 VkSubpassDescriptionDepthStencilResolve
结构,则该结构描述子通道中深度/模板附件的多重采样解析操作。如果此结构不包含在 VkSubpassDescription2 的 pNext
链中,或者如果包含但 pDepthStencilResolveAttachment
为 NULL
或其附件索引为 VK_ATTACHMENT_UNUSED
,则表示子通道中不会使用深度/模板解析附件。
VkFragmentShadingRateAttachmentInfoKHR
结构定义如下:
// Provided by VK_KHR_fragment_shading_rate
typedef struct VkFragmentShadingRateAttachmentInfoKHR {
VkStructureType sType;
const void* pNext;
const VkAttachmentReference2* pFragmentShadingRateAttachment;
VkExtent2D shadingRateAttachmentTexelSize;
} VkFragmentShadingRateAttachmentInfoKHR;
-
sType
是一个 VkStructureType 值,用于标识此结构。 -
pNext
为NULL
或指向扩展此结构的结构的指针。 -
pFragmentShadingRateAttachment
为NULL
或指向 VkAttachmentReference2 结构的指针,该结构定义此子通道的片元着色率附件。 -
shadingRateAttachmentTexelSize
指定pFragmentShadingRateAttachment
中每个纹素对应的帧缓冲区部分的大小。
如果未指定着色率附件,或者未指定此结构,则实现的行为如同指定了一个有效的着色率附件,该附件的所有纹素都指定每个片段一个像素。
如果 VkSubpassDescription2 或 VkRenderingInfo 的 pNext
链包含 VkMultisampledRenderToSingleSampledInfoEXT
结构,则该结构描述如何在子通道中的单采样附件上执行多采样渲染。
VkMultisampledRenderToSingleSampledInfoEXT
结构定义如下
// Provided by VK_EXT_multisampled_render_to_single_sampled
typedef struct VkMultisampledRenderToSingleSampledInfoEXT {
VkStructureType sType;
const void* pNext;
VkBool32 multisampledRenderToSingleSampledEnable;
VkSampleCountFlagBits rasterizationSamples;
} VkMultisampledRenderToSingleSampledInfoEXT;
-
sType
是一个 VkStructureType 值,用于标识此结构。 -
pNext
为NULL
或指向扩展此结构的结构的指针。 -
multisampledRenderToSingleSampledEnable
控制是否按照以下描述执行多采样渲染到单采样附件。 -
rasterizationSamples
是一个 VkSampleCountFlagBits,用于指定光栅化中使用的采样数。
如果 VkSubpassDescription2 或 VkRenderingInfo 的 pNext
链包含一个 multisampledRenderToSingleSampledEnable
字段为 VK_TRUE
的 VkMultisampledRenderToSingleSampledInfoEXT 结构,则图形管线必须具有等于 VkMultisampledRenderToSingleSampledInfoEXT::rasterizationSamples
的 VkGraphicsPipelineCreateInfo::rasterizationSamples
,并且子通道附件的采样计数可以为 VK_SAMPLE_COUNT_1_BIT
。对于采样计数为 VK_SAMPLE_COUNT_1_BIT
的附件,多重采样渲染将执行到中间多重采样图像,该图像具有 VkMultisampledRenderToSingleSampledInfoEXT::rasterizationSamples
个采样,由实现隐式分配,其存在时间为子通道的持续时间。对于此类附件
-
如果
loadOp
等于VK_ATTACHMENT_LOAD_OP_LOAD
,则隐式图像的采样通过复制附件中相应像素的值进行初始化。 -
如果
storeOp
或stencilStoreOp
等于VK_ATTACHMENT_STORE_OP_STORE
,则隐式图像在存储到附件之前被隐式解析。
由于高图元计数引起的内存约束可能导致子通道的隐式拆分。这等效于渲染通道中几何体的部分光栅化,该渲染通道以等于 VK_ATTACHMENT_STORE_OP_STORE
的 storeOp
和 stencilStoreOp
结束,然后是另一个渲染通道,其 loadOp
和 stencilLoadOp
等于 VK_ATTACHMENT_LOAD_OP_LOAD
,两者之间有适当的屏障。当使用 VkMultisampledRenderToSingleSampledInfoEXT 时,允许实现解析采样计数为 VK_SAMPLE_COUNT_1_BIT
的附件,并在这种拆分时丢失多重采样数据。即使子通道使用相同的 VkMultisampledRenderToSingleSampledInfoEXT::rasterizationSamples
值,实现也可以类似地在子通道边界处拆分渲染通道。
VkAttachmentReference2
结构定义为
// Provided by VK_VERSION_1_2
typedef struct VkAttachmentReference2 {
VkStructureType sType;
const void* pNext;
uint32_t attachment;
VkImageLayout layout;
VkImageAspectFlags aspectMask;
} VkAttachmentReference2;
或等效的
// Provided by VK_KHR_create_renderpass2
typedef VkAttachmentReference2 VkAttachmentReference2KHR;
-
sType
是一个 VkStructureType 值,用于标识此结构。 -
pNext
为NULL
或指向扩展此结构的结构的指针。 -
attachment
要么是标识 VkRenderPassCreateInfo2::pAttachments
中对应索引处的附件的整数值,要么是VK_ATTACHMENT_UNUSED
,表示不使用此附件。 -
layout
是一个 VkImageLayout 值,用于指定附件在子通道期间使用的布局。 -
aspectMask
是一个掩码,指示哪些方面可以在指定的子通道内作为输入附件进行访问。
此结构定义的参数与 VkAttachmentReference 中具有相同名称的参数具有相同的效果。
当此结构用于描述输入附件引用以外的任何内容时,aspectMask
将被忽略。
如果启用了 separateDepthStencilLayouts
功能,并且 attachment
具有深度/模板格式,则 layout
可以设置为仅指定深度方面布局的布局。
如果 layout
仅指定附件的深度方面的布局,则模板方面的布局由包含在 pNext
链中的 VkAttachmentReferenceStencilLayout 结构的 stencilLayout
成员指定。否则,layout
描述所有相关图像方面的布局。
VkAttachmentReferenceStencilLayout
结构定义为
// Provided by VK_VERSION_1_2
typedef struct VkAttachmentReferenceStencilLayout {
VkStructureType sType;
void* pNext;
VkImageLayout stencilLayout;
} VkAttachmentReferenceStencilLayout;
或等效的
// Provided by VK_KHR_separate_depth_stencil_layouts
typedef VkAttachmentReferenceStencilLayout VkAttachmentReferenceStencilLayoutKHR;
-
sType
是一个 VkStructureType 值,用于标识此结构。 -
pNext
为NULL
或指向扩展此结构的结构的指针。 -
stencilLayout
是一个 VkImageLayout 值,指定子通道期间附件的模板方面使用的布局。
VkSubpassDependency2
结构定义为
// Provided by VK_VERSION_1_2
typedef struct VkSubpassDependency2 {
VkStructureType sType;
const void* pNext;
uint32_t srcSubpass;
uint32_t dstSubpass;
VkPipelineStageFlags srcStageMask;
VkPipelineStageFlags dstStageMask;
VkAccessFlags srcAccessMask;
VkAccessFlags dstAccessMask;
VkDependencyFlags dependencyFlags;
int32_t viewOffset;
} VkSubpassDependency2;
或等效的
// Provided by VK_KHR_create_renderpass2
typedef VkSubpassDependency2 VkSubpassDependency2KHR;
-
sType
是一个 VkStructureType 值,用于标识此结构。 -
pNext
为NULL
或指向扩展此结构的结构的指针。 -
srcSubpass
是依赖关系中第一个子通道的索引,或VK_SUBPASS_EXTERNAL
。 -
dstSubpass
是依赖关系中第二个子通道的索引,或VK_SUBPASS_EXTERNAL
。 -
srcStageMask
是一个 VkPipelineStageFlagBits 的位掩码,指定 源阶段掩码。 -
dstStageMask
是一个 VkPipelineStageFlagBits 的位掩码,指定 目标阶段掩码。 -
srcAccessMask
是一个 VkAccessFlagBits 的位掩码,指定 源访问掩码。 -
dstAccessMask
是一个 VkAccessFlagBits 的位掩码,指定 目标访问掩码。 -
dependencyFlags
是一个 VkDependencyFlagBits 的位掩码。 -
viewOffset
控制目标子通道中的视图所依赖的源子通道中的哪些视图。
此结构定义的参数与 VkSubpassDependency 中具有相同名称的参数具有相同的效果。
viewOffset
对所描述的子通道依赖关系具有与 VkRenderPassMultiviewCreateInfo::pViewOffsets
对每个对应的子通道依赖关系相同的效果。
如果 pNext
链中包含 VkMemoryBarrier2,则将忽略 srcStageMask
、dstStageMask
、srcAccessMask
和 dstAccessMask
参数。同步和访问范围改为由 VkMemoryBarrier2 的参数定义。
要销毁渲染通道,请调用
// Provided by VK_VERSION_1_0
void vkDestroyRenderPass(
VkDevice device,
VkRenderPass renderPass,
const VkAllocationCallbacks* pAllocator);
-
device
是销毁渲染通道的逻辑设备。 -
renderPass
是要销毁的渲染通道的句柄。 -
pAllocator
控制主机内存分配,如内存分配章节所述。
渲染通道兼容性
帧缓冲区和图形管线是基于特定的渲染通道对象创建的。它们必须仅与该渲染通道对象或与其兼容的对象一起使用。
如果两个附件引用具有匹配的格式和采样计数,或者均为 VK_ATTACHMENT_UNUSED
或包含引用的指针为 NULL
,则它们是兼容的。
如果所有对应的附件对都兼容,则两个附件引用数组是兼容的。如果数组的长度不同,则较小数组中不存在的附件引用将被视为 VK_ATTACHMENT_UNUSED
。
如果两个渲染通道的对应颜色、输入、解析和深度/模板附件引用兼容,并且除了以下情况外它们是相同的,则这两个渲染通道是兼容的
-
附件描述中的初始和最终图像布局
-
附件描述中的加载和存储操作
-
附件引用中的图像布局
作为额外的特殊情况,如果两个渲染通道只有一个子通道,则解析附件引用和深度/模板解析模式的兼容性要求将被忽略。
如果帧缓冲区是使用相同的渲染通道或兼容的渲染通道创建的,则该帧缓冲区与渲染通道兼容。
帧缓冲区
渲染通道与帧缓冲区结合使用。帧缓冲区表示渲染通道实例使用的一组特定内存附件。
帧缓冲区由 VkFramebuffer
句柄表示
// Provided by VK_VERSION_1_0
VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkFramebuffer)
要创建帧缓冲区,请调用
// Provided by VK_VERSION_1_0
VkResult vkCreateFramebuffer(
VkDevice device,
const VkFramebufferCreateInfo* pCreateInfo,
const VkAllocationCallbacks* pAllocator,
VkFramebuffer* pFramebuffer);
-
device
是创建帧缓冲区的逻辑设备。 -
pCreateInfo
是指向 VkFramebufferCreateInfo 结构的指针,该结构描述了有关帧缓冲区创建的其他信息。 -
pAllocator
控制主机内存分配,如内存分配章节所述。 -
pFramebuffer
是指向 VkFramebuffer 句柄的指针,其中返回生成的帧缓冲区对象。
VkFramebufferCreateInfo
结构定义如下:
// Provided by VK_VERSION_1_0
typedef struct VkFramebufferCreateInfo {
VkStructureType sType;
const void* pNext;
VkFramebufferCreateFlags flags;
VkRenderPass renderPass;
uint32_t attachmentCount;
const VkImageView* pAttachments;
uint32_t width;
uint32_t height;
uint32_t layers;
} VkFramebufferCreateInfo;
-
sType
是一个 VkStructureType 值,用于标识此结构。 -
pNext
为NULL
或指向扩展此结构的结构的指针。 -
flags
是 VkFramebufferCreateFlagBits 的位掩码。 -
renderPass
是一个渲染通道,定义帧缓冲将与之兼容的渲染通道。有关详细信息,请参阅 渲染通道兼容性。 -
attachmentCount
是附件的数量。 -
pAttachments
是指向 VkImageView 句柄数组的指针,每个句柄将在渲染通道实例中用作相应的附件。如果flags
包含VK_FRAMEBUFFER_CREATE_IMAGELESS_BIT
,则忽略此参数。 -
width
、height
和layers
定义帧缓冲的尺寸。如果渲染通道使用多视口,则layers
必须 为 1,并且每个附件都需要大于在其使用的子通道中视图掩码中设置的最大位索引的层数。
子通道可以使用没有颜色或深度/模板附件是合法的,要么是因为它没有附件引用,要么是因为所有附件引用都是 VK_ATTACHMENT_UNUSED
。这种子通道 可以 使用着色器副作用(例如图像存储和原子操作)来生成输出。在这种情况下,子通道继续使用帧缓冲的 width
、height
和 layers
来定义渲染区域的尺寸,并使用每个管线的 VkPipelineMultisampleStateCreateInfo 中的 rasterizationSamples
来定义光栅化中使用的样本数;但是,如果 VkPhysicalDeviceFeatures::variableMultisampleRate
为 VK_FALSE
,则要与子通道绑定的所有管线 必须 具有相同的 VkPipelineMultisampleStateCreateInfo::rasterizationSamples
值。在所有这些情况下,rasterizationSamples
必须 是一个有效的 VkSampleCountFlagBits 值,该值在 VkPhysicalDeviceLimits::framebufferNoAttachmentsSampleCounts
中设置。
VkFramebufferAttachmentsCreateInfo
结构定义如下:
// Provided by VK_VERSION_1_2
typedef struct VkFramebufferAttachmentsCreateInfo {
VkStructureType sType;
const void* pNext;
uint32_t attachmentImageInfoCount;
const VkFramebufferAttachmentImageInfo* pAttachmentImageInfos;
} VkFramebufferAttachmentsCreateInfo;
或等效的
// Provided by VK_KHR_imageless_framebuffer
typedef VkFramebufferAttachmentsCreateInfo VkFramebufferAttachmentsCreateInfoKHR;
-
sType
是一个 VkStructureType 值,用于标识此结构。 -
pNext
为NULL
或指向扩展此结构的结构的指针。 -
attachmentImageInfoCount
是所描述的附件的数量。 -
pAttachmentImageInfos
是指向 VkFramebufferAttachmentImageInfo 结构数组的指针,每个结构描述渲染通道实例中相应附件的一些参数。
VkFramebufferAttachmentImageInfo
结构定义如下:
// Provided by VK_VERSION_1_2
typedef struct VkFramebufferAttachmentImageInfo {
VkStructureType sType;
const void* pNext;
VkImageCreateFlags flags;
VkImageUsageFlags usage;
uint32_t width;
uint32_t height;
uint32_t layerCount;
uint32_t viewFormatCount;
const VkFormat* pViewFormats;
} VkFramebufferAttachmentImageInfo;
或等效的
// Provided by VK_KHR_imageless_framebuffer
typedef VkFramebufferAttachmentImageInfo VkFramebufferAttachmentImageInfoKHR;
-
sType
是一个 VkStructureType 值,用于标识此结构。 -
pNext
为NULL
或指向扩展此结构的结构的指针。 -
flags
是一个 VkImageCreateFlagBits 的位掩码,与用于创建将用于此帧缓冲区的图像的 VkImageCreateInfo::flags
的值匹配。 -
usage
是一个 VkImageUsageFlagBits 的位掩码,与用于创建将用于此帧缓冲区的图像的 VkImageCreateInfo::usage
的值匹配。 -
width
是用于渲染的图像视图的宽度。 -
height
是用于渲染的图像视图的高度。 -
layerCount
是用于渲染的图像视图的数组层数。 -
viewFormatCount
是pViewFormats
数组中的条目数,与用于创建将用于此帧缓冲区的图像的 VkImageFormatListCreateInfo::viewFormatCount
的值匹配。 -
pViewFormats
是指向 VkFormat 值数组的指针,该数组指定创建图像视图时可以使用的所有格式,与用于创建将用于此帧缓冲区的图像的 VkImageFormatListCreateInfo::pViewFormats
的值匹配。
当开始渲染通道时,如 VkRenderPassAttachmentBeginInfo 所指定,可以与帧缓冲区一起使用的图像,必须使用与此处指定的参数相同的参数创建。
可以在 VkFramebufferCreateInfo::flags
中设置的位,指定帧缓冲区的选项,如下所示:
// Provided by VK_VERSION_1_0
typedef enum VkFramebufferCreateFlagBits {
// Provided by VK_VERSION_1_2
VK_FRAMEBUFFER_CREATE_IMAGELESS_BIT = 0x00000001,
// Provided by VK_KHR_imageless_framebuffer
VK_FRAMEBUFFER_CREATE_IMAGELESS_BIT_KHR = VK_FRAMEBUFFER_CREATE_IMAGELESS_BIT,
} VkFramebufferCreateFlagBits;
-
VK_FRAMEBUFFER_CREATE_IMAGELESS_BIT
指定不指定图像视图,并且只通过 VkFramebufferAttachmentImageInfo 结构提供附件兼容性信息。
// Provided by VK_VERSION_1_0
typedef VkFlags VkFramebufferCreateFlags;
VkFramebufferCreateFlags
是一种位掩码类型,用于设置零个或多个 VkFramebufferCreateFlagBits 的掩码。
要销毁帧缓冲区,请调用:
// Provided by VK_VERSION_1_0
void vkDestroyFramebuffer(
VkDevice device,
VkFramebuffer framebuffer,
const VkAllocationCallbacks* pAllocator);
-
device
是销毁帧缓冲区的逻辑设备。 -
framebuffer
是要销毁的帧缓冲区的句柄。 -
pAllocator
控制主机内存分配,如内存分配章节所述。
渲染通道加载操作
渲染通道加载操作定义渲染通道实例期间附件的初始值。
对于具有深度/模板格式的附件,加载操作在 VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
管线阶段执行。对于具有颜色格式的附件,加载操作在 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
管线阶段执行。附件中每个样本的加载操作发生在任何记录的命令之前,这些命令通过该附件或别名在渲染通道实例中访问该样本。
由于加载操作总是首先发生,因此与附件访问的外部同步只需要将加载操作与之前的命令同步;而不是渲染通道实例中的操作。当使用 |
加载操作仅更新渲染通道实例的已定义渲染区域内的值。然而,加载操作(由其访问掩码定义)对给定附件执行的任何写入可能会读取和写回该附件绑定的图像子资源内的任何内存位置。对于深度/模板图像,如果未启用 maintenance7 功能或 separateDepthStencilAttachmentAccess
为 VK_FALSE
,则对一个方面的写入可能也会导致对另一个方面执行读-修改-写操作。如果子资源处于 VK_IMAGE_LAYOUT_ATTACHMENT_FEEDBACK_LOOP_OPTIMAL_EXT
布局中,则实现必须不访问渲染区域之外的像素。
由于整个子资源可能被加载操作访问,因此当使用修改值的加载操作时,应用程序无法在渲染通道实例期间安全地访问渲染区域之外的值。 |
可以用于渲染通道的加载操作是
// Provided by VK_VERSION_1_0
typedef enum VkAttachmentLoadOp {
VK_ATTACHMENT_LOAD_OP_LOAD = 0,
VK_ATTACHMENT_LOAD_OP_CLEAR = 1,
VK_ATTACHMENT_LOAD_OP_DONT_CARE = 2,
// Provided by VK_VERSION_1_4
VK_ATTACHMENT_LOAD_OP_NONE = 1000400000,
// Provided by VK_EXT_load_store_op_none
VK_ATTACHMENT_LOAD_OP_NONE_EXT = VK_ATTACHMENT_LOAD_OP_NONE,
// Provided by VK_KHR_load_store_op_none
VK_ATTACHMENT_LOAD_OP_NONE_KHR = VK_ATTACHMENT_LOAD_OP_NONE,
} VkAttachmentLoadOp;
-
VK_ATTACHMENT_LOAD_OP_LOAD
指定渲染区域内图像的先前内容将保留为初始值。对于具有深度/模板格式的附件,这使用VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT
访问类型。对于具有颜色格式的附件,这使用VK_ACCESS_COLOR_ATTACHMENT_READ_BIT
访问类型。 -
VK_ATTACHMENT_LOAD_OP_CLEAR
指定渲染区域内的内容将被清除为统一值,该值在开始渲染通道实例时指定。对于具有深度/模板格式的附件,这使用VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT
访问类型。对于具有颜色格式的附件,这使用VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT
访问类型。 -
VK_ATTACHMENT_LOAD_OP_DONT_CARE
指定不需要保留区域内的先前内容;附件的内容将在渲染区域内是未定义的。对于具有深度/模板格式的附件,这使用VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT
访问类型。对于具有颜色格式的附件,这使用VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT
访问类型。 -
VK_ATTACHMENT_LOAD_OP_NONE
指定图像的先前内容在渲染通道内是未定义的。由于不访问图像,因此不使用任何访问类型。
渲染通道存储操作
渲染通道存储操作定义了渲染通道实例期间写入附件的值如何存储到内存中。
对于具有深度/模板格式的附件,存储操作在 VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT
管线阶段执行。对于具有颜色格式的附件,存储操作在 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
管线阶段执行。附件中每个样本的存储操作发生在通过该附件或别名访问该样本的任何记录的命令之后。
由于存储操作总是在渲染通道实例中的其他访问之后发生,因此在较早的渲染通道中与附件访问的外部同步只需要与存储操作同步;而不是渲染通道实例中的操作。当使用 |
存储操作仅更新渲染通道实例的已定义渲染区域内的值。然而,存储操作(由其访问掩码定义)对给定附件执行的任何写入可能会读取和写回该附件绑定的图像子资源内的任何内存位置。对于深度/模板图像,如果 separateDepthStencilAttachmentAccess
为 VK_FALSE
,则对一个方面的写入可能也会导致对另一个方面执行读-修改-写操作。如果子资源处于 VK_IMAGE_LAYOUT_ATTACHMENT_FEEDBACK_LOOP_OPTIMAL_EXT
布局中,则实现必须不访问渲染区域之外的像素。
由于整个子资源可能被存储操作访问,因此当使用修改值的存储操作时,应用程序无法在渲染通道实例期间通过别名资源安全地访问渲染区域之外的值。 |
VkAttachmentDescription::storeOp
和 stencilStoreOp
的可能值,指定如何处理附件的内容,是
// Provided by VK_VERSION_1_0
typedef enum VkAttachmentStoreOp {
VK_ATTACHMENT_STORE_OP_STORE = 0,
VK_ATTACHMENT_STORE_OP_DONT_CARE = 1,
// Provided by VK_VERSION_1_3
VK_ATTACHMENT_STORE_OP_NONE = 1000301000,
// Provided by VK_KHR_dynamic_rendering, VK_KHR_load_store_op_none
VK_ATTACHMENT_STORE_OP_NONE_KHR = VK_ATTACHMENT_STORE_OP_NONE,
// Provided by VK_QCOM_render_pass_store_ops
VK_ATTACHMENT_STORE_OP_NONE_QCOM = VK_ATTACHMENT_STORE_OP_NONE,
// Provided by VK_EXT_load_store_op_none
VK_ATTACHMENT_STORE_OP_NONE_EXT = VK_ATTACHMENT_STORE_OP_NONE,
} VkAttachmentStoreOp;
-
VK_ATTACHMENT_STORE_OP_STORE
指定在渲染通道期间以及在渲染区域内生成的内容写入到内存中。对于具有深度/模板格式的附件,这使用VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT
访问类型。对于具有颜色格式的附件,这使用VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT
访问类型。 -
VK_ATTACHMENT_STORE_OP_DONT_CARE
指定在渲染后不需要渲染区域内的内容,并且可能被丢弃;附件的内容将在渲染区域内是未定义的。对于具有深度/模板格式的附件,这使用VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT
访问类型。对于具有颜色格式的附件,这使用VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT
访问类型。 -
VK_ATTACHMENT_STORE_OP_NONE
指定只要在渲染通道期间不向附件写入任何值,存储操作就不会访问渲染区域内的内容。如果在渲染通道期间写入值,则其行为与VK_ATTACHMENT_STORE_OP_DONT_CARE
相同,并具有匹配的访问语义。
即使在当前渲染通道期间没有发生对附件的写入, |
渲染通道多重采样解析操作
渲染通道多重采样解析操作将多重采样附件中单个像素的样本值组合在一起,并将结果存储到单样本附件中的相应像素。
多重采样附件的解析操作在 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
管线阶段执行。渲染区域中所有像素的最终解析操作发生在任何已记录的命令之后,这些命令通过要解析的多重采样附件或在其指定的子通道中的显式别名写入像素。用于多重采样解析操作的任何单样本附件,一旦渲染通道实例开始渲染,可能在任何时候修改其内容。从多重采样附件的读取可以使用 VK_ACCESS_COLOR_ATTACHMENT_READ_BIT
进行同步。对单样本附件的访问可以使用 VK_ACCESS_COLOR_ATTACHMENT_READ_BIT
和 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT
进行同步。无论附件是颜色附件还是深度/模板附件,都使用这些管线阶段和访问类型。
当使用渲染通道对象时,使用上述管线阶段和访问标志指定的子通道依赖关系将确保与该子通道最后访问的任何附件的多重采样解析操作同步。这允许后续的子通道将解析后的值读取为输入附件。
解析操作仅更新渲染通道实例的定义渲染区域内的值。但是,解析操作(由其访问掩码定义)对给定附件执行的任何写入操作可能读取并写回该附件绑定的图像子资源内的任何内存位置。对于深度/模板图像,如果 separateDepthStencilAttachmentAccess
为 VK_FALSE
,则对一个方面的写入操作可能还会导致对另一个方面的读-修改-写操作。如果子资源处于 VK_IMAGE_LAYOUT_ATTACHMENT_FEEDBACK_LOOP_OPTIMAL_EXT
布局中,则实现必须不访问渲染区域之外的像素。
由于整个子资源可能被多重采样解析操作访问,因此当执行多重采样解析操作时,应用程序无法在渲染通道实例期间安全地通过别名资源访问渲染区域之外的值。 |
多重采样附件中的多重采样值会根据所使用的解析模式进行组合
// Provided by VK_VERSION_1_2
typedef enum VkResolveModeFlagBits {
VK_RESOLVE_MODE_NONE = 0,
VK_RESOLVE_MODE_SAMPLE_ZERO_BIT = 0x00000001,
VK_RESOLVE_MODE_AVERAGE_BIT = 0x00000002,
VK_RESOLVE_MODE_MIN_BIT = 0x00000004,
VK_RESOLVE_MODE_MAX_BIT = 0x00000008,
// Provided by VK_ANDROID_external_format_resolve with VK_KHR_dynamic_rendering or VK_VERSION_1_3
VK_RESOLVE_MODE_EXTERNAL_FORMAT_DOWNSAMPLE_ANDROID = 0x00000010,
// Provided by VK_KHR_depth_stencil_resolve
VK_RESOLVE_MODE_NONE_KHR = VK_RESOLVE_MODE_NONE,
// Provided by VK_KHR_depth_stencil_resolve
VK_RESOLVE_MODE_SAMPLE_ZERO_BIT_KHR = VK_RESOLVE_MODE_SAMPLE_ZERO_BIT,
// Provided by VK_KHR_depth_stencil_resolve
VK_RESOLVE_MODE_AVERAGE_BIT_KHR = VK_RESOLVE_MODE_AVERAGE_BIT,
// Provided by VK_KHR_depth_stencil_resolve
VK_RESOLVE_MODE_MIN_BIT_KHR = VK_RESOLVE_MODE_MIN_BIT,
// Provided by VK_KHR_depth_stencil_resolve
VK_RESOLVE_MODE_MAX_BIT_KHR = VK_RESOLVE_MODE_MAX_BIT,
} VkResolveModeFlagBits;
或等效的
// Provided by VK_KHR_depth_stencil_resolve
typedef VkResolveModeFlagBits VkResolveModeFlagBitsKHR;
-
VK_RESOLVE_MODE_NONE
指定不进行解析操作。 -
VK_RESOLVE_MODE_SAMPLE_ZERO_BIT
指定解析操作的结果等于样本 0 的值。 -
VK_RESOLVE_MODE_AVERAGE_BIT
指定解析操作的结果是样本值的平均值。 -
VK_RESOLVE_MODE_MIN_BIT
指定解析操作的结果是样本值的最小值。 -
VK_RESOLVE_MODE_MAX_BIT
指定解析操作的结果是样本值的最大值。 -
VK_RESOLVE_MODE_EXTERNAL_FORMAT_DOWNSAMPLE_ANDROID
指定不是多重采样解析,而是将单个采样的颜色附件下采样为外部 Android 格式指定的 Y′CBCR 格式图像。与其他解析模式不同,实现可以在渲染期间多次解析,甚至完全绕过写入颜色附件的操作,只要最终值被解析到解析附件即可。颜色附件的 G、B 和 R 通道中的值将分别写入外部格式图像的 Y、CB 和 CR 通道。色度值的计算方式就好像使用线性滤波器以全速率从颜色附件采样,采样位置根据 VkPhysicalDeviceExternalFormatResolvePropertiesANDROID::chromaOffsetX
、VkPhysicalDeviceExternalFormatResolvePropertiesANDROID::chromaOffsetY
和解析图像的色度采样率确定。
如果没有另外指定解析模式,则使用 VK_RESOLVE_MODE_AVERAGE_BIT
。
|
// Provided by VK_VERSION_1_2
typedef VkFlags VkResolveModeFlags;
或等效的
// Provided by VK_KHR_depth_stencil_resolve
typedef VkResolveModeFlags VkResolveModeFlagsKHR;
VkResolveModeFlags
是一个位掩码类型,用于设置零个或多个 VkResolveModeFlagBits 的掩码。
渲染通道命令
应用程序通过开始一个渲染通道实例,迭代子通道以记录该子通道的命令,然后结束渲染通道实例,来一次记录一个子通道的渲染通道实例命令。
要开始渲染通道实例,请调用
// Provided by VK_VERSION_1_0
void vkCmdBeginRenderPass(
VkCommandBuffer commandBuffer,
const VkRenderPassBeginInfo* pRenderPassBegin,
VkSubpassContents contents);
-
commandBuffer
是在其中记录命令的命令缓冲区。 -
pRenderPassBegin
是一个指向 VkRenderPassBeginInfo 结构的指针,该结构指定要开始实例的渲染通道,以及该实例使用的帧缓冲。 -
contents
是一个 VkSubpassContents 值,指定如何提供第一个子通道中的命令。
开始渲染通道实例后,命令缓冲区已准备好记录该渲染通道的第一个子通道的命令。
或者,要开始渲染通道,请调用
// Provided by VK_VERSION_1_2
void vkCmdBeginRenderPass2(
VkCommandBuffer commandBuffer,
const VkRenderPassBeginInfo* pRenderPassBegin,
const VkSubpassBeginInfo* pSubpassBeginInfo);
或等效命令
// Provided by VK_KHR_create_renderpass2
void vkCmdBeginRenderPass2KHR(
VkCommandBuffer commandBuffer,
const VkRenderPassBeginInfo* pRenderPassBegin,
const VkSubpassBeginInfo* pSubpassBeginInfo);
-
commandBuffer
是在其中记录命令的命令缓冲区。 -
pRenderPassBegin
是一个指向 VkRenderPassBeginInfo 结构的指针,该结构指定要开始实例的渲染通道,以及该实例使用的帧缓冲。 -
pSubpassBeginInfo
是指向 VkSubpassBeginInfo 结构的指针,其中包含有关即将开始渲染的子通道的信息。
开始渲染通道实例后,命令缓冲区已准备好记录该渲染通道的第一个子通道的命令。
VkRenderPassBeginInfo
结构的定义如下:
// Provided by VK_VERSION_1_0
typedef struct VkRenderPassBeginInfo {
VkStructureType sType;
const void* pNext;
VkRenderPass renderPass;
VkFramebuffer framebuffer;
VkRect2D renderArea;
uint32_t clearValueCount;
const VkClearValue* pClearValues;
} VkRenderPassBeginInfo;
-
sType
是一个 VkStructureType 值,用于标识此结构。 -
pNext
为NULL
或指向扩展此结构的结构的指针。 -
renderPass
是要开始实例化的渲染通道。 -
framebuffer
是包含用于渲染通道的附件的帧缓冲。 -
renderArea
是受渲染通道实例影响的渲染区域,将在下面详细描述。 -
clearValueCount
是pClearValues
中元素的数量。 -
pClearValues
是指向一个包含clearValueCount
个 VkClearValue 结构的数组的指针,该数组包含每个附件的清除值,如果附件使用了loadOp
值为VK_ATTACHMENT_LOAD_OP_CLEAR
,或者如果附件具有深度/模板格式并使用stencilLoadOp
值为VK_ATTACHMENT_LOAD_OP_CLEAR
。数组的索引是附件编号。只使用与清除的附件相对应的元素。pClearValues
的其他元素将被忽略。
renderArea
是受渲染通道实例影响的渲染区域。附件的加载、存储和多重采样解析操作的效果仅限于所有附件上 x 和 y 坐标落在渲染区域内的像素。渲染区域扩展到 framebuffer
的所有层。应用程序必须确保(必要时使用裁剪)所有渲染都包含在渲染区域内。在应用 VkRenderPassTransformBeginInfoQCOM::transform
指定的任何变换之后,渲染区域必须包含在帧缓冲的尺寸内。
如果启用了 渲染通道变换,则 renderArea
必须等于帧缓冲的预变换尺寸。在 renderArea
被 VkRenderPassTransformBeginInfoQCOM::transform
变换之后,结果渲染区域必须等于帧缓冲的尺寸。
如果在 renderPass
中启用了多视图,并且启用了 multiviewPerViewRenderAreas
功能,并且在 pNext
链中包含了一个 perViewRenderAreaCount
不等于 0
的 VkMultiviewPerViewRenderAreasRenderPassBeginInfoQCOM 实例,则 VkMultiviewPerViewRenderAreasRenderPassBeginInfoQCOM::pPerViewRenderAreas
的元素将覆盖 renderArea
并为每个视图定义一个渲染区域。在这种情况下,renderArea
必须是至少与所有每个视图的渲染区域的并集一样大的区域。
如果启用了 subpassShading
功能,则 renderArea
必须等于帧缓冲的尺寸。
对于使用小于帧缓冲的渲染区域,除非它与渲染通道的渲染区域粒度匹配,否则可能存在性能成本。 |
深度/模板附件的深度方面的图像布局(指使用 VK_IMAGE_CREATE_SAMPLE_LOCATIONS_COMPATIBLE_DEPTH_BIT_EXT
创建的图像)取决于最后用于渲染图像子资源的采样位置。因此,为了在子通道边界之间保留此类深度/模板附件的内容,应用程序需要在附件的布局转换可能发生时指定这些采样位置。此信息可以通过将 VkRenderPassSampleLocationsBeginInfoEXT
结构添加到 VkRenderPassBeginInfo
的 pNext
链中来提供。
VkRenderPassSampleLocationsBeginInfoEXT
结构的定义如下:
// Provided by VK_EXT_sample_locations
typedef struct VkRenderPassSampleLocationsBeginInfoEXT {
VkStructureType sType;
const void* pNext;
uint32_t attachmentInitialSampleLocationsCount;
const VkAttachmentSampleLocationsEXT* pAttachmentInitialSampleLocations;
uint32_t postSubpassSampleLocationsCount;
const VkSubpassSampleLocationsEXT* pPostSubpassSampleLocations;
} VkRenderPassSampleLocationsBeginInfoEXT;
-
sType
是一个 VkStructureType 值,用于标识此结构。 -
pNext
为NULL
或指向扩展此结构的结构的指针。 -
attachmentInitialSampleLocationsCount
是pAttachmentInitialSampleLocations
数组中的元素数量。 -
pAttachmentInitialSampleLocations
是指向attachmentInitialSampleLocationsCount
个 VkAttachmentSampleLocationsEXT 结构的数组的指针,这些结构指定了附件的索引及其对应的采样位置状态。pAttachmentInitialSampleLocations
的每个元素可以指定在执行自动布局转换时使用的采样位置状态,以便将深度/模板附件从附件的初始布局转换为使用该附件的第一个子通道中为该附件指定的图像布局。 -
postSubpassSampleLocationsCount
是pPostSubpassSampleLocations
数组中的元素数量。 -
pPostSubpassSampleLocations
是指向postSubpassSampleLocationsCount
个 VkSubpassSampleLocationsEXT 结构的数组的指针,这些结构指定了子通道的索引及其对应的采样位置状态。pPostSubpassSampleLocations
的每个元素可以指定在执行自动布局转换时使用的采样位置状态,以便将指定子通道使用的深度/模板附件转换为依赖子通道中指定的图像布局,或者如果指定的子通道是使用该附件的最后一个子通道,则转换为该附件的最终布局。此外,如果 VkPhysicalDeviceSampleLocationsPropertiesEXT::variableSampleLocations
为VK_FALSE
,则pPostSubpassSampleLocations
的每个元素必须指定与在指定子通道期间将绑定到命令缓冲区的所有管道使用的采样位置匹配的采样位置状态。 如果variableSampleLocations
为VK_TRUE
,则用于光栅化的采样位置不依赖于pPostSubpassSampleLocations
。
VkAttachmentSampleLocationsEXT
结构的定义如下:
// Provided by VK_EXT_sample_locations
typedef struct VkAttachmentSampleLocationsEXT {
uint32_t attachmentIndex;
VkSampleLocationsInfoEXT sampleLocationsInfo;
} VkAttachmentSampleLocationsEXT;
-
attachmentIndex
是提供采样位置状态的附件的索引。 -
sampleLocationsInfo
是用于给定附件的布局转换的采样位置状态,该转换从附件的初始布局到使用它的第一个子通道中为该附件指定的图像布局。
如果索引为 attachmentIndex
的帧缓冲区附件引用的图像不是使用 VK_IMAGE_CREATE_SAMPLE_LOCATIONS_COMPATIBLE_DEPTH_BIT_EXT
创建的,则会忽略 sampleLocationsInfo
中指定的值。
VkSubpassSampleLocationsEXT
结构的定义如下:
// Provided by VK_EXT_sample_locations
typedef struct VkSubpassSampleLocationsEXT {
uint32_t subpassIndex;
VkSampleLocationsInfoEXT sampleLocationsInfo;
} VkSubpassSampleLocationsEXT;
-
subpassIndex
是提供采样位置状态的子通道的索引。 -
sampleLocationsInfo
是用于深度/模板附件的布局转换的采样位置状态,该转换从在subpassIndex
中指定的子通道中使用的图像布局移开。
如果由 subpassIndex
标识的子通道中使用的深度/模板附件引用的图像不是使用 VK_IMAGE_CREATE_SAMPLE_LOCATIONS_COMPATIBLE_DEPTH_BIT_EXT
创建的,或者如果子通道不使用深度/模板附件,并且 VkPhysicalDeviceSampleLocationsPropertiesEXT::variableSampleLocations
为 VK_TRUE
,则会忽略 sampleLocationsInfo
中指定的值。
要开始启用 渲染通道变换 的渲染通道实例,请将 VkRenderPassTransformBeginInfoQCOM 添加到传递给 vkCmdBeginRenderPass 命令的 VkRenderPassBeginInfo 结构的 pNext
链中,以指定渲染通道变换。
VkRenderPassTransformBeginInfoQCOM
结构的定义如下:
// Provided by VK_QCOM_render_pass_transform
typedef struct VkRenderPassTransformBeginInfoQCOM {
VkStructureType sType;
void* pNext;
VkSurfaceTransformFlagBitsKHR transform;
} VkRenderPassTransformBeginInfoQCOM;
-
sType
是一个 VkStructureType 值,用于标识此结构。 -
pNext
为NULL
或指向扩展此结构的结构的指针。 -
transform
是一个 VkSurfaceTransformFlagBitsKHR 值,描述要应用于光栅化的变换。
VkSubpassBeginInfo
结构的定义如下:
// Provided by VK_VERSION_1_2
typedef struct VkSubpassBeginInfo {
VkStructureType sType;
const void* pNext;
VkSubpassContents contents;
} VkSubpassBeginInfo;
或等效的
// Provided by VK_KHR_create_renderpass2
typedef VkSubpassBeginInfo VkSubpassBeginInfoKHR;
-
sType
是一个 VkStructureType 值,用于标识此结构。 -
pNext
为NULL
或指向扩展此结构的结构的指针。 -
contents
是一个 VkSubpassContents 值,指定如何在下一个子通道中提供命令。
vkCmdBeginRenderPass::contents
的可能值(指定如何在第一个子通道中提供命令)如下:
// Provided by VK_VERSION_1_0
typedef enum VkSubpassContents {
VK_SUBPASS_CONTENTS_INLINE = 0,
VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS = 1,
// Provided by VK_KHR_maintenance7
VK_SUBPASS_CONTENTS_INLINE_AND_SECONDARY_COMMAND_BUFFERS_KHR = 1000451000,
// Provided by VK_EXT_nested_command_buffer
VK_SUBPASS_CONTENTS_INLINE_AND_SECONDARY_COMMAND_BUFFERS_EXT = VK_SUBPASS_CONTENTS_INLINE_AND_SECONDARY_COMMAND_BUFFERS_KHR,
} VkSubpassContents;
-
VK_SUBPASS_CONTENTS_INLINE
指定子通道的内容将以内联方式记录在主命令缓冲区中,并且不得在子通道内执行辅助命令缓冲区。 -
VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS
指定内容记录在二级命令缓冲区中,这些二级命令缓冲区将从主命令缓冲区中调用,并且在执行 vkCmdNextSubpass 或 vkCmdEndRenderPass 之前,vkCmdExecuteCommands 是命令缓冲区中唯一有效的命令。 -
VK_SUBPASS_CONTENTS_INLINE_AND_SECONDARY_COMMAND_BUFFERS_KHR
指定子通道的内容可以内联记录,也可以通过 vkCmdExecuteCommands 从该命令缓冲区执行的二级命令缓冲区中记录。
如果 VkRenderPassBeginInfo 或 VkRenderingInfo 的 pNext
链包含 VkDeviceGroupRenderPassBeginInfo
结构,则该结构包含渲染通道实例的设备掩码和渲染区域集合。
VkDeviceGroupRenderPassBeginInfo
结构的定义如下:
// Provided by VK_VERSION_1_1
typedef struct VkDeviceGroupRenderPassBeginInfo {
VkStructureType sType;
const void* pNext;
uint32_t deviceMask;
uint32_t deviceRenderAreaCount;
const VkRect2D* pDeviceRenderAreas;
} VkDeviceGroupRenderPassBeginInfo;
或等效的
// Provided by VK_KHR_device_group
typedef VkDeviceGroupRenderPassBeginInfo VkDeviceGroupRenderPassBeginInfoKHR;
-
sType
是一个 VkStructureType 值,用于标识此结构。 -
pNext
为NULL
或指向扩展此结构的结构的指针。 -
deviceMask
是渲染通道实例的设备掩码。 -
deviceRenderAreaCount
是pDeviceRenderAreas
数组中的元素数量。 -
pDeviceRenderAreas
是指向 VkRect2D 结构数组的指针,这些结构定义了每个物理设备的渲染区域。
deviceMask
有几个用途。它是渲染通道实例期间可以使用的物理设备集合的上限,也是渲染通道实例开始时的初始设备掩码。此外,过渡到渲染通道实例中的下一个子通道的命令和结束渲染通道实例的命令,以及相应的渲染通道加载、存储和多重采样解析操作以及与渲染通道实例对应的子通道依赖关系,都在此处提供的设备掩码中包含的物理设备上执行。
如果 deviceRenderAreaCount
不为零,则 pDeviceRenderAreas
的元素将覆盖 VkRenderPassBeginInfo::renderArea
的值,并为每个物理设备提供特定的渲染区域。这些渲染区域与 VkRenderPassBeginInfo::renderArea
的作用相同,包括控制由 VK_ATTACHMENT_LOAD_OP_CLEAR
清除和解析为解析附件的附件区域。
如果此结构不存在,则渲染通道实例的设备掩码为 VkDeviceGroupCommandBufferBeginInfo::deviceMask
的值。如果此结构不存在或 deviceRenderAreaCount
为零,则所有物理设备都使用 VkRenderPassBeginInfo::renderArea
。
VkRenderPassAttachmentBeginInfo
结构的定义如下:
// Provided by VK_VERSION_1_2
typedef struct VkRenderPassAttachmentBeginInfo {
VkStructureType sType;
const void* pNext;
uint32_t attachmentCount;
const VkImageView* pAttachments;
} VkRenderPassAttachmentBeginInfo;
或等效的
// Provided by VK_KHR_imageless_framebuffer
typedef VkRenderPassAttachmentBeginInfo VkRenderPassAttachmentBeginInfoKHR;
-
sType
是一个 VkStructureType 值,用于标识此结构。 -
pNext
为NULL
或指向扩展此结构的结构的指针。 -
attachmentCount
是附件的数量。 -
pAttachments
是指向VkImageView
句柄数组的指针,每个句柄都将在渲染通道实例中用作相应的附件。
如果渲染通道实例启用了多视口,并且启用了multiviewPerViewRenderAreas
特性,则可以将 VkMultiviewPerViewRenderAreasRenderPassBeginInfoQCOM
结构包含在 VkRenderPassBeginInfo 或 VkRenderingInfo 的 pNext
链中
VkMultiviewPerViewRenderAreasRenderPassBeginInfoQCOM
结构的定义如下:
// Provided by VK_QCOM_multiview_per_view_render_areas
typedef struct VkMultiviewPerViewRenderAreasRenderPassBeginInfoQCOM {
VkStructureType sType;
const void* pNext;
uint32_t perViewRenderAreaCount;
const VkRect2D* pPerViewRenderAreas;
} VkMultiviewPerViewRenderAreasRenderPassBeginInfoQCOM;
-
sType
是一个 VkStructureType 值,用于标识此结构。 -
pNext
为NULL
或指向扩展此结构的结构的指针。 -
perViewRenderAreaCount
是pPerViewRenderAreas
数组中的元素数量。 -
pPerViewRenderAreas
是一个指向 VkRect2D 结构体数组的指针,该数组定义了每个视图的渲染区域。
如果 perViewRenderAreaCount
不为零,则 pPerViewRenderAreas
的元素会覆盖 VkRenderPassBeginInfo::renderArea
或 VkRenderingInfo::renderArea
的值,并为多视图渲染通道的各个视图定义每个视图的渲染区域。视图索引为 i
的视图的渲染区域由 pPerViewRenderAreas
[i] 指定。
每个视图的渲染区域定义了附件的每个视图区域,这些区域会根据渲染通道实例的 loadOp
、storeOp
和 resolveMode
值进行加载、存储和解析。定义每个视图的渲染区域时,VkRenderPassBeginInfo::renderArea
或 VkRenderingInfo::renderArea
的值必须是一个包含所有每个视图渲染区域的并集的渲染区域,可能会被实现用于优化,但不会影响加载、存储或解析。
如果存在此结构体,且 perViewRenderAreaCount
不为零,则 perViewRenderAreaCount
必须至少比 VkRenderPassMultiviewCreateInfo::pViewMasks
或 VkRenderingInfo::viewMask
的任何元素中设置的最高有效位大一。
如果此结构体不存在或 perViewRenderAreaCount
为零,则 VkRenderPassBeginInfo::renderArea
或 VkRenderingInfo::renderArea
将用于所有视图。
要查询渲染区域粒度,请调用
// Provided by VK_VERSION_1_0
void vkGetRenderAreaGranularity(
VkDevice device,
VkRenderPass renderPass,
VkExtent2D* pGranularity);
-
device
是拥有渲染通道的逻辑设备。 -
renderPass
是渲染通道的句柄。 -
pGranularity
是指向 VkExtent2D 结构的指针,其中返回粒度。
导致最佳 renderArea
的条件是
-
renderArea
中的offset.x
成员是返回的 VkExtent2D 的width
成员(水平粒度)的倍数。 -
renderArea
中的offset.y
成员是返回的 VkExtent2D 的height
成员(垂直粒度)的倍数。 -
renderArea
中的extent.width
成员是水平粒度的倍数,或者offset.x
+extent.width
等于 VkRenderPassBeginInfo 中framebuffer
的width
。 -
renderArea
中的extent.height
成员是垂直粒度的倍数,或者offset.y
+extent.height
等于 VkRenderPassBeginInfo 中framebuffer
的height
。
子通道依赖项不受渲染区域的影响,并且适用于附加到帧缓冲区的整个图像子资源,如 自动布局转换 的描述中所指定。同样,即使管线屏障的效果扩展到渲染区域之外,它们也是有效的。
要在记录子通道命令后过渡到渲染通道实例中的下一个子通道,请调用
// Provided by VK_VERSION_1_0
void vkCmdNextSubpass(
VkCommandBuffer commandBuffer,
VkSubpassContents contents);
-
commandBuffer
是在其中记录命令的命令缓冲区。 -
contents
指定下一个子通道中的命令的提供方式,与 vkCmdBeginRenderPass 的相应参数方式相同。
当记录 vkCmdBeginRenderPass
时,渲染通道的子通道索引从零开始,并且每次记录 vkCmdNextSubpass
时都会递增。
在过渡到下一个子通道后,应用程序可以记录该子通道的命令。
要在记录子通道命令后过渡到渲染通道实例中的下一个子通道,请调用
// Provided by VK_VERSION_1_2
void vkCmdNextSubpass2(
VkCommandBuffer commandBuffer,
const VkSubpassBeginInfo* pSubpassBeginInfo,
const VkSubpassEndInfo* pSubpassEndInfo);
或等效命令
// Provided by VK_KHR_create_renderpass2
void vkCmdNextSubpass2KHR(
VkCommandBuffer commandBuffer,
const VkSubpassBeginInfo* pSubpassBeginInfo,
const VkSubpassEndInfo* pSubpassEndInfo);
-
commandBuffer
是在其中记录命令的命令缓冲区。 -
pSubpassBeginInfo
是指向 VkSubpassBeginInfo 结构的指针,其中包含有关即将开始渲染的子通道的信息。 -
pSubpassEndInfo
是一个指向 VkSubpassEndInfo 结构的指针,其中包含有关如何结束上一个子通道的信息。
vkCmdNextSubpass2
在语义上与 vkCmdNextSubpass 相同,不同之处在于它是可扩展的,并且 contents
是作为可扩展结构的一部分而不是作为平面参数提供的。
要在记录最后一个子通道的命令后记录结束渲染通道实例的命令,请调用
// Provided by VK_VERSION_1_0
void vkCmdEndRenderPass(
VkCommandBuffer commandBuffer);
-
commandBuffer
是用于结束当前渲染通道实例的命令缓冲区。
结束渲染通道实例会对最后一个子通道执行任何多重采样解析操作。
要在记录最后一个子通道的命令后记录结束渲染通道实例的命令,请调用
// Provided by VK_VERSION_1_2
void vkCmdEndRenderPass2(
VkCommandBuffer commandBuffer,
const VkSubpassEndInfo* pSubpassEndInfo);
或等效命令
// Provided by VK_KHR_create_renderpass2
void vkCmdEndRenderPass2KHR(
VkCommandBuffer commandBuffer,
const VkSubpassEndInfo* pSubpassEndInfo);
-
commandBuffer
是用于结束当前渲染通道实例的命令缓冲区。 -
pSubpassEndInfo
是一个指向 VkSubpassEndInfo 结构的指针,其中包含有关如何结束最后一个子通道的信息。
vkCmdEndRenderPass2
在语义上与 vkCmdEndRenderPass 相同,不同之处在于它是可扩展的。
VkSubpassEndInfo
结构定义如下:
// Provided by VK_VERSION_1_2
typedef struct VkSubpassEndInfo {
VkStructureType sType;
const void* pNext;
} VkSubpassEndInfo;
或等效的
// Provided by VK_KHR_create_renderpass2
typedef VkSubpassEndInfo VkSubpassEndInfoKHR;
-
sType
是一个 VkStructureType 值,用于标识此结构。 -
pNext
为NULL
或指向扩展此结构的结构的指针。
如果 VkSubpassEndInfo::pNext
链包含 VkSubpassFragmentDensityMapOffsetEndInfoQCOM
结构,则该结构包含渲染通道的每个图层的片段密度图偏移量数组。
VkSubpassFragmentDensityMapOffsetEndInfoQCOM
结构定义如下:
// Provided by VK_QCOM_fragment_density_map_offset
typedef struct VkSubpassFragmentDensityMapOffsetEndInfoQCOM {
VkStructureType sType;
const void* pNext;
uint32_t fragmentDensityOffsetCount;
const VkOffset2D* pFragmentDensityOffsets;
} VkSubpassFragmentDensityMapOffsetEndInfoQCOM;
-
sType
是一个 VkStructureType 值,用于标识此结构。 -
pNext
为NULL
或指向扩展此结构的结构的指针。 -
fragmentDensityOffsetCount
是指定的偏移量数量。 -
pFragmentDensityOffsets
是指向 VkOffset2D 结构数组的指针,每个结构描述每个图层的偏移量。
数组元素按 获取密度值 定义的每 layer
给出,其中 index = layer。每个 (x,y) 偏移量均以帧缓冲区像素为单位,并将片段密度图的获取量移动该量。偏移量可以是正数或负数。
为渲染过程中的任何子过程(非最后一个子过程)指定的偏移值将被忽略。如果渲染过程的最后一个子过程的 VkSubpassEndInfo::pNext
链不包含 VkSubpassFragmentDensityMapOffsetEndInfoQCOM
,或者如果 fragmentDensityOffsetCount
为零,则 提取密度值 将使用偏移量 (0,0)。
渲染过程创建反馈
VkRenderPassCreationControlEXT
结构可以包含在 VkRenderPassCreateInfo2
的 pNext
链中,或者包含在 VkSubpassDescription2 的 pNext
链中。VkRenderPassCreationControlEXT
结构定义如下:
// Provided by VK_EXT_subpass_merge_feedback
typedef struct VkRenderPassCreationControlEXT {
VkStructureType sType;
const void* pNext;
VkBool32 disallowMerging;
} VkRenderPassCreationControlEXT;
-
sType
是一个 VkStructureType 值,用于标识此结构。 -
pNext
为NULL
或指向扩展此结构的结构的指针。 -
disallowMerging
是一个布尔值,指示是否禁用子过程合并。
如果 VkRenderPassCreationControlEXT
结构包含在 VkRenderPassCreateInfo2 的 pNext
链中,且其 disallowMerging
的值为 VK_TRUE
,则实现将禁用整个渲染过程的子过程合并。如果 VkRenderPassCreationControlEXT
结构包含在 VkSubpassDescription2 的 pNext
链中,且其 disallowMerging
的值为 VK_TRUE
,则实现将禁用所描述的子过程与渲染过程中的先前子过程的合并。
要获取有关渲染过程创建的反馈,请在 VkRenderPassCreateInfo2 的 pNext
链中包含 VkRenderPassCreationFeedbackCreateInfoEXT
结构。VkRenderPassCreationFeedbackCreateInfoEXT
结构定义如下:
// Provided by VK_EXT_subpass_merge_feedback
typedef struct VkRenderPassCreationFeedbackCreateInfoEXT {
VkStructureType sType;
const void* pNext;
VkRenderPassCreationFeedbackInfoEXT* pRenderPassFeedback;
} VkRenderPassCreationFeedbackCreateInfoEXT;
-
sType
是一个 VkStructureType 值,用于标识此结构。 -
pNext
为NULL
或指向扩展此结构的结构的指针。 -
pRenderPassFeedback
是指向 VkRenderPassCreationFeedbackInfoEXT 结构的指针,反馈信息将返回到该结构中。
VkRenderPassCreationFeedbackInfoEXT
结构定义如下:
// Provided by VK_EXT_subpass_merge_feedback
typedef struct VkRenderPassCreationFeedbackInfoEXT {
uint32_t postMergeSubpassCount;
} VkRenderPassCreationFeedbackInfoEXT;
-
postMergeSubpassCount
是合并后的子过程计数。
要获取有关子过程创建的反馈,可以在 VkSubpassDescription2 的 pNext
链中包含 VkRenderPassSubpassFeedbackCreateInfoEXT
结构。VkRenderPassSubpassFeedbackCreateInfoEXT
结构定义如下:
// Provided by VK_EXT_subpass_merge_feedback
typedef struct VkRenderPassSubpassFeedbackCreateInfoEXT {
VkStructureType sType;
const void* pNext;
VkRenderPassSubpassFeedbackInfoEXT* pSubpassFeedback;
} VkRenderPassSubpassFeedbackCreateInfoEXT;
-
sType
是一个 VkStructureType 值,用于标识此结构。 -
pNext
为NULL
或指向扩展此结构的结构的指针。 -
pSubpassFeedback
是指向 VkRenderPassSubpassFeedbackInfoEXT 结构的指针,反馈信息将返回到该结构中。
VkRenderPassSubpassFeedbackInfoEXT
结构定义如下
// Provided by VK_EXT_subpass_merge_feedback
typedef struct VkRenderPassSubpassFeedbackInfoEXT {
VkSubpassMergeStatusEXT subpassMergeStatus;
char description[VK_MAX_DESCRIPTION_SIZE];
uint32_t postMergeIndex;
} VkRenderPassSubpassFeedbackInfoEXT;
-
subpassMergeStatus
是一个VkSubpassMergeStatusEXT
值,指定了子通道是否与前一个子通道合并以及未合并的原因信息。 -
description
是一个包含以空字符结尾的 UTF-8 字符串的VK_MAX_DESCRIPTION_SIZE
大小的char
数组,提供额外的细节信息。 -
postMergeIndex
是子通道合并后的子通道索引。
VkRenderPassSubpassFeedbackInfoEXT
:subpassMergeStatus 的可能值为
// Provided by VK_EXT_subpass_merge_feedback
typedef enum VkSubpassMergeStatusEXT {
VK_SUBPASS_MERGE_STATUS_MERGED_EXT = 0,
VK_SUBPASS_MERGE_STATUS_DISALLOWED_EXT = 1,
VK_SUBPASS_MERGE_STATUS_NOT_MERGED_SIDE_EFFECTS_EXT = 2,
VK_SUBPASS_MERGE_STATUS_NOT_MERGED_SAMPLES_MISMATCH_EXT = 3,
VK_SUBPASS_MERGE_STATUS_NOT_MERGED_VIEWS_MISMATCH_EXT = 4,
VK_SUBPASS_MERGE_STATUS_NOT_MERGED_ALIASING_EXT = 5,
VK_SUBPASS_MERGE_STATUS_NOT_MERGED_DEPENDENCIES_EXT = 6,
VK_SUBPASS_MERGE_STATUS_NOT_MERGED_INCOMPATIBLE_INPUT_ATTACHMENT_EXT = 7,
VK_SUBPASS_MERGE_STATUS_NOT_MERGED_TOO_MANY_ATTACHMENTS_EXT = 8,
VK_SUBPASS_MERGE_STATUS_NOT_MERGED_INSUFFICIENT_STORAGE_EXT = 9,
VK_SUBPASS_MERGE_STATUS_NOT_MERGED_DEPTH_STENCIL_COUNT_EXT = 10,
VK_SUBPASS_MERGE_STATUS_NOT_MERGED_RESOLVE_ATTACHMENT_REUSE_EXT = 11,
VK_SUBPASS_MERGE_STATUS_NOT_MERGED_SINGLE_SUBPASS_EXT = 12,
VK_SUBPASS_MERGE_STATUS_NOT_MERGED_UNSPECIFIED_EXT = 13,
} VkSubpassMergeStatusEXT;
-
VK_SUBPASS_MERGE_STATUS_MERGED_EXT
指定子通道已与之前的子通道合并。 -
VK_SUBPASS_MERGE_STATUS_DISALLOWED_EXT
指定子通道未合并,因为使用 VkRenderPassCreationControlEXT 禁用了合并。如果渲染通道不允许子通道合并,则所有子通道状态都设置为此值。如果子通道描述不允许子通道合并,则只有该子通道的状态设置为此值。 -
VK_SUBPASS_MERGE_STATUS_NOT_MERGED_SIDE_EFFECTS_EXT
指定子通道未合并,因为它包含副作用。 -
VK_SUBPASS_MERGE_STATUS_NOT_MERGED_SAMPLES_MISMATCH_EXT
指定子通道未合并,因为样本计数与之前的子通道不兼容。 -
VK_SUBPASS_MERGE_STATUS_NOT_MERGED_VIEWS_MISMATCH_EXT
指定子通道未合并,因为视图掩码与之前的子通道不匹配。 -
VK_SUBPASS_MERGE_STATUS_NOT_MERGED_ALIASING_EXT
指定子通道未合并,因为它们之间存在附件别名。 -
VK_SUBPASS_MERGE_STATUS_NOT_MERGED_DEPENDENCIES_EXT
指定子通道未合并,因为子通道依赖关系不允许合并。 -
VK_SUBPASS_MERGE_STATUS_NOT_MERGED_INCOMPATIBLE_INPUT_ATTACHMENT_EXT
指定子通道未合并,因为输入附件不是来自之前子通道的颜色附件,或者格式不兼容。 -
VK_SUBPASS_MERGE_STATUS_NOT_MERGED_TOO_MANY_ATTACHMENTS_EXT
指定子通道未合并,因为附件太多。 -
VK_SUBPASS_MERGE_STATUS_NOT_MERGED_INSUFFICIENT_STORAGE_EXT
指定子通道未合并,因为内存不足。 -
VK_SUBPASS_MERGE_STATUS_NOT_MERGED_DEPTH_STENCIL_COUNT_EXT
指定子通道未合并,因为深度/模板附件太多。 -
VK_SUBPASS_MERGE_STATUS_NOT_MERGED_RESOLVE_ATTACHMENT_REUSE_EXT
指定子通道未合并,因为解析附件在后续子通道中被重用为输入附件。 -
VK_SUBPASS_MERGE_STATUS_NOT_MERGED_SINGLE_SUBPASS_EXT
指定子通道未合并,因为渲染通道只有一个子通道。 -
VK_SUBPASS_MERGE_STATUS_NOT_MERGED_UNSPECIFIED_EXT
指定子通道由于未指明的原因而未合并。当没有其他VkSubpassMergeStatusEXT
值适用时,实现**应该**返回此值。
常见的渲染通道数据竞争(信息性)
由于渲染执行方式的复杂性,应用程序可能会意外引入数据竞争,通常是做了一些看似无害但实际上不支持的操作。本节列出了一些更常见的情况作为指导,以帮助避免它们。
从只读附件采样
Vulkan 包括用于深度/模板图像的只读布局,允许在渲染通道期间读取图像以进行深度/模板测试,并将其作为非附件读取。
但是,由于 VK_ATTACHMENT_STORE_OP_STORE
和 VK_ATTACHMENT_STORE_OP_DONT_CARE
可能会执行写操作,即使没有记录的命令写入附件,在使用这些存储操作的同时读取图像也可能导致数据竞争。如果从非附件的读取是在片元着色器中执行的,并且访问的样本与片元着色器覆盖的样本匹配,则不会发生数据竞争,因为存储操作保证在片元着色器执行之后对片元覆盖的样本集进行操作。值得注意的是,输入附件也可以用于这种情况。读取其他样本或在任何其他着色器阶段都可能导致由于潜在的数据竞争而产生意外行为,并且应为此生成验证错误。实际上,许多应用程序在没有观察到任何问题的情况下,已经发布了在覆盖的片元之外读取样本的情况,但是不能保证这种情况始终有效,并且不建议在新代码或重构的代码库中依赖这种情况。由于 VK_ATTACHMENT_STORE_OP_NONE
保证不执行任何写入,因此希望将图像同时作为附件和非附件读取的应用程序应使用此存储操作,并结合也不执行任何写入的加载操作。
资源之间的非重叠访问
在依赖附件和其他资源之间的非重叠访问时,重要的是要注意 加载 和 存储 操作具有相当宽的对齐要求 - 可能会影响整个子资源和相邻的深度/模板方面。这使得访问同时用作附件且任一访问都执行写操作的非附件子资源无效。
唯一的例外是子资源处于 VK_IMAGE_LAYOUT_ATTACHMENT_FEEDBACK_LOOP_OPTIMAL_EXT
图像布局时,在这种情况下,重叠被定义为以每个像素的粒度发生,并且应用程序可以读取渲染区域之外像素的数据,而不会引入数据竞争。
深度/模板和输入附件
当仅渲染到图像的深度或模板方面时,仅在非常特定的条件下,访问另一方面的输入附件才不会导致数据竞争。为了避免数据竞争,未写入的方面**必须**处于只读布局中,并且在绘制状态下**必须**禁用对其的写入。例如,要从模板读取同时写入深度,附件**必须**处于 VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL
(或等效布局),并且模板写入掩码**必须**为 0。类似地,要从深度读取同时写入模板,附件**必须**处于 VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL
(或等效布局),并且深度写入启用**必须**为 VK_FALSE
。
同步选项
有几种同步选项可用于同步渲染通道内对资源的访问。下面概述了一些选项
-
渲染通道对象中的 VkSubpassDependency 可以同步先前子通道的附件写入和 多重采样解析操作,以用于后续的输入附件读取。
-
子通道内的 vkCmdPipelineBarrier 可以同步子通道中先前的附件写入与后续的输入附件读取。
-
如果附件处于
VK_IMAGE_LAYOUT_ATTACHMENT_FEEDBACK_LOOP_OPTIMAL_EXT
图像布局中,则子通道内的 vkCmdPipelineBarrier 可以同步子通道中先前的附件写入与后续的非附件读取。 -
如果将子资源用作颜色和输入附件,并且执行读取的管道是使用
VK_PIPELINE_COLOR_BLEND_STATE_CREATE_RASTERIZATION_ORDER_ATTACHMENT_ACCESS_BIT_EXT
创建的 -
如果子资源被用作深度和输入附件,且执行读取的管线是使用
VK_PIPELINE_DEPTH_STENCIL_STATE_CREATE_RASTERIZATION_ORDER_ATTACHMENT_DEPTH_ACCESS_BIT_EXT
创建的 -
如果子资源被用作模板和输入附件,且执行读取的管线是使用
VK_PIPELINE_DEPTH_STENCIL_STATE_CREATE_RASTERIZATION_ORDER_ATTACHMENT_STENCIL_ACCESS_BIT_EXT
创建的 -
如果子资源被用作两个独立的非附件资源,通过使用其中一个片段互锁执行模式,可以使片段着色器中对像素或单个样本的写入与另一个片段着色器中对同一像素或样本的访问同步。