vkCmdBlitImage到Frambuffer,然后绘制UI:UI闪烁

时间:2018-07-16 09:12:12

标签: vulkan

我正在制作一个Vulkan(LWJGL)应用程序,该应用程序将直接绘制到帧缓冲区图像上。没有顶点或片段着色器,只有一些计算着色器来构建图像,我直接将其着色为FrameBuffer图像。一切正常。

现在,我尝试在此之上渲染UI(imgui),但我认为我有一些同步麻烦:UI有时会闪烁(blit可能尚未结束?)。该渲染在几秒钟内将是完美的,但迟早UI可能会在一帧内消失。我只生成一次渲染过程,对于此测试,我不会多次记录命令缓冲区,因此我认为问题是在记录命令缓冲区时发生的。

问题可能出在UI开始绘制时vkCmdBlitImage仍在运行吗? 我试图在blit和UI渲染之间添加一些障碍,但是问题仍然存在。

我想我真的很想念什么,所以我请求您的帮助。我在这里放置了我认为相关的代码,但请随时询问更多代码。

CommandBuffer的记录:

for (int i = 0; i < commandBuffers.size(); i++)
{
    RenderCommandBuffer commandBuffer = commandBuffers.get(i);
    ImageView imageView = configuration.imageViewManager.getImageViews().get(i);

    commandBuffer.startCommand();

    copyPixelBufferToFB(commandBuffer, imageView);

    commandBuffer.startRenderPass();

    imGui.drawFrame(commandBuffer.getVkCommandBuffer());

    commandBuffer.endRenderPass();
    commandBuffer.endCommand();
}

copyPixelBufferToFB方法:

Extent2D extent = context.swapChainManager.getExtent();
ImageView dstImageView = context.imageViewManager.getImageViews().get(commandBuffer.id);

// Intend to blit from this image, set the layout accordingly
// Prepare transfer from Image to Frambuffer
ImageBarrier barrier = new ImageBarrier(VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
        VK_PIPELINE_STAGE_TRANSFER_BIT);
barrier.addImageBarrier(srcImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
        VK_ACCESS_TRANSFER_READ_BIT);
barrier.addImageBarrier(dstImageView.getImageId(), dstImageView.getImageFormat(), 1, 0,
        VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 0, VK_ACCESS_TRANSFER_WRITE_BIT);

barrier.execute(commandBuffer.getVkCommandBuffer());

long bltSrcImage = srcImage.getId();
long bltDstImage = dstImageView.getImageId();

VkImageBlit.Buffer region = VkImageBlit.calloc(1);
region.srcSubresource().aspectMask(VK_IMAGE_ASPECT_COLOR_BIT);
region.srcSubresource().mipLevel(0);
region.srcSubresource().baseArrayLayer(0);
region.srcSubresource().layerCount(1);
region.srcOffsets(0).x(0);
region.srcOffsets(0).y(0);
region.srcOffsets(0).z(0);
region.srcOffsets(1).x(srcImage.getWidth());
region.srcOffsets(1).y(srcImage.getHeight());
region.srcOffsets(1).z(1);
region.dstSubresource().aspectMask(VK_IMAGE_ASPECT_COLOR_BIT);
region.dstSubresource().mipLevel(0);
region.dstSubresource().baseArrayLayer(0);
region.dstSubresource().layerCount(1);
region.dstOffsets(0).x(0);
region.dstOffsets(0).y(0);
region.dstOffsets(0).z(0);
region.dstOffsets(1).x(extent.getWidth());
region.dstOffsets(1).y(extent.getHeight());
region.dstOffsets(1).z(1);

vkCmdBlitImage(commandBuffer.getVkCommandBuffer(), bltSrcImage,
        VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, bltDstImage,
        VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, region, VK_FILTER_NEAREST);


