Visitar URL original
vpool never rests (streamingStatus never idle) when the WebGPU pipeline has no depth pass (edges/AO off) · Issue #56 · ThatOpen/platform_services · GitHub
Skip to content

vpool never rests (streamingStatus never idle) when the WebGPU pipeline has no depth pass (edges/AO off) #56

Open

Description

@rihokirss

Thanks for 3.5.11: with vpool, the parts of #46–#53 we have re-tested work for us. One thing we hit while wiring up the new on-demand contract from #50:

Summary

When the WebGPU postproduction pipeline has no pass that needs the scene depth (webgpuPost.edges and webgpuPost.ao both off, e.g. an FXAA-only pipeline), vpool never captures a depth texture, runs with occOn = 2, and never rests. As a result:

  • fragments.streamingStatus.idle stays false forever and onStreamingStatus never reports idle, even with an empty queue and nothing in flight;
  • the frame body runs every frame and wantFrame() is called every frame, so a host in RendererMode.MANUAL that follows host.requestFrame would never stop rendering;
  • occlusion culling is also off in that configuration.

With edges/AO on, the same scene rests within about a second and reports idle, as expected.

Measurements

One streamed model (suspended ceilings, ~9 MB .frag), camera still, queue and downloads at 0, values read 6 s after loading settled, then frames counted over 3 s at a 50 FPS host limit. Hardware WebGPU (Chromium on Linux, Vulkan, AMD RDNA 3).

webgpuPost (ao / edges / fxaa) antialias st.occOn st.hasDepth streamingStatus.idle vpool frame bodies in 3 s rest frames in 3 s
on / on / on 4 samples 1 true true 0 150
on / on / on off 1 true true 0 150
off / on / on 4 samples 1 true true 0 150
off / off / on 4 samples 2 false false 150 0
off / off / on off 2 false false 150 0
off / off / off off 2 false false 150 0

MSAA makes no difference; only whether a depth-consuming pass is compiled into the pipeline does.

Where it comes from (fragments-beta 3.5.11, src/FragmentsModels/src/streamed/vpool/vpool.mjs)

  • occOn becomes 2 when no depth is caught: cullUU[46] = useRep && st.occlusion !== false ? 1 : st.occlusion === false || (!R.depth && st.selections > 20) ? 2 : 0.
  • The rest test requires occlusion to be on: if (!moving && !busy && !pictureChanged && restOk && st.occOn === 1 && … && st.unchanged > 8 && st.settled >= 3) { st.skip = true; … }. With occOn === 2 this is never true, so st.skip stays false, P.progress().idle stays false, and wantFrame() runs at the end of every frame.

The comment on the finest levels in wgsl.mjs already treats occOn 2 as a settled state ("no depth will come … so waiting for it left those levels as stand-ins for good"), so it seems the rest test could accept it as well.

Expected

Either of these would solve it for us:

  1. Allow rest (and idle) when occlusion is permanently unavailable (occOn === 2), with the other conditions unchanged; or
  2. Have the components-front WebGPU pipeline keep a sampled scene depth even when edges/AO are off, so vpool gets occlusion and rest in every configuration.

Option 2 would also bring back occlusion culling for FXAA-only pipelines, which is the configuration lower-end machines are likely to use.

Repro

  1. PostproductionRenderer (WebGPU), fragments.settings.streaming.host = { renderer: world.renderer.three, scene, camera, onHook: world.renderer.onBeforeUpdate, controls, owner: world.renderer }.
  2. Set world.renderer.webgpuPost = { ...world.renderer.webgpuPost, ao: false, edges: false, fxaa: true }.
  3. Load one streamed model and wait until streamingStatus.queue === 0 && fetchesUnderway === 0.
  4. Keep the camera still and read (await fragmentsModels._systemLive).vpool.st (occOn, hasDepth, skip, frames, idleFrames) and fragments.streamingStatus.idle over a few seconds.
  5. Repeat with edges: true: it rests and reports idle.

Versions

  • @thatopen-platform/fragments-beta 3.5.11
  • @thatopen-platform/components-beta 3.5.19
  • @thatopen-platform/components-front-beta 3.5.17
  • three 0.185.0

Our workaround

We do not pass host.requestFrame (our renderer stays in AUTO mode behind an application-side idle gate) and decide "streaming still has work" from streamingStatus.queue > 0 || fetchesUnderway > 0 instead of idle. That works, but it cannot see vpool's own refinement after the last block arrives, which idle would.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions