Skip to content

Render policy and device capabilities for SplatMetalView - #1

Merged
Xget7 merged 1 commit into
mainfrom
render-policy
Sep 16, 2026
Merged

Xget7 merged 1 commit into
mainfrom
render-policy

Conversation

@Xget7

@Xget7 Xget7 commented Sep 16, 2026

Copy link
Copy Markdown
Owner

Summary

  • SplatMetalView.renderPolicy and deviceCapabilities, with SKRenderPolicy, SKDeviceCapabilities and -[SKSplatEngine applyRenderPolicy:reason:warnings:].
  • The shared engine (resolveRenderPolicy, SplatEngine::setRenderPolicy) re-validates each request on the render thread.
    Metal applies the sort depth with GPU sort and the sub-pixel threshold under tight culling; every other field falls back with a warning, and an invalid request keeps the previous policy.
  • Removes SPLATKIT_METAL_MIN_PIXEL_RADIUS and SPLATKIT_METAL_DEPTH_KEY_BITS; set renderPolicy instead.
  • Benchmarks log 30-second windows and final p99 frame and GPU times, and reject durations outside (0, 3600] seconds.
  • Adds CHANGELOG.md; the duplicate packages/splatkit-ios/distribution/ copies of README, CONTRIBUTING and AGENTS are removed, since their links resolve only from the root.

Exported from the SplatKit monorepo at 6237bb8 with scripts/export-ios-source.py --platform ios.

Validation

  • Engine tests (176) and the Metal suite (215) passed on a Mac host.
  • Python harness and export tests passed.
  • Not run on an iPhone yet; the React Native iOS adapter compiles against the simulator SDK only.

Before merging

  • Run the dev app on an iPhone with a policy change.
  • Package.swift still pins the 0.1.0-alpha.2 XCFramework, so renderPolicy stays unreleased until an alpha.3 binary is published.

SplatMetalView.renderPolicy and deviceCapabilities, over SKRenderPolicy,
SKDeviceCapabilities and -[SKSplatEngine applyRenderPolicy:reason:warnings:].
The shared engine re-validates each request on the render thread; Metal
applies the sort depth with GPU sort and the sub-pixel threshold under tight
culling, and other fields fall back with a warning. The
SPLATKIT_METAL_MIN_PIXEL_RADIUS and SPLATKIT_METAL_DEPTH_KEY_BITS environment
variables are removed.

Benchmarks log 30-second windows and p99 frame and GPU times, and reject
durations outside (0, 3600] seconds. Adds CHANGELOG.md; README, CONTRIBUTING
and AGENTS live only at the repository root.
@Xget7

Xget7 commented Sep 16, 2026

Copy link
Copy Markdown
Owner Author

iPhone run

iPhone 17 Pro (A19 Pro), physical device, Release build of apps/ios-dev against static libraries built from monorepo 6237bb8 plus a dev-app log of the applied policy and capabilities.
World kitchen_500k.spz, fixed pose, capture after 8 s, 1206x2622.

Launch args Applied policy Drawn of 500,000 Capture vs baseline
(default) sortDepth 32, subpixel 0.5 96,029 repeat run: 0.002% of pixels differ, max 3/255
--depth-key-bits 16 sortDepth 16 96,029 PSNR 43.1 dB, 0.89% of pixels over 8/255, edge ordering only
--metal-culling 1 subpixel 0.5 73,906 reference for the rows below
--metal-culling 1 --min-pixel-radius 1.2 subpixel 1.2 73,893 PSNR 65.2 dB
--metal-culling 1 --min-pixel-radius 3 subpixel 3 73,648 PSNR 64.0 dB
--metal-culling 1 --min-pixel-radius 8 subpixel 8 70,556 PSNR 42.1 dB
  • The renderer logged Metal policy: 16-bit sort keys and each sub-pixel radius, so both applicable fields reconfigure Metal on device.
  • Capabilities report sortDepth supported and subpixelThreshold supported only with the culling experiment on, matching the changelog.
  • World upload took 140 ms and the first frame was ready at 180 ms; no policy rejections or GPU errors were logged.
  • Not covered on device: rejected and preparation-failed outcomes (engine tests only) and sustained frame timing.

@Xget7

Xget7 commented Sep 16, 2026

Copy link
Copy Markdown
Owner Author

iPhone heavy run: ISS

iPhone 17 Pro (A19 Pro), same build as above.
iss_10M-sse-depth10-sh1.lodsplat (10M splats, 11,744,642 resident nodes), 2.2M selection capacity, SH 1, 1206x2622, horizontal 45 m orbit at 4 degrees/s from 90 degrees, --metal-culling 1 --tile-raster 1, 30 s after the first frame, back to back.
The sort depth and sub-pixel radius now come from renderPolicy, not the removed environment variables.

Run Policy FPS mean (min-max) GPU ms Sort ms Drawn mean First frame
1 sortDepth 16, subpixel 1.0 22.3 (19.0-29.0) 66.4 23.3 1,958,282 3.69 s
2 sortDepth 32, subpixel 1.0 19.2 (17.5-25.3) 86.2 39.8 1,959,609 1.92 s
3 run 1 repeated 23.3 (21.3-30.8) 57.5 21.8 1,957,768 3.18 s
4 sortDepth 16, subpixel 0.5 23.2 (21.3-30.6) 63.8 22.7 2,021,273 1.93 s
  • 16-bit keys cut sort time from 39.8 ms to 22-23 ms and raise the mean from 19.2 to 22.3-23.3 FPS, in line with the 2026-09-12 environment-variable A/B (18.9 to 23.4 FPS).
  • Lowering the sub-pixel radius from 1.0 to 0.5 px draws 63,000 more splats.
  • Every run logged the requested Metal policy line and stopped on duration-complete.
  • Sampled peak footprint was 2,827,848,480 to 2,828,651,296 bytes across runs (2026-09-12: 2,827,044,672); footprint after each run stopped was 1.08 GB, or 1.35 GB in the 32-bit run.
  • Thermal state stayed fair, and no GPU errors or policy rejections were logged.
  • The signal 14 after each run is the test harness's timeout closing the console, after the app had already stopped.
  • Short runs, not sustained benchmarks; the 30 FPS target at 2.2M is still not met.

@Xget7
Xget7 merged commit dfce7b6 into main Sep 16, 2026
5 checks passed
@Xget7
Xget7 deleted the render-policy branch September 16, 2026 23:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant