Skip to content

feat(mcp): shader recompile observability#62

Merged
alandtse merged 2 commits into
devfrom
feat/shader-recompile-observability
May 30, 2026
Merged

feat(mcp): shader recompile observability#62
alandtse merged 2 commits into
devfrom
feat/shader-recompile-observability

Conversation

@alandtse
Copy link
Copy Markdown
Owner

@alandtse alandtse commented May 30, 2026

Summary

Surfaces shader (re)compile state two ways from one event, so hot-reload A/B testing stops relying on guesswork.

MCP (build-agnostic) — new inspect(kind='shadercache')

Returns { compiling, completedTasks, totalTasks, failedTasks, currentFailedCount, frame_count }, built entirely from existing thread-safe ShaderCache accessors (no new state on the hot class). Poll completedTasks against a pre-deploy snapshot to confirm a hot-reloaded shader recompiled; a rising failedTasks/currentFailedCount surfaces a failed compile that was previously invisible (no log-diving).

Tracy (profiling builds) — recompile messages

TracyMessage on success / red TracyMessageC on failure at both CompileShader completion points, #ifdef TRACY_ENABLE-guarded (no formatting cost in normal builds). Gives the exact frame so A/B perf windows split on the recompile via get_messages().

Decoupling (ShaderCompileStatus.h)

RemoteControl.cpp must not include ShaderCache.h — its global-scope using namespace std::chrono leaks chrono names (e.g. last) into the vendored cpp-mcp httplib/base64 headers and trips warning-as-error. The status read is exposed through a tiny dependency-free header implemented in ShaderCache.cpp.

Validation

  • ALL-TRACY build green.
  • Runtime-validated in a live Skyrim SE session: inspect(shadercache) counters climbed through a 3455-task cache rebuild (compiling: true, 0 failures), and Tracy showed "Shader compiled: …" messages firing per compile alongside ShaderCompilationTask::Perform zones.

Notes

Success messages fire for every compile, so a cold-cache startup emits many (early-timeline, Tracy-only) — acceptable; a follow-up could gate on steady state if it's noise. The MCP counters are the primary, build-agnostic signal.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Added shader cache status inspection to diagnostic tools.
  • Bug Fixes

    • Improved contact-shadow intensity calculations for deferred lighting with clustered lights.
  • Refactor

    • Enhanced shader compilation diagnostics with performance profiling instrumentation.
    • Refactored Weather Editor UI code for improved readability and maintainability.

Review Change Stack

Copilot AI review requested due to automatic review settings May 30, 2026 18:48
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 30, 2026

Warning

Review limit reached

@alandtse, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 39 minutes and 15 seconds. Learn how PR review limits work.

Your organization has run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 4cd81834-6bbd-4e80-99cd-6d6cb3323666

📥 Commits

Reviewing files that changed from the base of the PR and between 4a6f49f and 4563d40.

📒 Files selected for processing (3)
  • src/Features/RemoteControl.cpp
  • src/ShaderCache.cpp
  • src/ShaderCompileStatus.h
📝 Walkthrough

Walkthrough

This PR adds shader compilation status monitoring for RemoteControl inspection, updates contact-shadow intensity gating logic for ISL builds in the lighting shader, and refactors shader and C++ code across multiple files for readability and formatting consistency. New ShaderCompileStatus API is integrated end-to-end from cache snapshot through RemoteControl JSON response with Tracy instrumentation along the compilation path.

Changes

Code Quality and Feature Enhancements

Layer / File(s) Summary
Shader compile status API and implementation
src/ShaderCompileStatus.h, src/ShaderCache.cpp
New SIE::ShaderCompileStatus struct and GetShaderCompileStatus() function snapshot shader cache compilation state atomically; Tracy timeline events (TRACY_ENABLE) are added to emit success/failure markers during shader compilation with type/class identifiers.
RemoteControl shader cache inspection
src/Features/RemoteControl.cpp
Adds ShaderCacheBlob() helper producing MCP JSON from shader cache status; extends inspect tool to route kind="shadercache" requests and updates tool documentation to describe the new kind and returned fields.
Contact-shadow intensity gating for ISL
package/Shaders/Lighting.hlsl
ISL builds now compute passesIntensityGate for clustered lights using falloffFactor (from lightDist * light.invRadius); non-ISL paths retain intensity multiplier comparison.
Shader file formatting standardization
features/Water Effects/Shaders/WaterEffects/WaterCaustics.hlsli, package/Shaders/ISTemporalAA.hlsl
Reformats ternary expressions in WaterCaustics to single-line style; standardizes ISTemporalAA struct field semantics spacing, macro preprocessor formatting, and variable declarations.
C++ infrastructure formatting
src/Features/HDRDisplay.cpp, src/Features/LightLimitFix.cpp, src/Hooks.cpp, src/ShaderCache.h, src/Utils/RestartSettings.h
Adjusts line wrapping in HDRDisplay conditionals, reorders LightLimitFix includes, moves exception handler braces to same line, normalizes whitespace in ShaderCache.h and RestartSettings.h.
Weather Editor UI refactoring for readability
src/WeatherEditor/Weather/CellLightingWidget.cpp, src/WeatherEditor/Weather/LightingTemplateWidget.cpp, src/WeatherEditor/Weather/PrecipitationWidget.cpp, src/WeatherEditor/Weather/WeatherWidget.cpp
Expands single-line conditionals and lambdas into multi-line blocks; refactors inheritance-style handling in DrawProperties, synchronization loops, and searchable settings generation for clarity while preserving behavior.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • alandtse/open-shaders#43: Both PRs modify the clustered contact-shadow intensity gating logic in package/Shaders/Lighting.hlsl to refine the passesIntensityGate decision-making for ISL builds.
  • alandtse/open-shaders#45: Both PRs adjust contact-shadow eligibility gating in package/Shaders/Lighting.hlsl (main PR refines ISL intensity-gate derivation; PR #45 adds particle-light contact-shadow gating via new flags).

