在 WebGPU 中,您可以在多个帧中重复使用相同的渲染通道吗?

In WebGPU, can you reuse the same render pass in multiple frames?

在 WebGPU 中,您可以通过定义其描述符来创建渲染通道:

const renderPassDesc: GPURenderPassDescriptor = {
  colorAttachments: [
    {
      view: context.getCurrentTexture().createView(),
      loadValue: [0.2, 0.3, 0.5, 1],
      storeOp: "store"
    }
  ]
};

然后运行它通过命令编码器开始记录。

const commandEncoder = device.createCommandEncoder();
const renderPass = commandEncoder.beginRenderPass(renderPassDesc);

所以,从本质上讲,看来您需要当前纹理才能开始记录(即,如果不调用 context.getCurrentTexture().createView(),您将无法创建描述符,没有它,您无法开始录制)。但是 API 似乎表明 纹理可以在每一帧改变 (请注意,即使在几个月前也是如此,当时 API 是不同的并且您将从交换链中检索纹理)。所以,基本上,似乎你不能在不同的帧中重复使用渲染通道(当然除非你不渲染到交换链,而是瞄准屏幕外纹理)。

那么,问题来了。 在 WebGPU 中,您可以在多个帧中重复使用相同的渲染通道吗?

与 Vulkan 的比较

我的问题源于我对 Vulkan 的(小)接触。在 Vulkan 中,您可以重用记录的资源,因为有一种方法可以预先知道交换链中有多少 VKImage 个对象;他们将拥有基于 0 的索引,例如 012。我不记得确切的语法,但我记得基本上你可以记录 3 个单独的命令缓冲区,每个 VKImage 一个,并跨帧重用它们。您所要做的就是在渲染循环中查询当前 VKImage 的索引并检索相应的记录命令缓冲区。

通过查看有关 getCurrentTexture 的规范,目前似乎没有 控制“交换”纹理的数量。

纹理是在“分配新的上下文纹理”步骤中创建的(如果它是 null 或被销毁),如注释所述:

If a previously presented texture from context matches the required criteria, its GPU memory may be re-used.

每次在“更新文档的渲染”步骤中,如果当前纹理不是 null 并且未销毁,那么它将被 presented、销毁并设置至 null.

规范中的另一条注释:

Developers can expect that the same GPUTexture object will be returned by every call to getCurrentTexture() made within the same frame (i.e. between invocations of Update the rendering) unless configure() is called.

所有这些似乎都表明您必须为每一帧获取当前纹理并创建所有相关的其他对象。