Skip to content

fix(slf): VR accumulator OOB heap write#2432

Closed
alandtse wants to merge 25 commits into
community-shaders:devfrom
alandtse:fix/slf-vr-accum-rdx-oob
Closed

fix(slf): VR accumulator OOB heap write#2432
alandtse wants to merge 25 commits into
community-shaders:devfrom
alandtse:fix/slf-vr-accum-rdx-oob

Conversation

@alandtse
Copy link
Copy Markdown
Collaborator

@alandtse alandtse commented May 28, 2026

Summary

Hook_AccumulatedLightsArray bumped RDI (fill-loop count) but not RDX (BSTArray resize count) on VR, producing an OOB heap write proportional to ShadowLightCount. Symptom: random later crashes in the Papyrus VM string heap with RDI = 0x83485708245C8948 — byte-reversed, those are the prologue bytes (48 89 5C 24 08 57 48 83) of the inlined BSTArray::resize callee, indicating a tbbmalloc freelist next-pointer was stomped and a later allocation returned code memory.

Mechanism

The hook installs with includeSize=+5, so the original 5 bytes run before the CONTEXT-capture stub. On SE and VR the patched 5 bytes are:

LEA EDI,[RBP+0x8]   ; 3 bytes -- count+8
MOV EDX,EDI         ; 2 bytes -- EDX latched to un-bumped count

After the stub, EDI is bumped but EDX is not. Downstream BSTArray::resize then allocates the original 10-slot buffer while the fill loop writes (ShadowLightCount + ConvertedShadowSlots + 1) * 2 entries. Higher counts crash earlier — matches user reports.

AE inlines the resize and re-derives EDX from EDI after the stub, so its RDX at the hook point is a dead caller-saved value and must not be touched. SE was already bumping RDX correctly. The original gate (!IsVR && !IsAE) inverted the VR case — it should have been !IsAE.

Verification

Confirmed at the patch site in all three runtimes via Ghidra static disasm:

Runtime Patched 5 bytes EDX source for resize RDX bump
SE LEA EDI / MOV EDX,EDI inside patch (pre-stub) needed (was present)
AE LEA EDI / TEST EDI,EDI inlined resize re-reads EDI post-stub not needed (correctly absent)
VR LEA EDI / MOV EDX,EDI inside patch (pre-stub) needed (was missing — bug)

Test plan

  • Build ALL preset, verify SE behavior unchanged at default shadow counts
  • VR + high ShadowLightCount (16+): play 15+ minutes loading interiors/exteriors, no Papyrus VM heap crash
  • RenderDoc once on VR: confirm kSHADOWMAPS slices populate correctly at high count

🤖 Generated with Claude Code

Summary by CodeRabbit

Release Notes

  • New Features

    • Added Remote Control feature for AI assistant integration via MCP protocol.
    • Implemented foveated DLSS rendering for VR upscaling.
    • Added PerfMode for VR render-target resizing and post-processing.
    • Enhanced shadow rendering with contact shadow support and improved caster management.
  • Improvements

    • Rebranded from Community Shaders to Open Shaders across UI and documentation.
    • Updated build system and CI/CD workflows.
    • Added comprehensive upstream synchronization workflow.
  • Documentation

    • New developer guides for upstream sync and VR integration.

Review Change Stack

alandtse and others added 25 commits May 20, 2026 01:36
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
Co-authored-by: YtzyFvra <59631290+YtzyFvra@users.noreply.github.com>
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
Co-authored-by: ParticleTroned <248299730+ParticleTroned@users.noreply.github.com>
Co-authored-by: jiayev <jiayev1@gmail.com>
Co-authored-by: ParticleTroned <248299730+ParticleTroned@users.noreply.github.com>
## Summary

Adds **DLSSperf** — a VR-only opt-in mode of the Upscaling feature.

In Skyrim VR's standard DLSS pipeline, the engine allocates its
render-target chain (kMAIN, depth, motion vectors, refraction, etc.) at
the HMD's full native resolution. DLSS upscales the small render content
into those large targets, and **the entire post-process chain — HDR,
bloom, refraction, tonemap — then runs at the upscaled HMD resolution**.
The post-process work is the most expensive part of the chain after
world rendering, and most of it doesn't visibly benefit from being
computed at the upscaled resolution.

DLSSperf shrinks the engine's render targets to match DLSS's own
internal (smaller) resolution. DLSS still reconstructs to HMD-native via
a private `testTexture` used for OpenVR submit, but everything the
engine itself draws and post-processes stays at the smaller working
resolution. Decomposed from upstream PR-2096
(`YtzyFvra/feature/DLSSenhancer`).

Co-authored-by: YtzyFvra <59631290+YtzyFvra@users.noreply.github.com>
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
## Summary

- Drop `/XO` (eXclude Older) from the three robocopy invocations under
`AUTO_PLUGIN_DEPLOYMENT` so changed source files actually reach the
install
- Update inline comments to document the trap (any prior touch to dest
can give it a newer mtime than git-checkout source, which silently
disables deploy)

## Why

`/XO` skips files where source is older than dest. In a normal git
workflow that's usually safe — but as soon as anything *else* touches
the destination (a manual `cp` during debugging, a package install, even
a previous build that ran later in wall time than the source's git
checkout), dest gets a newer mtime and `/XO` then refuses to overwrite
even when the source file's **size and content** have changed.

## Concrete failure that prompted this

While debugging SLF I had RunGrass.hlsl fixed in source (commit
`f11bfaa32`, source size 33287 bytes with the corrected ShadowSampling
include order), but the deployed file stayed at the previous 31877 bytes
across multiple full builds. Mtime on dest (from a manual `cp` during
earlier diagnostics) was newer than the git-checkout mtime on source, so
`/XO` skipped the copy. Grass and Particle pixel shaders failed to
compile in-game:

> `LightLimitFix/LightLimitFix.hlsli(85,3-28): error X3000: unrecognized
identifier 'DirectionalShadowLightData'`

Same shape of bug can hit any contributor who: tests a package install
over their dev build, copies files manually for any reason, or just has
clock skew across filesystem boundaries.

## What this changes

