Skip to content

PBR: default Forward+, device-local light SSBO for tile cull#154

Draft
timfox wants to merge 3 commits intomainfrom
cursor/pbr-forwardplus-device-ssbo-f2d7
Draft

PBR: default Forward+, device-local light SSBO for tile cull#154
timfox wants to merge 3 commits intomainfrom
cursor/pbr-forwardplus-device-ssbo-f2d7

Conversation

@timfox
Copy link
Copy Markdown
Owner

@timfox timfox commented Apr 27, 2026

Summary

PBR / Forward+ as the default path (Vulkan)
r_forwardPlus now defaults to 1 (still latched; set 0 + vid_restart to disable). This turns on GPU tile cull + PBR descriptor integration without users manually enabling scaffolding.

Device-local light SSBO (more “GPU”, less host-mapped shader memory)
Dynamic light records are still packed on the CPU (source data is dlight_t in refdef), but the read path for forward_plus_tile_cull and PBR fragment code now uses a device-local STORAGE | TRANSFER_DST buffer. Each frame we copy only the used prefix (header + n records) from a host staging buffer via vkCmdCopyBuffer, with correct transfer and shader barriers. This matches the architecture goal: compute + PBR sample lights from VRAM instead of a host-visible SSBO.

New call
vk_forward_plus_upload_refdef() runs after RB_BeginDrawingView (command buffer valid, inside main pass) and before vk_forward_plus_dispatch_tile_cull().

Docs
docs/FORWARD_PLUS_PIPELINE_AUDIT.md updated for ordering and synchronization.

Validation

  • ./scripts/compile_engine.sh vulkan
  • ctest (19/19 passed)

Notes / follow-ups

  • Full “GPU pack” of lights would need dlight_t in a UBO/SSBO from the game without a CPU refdef path—larger change.
  • Param SSBO is still host-visible; could be moved similarly if we want to push further.
Open in Web Open in Cursor 

cursoragent and others added 3 commits April 27, 2026 19:39
r_forwardPlusShade changes PBR fragment specialization on world draw pipelines
only. vk_destroy_pipelines() also destroyed gamma, overlay compose, bloom,
SMAA, and other post paths unrelated to Forward+, which could leave the
swapchain with no valid gamma blit (black screen with audio).

Add vk_destroy_world_graphics_pipelines() (same slice as vk_release_resources:
indices >= vk.pipelines_world_base) and use it for r_forwardPlusShade
invalidation. Persistent pipelines (skybox, fog, etc.) stay valid; PBR world
pipelines are recreated lazily via vk_gen_pipeline as before.

Co-authored-by: Tim Fox <timfox@outlook.com>
vk_destroy_world_graphics_pipelines() must not shrink vk.pipelines_count or
zero Vk_Pipeline_Def rows: shader_t stores uint32_t indices into the table;
dropping the tail reuses slots and breaks cached indices (wrong draws or
vk_gen_pipeline ERR_FATAL). Destroy only VkPipeline handles; lazy recreation
picks up the new r_forwardPlusShade specialization.

Co-authored-by: Tim Fox <timfox@outlook.com>
- r_forwardPlus default 1 (latched): prioritize clustered tile cull + PBR path
- Light records: pack to host staging, vkCmdCopyBuffer to DEVICE_LOCAL SSBO each
  frame so compute cull and fragment shaders read VRAM (not host-mapped SSBO)
- vk_forward_plus_upload_refdef after RB_BeginDrawingView: transfer barriers
- Tile cull light buffer barrier updated for device-local read path
- docs/FORWARD_PLUS_PIPELINE_AUDIT.md: ordering and sync notes

Startup log: [VK][Forward+] r_forwardPlus=1 device-local light SSBO + staging...

Co-authored-by: Tim Fox <timfox@outlook.com>
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.

2 participants