vkCmdClearColorImage无法清除布局为

时间:2019-06-11 16:49:05

标签: c++ vulkan

我正在尝试清除屏幕,但是在调用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

2 个答案:

答案 0 :(得分:1)

您在第一个“从现在到清除”关卡中的srcStageVK_PIPELINE_STAGE_TRANSFER_BIT

仅当命令缓冲区与pWaitDstStageMask的{​​{1}}一起等待信号量一起提交时,这才是正确的,以便使该障碍物能够隔离信号量等待,以获取交换链图像信号。 / p>

答案 1 :(得分:1)

如果可以避免,请不要vkCmdClearColorImage();在许多体系结构(尤其是移动设备)上,在渲染过程中使用清晰的loadOp更为有效。