Skip to content

PRD-775: virtual shadow pages are managed and drawn on the GPU (plan) - #596

Closed
jonit-dev wants to merge 1 commit into
developfrom
prd/vsm-gpu-page-management
Closed

jonit-dev wants to merge 1 commit into
developfrom
prd/vsm-gpu-page-management

Conversation

@jonit-dev

Copy link
Copy Markdown
Contributor

What is this PR about?

The plan (PRD-775) to move virtual shadow map page work from the CPU to the GPU, the way Unreal 5.8.3 does it. This first commit is the PRD only; no engine code yet.

Why does it matter?

The stress lab's CPU frame is p50 12.82 / p95 17.64 ms against Unreal's 9.45 / 11.03 ms on the same scene. With the plain sun map we are already at 9.09 / 10.7 ms, so the gap is the virtual shadow map's CPU work: per-page caster selection, per-page rows, one render pass per page (256 on a grant), a per-frame scan of every caster, and a CPU page table and pool. Unreal does all of this with GPU compute passes and one batched shadow pass.

Plan (three phases, ordered by measured CPU ceiling)

  1. One shadow pass per light: a compute kernel culls each instance against the pages to draw (Unreal VirtualShadowMapBuildPerPageDrawCommands.usf), and one indirect draw per caster row replaces 256 page passes. Ceiling: about 0.96 ms native on a granting frame, plus about 1 ms of web encode. This is the p95 lever.
  2. The VSM stage reads the scene's change set, so an unchanged caster costs nothing (Unreal cache manager). Ceiling: 0.41 ms native, about 1.75 ms web, on every frame. This is the p50 lever.
  3. The page table and the physical page pool live on the GPU (Unreal VirtualShadowMapPhysicalPageManagement.usf). Ceiling: 0.06 to 0.24 ms native, plus the table upload. It also gives PRD-457 its GPU request flags.

Folds into PRD-457, 524, 652 and 773 without duplicating them; the feature map's three VSM rows now name PRD-775.

Checklist (mirrors the PRD)

Phase 1

  • A granted level draws in one render pass per light, from GPU rows (native red-green, pixels max diff 0).
  • Phase 1 passes the keep rule on the stress lab.

Phase 2

  • A frame where no caster changed visits no caster state; invalidations equal today's.
  • Phase 2 passes the keep rule on the stress lab.

Phase 3

  • The GPU page manager maps the same pages as the CPU PageAtlas (differential case, pixels max diff 0).
  • Phase 3 passes the keep rule on the stress lab.

Acceptance

  • AC-1: fair window ?stress CPU p95 < 11.03 ms and p50 < 9.45 ms, GPU p95 not worse.
  • AC-2: Opus visual judge NEUTRAL or IMPROVEMENT on the whole stack.

Still open

  • Coordinator decision: Phase 1 cuts granting frames, so it moves CPU p95, not p50. Keep the brief's p50 > 3 % rule, or accept "p95 > 3 % better, p50 not worse" for Phase 1.
  • Engine work starts only after the coordinator's "go phase B" and the FV1, FV3, FGL3 and FC1s-b verdicts.

Checks run

  • pnpm check:docs: 3638 links OK; pnpm unreal:status refreshed the map.
  • pnpm prd:progress: 0/3 phases, 0/6 boxes, label prd:0%.

Ports Unreal 5.8.3's GPU page management in three phases ordered by measured
CPU ceiling: one GPU-culled shadow pass per light (BuildPerPageDrawCommands),
caster changes pushed by the scene (CacheManager change set), and the page
table and physical pool on the GPU (PhysicalPageManagement). Folds PRD-457,
524, 652 and 773; maps the three VSM subsystem rows to PRD-775.
@jonit-dev jonit-dev added the prd:0% PRD implementation has no verified phase yet label Oct 30, 2026
@jonit-dev

Copy link
Copy Markdown
Contributor Author

Folded into #595 (develop -> main) at owner request: the commit is cherry-picked onto develop as 9d104566b and reaches #595 with the next develop push. Branch kept. Phase B work commits to develop, not to a separate PR.

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

Labels

prd:0% PRD implementation has no verified phase yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant