【问题标题】:In WebGPU, can you reuse the same render pass in multiple frames?在 WebGPU 中,您可以在多个帧中重复使用相同的渲染通道吗?
【发布时间】:2022-01-26 02:03:58
【问题描述】:

在 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 的索引并检索相应的记录命令缓冲区。

【问题讨论】:

    标签: webgpu


    【解决方案1】:

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

    纹理是在“分配一个新的上下文纹理”步骤中创建的(如果它是null 或被销毁),因为那里的注释指出:

    如果上下文中先前呈现的纹理符合要求的标准,则可以重新使用其 GPU 内存。

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

    规范中的另一个说明:

    除非调用了 configure(),否则开发人员可以预期,在同一帧内(即在调用更新渲染之间)每次调用 getCurrentTexture() 都会返回相同的 GPUTexture 对象。

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

    【讨论】:

    • 有道理,谢谢。看起来,在引擎盖下,WebGPU 将做的比我预期的要多得多。在阅读了一些 Vulkan 教程后,我就像“哦,哇,这是开发人员需要做的很多簿记”,我开始理解为什么必须这样才能获得最大性能,所以我期待 WebGPU 能够完全模仿.但也许它会是矫枉过正。
    • 不客气。在之前的阶段中,“交换”纹理被定义为从 1 到 3(参见 gpuweb.github.io/gpuweb/explainer/#canvas-output-swap-chains),但是已经改变了(因此解释器似乎不是最新的)。
    猜你喜欢
    • 2022-11-11
    • 2018-08-19
    • 1970-01-01
    • 1970-01-01
    • 2016-09-14
    • 1970-01-01
    • 2015-05-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多