我尝试用vulkan api实现多线程渲染。我从其他线程构建了多个命令缓冲区。然后执行它们。但是由于在每个命令缓冲区中都有一个清晰的屏幕,所以我没有看到图片。
VkCommandBufferBeginInfo beginInfo{};
beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
VkRenderPassBeginInfo renderPassInfo{};
renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
renderPassInfo.renderPass = m_pRenderPass;
renderPassInfo.framebuffer = m_swapChainFrameBufferPtrs[m_nImageIndex];
renderPassInfo.renderArea.offset = { 0, 0 };
renderPassInfo.renderArea.extent = { m_nWidth, m_nHeight };
std::array<VkClearValue, 2> clearValues{};
clearValues[0].color = { {0.0f, 0.0f, 0.0f, 1.0f} };
clearValues[1].depthStencil = { 1.0f, 0 };
renderPassInfo.clearValueCount = static_cast<uint32_t>(clearValues.size());
renderPassInfo.pClearValues = clearValues.data();
VkViewport viewport{...};
VkRect2D scissor{...};
CFrameCommandBuffer& currentFrame = m_frames[m_nCurrentFrame];
for (std::uint32_t n = 0; n < currentFrame.m_commandBufferPtrs.size(); ++n)
{
auto& pCmdBuffer = currentFrame.m_commandBufferPtrs[n];
vkResetCommandBuffer(pCmdBuffer, 0);
vkBeginCommandBuffer(pCmdBuffer, &beginInfo);
vkCmdBeginRenderPass(pCmdBuffer, &renderPassInfo, VK_SUBPASS_CONTENTS_INLINE);
vkCmdSetViewport(pCmdBuffer, 0, 1, &viewport);
vkCmdSetScissor(pCmdBuffer, 0, 1, &scissor);
}
如果我不使用屏幕清除第二个和后续缓冲区
renderPassInfo.clearValueCount = 0;
renderPassInfo.pClearValues = nullptr;
我得到一个错误:
In vkCmdBeginRenderPass the VkRenderPassBeginInfo struct has a clearValueCount of 0 but there must be at least 2 entries in pClearValues array to account for the highest index attachment in VkRenderPass 0x1ebe0f000000012a[] that uses VK_ATTACHMENT_LOAD_OP_CLEAR is 2. Note that the pClearValues array is indexed by attachment number so even if some pClearValues entries between 0 and 1 correspond to attachments that aren't cleared they will be ignored.
如何在第一个命令缓冲区中正确清除屏幕?
调用vkCmdBeginRenderPass
时,需要一组值来清除渲染通道附件。
pClearValues
是指向clearValueCount
-VkClearValue
结构数组的指针,包含每个附件的明确值,如果附件使用loadOp
值为VK_ATTACHMENT_LOAD_OP_CLEAR
,或者如果附件具有深度/模板格式并使用stencilLoadOp
值为VK_ATTACHMENT_LOAD_OP_CLEAR
。该数组按附件编号索引。只使用与已清除附件相对应的元素。pClearValues
的其他元素被忽略。<一口>1归档一口>
在创建VkRenderPass
对象时,您指定了是否希望在VkRenderPassCreateInfo
结构中清除每个附件。如果你不想在渲染通道开始时清除附件,那么你需要将每个VkAttachmentDescription
的loadOp
设置为VK_ATTACHMENT_LOAD_OP_LOAD
。