Vulkan 验证层 VkCmdWaitEvents srcStageMask 错误含义

Vulkan validation layers VkCmdWaitEvents srcStageMask error meaning

事件由具有 VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT 阶段掩码的同一队列上的另一个 cmd 缓冲区发出信号。

事件不是通过主机上的vkSetEvent发出信号。

事件由 vkCmdWaitEvents 使用 src 阶段掩码 VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT 和 dst 阶段掩码 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT.

等待

深度附件写入和阅读后的颜色附件是否正确?

验证层回调消息:

Submitting cmdbuffer with call to VkCmdWaitEvents using srcStageMask 0x200 which must be the 
bitwise OR of the stageMask parameters used in calls to vkCmdSetEvent and 
VK_PIPELINE_STAGE_HOST_BIT if used with vkSetEvent but instead is 0x0. The Vulkan spec 
states: srcStageMask must be a valid combination of VkPipelineStageFlagBits values 
(https://www.khronos.org/registry/vulkan/specs/1.1-extensions/html/vkspec.html#VUID-
vkCmdWaitEvents-srcStageMask-parameter)

实际上是说 "submitted value is 0x200, but is 0x0"。 这是一个错误吗? 0x0的值从哪里来,怎么会同时是0x200和0x0?


一些代码

深度缓冲区渲染通过后的信号:

cmd.cmd_event_set_signaled(cmd_data.event<EventId::SHADOW_MAP>(),
                           vkw::StageFlag::LATE_FRAGMENT_TESTS);

在主渲染通过另一个 cmd 之前等待:

vkw::StageMaskChange stage_masks;
stage_masks.src = vkw::StageFlag::LATE_FRAGMENT_TESTS;
stage_masks.dst = vkw::StageFlag::FRAGMENT_SHADER;
auto &shadow_map_event = cmd_data.event<EventId::SHADOW_MAP>();
cmd.cmd_event_wait(shadow_map_event, stage_masks);
cmd.cmd_event_set_unsignaled(shadow_map_event, stage_masks.dst);

包装代码。有一些 C++ 类型转换魔术,但值正确传递给 vkCmd 函数。

void cmd_event_set_signaled(Event e, StageMask stage_mask) {
    vkCmdSetEvent(*this, e, stage_mask);
}
void cmd_event_set_unsignaled(Event e, StageMask stage_mask) {
    vkCmdResetEvent(*this, e, stage_mask);
}
void cmd_event_wait(Events es, StageMaskChange smc) {
    vkCmdWaitEvents(*this, es.count32(), &es.begin()->p_vk, smc.src, smc.dst,
                    0, {}, 0, {}, 0, {});
}

在消息中,一个引用 vkCmdWaitEvents 中使用的管道阶段,另一个引用传递给 vkCmdSetEvent 的阶段。

该问题在 VulkanSDK 1.2.131.2 中不存在,因此 vulkan-loader-1.1.125 有点过时了。