7.4. Render Pass 命令
应用程序按照每个subpass记录一个命令到render pass实例,从render pass开始迭代,遍历subpass并记录命令到subpass, 直到render pass对象结束。
可以调用如下命令来开始一个render pass实例:
void vkCmdBeginRenderPass(
VkCommandBuffer commandBuffer,
const VkRenderPassBeginInfo* pRenderPassBegin,
VkSubpassContents contents);
-
commandBuffer
是记录命令的命令缓冲区。 -
pRenderPassBegin
是一个指针,指向了一个VkRenderPassBeginInfo
实例(下有定义),它指明了要开启的render pass,和实例使用的帧缓冲区。 -
contents
指定了第一个subpass中的命令是如何提供的,需为以下值之一:typedef enum VkSubpassContents { VK_SUBPASS_CONTENTS_INLINE = 0, VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS = 1, } VkSubpassContents;
如果
contents
是VK_SUBPASS_CONTENTS_INLINE
,subpass的内容将被嵌入记录到主命令缓冲区, 次命令缓冲区不能在subpass内执行。 如果contents
是VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS
,内容将被记录到被主缓冲区调用的 次命令缓冲区,vkCmdExecuteCommands
是唯一的有效命令,直到vkCmdNextSubpass
或者vkCmdEndRenderPass
。
一个render pass实例开始后,命令缓冲区就准备好了记录命令到该render pass的第一个subpass。
VkRenderPassBeginInfo
结构定义如下:
typedef struct VkRenderPassBeginInfo {
VkStructureType sType;
const void* pNext;
VkRenderPass renderPass;
VkFramebuffer framebuffer;
VkRect2D renderArea;
uint32_t clearValueCount;
const VkClearValue* pClearValues;
} VkRenderPassBeginInfo;
-
sType
是本数据结构的类型。 -
pNext
为NULL
或者指向拓展特定结构的指针。 -
renderPass
是开始记录的render pass对象 。 -
framebuffer
是包含被用于render pass的附件的帧缓冲区。 -
renderArea
是被render pass实例影响的渲染区域,下方有详细描述。 -
clearValueCount
pClearValues
数组中元素的个数。 -
pClearValues
是一个VkClearValue
类型的数组,包含了每一个附件需要清除的值,如果附件使用了VK_ATTACHMENT_LOAD_OP_CLEAR
的loadOp
值,或者附件拥有深度/挡板格式并使用VK_ATTACHMENT_LOAD_OP_CLEAR
的stencilLoadOp
值。只有对应的呗清除了附件的元素才能被使用。pClearValues
中其他的元素被忽略。
renderArea
是被render pass实例影响的渲染区域。 附件load,store和多采样解析操作的效果被限制到所有附件的像素x和y坐标所限定的区域。 render aera拓展到 framebuffer
的所有层。 应用程序必须保证所有的渲染都在这个render area,否则在此范围之外的像素就是未定义的, 或着色器副作用也许出现在此范围外的fragment(若有必要,需使用scissor)。 render area 必须包含在帧缓冲区维度的中。
注意
当render area比帧缓冲区小的时候会造成性能损失,除非它和render pass的render area粒度。 |
可调用如下命令来查询render area的粒度:
void vkGetRenderAreaGranularity(
VkDevice device,
VkRenderPass renderPass,
VkExtent2D* pGranularity);
-
device
是拥有该render pass的逻辑设备。 -
renderPass
是 render pass 的handle。 -
pGranularity
指向一个VkExtent2D
数据结构,它接受返回的粒度。
The conditions leading to an optimal renderArea
are:
-
the
offset.x
member inrenderArea
is a multiple of thewidth
member of the returnedVkExtent2D
(the horizontal granularity). -
the
offset.y
member inrenderArea
is a multiple of theheight
of the returnedVkExtent2D
(the vertical granularity). -
either the
offset.width
member inrenderArea
is a multiple of the horizontal granularity oroffset.x
+offset.width
is equal to thewidth
of theframebuffer
in theVkRenderPassBeginInfo
. -
either the
offset.height
member inrenderArea
is a multiple of the vertical granularity oroffset.y
+offset.height
is equal to theheight
of theframebuffer
in theVkRenderPassBeginInfo
.
Subpass dependencies不受render area的影响,并且应用到附属到帧缓冲区的整个图像子资源。 同样的,即使它们的效果拓展到了render area外,管线屏障依然有效。
To transition to the next subpass in the render pass instance after recording the commands for a subpass, call:
void vkCmdNextSubpass(
VkCommandBuffer commandBuffer,
VkSubpassContents contents);
-
commandBuffer
is the command buffer in which to record the command. -
contents
specifies how the commands in the next subpass will be provided, in the same fashion as the corresponding parameter ofvkCmdBeginRenderPass
.
The subpass index for a render pass begins at zero when vkCmdBeginRenderPass
is recorded, and increments each timevkCmdNextSubpass
is recorded.
Moving to the next subpass automatically performs any multisample resolve operations in the subpass being ended. End-of-subpass multisample resolves are treated as color attachment writes for the purposes of synchronization. That is, they are considered to execute in the VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
pipeline stage and their writes are synchronized with VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT
. Synchronization between rendering within a subpass and any resolve operations at the end of the subpass occurs automatically, without need for explicit dependencies or pipeline barriers. However, if the resolve attachment is also used in a different subpass, an explicit dependency is needed.
After transitioning to the next subpass, the application can record the commands for that subpass.
可调用如下命令来在为最后一个subpass记录命令时记录一个命令来完成render pass实例:
void vkCmdEndRenderPass(
VkCommandBuffer commandBuffer);
-
commandBuffer
是将结束当前render pass实例的命令缓冲区。
Ending a render pass instance performs any multisample resolve operations on the final subpass.