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

Vulkan中图像兼作颜色与输入附件时的异常行为排查

Vulkan子通道自依赖下subpassLoad读取异常问题

我正尝试在片段着色器中实现颜色混合,将alpha通道用作后续绘制调用的动态模板缓冲区。具体做法是把交换链图像同时附加为输入附件和颜色附件,并在绘制调用间设置了子通道自依赖及管线屏障。

渲染通道依赖配置

const dependencies = [_]vk.SubpassDependency{ .{
    .src_subpass = vk.SUBPASS_EXTERNAL,
    .dst_subpass = 0,
    .src_stage_mask = .{ .color_attachment_output_bit = true },
    .dst_stage_mask = .{ .color_attachment_output_bit = true },
    .src_access_mask = .{},
    .dst_access_mask = .{ .color_attachment_write_bit = true },
    // .dependency_flags = .{ .by_region_bit = true },
}, .{
    .src_subpass = 0,
    .dst_subpass = 0,
    .src_stage_mask = .{ .color_attachment_output_bit = true },
    .dst_stage_mask = .{ .fragment_shader_bit = true, .color_attachment_output_bit = true },
    .src_access_mask = .{ .color_attachment_write_bit = true },
    .dst_access_mask = .{ .input_attachment_read_bit = true, .color_attachment_write_bit = true },
    .dependency_flags = .{ .by_region_bit = true },
} };

子通道描述

const subpasses = [_]vk.SubpassDescription{.{ 
    .pipeline_bind_point = .graphics,
    .input_attachment_count = 1,
    .p_input_attachments = &.{.{ .attachment = 0, .layout = .general }},
    .color_attachment_count = 1,
    .p_color_attachments = &.{.{ .attachment = 0, .layout = .general }},
}};

管线屏障代码

dev.cmdPipelineBarrier(
    cb,
    .{ .color_attachment_output_bit = true },
    .{ .fragment_shader_bit = true, .color_attachment_output_bit = true },
    .{ .by_region_bit = true },
    0,
    undefined,
    0,
    undefined,
    1,
    &.{.{ 
        .src_access_mask = .{ .color_attachment_write_bit = true },
        .dst_access_mask = .{ .input_attachment_read_bit = true, .color_attachment_write_bit = true },
        .old_layout = .general,
        .new_layout = .general,
        .src_queue_family_index = vk.QUEUE_FAMILY_IGNORED,
        .dst_queue_family_index = vk.QUEUE_FAMILY_IGNORED,
        .image = image,
        .subresource_range = .{
            .aspect_mask = .{ .color_bit = true },
            .base_mip_level = 0,
            .level_count = 1,
            .base_array_layer = 0,
            .layer_count = 1,
        },
    }},
);

其中image为交换链图像,我在绘制调用之间及首次绘制前调用该屏障,以与渲染通道清除操作同步。

异常现象

调试片段着色器时发现,subpassLoad()竟返回绘制后的最终颜色(仿佛“预知未来”):

  • 首次绘制前清除操作将像素设为(1,1,1,1),但subpassLoad()返回(1,1,1,0)(绘制后的值)
  • 第二次绘制时,subpassLoad()读取到本次绘制后的结果,导致输出不符合预期

已尝试的排查手段

  • 将绘制调用拆分到不同渲染通道实例
  • 修改屏障参数(最初版本的dst_access_mask不含.color_attachment_write_bit)
  • 在不同Mesa驱动设备测试(Intel集成显卡、AMD独立显卡)

Vulkan验证层(核心、同步、GPUAV)未报错,RenderDoc捕获中像素历史的“Tex Before”值与subpassLoad()返回值不符。

内容的提问来源于stack exchange,提问作者Jim Morrison

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.12 04:03:17