// Change layout again before render pass.
ImageBarrier barrierEnd = new ImageBarrier(VK_PIPELINE_STAGE_TRANSFER_BIT,
        VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
barrierEnd.addImageBarrier(srcImage, VK_IMAGE_LAYOUT_GENERAL, VK_ACCESS_SHADER_WRITE_BIT);
barrierEnd.addImageBarrier(dstImageView.getImageId(), dstImageView.getImageFormat(), 1,
        VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
        VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_SHADER_WRITE_BIT);

barrierEnd.execute(commandBuffer.getVkCommandBuffer());

我如何提交CommandBuffer,诸如此类:

bWaitSemaphores.put(waitSemaphore.getId());
bwaitStage.put(VK_PIPELINE_STAGE_TRANSFER_BIT);
pCommandBuffers.put(commandBuffer.getVkCommandBuffer());

submitInfo = VkSubmitInfo.calloc();
submitInfo.sType(VK_STRUCTURE_TYPE_SUBMIT_INFO);
submitInfo.waitSemaphoreCount(bWaitSemaphores.size());
submitInfo.pWaitSemaphores(bWaitSemaphores);
submitInfo.pWaitDstStageMask(bwaitStage);
submitInfo.pCommandBuffers(pCommandBuffers);

[...]
vkQueueSubmit(queue, submitInfo, VK_NULL_HANDLE);

RenderPass的创建:

VkAttachmentDescription colorAttachment = VkAttachmentDescription.calloc();
colorAttachment.format(context.swapChainManager.getColorDomain().getColorFormat());
colorAttachment.samples(VK_SAMPLE_COUNT_1_BIT);
colorAttachment.loadOp(VK_ATTACHMENT_LOAD_OP_LOAD);
colorAttachment.storeOp(VK_ATTACHMENT_STORE_OP_STORE);
colorAttachment.stencilLoadOp(VK_ATTACHMENT_LOAD_OP_DONT_CARE);
colorAttachment.stencilStoreOp(VK_ATTACHMENT_STORE_OP_DONT_CARE);
colorAttachment.initialLayout(VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
colorAttachment.finalLayout(VK_IMAGE_LAYOUT_PRESENT_SRC_KHR);

VkAttachmentReference.Buffer colorAttachmentRef = VkAttachmentReference.calloc(1);
colorAttachmentRef.attachment(0);
colorAttachmentRef.layout(VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);

VkSubpassDescription.Buffer subpass = VkSubpassDescription.calloc(1);
subpass.pipelineBindPoint(VK_PIPELINE_BIND_POINT_GRAPHICS);
subpass.colorAttachmentCount(1);
subpass.pColorAttachments(colorAttachmentRef);

VkSubpassDependency.Buffer dependency = VkSubpassDependency.calloc(1);
dependency.srcSubpass(VK_SUBPASS_EXTERNAL);
dependency.dstSubpass(0);
dependency.srcStageMask(VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT);
dependency.dstStageMask(VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT);
dependency.srcAccessMask(0);
dependency.dstAccessMask(
        VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT);

int attachmentCount = 1;
VkAttachmentDescription.Buffer attachments = VkAttachmentDescription
        .calloc(attachmentCount);
attachments.put(colorAttachment);
attachments.flip();

VkRenderPassCreateInfo renderPassInfo = VkRenderPassCreateInfo.calloc();
renderPassInfo.sType(VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO);
renderPassInfo.pAttachments(attachments);
renderPassInfo.pSubpasses(subpass);
renderPassInfo.pDependencies(dependency);

long[] aRenderPass = new long[1];
if (vkCreateRenderPass(logicalDevice.getVkDevice(), renderPassInfo, null,
        aRenderPass) != VK_SUCCESS)
{
    throw new AssertionError("Failed to create render pass!");
}
renderPass = aRenderPass[0];

编辑12/12/2018:

上面的代码中的imGui.drawFrame()无关紧要,我将gui从ImGui更改为Nuklear,并完全重写了gui管道。不幸的是,出现了同样的问题。 但是,我仍在使用vkCmdDrawIndexed来绘制它。

0 个答案:

没有答案