我正在尝试清除屏幕,但是在调用vkCmdClearColorImage()时出现错误。它(验证层)报告当前图像布局为VK_IMAGE_LAYOUT_PRESENT_SRC_KHR,而vkCmdClearColorImage使用VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL(这是应该使用的布局)
我检查了一下,以确保VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL在交换链创建中可用(确实如此)。当我结束命令缓冲区记录时,出现异常。
这是命令缓冲区记录
VkCommandBufferAllocateInfo allocationInfo = {};
allocationInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
allocationInfo.commandPool = m_ContextPtr->commandPool;
allocationInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
allocationInfo.commandBufferCount = (uint32_t)commandBuffers.size();
VkCommandBufferBeginInfo beginInfo = {};
beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
beginInfo.flags = VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT;
beginInfo.pInheritanceInfo = nullptr;
if (vkAllocateCommandBuffers(m_ContextPtr->device, &allocationInfo, commandBuffers.data()) != VK_SUCCESS)
Utils::Logger::logMSG("Failed to allocate command buffers\n", "Rendering", Utils::Severity::Error);
uint32_t presentQueueFamily = VulkanPhysicalDevice::getQueueFamilyIndices(m_CurrentWindow->m_Surface, m_ContextPtr->mainPhysicalDevice.physicalDevice).presentFamily;
VkClearColorValue clearColor = { m_ClearValue.x, m_ClearValue.y, m_ClearValue.z, 1.0f };
VkImageSubresourceRange subResourceRange = {};
subResourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
subResourceRange.baseMipLevel = 0;
subResourceRange.levelCount = 1;
subResourceRange.baseArrayLayer = 0;
subResourceRange.layerCount = 1;
for (size_t i = 0; i < commandBuffers.size(); i++)
{
VkImageMemoryBarrier presentToClearBarrier = {};
presentToClearBarrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
presentToClearBarrier.srcAccessMask = VK_ACCESS_MEMORY_READ_BIT;
presentToClearBarrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
presentToClearBarrier.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED;
presentToClearBarrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
presentToClearBarrier.srcQueueFamilyIndex = presentQueueFamily;
presentToClearBarrier.dstQueueFamilyIndex = presentQueueFamily;
presentToClearBarrier.image = m_CurrentWindow->m_SwapChain.swapChainImages[i];
presentToClearBarrier.subresourceRange = subResourceRange;
VkImageMemoryBarrier clearToPresentBarrier = {};
presentToClearBarrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
presentToClearBarrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
presentToClearBarrier.dstAccessMask = VK_ACCESS_MEMORY_READ_BIT;
presentToClearBarrier.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
presentToClearBarrier.newLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
presentToClearBarrier.srcQueueFamilyIndex = presentQueueFamily;
presentToClearBarrier.dstQueueFamilyIndex = presentQueueFamily;
presentToClearBarrier.image = m_CurrentWindow->m_SwapChain.swapChainImages[i];
presentToClearBarrier.subresourceRange = subResourceRange;
vkBeginCommandBuffer(commandBuffers[i], &beginInfo);
vkCmdPipelineBarrier
(
commandBuffers[i],
VK_PIPELINE_STAGE_TRANSFER_BIT,
VK_PIPELINE_STAGE_TRANSFER_BIT,
0, 0, nullptr, 0, nullptr, 1,
&presentToClearBarrier
);
vkCmdClearColorImage
(
commandBuffers[i],
m_CurrentWindow->m_SwapChain.swapChainImages[i],
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
&clearColor, 1,
&subResourceRange
);
vkCmdPipelineBarrier
(
commandBuffers[i],
VK_PIPELINE_STAGE_TRANSFER_BIT,
VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
0, 0, nullptr, 0, nullptr, 1,
&clearToPresentBarrier
);
if (vkEndCommandBuffer(commandBuffers[i]) != VK_SUCCESS)
Utils::Logger::logMSG("Failed to record command buffer\n", "Rendering", Utils::Severity::Error);
}
应该将屏幕清除为特定的颜色。 这是我从验证中得到的错误
vkCmdClearColorImage(): Cannot clear an image whose layout is
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL and doesn't match the current layout
VK_IMAGE_LAYOUT_PRESENT_SRC_KHR
答案 0 :(得分:1)
您在第一个“从现在到清除”关卡中的srcStage
是VK_PIPELINE_STAGE_TRANSFER_BIT
。
仅当命令缓冲区与pWaitDstStageMask
的{{1}}一起等待信号量一起提交时,这才是正确的,以便使该障碍物能够隔离信号量等待,以获取交换链图像信号。 / p>
答案 1 :(得分:1)
如果可以避免,请不要vkCmdClearColorImage()
;在许多体系结构(尤其是移动设备)上,在渲染过程中使用清晰的loadOp
更为有效。