前面一节在聊同步的时候,说到 render pass也是一种同步。而在command buffer一节也多次提到了 render pass。比如:在同一个CommandBuffer中,不在RenderPass中的命令,即除去所有在vkCmdBeginRenderPass和vkCmdEndRenderPass之间的命令,这些命令的提交顺序为按照在CPU上写入CommandBuffer时的顺序。在RenderPass中的命令,在RenderPass中的命令,只定义在同一SubPass中的其他命令的提交顺序,这些命令的提交顺序也是按照在CPU上写入CommandBuffer时的顺序。注意,如果几个命令在vkCmdBeginRenderPass和vkCmdEndRenderPass之间,但是它们不在同一SubPass中,那么它们之间是不存在任何提交顺序的。

https://zhuanlan.zhihu.com/p/47769196


a render pass包含一组attachments、subpass、以及subpass之间的依赖,以及描述了subpass如何使用这些attachments。在command buffer中使用的render pass为a render pass instance。

render pass是通过VkRenderPass handle来表示的。

an attachment description描述了an attachment的属性,包括它的格式、sample count,以及在render pass instance的开始和结尾如何处理其内容。

a subpass表示在渲染过程中读取和写入a render pass中attachments的一个子集。渲染命令被录制到a render pass instance中的一个特定subpasss中。

a subpass description描述了a subpass包含的attachments(是render pass attachments的子集)。每个subpass可以将一些attachments作为input attachments来读取,写入一些attachment作为color、depth/stencil attachments,也可以使用multisample resolve操作来resolve attachments。a subpass description还可以包含一些保留的attachments,哪些attachments在该subpass中不读不写,但是在整个subpass中,这些内容必须被保留。

如果attachment是一个color,depth/stencil,resolve,depth/stencil resolve或者input attachment for that subpass,则说明该subpass要使用该attachment(通过VkSubpassDescription的pColorAttachments, pDepthStencilAttachment, pResolveAttachments, VkSubpassDescriptionDepthStencilResolve::pDepthStencilResolveAttachment, and pInputAttachments 参数来表示 )。subpass不使用其保留的attachment。an attachment的第一次使用是,使用该attachment的最小的subpass。相应的,最后一次使用,是使用该attachment的最大的subpass。

a render pass中的所有subpass都渲染到相同dimensions。在一个subpass的ps阶段,处理(x,y,layer)处的片元的时候,只能读取由之前subpass输出的相同位置的内容。(Patrick:划重点,framebufferfetch。)

注意:预先描述一组完整的subpass,这样的话implementation就可以在subpsas之间优化attachment data的存储和transfer了。

注意:这也就意味着具有简单framebuffer依赖的多个subpass就可以放入同一个tiled render pass中,这样可以在a render pass instance中保持attachment data on-chip。当然,一个render pass只包含一个subpass也很常见。

subpass dependencies描述了subpass之间的执行和memory dependencies。

subpass dependencies是a render pass中一系列的subpass dependencies组合,其中,每个subpass dependency(除了第一个)的source subpasss为前一个dependency的destination subpass。

subpass的执行可能与其它subpass重叠或者执行顺序不正确,除非强行规定execution dependency。每个subpass只规定,同一个subpass中的command 录制顺序为submission顺序,以及renderpass中用vkCmdBeginRenderPass和vkCmdEndRenderPass commands范围内的提交,不包括其它subpass中的顺序。这个规则影响大多数隐式排序。

a render pass描述了subpass和attachment的结构,与attachment的特定image views无关。用于attachments的特定image view,以及它们的dimension,是通过VkFramebuffer指定。Framebuffer是通过与其兼容的特定render pass创建的(后面会介绍)。总的来说,renderpass和framebuffer共同定义了一个或者多个subpass的complete render target state,以及subpass之间的算法依赖关系。

一个subpass中的渲染命令的不同 pipeline stage可以在渲染命令内和渲染命令之间无序执行,但必须遵守管线顺序。但对给给定位置(x,y,layer,sample),特定per-sample操作必须按照光栅化的顺序。(Patrick:没看懂)

VkResult vkCreateRenderPass( VkDevice device, const VkRenderPassCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkRenderPass* pRenderPass);

该API用于创建一个render pass

第一个输入参数,为用于创建render pass的logical device

第二个输入参数,为一个 VkRenderPassCreateInfo 的结构体,用于表明该render pass的属性

第三个输入参数,用于内存分配

第四个输入参数,用于获取生成的render pass

