使用查询测量片段着色器的时间

Measuring the time of the fragment shader with queries

我想使用查询系统来检索片段着色器的执行时间。

我正在创建一个包含两个时间戳查询的查询池,并且我正在使用 vkCmdWriteTimestamp

device.cmd_draw_indexed(draw_command_buffer, 6, 1, 0, 0, 1);
device.cmd_write_timestamp(
    draw_command_buffer,
    vk::PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT,
    query_pool,
    0,
);
device.cmd_write_timestamp(
    draw_command_buffer,
    vk::PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
    query_pool,
    1,
);
device.cmd_end_render_pass(draw_command_buffer);

我需要指定哪些流水线阶段才能仅跟踪片段着色器的时间?

vkCmdWriteTimestamp latches the value of the timer when all previous commands have completed executing as far as the specified pipeline stage, and writes the timestamp value to memory. When the timestamp value is written, the availability status of the query is set to available.

这是否包括指定的流水线阶段?例如,如果我指定 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,它会在片段着色器完成之前或之后锁定计时器吗?

我什么时候需要打电话给vkCmdWriteTimestamp?我注意到,如果对 vkCmdWriteTimestamp 的两次调用都直接在彼此之上,则生成的增量将接近 0。最初我认为调用它们时应该无关紧要,因为我指定了管道阶段。

您似乎误解了这些函数的作用。他们不会检测执行这些阶段所需的时间。他们检测系统在命令流中在那个点到达那个阶段需要多长时间。

也就是说,如果您使用 "EARLY_FRAGMENT_TESTS_BIT",您要问的问题是 "what is the time when all prior commands have finished executing up to the point when they're done with early fragment tests." "FRAGMENT_SHADER_BIT" 也是如此。这意味着它们之间的时间差实际上是 non-existent;这将是最后一个渲染命令的最后一个图元执行其片段着色器所花费的时间。

或者更糟的是,执行两个查询命令之间的时间。毕竟,它们不是 免费的

记住:渲染命令是流水线的。虽然一些图元正在进行早期片段测试,但其他图元是 运行 片段着色器,而其他图元仍然是 运行 post-FS 东西。等等。

时间戳,正如标准所说,用于"timing the execution of commands",而不是流水线阶段的执行。无法测量流水线阶段的执行时间。