You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vulkan片段着色器无法向交换链图像输出内容求助

Vulkan动态渲染绘制三角形无输出问题

原本使用OpenGL,现在基于Vulkan 1.3的动态渲染功能搭建简易渲染器,从绘制基础三角形开始,但片段着色器始终没有输出,交换链一直显示清除色。

通过RenderDoc捕获到以下信息:

  • vkCmdDraw调用期间图形管线的光栅化器配置
  • 混合与深度状态参数
  • 捕获帧的API检查结果

RenderDoc显示顶点着色器运行正常,但无最终输出。已尝试禁用光栅化丢弃、禁用面剔除,调整混合状态,均无效果。

仅在搭载英伟达RTX 4060 Mobile的Arch系统(使用闭源驱动)上,代码能正常运行。

以下是主循环代码:

VkRenderingAttachmentInfo renderingAttachmentInfos {};
renderingAttachmentInfos.sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO;
renderingAttachmentInfos.clearValue.color = {{0.1f, 0.1f, 0.1f, 1.f}};
renderingAttachmentInfos.imageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
renderingAttachmentInfos.imageView = context.getSwapchain()->getImageViews()[imageIndex];
renderingAttachmentInfos.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
renderingAttachmentInfos.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
renderingAttachmentInfos.resolveMode = VK_RESOLVE_MODE_NONE;
renderingAttachmentInfos.resolveImageLayout = VK_IMAGE_LAYOUT_UNDEFINED;
renderingAttachmentInfos.resolveImageView = VK_NULL_HANDLE;

VkRenderingInfo renderingInfos {};
renderingInfos.sType = VK_STRUCTURE_TYPE_RENDERING_INFO;
renderingInfos.colorAttachmentCount = 1;
renderingInfos.pColorAttachments = &renderingAttachmentInfos;
renderingInfos.renderArea.offset = {0, 0};
renderingInfos.renderArea.extent = context.getSwapchain()->getExtent();
renderingInfos.layerCount = 1;
renderingInfos.viewMask = 0;

VkCommandBufferBeginInfo beginInfos {};
beginInfos.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
beginInfos.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
beginInfos.pInheritanceInfo = nullptr;
(void)vkBeginCommandBuffer(graphicsCommandBuffer, &beginInfos);

VkImageMemoryBarrier imageMemoryBarrier {};
imageMemoryBarrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
imageMemoryBarrier.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
imageMemoryBarrier.oldLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
imageMemoryBarrier.newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
imageMemoryBarrier.image = context.getSwapchain()->getImages()[imageIndex];
imageMemoryBarrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
imageMemoryBarrier.subresourceRange.levelCount = 1;
imageMemoryBarrier.subresourceRange.baseMipLevel = 0;
imageMemoryBarrier.subresourceRange.baseArrayLayer = 0;
imageMemoryBarrier.subresourceRange.layerCount = 1;
vkCmdPipelineBarrier(
    graphicsCommandBuffer,
    VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
    VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
    0, 0, nullptr, 0, nullptr, 1, &imageMemoryBarrier
);

vkCmdBeginRendering(graphicsCommandBuffer, &renderingInfos);

vkCmdBindPipeline(graphicsCommandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline.getPipeline());

VkViewport viewport {};
viewport.x = 0.f;
viewport.y = 0.f;
viewport.width = context.getSwapchain()->getExtent().width;
viewport.height = context.getSwapchain()->getExtent().height;
viewport.minDepth = 0.f;
viewport.maxDepth = 1.f;
vkCmdSetViewport(graphicsCommandBuffer, 0, 1, &viewport);

VkRect2D scissor {};
scissor.offset = {0, 0};
scissor.extent = context.getSwapchain()->getExtent();
vkCmdSetScissor(graphicsCommandBuffer, 0, 1, &scissor);

VkBuffer buffer {vertexBuffer.getBuffer()};
VkDeviceSize offset {vertexBufferView.getInfos().offset};
vkCmdBindVertexBuffers(graphicsCommandBuffer, 0, 1, &buffer, &offset);

vkCmdDraw(graphicsCommandBuffer, vertices.size() / 5, vertices.size() / 15, 0, 0);

vkCmdEndRendering(graphicsCommandBuffer);

imageMemoryBarrier = {};
imageMemoryBarrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
imageMemoryBarrier.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
imageMemoryBarrier.oldLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
imageMemoryBarrier.newLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
imageMemoryBarrier.image = context.getSwapchain()->getImages()[imageIndex];
imageMemoryBarrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
imageMemoryBarrier.subresourceRange.levelCount = 1;
imageMemoryBarrier.subresourceRange.baseMipLevel = 0;
imageMemoryBarrier.subresourceRange.baseArrayLayer = 0;
imageMemoryBarrier.subresourceRange.layerCount = 1;
vkCmdPipelineBarrier(
    graphicsCommandBuffer,
    VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
    VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
    0, 0, nullptr, 0, nullptr, 1, &imageMemoryBarrier
);

(void)vkEndCommandBuffer(graphicsCommandBuffer);


VkSubmitInfo submitInfos {};
VkPipelineStageFlags dstStageMask {VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT};
submitInfos.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
submitInfos.commandBufferCount = 1;
submitInfos.pCommandBuffers = &graphicsCommandBuffer;
submitInfos.waitSemaphoreCount = 1;
submitInfos.pWaitSemaphores = &imageReadySemaphore;
submitInfos.pWaitDstStageMask = &dstStageMask;
submitInfos.signalSemaphoreCount = 1;
submitInfos.pSignalSemaphores = &imageDrawnSemaphore;
(void)vkQueueSubmit(context.getDevice()->getQueue(se::renderer::vulkan::QueueType::eGraphics), 1, &submitInfos, previousFrameReadyFence);

VkSwapchainKHR swapchain {context.getSwapchain()->getSwapChain()};
VkPresentInfoKHR presentInfos {};
presentInfos.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
presentInfos.swapchainCount = 1;
presentInfos.pSwapchains = &swapchain;
presentInfos.pImageIndices = &imageIndex;
presentInfos.pResults = nullptr;
presentInfos.waitSemaphoreCount = 1;
presentInfos.pWaitSemaphores = &imageDrawnSemaphore;
(void)vkQueuePresentKHR(context.getDevice()->getQueue(se::renderer::vulkan::QueueType::ePresent), &presentInfos);

内容的提问来源于stack exchange,提问作者Dv Senna

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 04:42:33