Skip to content

Fix silent elimination of fragment shaders (Issue #284) #288

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 3 commits into from

Conversation

zmr-233
Copy link

@zmr-233 zmr-233 commented Jun 19, 2025

Problem

When a fragment shader writes only its RGB components (leaving w uninitialized), dead-code elimination (DCE) would drop the entire entry point without warning. The SPIR-V still compiled, but at runtime the shader was missing entirely.

What changed

  • Post-DCE check: after the second DCE pass, we now scan all declared entry points and verify their functions still exist. Added validate_entry_points_exist() function that runs after the second DCE pass.

  • Error reporting: if an entry point is gone, emit a clear error.

    • Fragment shaders get a specific hint to use full-vector writes (e.g. *out = vec4(r,g,b,a)).
    • Other shaders get a generic “no observable effects” message.
  • Added comprehensive test cases:

    1. issue-284-dead-fragment-good.rs - Working fragment shader with proper output assignment
    2. issue-284-dead-fragment-bad.rs - Problematic fragment shader that triggers the new validation

Effects

The fix provides context-aware error messages:

error: entry point `main_fs` was eliminated during dead code elimination, likely because its function body was optimized away
   |
   = help: fragment shaders must write to output parameters. Use complete assignment like `*out_frag_color = vec4(r, g, b, a)` instead of individual component assignments
   = note: example: `*out_frag_color = vec4(in_color.x, in_color.y, in_color.z, 1.0);`
   = note: entry point functions that produce no observable effects are considered dead code and will be eliminated during optimization

Future improvements

Early Detection Framework:currently disabled an early detection system that could warn about potentially problematic shaders before DCE:

/// Check fragment shaders for meaningful output operations
pub fn check_fragment_output_validity(sess: &Session, module: &Module) -> Result<()>

This could be enhanced to provide warnings rather than errors for borderline cases

zmr-233 added 3 commits June 19, 2025 11:20
Replace deprecated egrep command with the modern equivalent 'grep -E'
to eliminate warnings about egrep being obsolescent. This improves
the lint script output clarity without changing functionality.

Also add codegen-backend override to prevent cranelift conflicts
from parent directory configurations, ensuring rust-gpu builds
with the required LLVM backend.
Remove redundant clone of `sig.ident` by using a reference instead.
The clone was unnecessary since we only need to reference the identifier
in the `stringify\!` call. This eliminates the need for the clippy
allow annotation and improves performance slightly.
Add post-DCE validation to detect when declared entry points
are eliminated during dead code elimination.

- Add validate_entry_points_exist() function in linker
- Provide context-aware error messages for missing entry points
- Special handling for fragment shaders with helpful examples
- Add comprehensive test cases for both working and failing scenarios

Fixes silent failures where fragment shaders would be optimized
away without warning, causing difficult-to-debug runtime issues.
@zmr-233 zmr-233 closed this Jun 19, 2025
@zmr-233 zmr-233 deleted the pr-zmr233 branch June 19, 2025 05:45
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