typedef struct VkRenderPassCreateInfo { VkStructureType sType; //当前结构体的类型,必须是 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO const void* pNext; //NULL,或者扩展该结构体的另外一个结构体,只能是 NULL or VkRenderPassInputAttachmentAspectCreateInfo or VkRenderPassMultiviewCreateInfo VkRenderPassCreateFlags flags; //reserved for future,必须为0 uint32_t attachmentCount; //render pass用到的attachments的数量 const VkAttachmentDescription* pAttachments; //一个包含 attachmentCount 个 VkAttachmentDescription 类型元素的数组,用于描述render pass用到的attachments uint32_t subpassCount; //创建的subpass的数量,必须大于0 const VkSubpassDescription* pSubpasses; //一个包含 subpassCount 个 VkSubpassDescription 类型元素的数组,用于描述每个subpass uint32_t dependencyCount; //subpass之间memory dependencies的数量 const VkSubpassDependency* pDependencies; //一个包含 dependencyCount 个 VkSubpassDependency 类型元素的数组,描述subpass之间的dependencies。 } VkRenderPassCreateInfo;

注意:这里需要避免数据竞争,如果任何subpass访问具有overlap内存位置的attachment,且其中有一个是写访问,则在它们之间需要一个subpass dependency

如果pNext包括 VkRenderPassInputAttachmentAspectCreateInfo 结构体,pAspectReferences 中的 subpass 必须小于 subpassCount

如果pNext包括 VkRenderPassInputAttachmentAspectCreateInfo 结构体,pAspectReferences 中的 inputAttachmentIndex 必须小于 pSubpasses 中对应 subpass 的 pInputAttachments

如果pNext包括 VkRenderPassInputAttachmentAspectCreateInfo 结构体,所涉及到的 inputAttachmentIndex 对应的 aspectMask,只能包含该attachment format所支持的 aspects

如果pNext包括 VkRenderPassMultiviewCreateInfo 结构体,且 subpassCount 不为 0,则其必须等于 subpassCount

如果pNext包括 VkRenderPassMultiviewCreateInfo 结构体,且 dependencyCount 不为 0,则其必须等于 dependencyCount

如果pNext包括 VkRenderPassMultiviewCreateInfo 结构体,针对每个非0的 pViewOffsets , 对应index的 pDependencies 的 srcSubpass 和 dstSubpass 必须不同

如果pNext包括 VkRenderPassMultiviewCreateInfo 结构体,针对 pDependencies::dependencyFlags 不包含 VK_DEPENDENCY_VIEW_LOCAL_BIT 的dependency,对应的 pViewOffsets 必须为0

如果pNext包括 VkRenderPassMultiviewCreateInfo 结构体,如果 pViewMasks 为0,则 pDependencies 的 dependencyFlags 必须不包含 VK_DEPENDENCY_VIEW_LOCAL_BIT

如果pNext包括 VkRenderPassMultiviewCreateInfo 结构体,如果 pViewMasks 为0,则 correlationMaskCount必须为0

如果 pDependencies 的 srcSubpass 不是 VK_SUBPASS_EXTERNAL,对应 dependency的 srcStageMask 中的所有stage flags必须被 source subpass的 pipelineBindPoint 对应的pipeline所支持

如果 pDependencies 的 dstSubpass 不是 VK_SUBPASS_EXTERNAL,对应 dependency的 dstStageMask 中的所有stage flags必须被 destination subpass的 pipelineBindPoint 对应的pipeline所支持

typedef struct VkRenderPassInputAttachmentAspectCreateInfo { VkStructureType sType; //当前结构体的类型,必须是 VK_STRUCTURE_TYPE_RENDER_PASS_INPUT_ATTACHMENT_ASPECT_CREATE_INFO const void* pNext; //NULL,或者扩展该结构体的另外一个结构体 uint32_t aspectReferenceCount; //pAspectReferences 数组的尺寸,必须大于0 const VkInputAttachmentAspectReference* pAspectReferences; //一个指向 aspectReferenceCount 个 VkInputAttachmentAspectReference 结构体元素的数组,包含一个mask用于表示给定subpass中的给定input attachment的哪些 aspect(s) 能被访问。如果某个input attachment没有设置该值,则所有的aspect都可以访问,如果设置了,那么就只能访问 aspectMask 中设置的aspects了。 } VkRenderPassInputAttachmentAspectCreateInfo;

typedef struct VkInputAttachmentAspectReference { uint32_t subpass; //为 VkRenderPassCreateInfo::pSubpasses 数组的index uint32_t inputAttachmentIndex; //为 subpass 中 pInputAttachments 数组的index VkImageAspectFlags aspectMask; //a mask 指出当前subpass中可以访问哪些 aspect。必须不能包含 VK_IMAGE_ASPECT_METADATA_BIT,不能为0,必须是 VkImageAspectFlagBits 的合法组合。 } VkInputAttachmentAspectReference;

typedef enum VkImageAspectFlagBits { VK_IMAGE_ASPECT_COLOR_BIT = 0x00000001, //特指 color aspect VK_IMAGE_ASPECT_DEPTH_BIT = 0x00000002, //特指 depth aspect VK_IMAGE_ASPECT_STENCIL_BIT = 0x00000004, //特指 stencil aspect VK_IMAGE_ASPECT_METADATA_BIT = 0x00000008, //特指 metadata aspect,用于sparse sparse resource operation // Provided by VK_VERSION_1_1 VK_IMAGE_ASPECT_PLANE_0_BIT = 0x00000010, //特指 a multi-planar image format 中的 plane 0 // Provided by VK_VERSION_1_1 VK_IMAGE_ASPECT_PLANE_1_BIT = 0x00000020, //特指 a multi-planar image format 中的 plane 1 // Provided by VK_VERSION_1_1 VK_IMAGE_ASPECT_PLANE_2_BIT = 0x00000040, //特指 a multi-planar image format 中的 plane 2 } VkImageAspectFlagBits;

typedef struct VkRenderPassMultiviewCreateInfo { VkStructureType sType; //当前结构体的类型,必须是 VK_STRUCTURE_TYPE_RENDER_PASS_MULTIVIEW_CREATE_INFO const void* pNext; //NULL,或者扩展该结构体的另外一个结构体 uint32_t subpassCount; //0 或者render pass中subpass的数量 const uint32_t* pViewMasks; //一个 subpassCount 个元素的数组,每个元素为一个针对一个subpass 的 view mask,表示如果开启 multiview 的话,该subpass应该将渲染广播到哪些view。如果 subpassCount为0,则每个view mask也被认为是0.要么全是0,要么全部不是0 uint32_t dependencyCount; //0 或者render pass中 dependencies 的数量 const int32_t* pViewOffsets; //一个 dependencyCount 个元素的数组,每个元素为一个针对一个 depenency 的 view offsets ,每个view offset代表着 destination subpass中的views依赖 source subpass中的哪些views。如果 dependencyCount 为0,则每个 depenency 的 view offsets也被认为是0 uint32_t correlationMaskCount; //0 或者 correlation masks 的数量 const uint32_t* pCorrelationMasks; //一个 correlationMaskCount 个元素的数组,包含的view masks 指出可能更高效的并行渲染的 sets of views。一个view index不能设置在不同的 pCorrelationMasks中 } VkRenderPassMultiviewCreateInfo;

当一个subpass使用一个non-zero view mask,就相当于开启了multiview模式。在render pass中multivew是一个all-or-nothing,也就是说,要么所有的subpass都使用non-zero view mask(尽管一些subpass只有一个view) 或者所有的都必须是0。Multiviews促使subpass中所有的draw和clear command都广播到每个view,view也就是framebuffer attachments的一个layer。所有的draw和clear都被广播到view mask中设置的view中。view index在 ViewIndex shader input variable,color,depth/stencil,input attachments都可以读写framebuffer中view index对应的layer

如果view mask为0,则相当于没有开启multiview,所有的draw commands都正常运行,没有任何广播。

一些implementations可能不支持gs or ts with multiview

当multiview开启的时候,在dependency中可以使用 VK_DEPENDENCY_VIEW_LOCAL_BIT 来表示 a view -local dependency,意思就是destination subpass中的每个view依赖source subpass中的一个view。和pipeline barrier不同,subpass dependency在soure和destination subpass中可以有不同的view mask。如果dependency是view-local,那么destination subpass中的每个view(dstView)依赖source subpass中 dstView + pViewOffsets的view。如果source subpass中没有该view,则该dependency对destination subpass中的对应view没有影响。如果dependency不是view-local,那么destination subpass中的所有view依赖source subpass章的所有view,相应的view offset也就被忽略了。self-dependency不支持非0 offset。

pCorrelationMasks 是一组mask,表示pCorrelationMasks 中的一组views之间可能exhibit spatial coherency,从而使得并发渲染它们更加有效。 pCorrelationMasks 不得对multiview render有功能性的影响

当开启multiview的时候,在每个subpass的开头,所有non-render pass state都是未定义。特别是,每次调用vkCmdBeginRenderPass or vkCmdNextSubpass的时候,都必须绑定graphics pipeline,relevant descriptor sets,vbo、ibo也都必须绑定,relevant dynamic state或者push constants都必须在使用之前设置好。

typedef struct VkAttachmentDescription { VkAttachmentDescriptionFlags flags; //a bitmask of VkAttachmentDescriptionFlagBits ,用于描述attachment的额外属性。必须是 VkAttachmentDescriptionFlagBits 组合出来的,或者0 VkFormat format; //用于attachment的image view的format VkSampleCountFlagBits samples; //该image的sample数量,类型是 VkSampleCountFlagBits VkAttachmentLoadOp loadOp; //是一个 VkAttachmentLoadOp 值,在第一次使用的subpass开始的时候,指定attachment的color和depth的内容如何处理 VkAttachmentStoreOp storeOp; //是一个 VkAttachmentStoreOp 值,在最后一次使用的subpass结束的时候,指定attachment的color和depth的内容如何处理 VkAttachmentLoadOp stencilLoadOp; //是一个 VkAttachmentLoadOp 值,在第一次使用的subpass开始的时候,指定attachment的stencil的内容如何处理 VkAttachmentStoreOp stencilStoreOp; //是一个 VkAttachmentStoreOp 值,在最后一次使用的subpass结束的时候,指定attachment的stencil的内容如何处理 VkImageLayout initialLayout; //是render pass instance开始的时候,attachment image subresource的layout VkImageLayout finalLayout; //是render pass instance结束的时候,attachment image subresource将转换到的layout,不能是 VK_IMAGE_LAYOUT_UNDEFINED or VK_IMAGE_LAYOUT_PREINITIALIZED } VkAttachmentDescription;

当 pAttachments 的 loadOp 为 VK_ATTACHMENT_LOAD_OP_CLEAR 的时候,该attachment第一次被使用的时候,不能使用 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL or VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL or VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL 的layout

当 pAttachments 的 stencilLoadOp 为 VK_ATTACHMENT_LOAD_OP_CLEAR 的时候,该attachment第一次被使用的时候,不能使用 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL or VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL or VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL 的layout

如果 attachment 使用 color format,则 loadOp 和 storeOp 有效, stencilLoadOp 和 stencilStoreOp 将被忽略。如果format含depth和stencil,则 loadOp 和 storeOp 被用于depth, stencilLoadOp 和 stencilStoreOp 被用于 stencil。 loadOp 和 stencilLoadOp 定义了第一个使用该attachment的subpass,在执行中的load operation。 storeOp 和 stencilStoreOp 定义了最后一个使用该attachment的subpass,在执行中的 store operation。

attachment中的sample的 load 操作发生在第一次使用该attachment的subpass中使用该sample的命令之前。对depth/stencil的load操作,发生在 VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT pipeline stage。对color的load操作,发生在 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT pipeline stage。

attachment中的sample的 store 操作发生在最后一次使用该attachment的subpass中使用该sample的命令之后。对depth/stencil的 store 操作,发生在 VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT pipeline stage。对color的 store 操作,发生在 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT pipeline stage。

如果某个attachment没有被subpass使用,则 loadOp 和 storeOp、stencilLoadOp 和 stencilStoreOp 均被忽略,该attachment的memory contents在render pass instance的执行过程中不会被修改。

load 和 store operation应用在render pass中每个view的第一次和最后一次使用中。如果attachment的一个view index没有被任何subpass的view mask使用,则load和store操作均被忽略,atttachment上的memory contents不会被render pass instance的执行修改。

在render pass instance中,input/color attachments是color format,每个component size为8/16/32,在整个render pass instance过程中,必须保持不变,使用float或者fixed-point color format或者depth components可以使用更高精度的format,但是范围一定要一样。当一个component被loadOp的时候,会被转化成render pass使用的implementation-dependent format。在render pass instance结束的时候,必须通过storeOp,从render pass format resolve or store 转回 attachment format。具体的转换过程见其他章节。

如果 flag 包括 VK_ATTACHMENT_DESCRIPTION_MAY_ALIAS_BIT ,则说明该attachment与同一个render pass中的其他 attachment共享physical memory。这个限制了implementation 对其进行重新排序的能力(比如layout transition以及loadOp)

如果一个render pass使用多个attachment alias相同的device memory,则每个attachment都必须包含 VK_ATTACHMENT_DESCRIPTION_MAY_ALIAS_BIT 。attachments alias相同内存有如下几种方式:

  • 多个attachment在创建framebuffer的时候,对应同一个iamge view
  • 多个attachment对应同一个image的同一个image subresource的不同image view
  • 多个attachment对应views of distinct image subresources bound to 覆盖的内存范围

render pass中如果有两个subpass会在同一个attachment或者aliasing attachment上操作,则必须包含dependency,其如果其中一个subpass对aliase执行写操作,则必须使用memory dependencies将aliase的使用分开。如果aliase 是上述第三种, views of distinct image subresouces 覆盖内存,则该dependency不能包含 VK_DEPENDENCY_BY_REGION_BIT

使用相同memory的多个attachment不能被使用在一个subpass中。一个subpass中同一个attachment index不能使用多次,但有一个例外:两个subpass可以使用相同的attachment,其中至少一个作为input attachment,而不能作为resolve或者preserve attachment。换句话说,同一个试图可以同事作为input、color、depth/stencil attachment,但不能用作多个color、depth/stencil attachment,也不能用作resolve、perserve attachment。下面会有更详细的说明。

If a set of attachments alias each other, then all except the first to be used in the render pass must use an initialLayout of VK_IMAGE_LAYOUT_UNDEFINED, since the earlier uses of the other aliases make their contents undefined. Once an alias has been used and a different alias has been used after it, the first alias must not be used in any later subpasses. However, an application can assign the same image view to multiple aliasing attachment indices, which allows that image view to be used multiple times even if other aliases are used in between.

Once an attachment needs the VK_ATTACHMENT_DESCRIPTION_MAY_ALIAS_BIT bit, there should be no additional cost of introducing additional aliases, and using these additional aliases may allow more efficient clearing of the attachments on multiple uses via VK_ATTACHMENT_LOAD_OP_CLEAR.

如果format为color format,则 initialLayout 必须不能是 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL, VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL, or VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL,VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL, VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL, or VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL

如果format为 depth/stencil format,则 initialLayout 必须不能是 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL

如果没有开启 separateDepthStencilLayouts feature,在 initialLayout 必须不能是 VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL, VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL, or VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL

如果没有开启 separateDepthStencilLayouts feature,在 finalLayout 必须不能是 VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL, VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL, or VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL

如果format为color format,则 finalLayout 必须不能是 VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL, VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL, or VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL

如果format为 包含depth 和 stencil aspects的depth/stencil format,则 initialLayout 必须不能是 VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL, VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL, or VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL

如果format为 包含depth 和 stencil aspects的depth/stencil format,则 finalLayout 必须不能是 VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL, VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL, or VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL

如果format为 只包含 depth aspect的depth/stencil format,则 initialLayout 必须不能是 VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL or VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL

如果format为 只包含 depth aspect的depth/stencil format,则 finalLayout 必须不能是 VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL or VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL

如果format为 只包含 stencil aspect的depth/stencil format,则 initialLayout 必须不能是 VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL or VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL

如果format为 只包含 stencil aspect的depth/stencil format,则 finalLayout 必须不能是 VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL or VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL

typedef enum VkAttachmentDescriptionFlagBits { VK_ATTACHMENT_DESCRIPTION_MAY_ALIAS_BIT = 0x00000001, //表明该attachment 和其它attachments aliases相同的device memory } VkAttachmentDescriptionFlagBits;

typedef enum VkFormat { VK_FORMAT_UNDEFINED = 0, VK_FORMAT_R4G4_UNORM_PACK8 = 1, VK_FORMAT_R4G4B4A4_UNORM_PACK16 = 2, VK_FORMAT_B4G4R4A4_UNORM_PACK16 = 3, VK_FORMAT_R5G6B5_UNORM_PACK16 = 4, VK_FORMAT_B5G6R5_UNORM_PACK16 = 5, VK_FORMAT_R5G5B5A1_UNORM_PACK16 = 6, VK_FORMAT_B5G5R5A1_UNORM_PACK16 = 7, VK_FORMAT_A1R5G5B5_UNORM_PACK16 = 8, VK_FORMAT_R8_UNORM = 9, VK_FORMAT_R8_SNORM = 10, VK_FORMAT_R8_USCALED = 11, VK_FORMAT_R8_SSCALED = 12, VK_FORMAT_R8_UINT = 13, VK_FORMAT_R8_SINT = 14, VK_FORMAT_R8_SRGB = 15, VK_FORMAT_R8G8_UNORM = 16, VK_FORMAT_R8G8_SNORM = 17, VK_FORMAT_R8G8_USCALED = 18, VK_FORMAT_R8G8_SSCALED = 19, VK_FORMAT_R8G8_UINT = 20, VK_FORMAT_R8G8_SINT = 21, VK_FORMAT_R8G8_SRGB = 22, VK_FORMAT_R8G8B8_UNORM = 23, VK_FORMAT_R8G8B8_SNORM = 24, VK_FORMAT_R8G8B8_USCALED = 25, VK_FORMAT_R8G8B8_SSCALED = 26, VK_FORMAT_R8G8B8_UINT = 27, VK_FORMAT_R8G8B8_SINT = 28, VK_FORMAT_R8G8B8_SRGB = 29, VK_FORMAT_B8G8R8_UNORM = 30, VK_FORMAT_B8G8R8_SNORM = 31, VK_FORMAT_B8G8R8_USCALED = 32, VK_FORMAT_B8G8R8_SSCALED = 33, VK_FORMAT_B8G8R8_UINT = 34, VK_FORMAT_B8G8R8_SINT = 35, VK_FORMAT_B8G8R8_SRGB = 36, VK_FORMAT_R8G8B8A8_UNORM = 37, VK_FORMAT_R8G8B8A8_SNORM = 38, VK_FORMAT_R8G8B8A8_USCALED = 39, VK_FORMAT_R8G8B8A8_SSCALED = 40, VK_FORMAT_R8G8B8A8_UINT = 41, VK_FORMAT_R8G8B8A8_SINT = 42, VK_FORMAT_R8G8B8A8_SRGB = 43, VK_FORMAT_B8G8R8A8_UNORM = 44, VK_FORMAT_B8G8R8A8_SNORM = 45, VK_FORMAT_B8G8R8A8_USCALED = 46, VK_FORMAT_B8G8R8A8_SSCALED = 47, VK_FORMAT_B8G8R8A8_UINT = 48, VK_FORMAT_B8G8R8A8_SINT = 49, VK_FORMAT_B8G8R8A8_SRGB = 50, VK_FORMAT_A8B8G8R8_UNORM_PACK32 = 51, VK_FORMAT_A8B8G8R8_SNORM_PACK32 = 52, VK_FORMAT_A8B8G8R8_USCALED_PACK32 = 53, VK_FORMAT_A8B8G8R8_SSCALED_PACK32 = 54, VK_FORMAT_A8B8G8R8_UINT_PACK32 = 55, VK_FORMAT_A8B8G8R8_SINT_PACK32 = 56, VK_FORMAT_A8B8G8R8_SRGB_PACK32 = 57, VK_FORMAT_A2R10G10B10_UNORM_PACK32 = 58, VK_FORMAT_A2R10G10B10_SNORM_PACK32 = 59, VK_FORMAT_A2R10G10B10_USCALED_PACK32 = 60, VK_FORMAT_A2R10G10B10_SSCALED_PACK32 = 61, VK_FORMAT_A2R10G10B10_UINT_PACK32 = 62, VK_FORMAT_A2R10G10B10_SINT_PACK32 = 63, VK_FORMAT_A2B10G10R10_UNORM_PACK32 = 64, VK_FORMAT_A2B10G10R10_SNORM_PACK32 = 65, VK_FORMAT_A2B10G10R10_USCALED_PACK32 = 66, VK_FORMAT_A2B10G10R10_SSCALED_PACK32 = 67, VK_FORMAT_A2B10G10R10_UINT_PACK32 = 68, VK_FORMAT_A2B10G10R10_SINT_PACK32 = 69, VK_FORMAT_R16_UNORM = 70, VK_FORMAT_R16_SNORM = 71, VK_FORMAT_R16_USCALED = 72, VK_FORMAT_R16_SSCALED = 73, VK_FORMAT_R16_UINT = 74, VK_FORMAT_R16_SINT = 75, VK_FORMAT_R16_SFLOAT = 76, VK_FORMAT_R16G16_UNORM = 77, VK_FORMAT_R16G16_SNORM = 78, VK_FORMAT_R16G16_USCALED = 79, VK_FORMAT_R16G16_SSCALED = 80, VK_FORMAT_R16G16_UINT = 81, VK_FORMAT_R16G16_SINT = 82, VK_FORMAT_R16G16_SFLOAT = 83, VK_FORMAT_R16G16B16_UNORM = 84, VK_FORMAT_R16G16B16_SNORM = 85, VK_FORMAT_R16G16B16_USCALED = 86, VK_FORMAT_R16G16B16_SSCALED = 87, VK_FORMAT_R16G16B16_UINT = 88, VK_FORMAT_R16G16B16_SINT = 89, VK_FORMAT_R16G16B16_SFLOAT = 90, VK_FORMAT_R16G16B16A16_UNORM = 91, VK_FORMAT_R16G16B16A16_SNORM = 92, VK_FORMAT_R16G16B16A16_USCALED = 93, VK_FORMAT_R16G16B16A16_SSCALED = 94, VK_FORMAT_R16G16B16A16_UINT = 95, VK_FORMAT_R16G16B16A16_SINT = 96, VK_FORMAT_R16G16B16A16_SFLOAT = 97, VK_FORMAT_R32_UINT = 98, VK_FORMAT_R32_SINT = 99, VK_FORMAT_R32_SFLOAT = 100, VK_FORMAT_R32G32_UINT = 101, VK_FORMAT_R32G32_SINT = 102, VK_FORMAT_R32G32_SFLOAT = 103, VK_FORMAT_R32G32B32_UINT = 104, VK_FORMAT_R32G32B32_SINT = 105, VK_FORMAT_R32G32B32_SFLOAT = 106, VK_FORMAT_R32G32B32A32_UINT = 107, VK_FORMAT_R32G32B32A32_SINT = 108, VK_FORMAT_R32G32B32A32_SFLOAT = 109, VK_FORMAT_R64_UINT = 110, VK_FORMAT_R64_SINT = 111, VK_FORMAT_R64_SFLOAT = 112, VK_FORMAT_R64G64_UINT = 113, VK_FORMAT_R64G64_SINT = 114, VK_FORMAT_R64G64_SFLOAT = 115, VK_FORMAT_R64G64B64_UINT = 116, VK_FORMAT_R64G64B64_SINT = 117, VK_FORMAT_R64G64B64_SFLOAT = 118, VK_FORMAT_R64G64B64A64_UINT = 119, VK_FORMAT_R64G64B64A64_SINT = 120, VK_FORMAT_R64G64B64A64_SFLOAT = 121, VK_FORMAT_B10G11R11_UFLOAT_PACK32 = 122, VK_FORMAT_E5B9G9R9_UFLOAT_PACK32 = 123, VK_FORMAT_D16_UNORM = 124, VK_FORMAT_X8_D24_UNORM_PACK32 = 125, VK_FORMAT_D32_SFLOAT = 126, VK_FORMAT_S8_UINT = 127, VK_FORMAT_D16_UNORM_S8_UINT = 128, VK_FORMAT_D24_UNORM_S8_UINT = 129, VK_FORMAT_D32_SFLOAT_S8_UINT = 130, VK_FORMAT_BC1_RGB_UNORM_BLOCK = 131, VK_FORMAT_BC1_RGB_SRGB_BLOCK = 132, VK_FORMAT_BC1_RGBA_UNORM_BLOCK = 133, VK_FORMAT_BC1_RGBA_SRGB_BLOCK = 134, VK_FORMAT_BC2_UNORM_BLOCK = 135, VK_FORMAT_BC2_SRGB_BLOCK = 136, VK_FORMAT_BC3_UNORM_BLOCK = 137, VK_FORMAT_BC3_SRGB_BLOCK = 138, VK_FORMAT_BC4_UNORM_BLOCK = 139, VK_FORMAT_BC4_SNORM_BLOCK = 140, VK_FORMAT_BC5_UNORM_BLOCK = 141, VK_FORMAT_BC5_SNORM_BLOCK = 142, VK_FORMAT_BC6H_UFLOAT_BLOCK = 143, VK_FORMAT_BC6H_SFLOAT_BLOCK = 144, VK_FORMAT_BC7_UNORM_BLOCK = 145, VK_FORMAT_BC7_SRGB_BLOCK = 146, VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK = 147, VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK = 148, VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK = 149, VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK = 150, VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK = 151, VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK = 152, VK_FORMAT_EAC_R11_UNORM_BLOCK = 153, VK_FORMAT_EAC_R11_SNORM_BLOCK = 154, VK_FORMAT_EAC_R11G11_UNORM_BLOCK = 155, VK_FORMAT_EAC_R11G11_SNORM_BLOCK = 156, VK_FORMAT_ASTC_4x4_UNORM_BLOCK = 157, VK_FORMAT_ASTC_4x4_SRGB_BLOCK = 158, VK_FORMAT_ASTC_5x4_UNORM_BLOCK = 159, VK_FORMAT_ASTC_5x4_SRGB_BLOCK = 160, VK_FORMAT_ASTC_5x5_UNORM_BLOCK = 161, VK_FORMAT_ASTC_5x5_SRGB_BLOCK = 162, VK_FORMAT_ASTC_6x5_UNORM_BLOCK = 163, VK_FORMAT_ASTC_6x5_SRGB_BLOCK = 164, VK_FORMAT_ASTC_6x6_UNORM_BLOCK = 165, VK_FORMAT_ASTC_6x6_SRGB_BLOCK = 166, VK_FORMAT_ASTC_8x5_UNORM_BLOCK = 167, VK_FORMAT_ASTC_8x5_SRGB_BLOCK = 168, VK_FORMAT_ASTC_8x6_UNORM_BLOCK = 169, VK_FORMAT_ASTC_8x6_SRGB_BLOCK = 170, VK_FORMAT_ASTC_8x8_UNORM_BLOCK = 171, VK_FORMAT_ASTC_8x8_SRGB_BLOCK = 172, VK_FORMAT_ASTC_10x5_UNORM_BLOCK = 173, VK_FORMAT_ASTC_10x5_SRGB_BLOCK = 174, VK_FORMAT_ASTC_10x6_UNORM_BLOCK = 175, VK_FORMAT_ASTC_10x6_SRGB_BLOCK = 176, VK_FORMAT_ASTC_10x8_UNORM_BLOCK = 177, VK_FORMAT_ASTC_10x8_SRGB_BLOCK = 178, VK_FORMAT_ASTC_10x10_UNORM_BLOCK = 179, VK_FORMAT_ASTC_10x10_SRGB_BLOCK = 180, VK_FORMAT_ASTC_12x10_UNORM_BLOCK = 181, VK_FORMAT_ASTC_12x10_SRGB_BLOCK = 182, VK_FORMAT_ASTC_12x12_UNORM_BLOCK = 183, VK_FORMAT_ASTC_12x12_SRGB_BLOCK = 184, // Provided by VK_VERSION_1_1 VK_FORMAT_G8B8G8R8_422_UNORM = 1000156000, // Provided by VK_VERSION_1_1 VK_FORMAT_B8G8R8G8_422_UNORM = 1000156001, // Provided by VK_VERSION_1_1 VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM = 1000156002, // Provided by VK_VERSION_1_1 VK_FORMAT_G8_B8R8_2PLANE_420_UNORM = 1000156003, // Provided by VK_VERSION_1_1 VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM = 1000156004, // Provided by VK_VERSION_1_1 VK_FORMAT_G8_B8R8_2PLANE_422_UNORM = 1000156005, // Provided by VK_VERSION_1_1 VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM = 1000156006, // Provided by VK_VERSION_1_1 VK_FORMAT_R10X6_UNORM_PACK16 = 1000156007, // Provided by VK_VERSION_1_1 VK_FORMAT_R10X6G10X6_UNORM_2PACK16 = 1000156008, // Provided by VK_VERSION_1_1 VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16 = 1000156009, // Provided by VK_VERSION_1_1 VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16 = 1000156010, // Provided by VK_VERSION_1_1 VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16 = 1000156011, // Provided by VK_VERSION_1_1 VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16 = 1000156012, // Provided by VK_VERSION_1_1 VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16 = 1000156013, // Provided by VK_VERSION_1_1 VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16 = 1000156014, // Provided by VK_VERSION_1_1 VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16 = 1000156015, // Provided by VK_VERSION_1_1 VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16 = 1000156016, // Provided by VK_VERSION_1_1 VK_FORMAT_R12X4_UNORM_PACK16 = 1000156017, // Provided by VK_VERSION_1_1 VK_FORMAT_R12X4G12X4_UNORM_2PACK16 = 1000156018, // Provided by VK_VERSION_1_1 VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16 = 1000156019, // Provided by VK_VERSION_1_1 VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16 = 1000156020, // Provided by VK_VERSION_1_1 VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16 = 1000156021, // Provided by VK_VERSION_1_1 VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16 = 1000156022, // Provided by VK_VERSION_1_1 VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16 = 1000156023, // Provided by VK_VERSION_1_1 VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16 = 1000156024, // Provided by VK_VERSION_1_1 VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16 = 1000156025, // Provided by VK_VERSION_1_1 VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16 = 1000156026, // Provided by VK_VERSION_1_1 VK_FORMAT_G16B16G16R16_422_UNORM = 1000156027, // Provided by VK_VERSION_1_1 VK_FORMAT_B16G16R16G16_422_UNORM = 1000156028, // Provided by VK_VERSION_1_1 VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM = 1000156029, // Provided by VK_VERSION_1_1 VK_FORMAT_G16_B16R16_2PLANE_420_UNORM = 1000156030, // Provided by VK_VERSION_1_1 VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM = 1000156031, // Provided by VK_VERSION_1_1 VK_FORMAT_G16_B16R16_2PLANE_422_UNORM = 1000156032, // Provided by VK_VERSION_1_1 VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM = 1000156033, } VkFormat;

typedef enum VkSampleCountFlagBits { VK_SAMPLE_COUNT_1_BIT = 0x00000001, //指定逐像素1个sample VK_SAMPLE_COUNT_2_BIT = 0x00000002, //指定逐像素2个sample VK_SAMPLE_COUNT_4_BIT = 0x00000004, //指定逐像素4个sample VK_SAMPLE_COUNT_8_BIT = 0x00000008, //指定逐像素8个sample VK_SAMPLE_COUNT_16_BIT = 0x00000010, //指定逐像素16个sample VK_SAMPLE_COUNT_32_BIT = 0x00000020, //指定逐像素32个sample VK_SAMPLE_COUNT_64_BIT = 0x00000040, //指定逐像素64个sample } VkSampleCountFlagBits;

typedef enum VkAttachmentLoadOp { VK_ATTACHMENT_LOAD_OP_LOAD = 0, //指出在本render pass之前该image的内容需要被保留。针对depth/stencil的attachment,将会使用 VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT 的访问类型,针对 color的attachment,将会使用 VK_ACCESS_COLOR_ATTACHMENT_READ_BIT 的访问类型。 VK_ATTACHMENT_LOAD_OP_CLEAR = 1, //在一个render pass instance 开始的时候,指定该渲染范围内的内容将会被clear成一个uniform值。针对depth/stencil的attachment,将会使用 VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT. 的访问类型,针对 color的attachment,将会使用 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT 的访问类型。 VK_ATTACHMENT_LOAD_OP_DONT_CARE = 2, //指出该范围内之前的内容不需要被保留,会被设置为未定义。针对depth/stencil的attachment,将会使用 VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT. 的访问类型,针对 color的attachment,将会使用 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT 的访问类型。 } VkAttachmentLoadOp;

typedef enum VkAttachmentStoreOp { VK_ATTACHMENT_STORE_OP_STORE = 0, //指出render pass中渲染范围之内的内容将会被写入内存。针对depth/stencil的attachment,将会使用 VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT. 的访问类型,针对 color的attachment,将会使用 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT 的访问类型。 VK_ATTACHMENT_STORE_OP_DONT_CARE = 1, //指出渲染范围之内的内容在之后不再需要,可能会被discarded,内容会变成未定义。针对depth/stencil的attachment,将会使用 VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT. 的访问类型,针对 color的attachment,将会使用 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT 的访问类型。这个会导致之前render pass生成的内容还没写入内存之前,也被discarded,即使当前render pass没有对该attachment进行写操作。 } VkAttachmentStoreOp;

typedef struct VkSubpassDescription { VkSubpassDescriptionFlags flags; //a bitmask of VkSubpassDescriptionFlagBits ,标记subpass的usage VkPipelineBindPoint pipelineBindPoint; //一个类型为 VkPipelineBindPoint 的值,表明subpass支持的pipeline 类型,必须是 VK_PIPELINE_BIND_POINT_GRAPHICS uint32_t inputAttachmentCount; //input attachment的数量 const VkAttachmentReference* pInputAttachments; //一个指向 VkAttachmentReference 数组的指针,定义subpass的input attachment以及它们的layout。该数组中的每个元素都对应了ps中的一个input attachment index。比如,一个shader声明使用 InputAttachmentIndex 为X的image,则它使用 pInputAttachments[x]对应的attachment。Input Attachments必须以descriptor set 的形式 bound to a pipeline。如果 pInputAttachments 对应的该元素为 VK_ATTACHMENT_UNUSED,则应用程序一定不能读取相应input attachment index。PS可以使用subpass input variable来访问input attachment对应(x,y,layer)位置的内容 uint32_t colorAttachmentCount; //color attachment的数量 const VkAttachmentReference* pColorAttachments; //一个指向 VkAttachmentReference 数组的指针,定义subpass的color attachment以及它们的layout。必须小于 VkPhysicalDeviceLimits::maxColorAttachments 。该数组中的每个元素都对应shader中的一个output location。比如,一个shader声明一个output variable为X,则它使用 pColorAttachments[x]对应的attachment。如果 pColorAttachments 的对应元素的attachment 为 VK_ATTACHMENT_UNUSED。则在该位置写入的fragment将会被discard。 const VkAttachmentReference* pResolveAttachments; //一个可选的数组,包含 colorAttachmentCount 个 VkAttachmentReference类型元素的数组,定义subpass 的resolve attachment以及它们的layout。如果该值非NULL,则其每个元素都对应了 pColorAttachments 中对应index的每个元素,并对每个attachment定义一个multisample resolve操作。在每个subpass结束的时候,multisample resolve操作胡i读取subpass 的colorattachment,并将渲染范围内的像素 resolve 到resolve attachment 对应的像素位置,除非resolve attachment index为 VK_ATTACHMENT_UNUSED。 const VkAttachmentReference* pDepthStencilAttachment; //一个指向 VkAttachmentReference 结构体的指针,指定subpass 的depth/stencil attachment以及它的layout。如果该值为null,或者为VK_ATTACHMENT_UNUSED,它代表该subpass没有depth/stencil attachment。如果VkSubpassDescriptionDepthStencilResolve::pDepthStencilResolveAttachment不为null或者 VK_ATTACHMENT_UNUSED,则它对应了 pDepthStencilAttachment,然后根据 VkSubpassDescriptionDepthStencilResolve::depthResolveMode and VkSubpassDescriptionDepthStencilResolve::stencilResolveMode 定义multisample revole操作。在每个subpass结束的时候,multisample resolve 操作读取subpass的depth/stencil操作,逐像素的将结果resolve到resolve attachment。如果 VkSubpassDescriptionDepthStencilResolve::depthResolveMode 为 VK_RESOLVE_MODE_NONE ,则resolve attachment的depth component将不写入,保留原值,如果 VkSubpassDescriptionDepthStencilResolve::stencilResolveMode 为 VK_RESOLVE_MODE_NONE ,则resolve attachment的 stencil component将不写入,保留原值。如果 pDepthStencilResolveAttachment 的VkFormat不包含depth component,则忽略 VkSubpassDescriptionDepthStencilResolve::depthResolveMode。如果 pDepthStencilResolveAttachment 的VkFormat不包含 stencil component,则忽略 VkSubpassDescriptionDepthStencilResolve::stencilResolveMode。 uint32_t preserveAttachmentCount; //preserved attachments的数量 const uint32_t* pPreserveAttachments; //一个指向 preserveAttachmentCount 个render pass attachment的数组指针,指出当前subpass不使用,但是需要被保留的attachments。 } VkSubpassDescription;

如果以下情况发生,则attachment对应渲染范围内的内容,在subpass S开始的时候,将变成未定义:attachment在render pass作为color、depth/stencil、resolveattachment,S1 使用或者preserve该attachment,S1依赖S,attachment在subpass S中没有使用和preserved。

当该attachment内容未定义后,在整个subpass dependency chains中,从S开始,除非它被再次写入,否则将保持未定义。然而,它一直保持合法状态。

如果attachment在render pass中第一次使用是作为input attachment,则该attachment在该subpass中不能作为color、depth/stencil attachment,且loadOp必须不是 VK_ATTACHMENT_LOAD_OP_CLEAR

如果 pResolveAttachments 不是NULL或者 VK_ATTACHMENT_UNUSED,则对应的 color attachment 必须不是 VK_ATTACHMENT_UNUSED,且sample count必须不是 VK_SAMPLE_COUNT_1_BIT。且两者 VkFormat必须相同

如果 pResolveAttachments 不是NULL或者 VK_ATTACHMENT_UNUSED,其sample cont必须是 VK_SAMPLE_COUNT_1_BIT

所有非 VK_ATTACHMENT_UNUSED 的 pColorAttachments必须拥有相同的 sample count

P232。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。

typedef enum VkSubpassDescriptionFlagBits { //该类型的所有bits都是由extension定义,在spec中全部都没有开启。 } VkSubpassDescriptionFlagBits;

typedef enum VkPipelineBindPoint { VK_PIPELINE_BIND_POINT_GRAPHICS = 0, //指出binding是一个graphics pipeline VK_PIPELINE_BIND_POINT_COMPUTE = 1, //指出binding是一个compute pipeline } VkPipelineBindPoint;

typedef struct VkAttachmentReference { uint32_t attachment; //要么是一个int值,指定 VkRenderPassCreateInfo::pAttachments 对应index的attachment,要么是 VK_ATTACHMENT_UNUSED 指出该attachment 没有被使用,要么就是一个小于 attachmentCount 的值,代表 pAttachments 中的一个元素 VkImageLayout layout; //一个 VkImageLayout 值,用于指出在该subpass中,attachment的layout } VkAttachmentReference;

typedef enum VkImageLayout { VK_IMAGE_LAYOUT_UNDEFINED = 0, //指出layout为unknown。Image memory 不能被transition到这个layout。该layout可以被用于 VkImageCreateInfo 的initialLayout。在做layout transition的时候可以将image layout设置为这个,但是这样做的话,会导致image memory的内容变成未定义。 VK_IMAGE_LAYOUT_GENERAL = 1, //支持所有的device access type。 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL = 2, //必须只能用与VkFramebuffer中的color/resolve attachment。该layout只适用于打开 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT 标记的image的image subresources。 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL = 3, //指出一个可读写的depth/stencil image的depth和stencil的layout。相当于 VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL and VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL = 4, //指出一个只读的depth/stencil attachment或者shader中的一个sampled image,combined image/sampler或者input attachment的depth和stencil的layout。相当于 VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL and VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL = 5, //指出一个制度的layout,比如shader中的一个sampled image,combined image/sampler或者input attachment的layout。该layout只适用于开启 VK_IMAGE_USAGE_SAMPLED_BIT or VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT 的image的image subresources VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL = 6, //必须只能被用于作为一个transfer命令的source image。该layout只适用于开启 VK_IMAGE_USAGE_TRANSFER_SRC_BIT 的image 的image subresources。 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL = 7, //必须只能被用于作为一个transfer命令的destination image (参考 VK_PIPELINE_STAGE_TRANSFER_BIT )。该layout只适用于开启 VK_IMAGE_USAGE_TRANSFER_DST_BIT 的image 的image subresources。 VK_IMAGE_LAYOUT_PREINITIALIZED = 8, //指出image memory位于已定义的layout中,并且可以由数据填充,但尚未被driver初始化。image memory不能被traansition到这个layout。该layout可以被用于 VkImageCreateInfo 的initialLayout。该layout被用于由host写入其内容的图像的初始化layout,可以将数据直接写入内存,而不需要先执行一次layout transition。当前该值只能被用于 linear image,因为不存在为 VK_IMAGE_TILING_OPTIMAL 图像设计的标准layout。 // Provided by VK_VERSION_1_1 VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL = 1000117000,//指出一个可读写的 stencil attachment + 只读的depth attachment或者shader中的一个sampled image,combined image/sampler或者input attachment的layout。相当于 VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL and VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL // Provided by VK_VERSION_1_1 VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL = 1000117001,//指出一个可读写的 depth attachment + 只读的stencil attachment或者shader中的一个sampled image,combined image/sampler或者input attachment的layout。相当于 VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL and VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL // Provided by VK_VERSION_1_2 VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL = 1000241000, //指出一个可读写的depth attachment的depth layout。 // Provided by VK_VERSION_1_2 VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL = 1000241001, //指出一个只读的depth attachment或者shader中的一个sampled image,combined image/sampler或者input attachment的layout。 // Provided by VK_VERSION_1_2 VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL = 1000241002, //指出一个可读写的 stencil attachment的 stencil layout。 // Provided by VK_VERSION_1_2 VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL = 1000241003, //指出一个只读的 stencil attachment或者shader中的一个sampled image,combined image/sampler或者input attachment的layout。 } VkImageLayout;

typedef struct VkSubpassDependency { uint32_t srcSubpass; //为dependency中第一个subpass的index,必须小于 subpassCount, 或者 VK_SUBPASS_EXTERNAL uint32_t dstSubpass; //为dependency中第二个subpass的index,必须小于 subpassCount, 或者 VK_SUBPASS_EXTERNAL VkPipelineStageFlags srcStageMask; //a bitmask of VkPipelineStageFlagBits ,表示 source stage mask VkPipelineStageFlags dstStageMask; //a bitmask of VkPipelineStageFlagBits ,表示 destination stage mask VkAccessFlags srcAccessMask; //a bitmask of VkAccessFlagBits ,表示 source access mask VkAccessFlags dstAccessMask; //a bitmask of VkAccessFlagBits ,表示 destination access mask VkDependencyFlags dependencyFlags; //a bitmask of VkDependencyFlagBits } VkSubpassDependency;

typedef enum VkPipelineStageFlagBits { VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT = 0x00000001, //表示second synchronization scope中 VkAccessFlags设置为0的时候的 VK_PIPELINE_STAGE_ALL_COMMANDS_BIT 。当fire scope的时候对应no stage of execution。 VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT = 0x00000002, //表示Draw/DispatchIndirect/TraceRaysIndirect consumed 的pipeline stage VK_PIPELINE_STAGE_VERTEX_INPUT_BIT = 0x00000004, //表示VBO和IBO sonsumed的pipeline stage VK_PIPELINE_STAGE_VERTEX_SHADER_BIT = 0x00000008, //表示 vs 的 stage VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT = 0x00000010, //表示 tesselation control shader 的 stage VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT = 0x00000020, //表示 tesselation evaluation shader 的 stage VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT = 0x00000040, //表示 gs 的 stage VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT = 0x00000080, //表示 ps 的 stage VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT = 0x00000100, //表示early fragment test所在的pipeline stage(depth/stencil test before ps)。该stage还包含了一个:附带 depth/stencil format的framebuffer attachments的subpass load operation VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT = 0x00000200, //表示late fragment test所在的pipeline stage(depth/stencil test after ps)。该stage还包含了一个附带 depth/stencil format的framebuffer attachments的subpass store operation VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT = 0x00000400, //表示在blending之后,最终颜色被输出的pipeline stage。该stage还包含一个附带 color or depth/stencil format的framebuffer attachments的subpass load and store operation 和 multisample resolve oepration VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT = 0x00000800, //表示 cs 的 执行 VK_PIPELINE_STAGE_TRANSFER_BIT = 0x00001000, //包含如下命令:所有的copy command,比如vkCmdCopyQueryPoolResults、vkCmdBlitImage、vkCmdResolveImage,所有的clear command,with the exception of vkCmdClearAttachments VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT = 0x00002000, //表示一个虚拟stage:主机读写device memory。该stage不通过任何command buffer中录制的command 触发。 VK_PIPELINE_STAGE_HOST_BIT = 0x00004000, VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT = 0x00008000, //表示所有的graphics pipeline stage。也就是上述除了 VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT 、 VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT 、 VK_PIPELINE_STAGE_TRANSFER_BIT 、 VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT 、 VK_PIPELINE_STAGE_HOST_BIT 之外所有的stage VK_PIPELINE_STAGE_ALL_COMMANDS_BIT = 0x00010000, //表示queue上所有command出发的operation } VkPipelineStageFlagBits;

typedef enum VkAccessFlagBits { VK_ACCESS_INDIRECT_COMMAND_READ_BIT = 0x00000001, //表示indirect draw或者dispatch对应的command data的read access VK_ACCESS_INDEX_READ_BIT = 0x00000002, //表示index draw command的index buffer的read access,bound by vkCmdBindIndexBuffer VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT = 0x00000004, //表示draw command 对应的vertex buffer 的read access,bound by vkCmdBindVertexBuffers VK_ACCESS_UNIFORM_READ_BIT = 0x00000008, //uniform buffer的read access VK_ACCESS_INPUT_ATTACHMENT_READ_BIT = 0x00000010, //在render pass中的ps里面获取到input attachment的read access VK_ACCESS_SHADER_READ_BIT = 0x00000020, //storage buffer、physical storage buffer、uniform texel buffer、storage texel buffer、sampled image、storage image的read access VK_ACCESS_SHADER_WRITE_BIT = 0x00000040, //storage buffer、physical storage buffer、uniform texel buffer、storage texel buffer、sampled image、storage image的write access VK_ACCESS_COLOR_ATTACHMENT_READ_BIT = 0x00000080, //color attachment的read access,比如blending、logical operation或者特定的subpass的load操作 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT = 0x00000100, //在render pass或者特定subpass load and store操作中针对color、resolve、depth/stencil resolve attachment的write access VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT = 0x00000200, //在depth or stencil操作或者特定subpass load操作中针对depth/stencil的read access VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT = 0x00000400, //在depth or stencil操作或者特定subpass load and store操作中针对depth/stencil的write access VK_ACCESS_TRANSFER_READ_BIT = 0x00000800, //指定copy操作中对image或者buffer的read access VK_ACCESS_TRANSFER_WRITE_BIT = 0x00001000, //指定clear或者copy操作中,对image或者buffer的write access VK_ACCESS_HOST_READ_BIT = 0x00002000, //host操作中的read access。该类型不针对一个资源,而直接针对内存 VK_ACCESS_HOST_WRITE_BIT = 0x00004000, //host操作中的write access。该类型不针对一个资源,而直接针对内存 VK_ACCESS_MEMORY_READ_BIT = 0x00008000, //特指所有的read access。当它被使用的时候,相当于所有的read access都被设置了 VK_ACCESS_MEMORY_WRITE_BIT = 0x00010000, //特指所有的write access。当它被使用的时候,相当于所有的write access都被设置了 } VkAccessFlagBits;

typedef enum VkDependencyFlagBits { VK_DEPENDENCY_BY_REGION_BIT = 0x00000001, //特指该dependencies为framebuffer-local // Provided by VK_VERSION_1_1 VK_DEPENDENCY_DEVICE_GROUP_BIT = 0x00000004, //特指一个subpass有超过一个view // Provided by VK_VERSION_1_1 VK_DEPENDENCY_VIEW_LOCAL_BIT = 0x00000002, //特指dependencies为non-device-local dependency } VkDependencyFlagBits;

可能会出现的错误:VK_ERROR_OUT_OF_HOST_MEMORY、VK_ERROR_OUT_OF_DEVICE_MEMORY

在UE中的使用:VERIFYVULKANRESULT_EXPANDED(VulkanRHI::vkCreateRenderPass(Device.GetInstanceHandle(), this, VULKAN_CPU_ALLOCATOR, &Handle));//struct FVulkanRenderPassCreateInfo

VkResult vkCreateRenderPass2( VkDevice device, const VkRenderPassCreateInfo2* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkRenderPass* pRenderPass);

void vkDestroyRenderPass( VkDevice device, VkRenderPass renderPass, const VkAllocationCallbacks* pAllocator);

VkResult vkCreateFramebuffer( VkDevice device, const VkFramebufferCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkFramebuffer* pFramebuffer);

Render pass与framebuffers结合使用。Framebuffers关联一系列memory attachment,用于render pass instance

该API用于创建一个framebuffer

第一个输入参数,为用于创建framebuffer的logical device

第二个输入参数,为一个 VkFramebufferCreateInfo 的结构体,用于表明该framebuffer的属性

第三个输入参数,用于内存分配

第四个输入参数,用于获取生成的framebuffer

typedef struct VkFramebufferCreateInfo { VkStructureType sType; //当前结构体的类型,必须是 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO const void* pNext; //NULL,或者扩展该结构体的另外一个结构体,只能是 NULL 或者 VkFramebufferAttachmentsCreateInfo VkFramebufferCreateFlags flags; //a bitmask of VkFramebufferCreateFlagBits。必须是0或者 VkFramebufferCreateFlagBits 的合法组合。 如果 pCreateInfo->flags 不包括 VK_FRAMEBUFFER_CREATE_IMAGELESS_BIT ,且 attachmentCount 不为0,则 pCreateInfo->pAttachments 中的每个元素都必须已经在device创建好了。 VkRenderPass renderPass; //framebuffer 兼容的 a render pass uint32_t attachmentCount; //attachment的数量 const VkImageView* pAttachments; //一个指向 attachmentCount 个 VkImageView元素的数组,每个都对应着render pass instance中的attachment。如果flags为 VK_FRAMEBUFFER_CREATE_IMAGELESS_BIT,则该参数被忽略 uint32_t width; //width、height、layers定义了framebuffer的dimensions。如果render pass使用multiview,layers必须是1,每个attachment都需要数量超过subpass viewmask中最大值个layers。 uint32_t height; uint32_t layers; } VkFramebufferCreateInfo;

P270。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。

typedef enum VkFramebufferCreateFlagBits { // Provided by VK_VERSION_1_2 VK_FRAMEBUFFER_CREATE_IMAGELESS_BIT = 0x00000001, //表明不指定image view,仅通过 VkFramebufferAttachmentImageInfo 结构体提供attachment compatibility的信息。 } VkFramebufferCreateFlagBits;

typedef struct VkFramebufferAttachmentsCreateInfo { VkStructureType sType; //当前结构体的类型,必须是 VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENTS_CREATE_INFO const void* pNext; //NULL,或者扩展该结构体的另外一个结构体, uint32_t attachmentImageInfoCount; //下面要描述的 attachment的数量 const VkFramebufferAttachmentImageInfo* pAttachmentImageInfos; //一个指向 attachmentImageInfoCount 个 VkFramebufferAttachmentImageInfo 元素的数组,每个都描述了render pass instance中的一个对应attachment的属性 } VkFramebufferAttachmentsCreateInfo;

typedef struct VkFramebufferAttachmentImageInfo { VkStructureType sType; //当前结构体的类型,必须是 VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENT_IMAGE_INFO const void* pNext; //NULL,或者扩展该结构体的另外一个结构体,必须是NULL VkImageCreateFlags flags; //a bitmask of VkImageCreateFlagBits ,必须与framebuffer使用的image,创建的时候使用的 VkImageCreateInfo::flags 匹配。 VkImageUsageFlags usage; //a bitmask of VkImageUsageFlagBits ,必须与framebuffer使用的image,创建的时候使用的 VkImageCreateInfo::usage 匹配。必须不能为0 uint32_t width; //渲染使用的image view 的宽度 uint32_t height; //渲染使用的image view 的高度 uint32_t layerCount; uint32_t viewFormatCount; //pViewFormats数组的尺寸,必须与framebuffer使用的image,创建的时候使用的 VkImageFormatListCreateInfo::viewFormatCount 匹配。 const VkFormat* pViewFormats; //一个数组包含了所有的,再创建views of the image时的formats,必须与framebuffer使用的image,创建的时候使用的 VkImageFormatListCreateInfo::pViewFormats 匹配。 } VkFramebufferAttachmentImageInfo;

typedef enum VkImageCreateFlagBits { VK_IMAGE_CREATE_SPARSE_BINDING_BIT = 0x00000001, VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT = 0x00000002, VK_IMAGE_CREATE_SPARSE_ALIASED_BIT = 0x00000004, VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT = 0x00000008, VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT = 0x00000010, // Provided by VK_VERSION_1_1 VK_IMAGE_CREATE_ALIAS_BIT = 0x00000400, // Provided by VK_VERSION_1_1 VK_IMAGE_CREATE_SPLIT_INSTANCE_BIND_REGIONS_BIT = 0x00000040, // Provided by VK_VERSION_1_1 VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT = 0x00000020, // Provided by VK_VERSION_1_1 VK_IMAGE_CREATE_BLOCK_TEXEL_VIEW_COMPATIBLE_BIT = 0x00000080, // Provided by VK_VERSION_1_1 VK_IMAGE_CREATE_EXTENDED_USAGE_BIT = 0x00000100, // Provided by VK_VERSION_1_1 VK_IMAGE_CREATE_PROTECTED_BIT = 0x00000800, // Provided by VK_VERSION_1_1 VK_IMAGE_CREATE_DISJOINT_BIT = 0x00000200, } VkImageCreateFlagBits;

typedef enum VkImageUsageFlagBits { VK_IMAGE_USAGE_TRANSFER_SRC_BIT = 0x00000001, VK_IMAGE_USAGE_TRANSFER_DST_BIT = 0x00000002, VK_IMAGE_USAGE_SAMPLED_BIT = 0x00000004, VK_IMAGE_USAGE_STORAGE_BIT = 0x00000008, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT = 0x00000010, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT = 0x00000020, VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT = 0x00000040, VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT = 0x00000080, } VkImageUsageFlagBits;

typedef struct VkImageCreateInfo { VkStructureType sType; const void* pNext; VkImageCreateFlags flags; VkImageType imageType; VkFormat format; VkExtent3D extent; uint32_t mipLevels; uint32_t arrayLayers; VkSampleCountFlagBits samples; VkImageTiling tiling; VkImageUsageFlags usage; VkSharingMode sharingMode; uint32_t queueFamilyIndexCount; const uint32_t* pQueueFamilyIndices; VkImageLayout initialLayout; } VkImageCreateInfo;

typedef struct VkImageFormatListCreateInfo { VkStructureType sType; const void* pNext; uint32_t viewFormatCount; const VkFormat* pViewFormats; } VkImageFormatListCreateInfo;

可能会出现的错误:VK_ERROR_OUT_OF_HOST_MEMORY、VK_ERROR_OUT_OF_DEVICE_MEMORY

在UE中的使用:VERIFYVULKANRESULT_EXPANDED(VulkanRHI::vkCreateFramebuffer(Device.GetInstanceHandle(), &CreateInfo, VULKAN_CPU_ALLOCATOR, &Framebuffer));//FVulkanFramebuffer::FVulkanFramebuffer(..)

void vkDestroyFramebuffer( VkDevice device, VkFramebuffer framebuffer, const VkAllocationCallbacks* pAllocator);

该API用于删除一个framebuffer

第一个输入参数,为用于创建framebuffer的logical device

第二个输入参数,即将被删除的framebuffer

第三个输入参数,用于内存分配,如果创建的时候定义了 VkAllocationCallbacks,这里需要定义一个对应的。反之,这里必须是NULL

framebuffer关联的submitted comand都必须处于completed execution状态

		Host access to framebuffer must be externally synchronized
	
void vkCmdBeginRenderPass( VkCommandBuffer commandBuffer, const VkRenderPassBeginInfo* pRenderPassBegin, VkSubpassContents contents);

应用程序一次录制a render pass instance中一个subpass的command,在render pass instance开始的时候,迭代录制subpass的command,最后结束该render pass instance

该API用于开启一个render pass instance

第一个输入参数,为录制该command 的command buffer,必须处于recording state,且对应的pool必须支持graphics operation,必须是一个primary command buffer

第二个输入参数,为一个指向 VkRenderPassBeginInfo 结构体的指针,用于指定render pass和framebuffer

第三个输入参数,为一个 VkSubpassContents 指定第一个subpass中如何provide 该command

开启一个render pass instance后,command buffer就可以录制command 到该render pass的第一个subpass中了。

该command 必须被在render pass instance 之外被调用

typedef struct VkRenderPassBeginInfo { VkStructureType sType; //当前结构体的类型,必须是 const void* pNext; //NULL,或者扩展该结构体的另外一个结构体 VkRenderPass renderPass; //指定render pass VkFramebuffer framebuffer; //指定framebuffer,包含了render pass所用的attachment VkRect2D renderArea; //指定render pass instance的渲染范围 uint32_t clearValueCount; //pClearValues数组的长度 const VkClearValue* pClearValues; //一个包含 clearValueCount 个元素的数组,每个元素为一个针对每个attachment的 VkClearValue 值(当loadOp为 VK_ATTACHMENT_LOAD_OP_CLEAR,或者attachment有depth/stencil format,且 stencilLoadOp 为 VK_ATTACHMENT_LOAD_OP_CLEAR)。该数组与attachment的index一一对应。而只有需要clear 的attachment才有效,其他值都将被忽略 } VkRenderPassBeginInfo;

typedef enum VkSubpassContents { VK_SUBPASS_CONTENTS_INLINE = 0, //指定subpass中的内容会被录制到primary command buffer中,secondary command buffers 不会在subpass中执行。 VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS = 1, //指定内容将被记录在secondary command buffer中,会被primary command buffer调用。并且在vkCmdNextSubpass or vkCmdEndRenderPass 之前, vkCmdExecuteCommands 是command buffer中唯一有效的命令。 } VkSubpassContents;

在UE中的使用:VulkanRHI::vkCmdBeginRenderPass(CommandBufferHandle, &Info, contents);//FVulkanPrimaryCmdBuffer::BeginRenderPass(..)

Vulkan
		Host access to commandBuffer must be externally synchronized
		Host access to the VkCommandPool that commandBuffer was allocated from must be externally synchronized
	

void vkCmdBeginRenderPass2( VkCommandBuffer commandBuffer, const VkRenderPassBeginInfo* pRenderPassBegin, const VkSubpassBeginInfo* pSubpassBeginInfo);

void vkGetRenderAreaGranularity( VkDevice device, VkRenderPass renderPass, VkExtent2D* pGranularity);

void vkCmdNextSubpass( VkCommandBuffer commandBuffer, VkSubpassContents contents);

在一个subpass录制结束后,通过该API切换到render pass中的下一个subpass

第一个输入参数,为录制该command 的command buffer,必须处于recording state,且对应的pool必须支持graphics operation,必须是一个primary command buffer

第二个输入参数,为一个指向 VkRenderPassBeginInfo 结构体的指针,用于指定render pass和framebuffer

第三个输入参数,和 vkCmdBeginRenderPass 的参数一样,用来表明下一个 subpass 中如何provide 该command

当前subpass的index需要比render pass中subpass的数量-1。

该命令必须在一个render pass instance内部调用

当开启transform feedback的时候,不能录制该命令

Vulkan
		Host access to commandBuffer must be externally synchronized
		Host access to the VkCommandPool that commandBuffer was allocated from must be externally synchronized
	

void vkCmdNextSubpass2( VkCommandBuffer commandBuffer, const VkSubpassBeginInfo* pSubpassBeginInfo, const VkSubpassEndInfo* pSubpassEndInfo);

void vkCmdEndRenderPass( VkCommandBuffer commandBuffer);

该API用于在最后一个subpass 的command 录制完毕后,录制一个结束render pass instance的command

第一个输入参数,为录制该command 的command buffer,必须处于recording state,且对应的pool必须支持graphics operation,必须是一个primary command buffer

结束一个render pass instance会触发最后一个subpass的resolve multisample 操作

当前subpass的index要等于render pass中subpass的数量-1。

该命令必须在一个render pass instance内部调用

当开启transform feedback的时候,不能录制该命令

Vulkan
		Host access to commandBuffer must be externally synchronized
		Host access to the VkCommandPool that commandBuffer was allocated from must be externally synchronized
	

void vkCmdEndRenderPass2( VkCommandBuffer commandBuffer, const VkSubpassEndInfo* pSubpassEndInfo);

本节教程就到此结束,希望大家继续阅读我之后的教程。

谢谢大家,再见!


Framebuffer和graphics pipeline都是基于一个特指的render pass创建的。它们必须被用于该render pass,或者一个可兼容的renderpass

attachment refernce在如下情况下兼容:1.拥有相同的format和sample count,2.都是VK_ATTACHMENT_UNUSED,3.对应的point为NULL

2个attachment数组在如下情况下兼容:1.其中的每个attachment都是兼容的。如果数组长度不同,则少的attachment对应的缺失的attachment,会被认为是 VK_ATTACHMENT_UNUSED

2个render pass,只有当它们对应的color、input、resolve、depth/stencil attachment 兼容,才认为是兼容,除了一下情况:1.Initial and final image layout in attachment descriptions、2.Load and store operations in attachment descriptions、3.Image layout in attachment references

如果2个render pass只有一个subpsas,resolve atttachment是否兼容就不重要了。

A framebuffer is compatible with a render pass if it was created using the same render pass or a compatible render pass.


原创技术文章,撰写不易,转载请注明出处:电子设备中的画家|王烁 于 2021 年 5 月 10 日发表,原文链接(http://geekfaner.com/shineengine/blog18_Vulkanv1.2_4.html)