Poem

🐰 Hops through the code with glee,
Status tracked for all to see!
Shaders glisten, clean and bright,
Weather UI refactored just right.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 21.43% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: adding shader recompile observability through MCP and Tracy instrumentation for monitoring compilation status.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/shader-recompile-observability

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds build-agnostic and profiling-only observability for shader (re)compiles, primarily to support MCP-driven hot-reload A/B testing and to make compile failures visible without log-diving. This is done by exposing shader-cache counters via inspect(kind="shadercache"), emitting Tracy timeline messages on compile success/failure, and introducing a small decoupling header so RemoteControl.cpp doesn’t need to include ShaderCache.h.

Changes:

  • Add ShaderCompileStatus.h + SIE::GetShaderCompileStatus() and expose it via MCP inspect(kind="shadercache").
  • Emit Tracy timeline messages for shader compile success/failure (#ifdef TRACY_ENABLE) from ShaderCache.cpp.
  • Apply formatting/cleanup-only changes across Weather Editor widgets, hooks, and several shader sources.

Reviewed changes

Copilot reviewed 9 out of 15 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
src/Features/RemoteControl.cpp Adds inspect(kind="shadercache") and documents the new kind.
src/ShaderCompileStatus.h New minimal header exposing shader compile counters without including ShaderCache.h.
src/ShaderCache.cpp Implements GetShaderCompileStatus() and emits Tracy messages on compile success/failure.
src/ShaderCache.h Minor formatting change; still contains global using namespace std::chrono;.
src/Hooks.cpp Formatting-only change to __except braces.
src/Features/LightLimitFix.cpp Include ordering + formatting-only changes.
src/Features/HDRDisplay.cpp Indentation-only changes in a couple conditional blocks.
src/Utils/RestartSettings.h Macro formatting tweak.
src/WeatherEditor/Weather/WeatherWidget.cpp Formatting-only changes (if-bracing/tooltip style blocks/spacing).
src/WeatherEditor/Weather/PrecipitationWidget.cpp Indentation/formatting-only changes.
src/WeatherEditor/Weather/LightingTemplateWidget.cpp Formatting-only changes in searchable settings list.
src/WeatherEditor/Weather/CellLightingWidget.cpp Formatting-only changes in inherited-style handling and search list.
package/Shaders/Lighting.hlsl Preprocessor directive indentation change only.
package/Shaders/ISTemporalAA.hlsl Formatting-only changes (semantic spacing, preprocessor indentation, alignment).
features/Water Effects/Shaders/WaterEffects/WaterCaustics.hlsli Formatting-only change to ternary expressions.

Comment thread src/Features/RemoteControl.cpp Outdated
Comment thread src/ShaderCache.cpp
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (2)
package/Shaders/Lighting.hlsl (1)

1-1: PR title could better reflect the shader gating change.

Current title is valid Conventional Commit format, but it doesn’t mention the ISL contact-shadow gating adjustment included here. Consider: feat(shader): add isl contact-shadow intensity gating (or include both MCP + shader scope in the body).

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@package/Shaders/Lighting.hlsl` at line 1, The PR title doesn't mention the
ISL contact-shadow intensity gating introduced in the shader; update the
commit/PR title to explicitly reference the shader gating change (for example:
"feat(shader): add isl contact-shadow intensity gating") and, if needed, expand
the PR body to note both the MCP and shader scope so reviewers can quickly see
the change affects Lighting.hlsl (macro/guard LIGHTING) and the ISL
contact-shadow logic.
package/Shaders/ISTemporalAA.hlsl (1)

41-41: 💤 Low value

Consider standard preprocessor directive spacing.

The space after # in # define is unconventional in HLSL/C preprocessor directives. Standard style uses #define without space.

🎨 Proposed fix to use standard preprocessor formatting
-#	define cmp -
+#	define cmp -

Note: Both forms are valid, but #define (no space) is the established convention.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@package/Shaders/ISTemporalAA.hlsl` at line 41, The preprocessor directive for
the macro "cmp" uses nonstandard spacing ("# define cmp -"); change it to the
conventional form by removing the space after the hash so the directive reads
"`#define` cmp -" in ISTemporalAA.hlsl (search for the "cmp" macro definition to
locate it).
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@package/Shaders/ISTemporalAA.hlsl`:
- Line 41: The preprocessor directive for the macro "cmp" uses nonstandard
spacing ("# define cmp -"); change it to the conventional form by removing the
space after the hash so the directive reads "`#define` cmp -" in ISTemporalAA.hlsl
(search for the "cmp" macro definition to locate it).

In `@package/Shaders/Lighting.hlsl`:
- Line 1: The PR title doesn't mention the ISL contact-shadow intensity gating
introduced in the shader; update the commit/PR title to explicitly reference the
shader gating change (for example: "feat(shader): add isl contact-shadow
intensity gating") and, if needed, expand the PR body to note both the MCP and
shader scope so reviewers can quickly see the change affects Lighting.hlsl
(macro/guard LIGHTING) and the ISL contact-shadow logic.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: d2bdb673-e144-4b53-8653-f3e0e4e34a43

📥 Commits

Reviewing files that changed from the base of the PR and between fcfaab0 and 4a6f49f.

📒 Files selected for processing (15)
  • features/Water Effects/Shaders/WaterEffects/WaterCaustics.hlsli
  • package/Shaders/ISTemporalAA.hlsl
  • package/Shaders/Lighting.hlsl
  • src/Features/HDRDisplay.cpp
  • src/Features/LightLimitFix.cpp
  • src/Features/RemoteControl.cpp
  • src/Hooks.cpp
  • src/ShaderCache.cpp
  • src/ShaderCache.h
  • src/ShaderCompileStatus.h
  • src/Utils/RestartSettings.h
  • src/WeatherEditor/Weather/CellLightingWidget.cpp
  • src/WeatherEditor/Weather/LightingTemplateWidget.cpp
  • src/WeatherEditor/Weather/PrecipitationWidget.cpp
  • src/WeatherEditor/Weather/WeatherWidget.cpp

@github-actions
Copy link
Copy Markdown

No actionable suggestions for changed features.

alandtse added a commit that referenced this pull request May 30, 2026
Read completedTasks/totalTasks once and derive `compiling` from that
single snapshot so callers never observe compiling=false with work
still outstanding; switch to named-field init so member reordering
can't silently misassign. Also list the `plugin` field in the
inspect(kind='shadercache') description to match the actual response.

Addresses Copilot review on PR #62.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
alandtse and others added 2 commits May 30, 2026 19:58
Surface shader (re)compile state two ways from one event so hot-reload
A/B testing stops relying on guesswork.

MCP (build-agnostic, drives the workflow):
- New inspect(kind='shadercache') on the RemoteControl server returns
  { compiling, completedTasks, totalTasks, failedTasks,
  currentFailedCount, frame_count }, built from existing thread-safe
  ShaderCache accessors (no new state on the hot class). Poll
  completedTasks against a pre-deploy snapshot to know a hot-reloaded
  shader finished recompiling; a rising failedTasks / currentFailedCount
  surfaces a failed compile that was previously invisible.

Tracy (profiling-only, precise correlation):
- TracyMessage on success / red TracyMessageC on failure at both
  CompileShader completion points, #ifdef TRACY_ENABLE-guarded (no
  formatting cost in normal builds). Gives the exact frame so A/B perf
  windows split on the recompile via get_messages().

To keep RemoteControl.cpp free of ShaderCache.h (whose global-scope
`using namespace std::chrono` leaks chrono names into the vendored
cpp-mcp httplib/base64 headers and trips warning-as-error), the status
read is exposed through a tiny dependency-free header
(ShaderCompileStatus.h) implemented in ShaderCache.cpp.

Validated with an ALL-TRACY build.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Read completedTasks/totalTasks once and derive `compiling` from that
single snapshot so callers never observe compiling=false with work
still outstanding; switch to named-field init so member reordering
can't silently misassign. Also list the `plugin` field in the
inspect(kind='shadercache') description to match the actual response.

Addresses Copilot review on PR #62.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@alandtse alandtse force-pushed the feat/shader-recompile-observability branch from c5e05c6 to 4563d40 Compare May 30, 2026 19:58
@alandtse alandtse merged commit 38c247f into dev May 30, 2026
13 checks passed
@alandtse alandtse deleted the feat/shader-recompile-observability branch May 30, 2026 20:12
@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