| Before | After |
|---|---|
| \`/E /XD ... /COPY:DAT /XO /R:1 /W:1 ...\` | \`/E /XD ... /COPY:DAT
/R:1 /W:1 ...\` |

Without `/XO`, robocopy uses its default name + size + timestamp delta —
copies whenever **any** of those differ. Catches both newer-source and
size-mismatch cases. The git-HEAD-change block above the deploy commands
already clears AIO and deploy stamps on branch switch, so the
bulk-redeploy story is unchanged.

## Trade-off

The property `/XO` nominally provided ("don't clobber files the user
intentionally edited in-game between builds at the same HEAD") was
fragile anyway — broken by any external touch to dest. Removing it costs
~100ms of extra IO per build on unchanged files (robocopy still skips
matching name+size+timestamp). Correctness wins.

## Test plan

- [ ] \`BuildRelease.bat ALL-WITH-AUTO-DEPLOYMENT\` produces a deployed
install that matches \`build/<preset>/aio\` byte-for-byte
- [ ] Manually \`touch\` a file in the deployed install to give it a
newer mtime, rebuild, confirm the source file overwrites it
- [ ] Verify unchanged files still skip on subsequent builds (robocopy's
default behavior)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Chores**
* Adjusted Windows plugin deployment configuration to improve
synchronization between deployed and built files. Updated build system
documentation comments.

<!-- review_stack_entry_start -->

[![Review Change
Stack](https://storage.googleapis.com/coderabbit_public_assets/review-stack-in-coderabbit-ui.svg)](https://app.coderabbit.ai/change-stack/alandtse/open-shaders/pull/37?utm_source=github_walkthrough&utm_medium=github&utm_campaign=change_stack)

<!-- review_stack_entry_end -->

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Co-authored-by: openai-code-agent[bot] <242516109+Codex@users.noreply.github.com>
Co-authored-by: alandtse <7086117+alandtse@users.noreply.github.com>
Co-authored-by: Alan Tse <alandtse@gmail.com>
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: doodlum <15017472+doodlum@users.noreply.github.com>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: Skrubby Skrub In A Shrub <87662196+SkrubbySkrubInAShrub@users.noreply.github.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-authored-by: YtzyFvra <59631290+YtzyFvra@users.noreply.github.com>
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
Hook_AccumulatedLightsArray bumped RDI (fill-loop count) but not RDX
(BSTArray resize count) on VR. On SE and VR the patched 5 bytes are
`LEA EDI,[RBP+0x8] ; MOV EDX,EDI`, executed via includeSize=+5 BEFORE
the CONTEXT-capture stub, so EDX latches the un-bumped count. The
resize then allocates the original 10-slot array while the fill loop
writes (ShadowLightCount+ConvertedShadowSlots+1)*2 entries -- an OOB
heap write proportional to the user's shadow count, corrupting a
tbbmalloc freelist next-pointer. Symptom: random later crashes in the
Papyrus VM string heap with RDI holding the prologue bytes of the
inlined resize fn (0x83485708245C8948 = `48 89 5C 24 08 57 48 83`).
Higher counts crash earlier.

SE was already bumping RDX; AE inlines the resize and re-derives EDX
from EDI AFTER the stub, so its RDX is dead at the hook point and must
not be touched. New gate is !IsAE() instead of IsSE().

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@alandtse
Copy link
Copy Markdown
Collaborator Author

Wrong target — recreating against alandtse/open-shaders

@alandtse alandtse closed this May 28, 2026
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 28, 2026

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 775db98e-f30a-49d0-9dff-60a15f1064bf

📥 Commits

Reviewing files that changed from the base of the PR and between 35b6f05 and 25ead9c.

⛔ Files ignored due to path filters (9)
  • package/Interface/CommunityShaders/Icons/Action Icons/discord.png is excluded by !**/*.png
  • package/Interface/CommunityShaders/Icons/Community Shaders Logo/Monochrome/cs-logo.png is excluded by !**/*.png
  • package/Interface/CommunityShaders/Icons/Community Shaders Logo/cs-logo.png is excluded by !**/*.png
  • package/SKSE/Plugins/CommunityShaders/Themes/DragonBlood/discord.png is excluded by !**/*.png
  • package/SKSE/Plugins/CommunityShaders/Themes/DwemerBronze/discord.png is excluded by !**/*.png
  • package/SKSE/Plugins/CommunityShaders/Themes/HighContrast/discord.png is excluded by !**/*.png
  • package/SKSE/Plugins/CommunityShaders/Themes/Light/cs-logo.png is excluded by !**/*.png
  • package/SKSE/Plugins/CommunityShaders/Themes/Light/discord.png is excluded by !**/*.png
  • package/SKSE/Plugins/CommunityShaders/Themes/NordicFrost/discord.png is excluded by !**/*.png
📒 Files selected for processing (130)
  • .claude/CLAUDE.md
  • .gitattributes
  • .github/copilot-instructions.md
  • .github/workflows/_shared-build.yaml
  • .github/workflows/auto-rebase-prs.yaml
  • .github/workflows/maint-cleanup-releases.yaml
  • .github/workflows/maint-update-wiki.yaml
  • .github/workflows/maint-upstream-sync.yaml
  • .github/workflows/nexus-upload.yaml
  • .github/workflows/pr-checks.yaml
  • .github/workflows/release-build.yaml
  • .github/workflows/release-hotfix.yaml
  • .github/workflows/release-semantic.yaml
  • .gitmodules
  • AI-INSTRUCTIONS.md
  • CMakeLists.txt
  • Dockerfile
  • README.md
  • cmake/cpp-mcp.cmake
  • containerbuild.ps1
  • docs/development/README.md
  • docs/development/upstream-sync.md
  • docs/development/vscode-setup.md
  • docs/new-feature-template/NewFeatureReadme.md
  • extern/cpp-mcp
  • features/Light Limit Fix/Shaders/Features/LightLimitFix.ini
  • features/Light Limit Fix/Shaders/LightLimitFix/Common.hlsli
  • features/Light Limit Fix/Shaders/LightLimitFix/LightLimitFix.hlsli
  • features/Remote Control/CORE
  • features/Remote Control/Shaders/Features/RemoteControl.ini
  • features/Upscaling/Shaders/Upscaling/FoveatedRender/SubrectStretchCS.hlsl
  • features/Upscaling/Shaders/Upscaling/PerfMode/BoxDownscalePS.hlsl
  • features/Upscaling/Shaders/Upscaling/PerfMode/MenuBGBlitPS.hlsl
  • features/VR/Shaders/Features/VR.ini
  • features/Volumetric Shadows/Shaders/Features/VolumetricShadows.ini
  • features/Volumetric Shadows/Shaders/VolumetricShadows/VolumetricShadows.hlsli
  • package/SKSE/Plugins/CommunityShaders/Overrides/README.md
  • package/Shaders/Common/FrameBuffer.hlsli
  • package/Shaders/Common/ShadowSampling.hlsli
  • package/Shaders/Common/SharedData.hlsli
  • package/Shaders/Effect.hlsl
  • package/Shaders/Lighting.hlsl
  • package/Shaders/Particle.hlsl
  • package/Shaders/RunGrass.hlsl
  • package/Shaders/Utility.hlsl
  • src/Deferred.cpp
  • src/Deferred.h
  • src/Feature.cpp
  • src/Feature.h
  • src/FeatureIssues.cpp
  • src/Features/DynamicCubemaps.cpp
  • src/Features/DynamicCubemaps.h
  • src/Features/GrassLighting.cpp
  • src/Features/InverseSquareLighting.cpp
  • src/Features/LightLimitFix.cpp
  • src/Features/LightLimitFix.h
  • src/Features/LightLimitFix/ShadowCasterManager.cpp
  • src/Features/LightLimitFix/ShadowCasterManager.h
  • src/Features/LightLimitFix/ShadowRenderer.cpp
  • src/Features/PerformanceOverlay.cpp
  • src/Features/RemoteControl.cpp
  • src/Features/RemoteControl.h
  • src/Features/RenderDoc.cpp
  • src/Features/RenderDoc.h
  • src/Features/ScreenshotFeature.cpp
  • src/Features/Upscaling.cpp
  • src/Features/Upscaling.h
  • src/Features/Upscaling/FidelityFX.cpp
  • src/Features/Upscaling/FidelityFX.h
  • src/Features/Upscaling/FoveatedRender.cpp
  • src/Features/Upscaling/FoveatedRender.h
  • src/Features/Upscaling/FoveatedRender/Bridge.cpp
  • src/Features/Upscaling/FoveatedRender/Bridge.h
  • src/Features/Upscaling/FoveatedRender/Core.cpp
  • src/Features/Upscaling/FoveatedRender/Core.h
  • src/Features/Upscaling/FoveatedRender/Modes.cpp
  • src/Features/Upscaling/FoveatedRender/Ops.h
  • src/Features/Upscaling/FoveatedRender/Params.cpp
  • src/Features/Upscaling/FoveatedRender/Params.h
  • src/Features/Upscaling/FoveatedRender/Postprocess.cpp
  • src/Features/Upscaling/FoveatedRender/Postprocess.h
  • src/Features/Upscaling/FoveatedRender/Preprocess.cpp
  • src/Features/Upscaling/FoveatedRender/Preprocess.h
  • src/Features/Upscaling/PerfMode.cpp
  • src/Features/Upscaling/PerfMode.h
  • src/Features/Upscaling/Streamline.cpp
  • src/Features/Upscaling/Streamline.h
  • src/Features/VR.cpp
  • src/Features/VR.h
  • src/Features/VR/Input.cpp
  • src/Features/VR/SettingsUI.cpp
  • src/Features/VRStereoOptimizations.cpp
  • src/Features/VRStereoOptimizations.h
  • src/Features/VolumetricLighting.cpp
  • src/Features/VolumetricLighting.h
  • src/Features/WeatherEditor.cpp
  • src/Globals.cpp
  • src/Globals.h
  • src/Hooks.cpp
  • src/Menu.cpp
  • src/Menu.h
  • src/Menu/AdvancedSettingsRenderer.cpp
  • src/Menu/AdvancedSettingsRenderer.h
  • src/Menu/FeatureListRenderer.cpp
  • src/Menu/HomePageRenderer.cpp
  • src/Menu/HomePageRenderer.h
  • src/Menu/IconLoader.cpp
  • src/Menu/MenuHeaderRenderer.cpp
  • src/Menu/OverlayRenderer.cpp
  • src/Menu/SettingsTabRenderer.cpp
  • src/Menu/ThemeManager.h
  • src/SettingsOverrideManager.h
  • src/ShaderCache.cpp
  • src/State.cpp
  • src/State.h
  • src/Utils/BootSnapshot.h
  • src/Utils/RestartSettings.h
  • src/Utils/Subrect.cpp
  • src/Utils/Subrect.h
  • src/Utils/Subrect_PreviewBlend.cpp
  • src/Utils/UI.cpp
  • src/Utils/UI.h
  • src/WeatherEditor/EditorWindow.cpp
  • src/XSEPlugin.cpp
  • tests/cpp/CMakeLists.txt
  • tests/cpp/test_bootsnapshot.cpp
  • tests/cpp/test_main.cpp
  • tests/cpp/test_subrect.cpp
  • tools/feature_version_audit.py
  • vcpkg.json

📝 Walkthrough

Walkthrough

This PR updates fork maintenance workflows and branding, adds restart-aware settings metadata, introduces a loopback MCP remote-control feature, expands Light Limit Fix shadow scheduling and shader paths, and adds VR perf-mode plus foveated upscaling support with new shaders, utilities, and tests.

Changes

Fork platform and maintenance flow

Layer / File(s) Summary
Fork identity and maintenance docs
.claude/CLAUDE.md, AI-INSTRUCTIONS.md, .github/copilot-instructions.md, README.md, docs/development/*, docs/new-feature-template/*, package/SKSE/Plugins/.../Overrides/README.md, tools/feature_version_audit.py, Dockerfile, containerbuild.ps1
Fork-facing guidance, branding text, clone/build instructions, wiki references, override docs, audit links, and container paths are updated for Open Shaders.
Fork merge and release workflows
.gitattributes, .github/workflows/auto-rebase-prs.yaml, .github/workflows/maint-*, .github/workflows/release-*
Fork-owned merge behavior, upstream sync, auto-rebase, wiki update gating, PAT-based release auth, and release naming are added or revised.
Build, packaging, and Nexus release flow
CMakeLists.txt, cmake/cpp-mcp.cmake, .gitmodules, extern/cpp-mcp, .github/workflows/_shared-build.yaml, .github/workflows/nexus-upload.yaml, .github/workflows/pr-checks.yaml, tests/cpp/CMakeLists.txt, vcpkg.json
Packaging now filters AIO contents by autoupload metadata, CI can run C++ tests, Nexus uploads support aio and matrix modes, and vendored/library build wiring is expanded.

Restart-aware settings metadata

Layer / File(s) Summary
Restart metadata primitives and shared UI
src/Feature.h, src/Utils/BootSnapshot.h, src/Utils/RestartSettings.h, src/Utils/UI.*, src/Menu/FeatureListRenderer.cpp, src/Features/WeatherEditor.cpp, src/WeatherEditor/EditorWindow.cpp
Shared restart-field metadata, boot snapshots, restart-colored UI helpers, and pending-restart detection are added and exposed to feature and menu code.
Feature restart adoption
src/Features/DynamicCubemaps.*, src/Features/RenderDoc.*, src/Features/VRStereoOptimizations.*, src/Features/VolumetricLighting.*, src/Features/VR.cpp
Several features switch from ad hoc boot-state handling to restart tables and boot snapshots, and their settings UIs render restart diffs from latched values.

Remote control MCP feature

Layer / File(s) Summary
Feature registration and shared state
src/Features/RemoteControl.h, src/Features/RemoteControl.cpp, src/Feature.cpp, src/Globals.*, src/State.*, features/Remote Control/Shaders/Features/RemoteControl.ini
A new core feature is registered, global access and frame-counter plumbing are added, and the RemoteControl interface and settings are declared.
MCP server lifecycle and tools
src/Features/RemoteControl.cpp
The feature starts a loopback MCP server, tracks sessions, renders connected-client UI, and implements inspect, feature, abtest, capture, and console tools with task-queue handoff where needed.

Light Limit Fix shadow pipeline

Layer / File(s) Summary
Scheduler, settings, and shadow upload
src/Features/LightLimitFix.*, src/Features/LightLimitFix/ShadowCasterManager.h, src/Features/LightLimitFix/ShadowRenderer.cpp, src/Features/InverseSquareLighting.cpp, features/Light Limit Fix/Shaders/Features/LightLimitFix.ini
Light Limit Fix gains shadow scheduler settings, contact-shadow controls, stable shadow slot assignment, per-frame shadow buffer upload, overlay rendering, and updated light collection logic.
Shadow data contracts and sampling helpers
src/Deferred.*, package/Shaders/Common/ShadowSampling.hlsli, package/Shaders/Common/SharedData.hlsli, features/Light Limit Fix/Shaders/LightLimitFix/*, features/Volumetric Shadows/Shaders/*, package/Shaders/Utility.hlsl, package/Shaders/Common/FrameBuffer.hlsli
CPU and HLSL shadow contracts are expanded with focus shadow projections, shadow slot metadata, contact-shadow settings, directional/local sampling helpers, and updated VSM inputs.
Shader integration call sites
package/Shaders/Effect.hlsl, package/Shaders/Lighting.hlsl, package/Shaders/Particle.hlsl, package/Shaders/RunGrass.hlsl
Lighting, particle, grass, and effect shaders are refactored to use the new directional and point-light shadow flow, LLF debug accumulation, and contact-shadow multiplication.

VR perf mode and foveated upscaling

Layer / File(s) Summary
Upscaling settings and initialization
src/Features/Upscaling.*, src/Hooks.cpp, src/Features/VR.*, features/VR/Shaders/Features/VR.ini
Upscaling adds restart-gated VR settings, new UI sections, foveated settings persistence, method locking during hook-active runs, and initialization-time perf-mode/foveated boot sequencing.
PerfMode render-target and post chain path
src/Features/Upscaling/PerfMode.*, src/Features/Upscaling/Streamline.*, src/Features/Upscaling/FidelityFX.*, features/Upscaling/Shaders/Upscaling/PerfMode/*, src/Globals.cpp
PerfMode enlarges VR render targets, redirects DLSS/FSR output sizing, intercepts post-processing and selected fullscreen passes, and adds menu background bridging plus underwater/depth repair support.
Foveated DLSS route and stereo subrects
src/Features/Upscaling/FoveatedRender/*, features/Upscaling/Shaders/Upscaling/FoveatedRender/SubrectStretchCS.hlsl, src/Utils/Subrect.*, src/Utils/Subrect_PreviewBlend.cpp, src/Features/ScreenshotFeature.cpp, tests/cpp/test_subrect.cpp
A new foveated VR DLSS route adds route state, preprocess/core/postprocess modules, subrect stretching, stereo crop persistence, preview blending, and regression tests for stereo subrect behavior.

UI branding and diagnostics reorganization

Layer / File(s) Summary
Branding text and menu layout
src/Menu/*, src/FeatureIssues.cpp, src/Features/GrassLighting.cpp, src/Features/PerformanceOverlay.cpp, src/Features/VR/Input.cpp, src/Features/VR/SettingsUI.cpp, src/ShaderCache.cpp, src/XSEPlugin.cpp
Menu branding switches to Open Shaders, the advanced settings UI is reorganized into new diagnostics and shader sections, Discord-specific home-page assets are removed, and assorted feature/UI text is updated.

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant RemoteControl
  participant MCP as mcp::server
  participant SKSE

  Client->>MCP: tool request
  MCP->>RemoteControl: dispatch handler
  alt main-thread action needed
    RemoteControl->>SKSE: queue task
    SKSE-->>RemoteControl: apply action
  end
  RemoteControl-->>MCP: JSON text result
  MCP-->>Client: SSE/HTTP response
Loading
sequenceDiagram
  participant CreateRT as BSShaderRenderTargets::Create
  participant PerfMode
  participant Upscaling
  participant Foveated as FoveatedRenderImpl::Core
  participant Streamline

  CreateRT->>PerfMode: enlarge RTs and setup resources
  Upscaling->>Foveated: preprocess and resolve VR params
  Foveated->>Streamline: per-eye DLSS evaluation
  Streamline-->>Foveated: upscaled eye outputs
  Foveated-->>Upscaling: final VR output
  Upscaling->>PerfMode: HandlePostProcessing when testTexture is active
Loading

Estimated code review effort

🎯 5 (Critical) | ⏱️ ~120 minutes

Possibly related PRs

Suggested reviewers

  • doodlum

Poem

A rabbit tapped a shader bright,
then labeled forks by moonlit light.
It taught restarts to softly show,
made shadows dance and upscales glow.
With loopback whispers, neat and small,
the burrow now can steer it all.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
⚔️ Resolve merge conflicts
  • Resolve merge conflict in branch fix/slf-vr-accum-rdx-oob

@github-actions
Copy link
Copy Markdown

Actionable Suggestions

  • Upscaling (Alan Tse): New feature (with ini v1-4-0)
  • VR (Alan Tse): Needs version bump to 1-2-0

@alandtse alandtse deleted the fix/slf-vr-accum-rdx-oob branch May 28, 2026 08:39
@github-actions
Copy link
Copy Markdown

✅ A pre-release build is available for this PR:
Download

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