- 
                Notifications
    You must be signed in to change notification settings 
- Fork 1.1k
[spirv] Make ray queries safer #8390
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
base: trunk
Are you sure you want to change the base?
Conversation
c1c88c1    to
    16a5189      
    Compare
  
    6d674a6    to
    934c556      
    Compare
  
            
          
                naga/src/back/spv/ray.rs
              
                Outdated
          
        
      | initialized_tracker_id, | ||
| super::RayQueryPoint::FINISHED_TRAVERSAL.bits(), | ||
| ); | ||
| // TODO: Is double calling this invalid? Can't find anything to suggest so. | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| // TODO: Is double calling this invalid? Can't find anything to suggest so. | |
| // Can't find anything to suggest that calling this twice is invalid. | 
Also what is "this" finished traversal?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, I should have been more clear on this. "this" is the function (or spir-v OP technically)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some small things, but broadly good. Honestly this is enough code that I'm really relying on tests to validate this is okay, so most of my comments are about trying to make sure that tests are covering as much as is possible.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thought: Would it be better to split this file up into validation/non-validation?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
From what I remember, I think that most of this is validation. IMO, it could be more useful to add helper functions for instructions like equal, logical ands, ect. (it takes 8 lines where only the last three really matter).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It could be worth adding a module for helpers functions in manually written spirv (which ray-tracing seems to be the largest user).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This pull request adds runtime tracking for ray query initialization and usage to prevent undefined behavior (UB) on SPIR-V backends (Vulkan). The main changes include:
- Added ray_query_initialization_trackingflag to track ray query state through initialization and proceed calls
- Implemented validation to ensure ray queries are used correctly (initialized before use, proceed called, etc.)
- Added test cases demonstrating invalid ray query usage patterns
- Currently only implemented for Vulkan/SPIR-V backend (noted as not yet implemented for DX12 and Metal)
Reviewed Changes
Copilot reviewed 17 out of 24 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description | 
|---|---|
| wgpu-types/src/lib.rs | Added ray_query_initialization_trackingfield toShaderRuntimeChecksstruct | 
| wgpu-hal/src/vulkan/device.rs | Integrated tracking flag into Vulkan backend shader compilation | 
| wgpu-hal/src/vulkan/adapter.rs | Added debug print support and tracking initialization | 
| wgpu-hal/src/dx12/device.rs | Added comment noting tracking not yet implemented for DX12 | 
| tests/tests/wgpu-gpu/ray_tracing/shader.wgsl | Added test shader with invalid ray query usage patterns | 
| tests/tests/wgpu-gpu/ray_tracing/shader.rs | Added test case for invalid ray query validation | 
| naga/src/back/spv/* | Implemented SPIR-V code generation for ray query tracking with helper functions | 
| naga/tests/in/wgsl/ray-query-no-init-tracking.* | Added test files for ray query without tracking | 
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| block: &mut Block, | ||
| mut bools: Vec<spirv::Word>, | ||
| ) -> spirv::Word { | ||
| assert!(bools.len() > 1, "Must have multiple booleans!"); | 
    
      
    
      Copilot
AI
    
    
    
      Oct 29, 2025 
    
  
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The panic message 'Must have multiple booleans!' could be more descriptive about why this assertion failed and what the caller should do. Consider: 'write_less_than_2_true requires at least 2 boolean values, but received {}'.
| assert!(bools.len() > 1, "Must have multiple booleans!"); | |
| assert!( | |
| bools.len() > 1, | |
| "write_less_than_2_true requires at least 2 boolean values, but received {}", | |
| bools.len() | |
| ); | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TBH, this assert probably could be downgraded to a debug assert, its just making sure I've written my code properly
| Feel free to take or leave any of ^ if it's useful. | 
44f8ebf    to
    b2210ed      
    Compare
  
    b2210ed    to
    85f6629      
    Compare
  
    | I forgot to note, https://docs.vulkan.org/spec/latest/appendices/spirvenv.html#VUID-RuntimeSpirv-OpRayQueryGenerateIntersectionKHR-06353 isn't rejected. However, we can't just validate the inputted value to this range because OpRayQueryGetIntersectionTKHR is UB if there is not yet another committed intersection (i.e its the first thing the traversal has processed). The equivalent is defined on HLSL as the maximum t value (Note: DXC directly translates from one to the other, which I think is a bug). | 
Connections
Vulkan side of #6761
Description
With every ray query, creates an extra variable that gets passed around with it that tracks the functions that have been called on it in spirv. HLSL still has UB so I haven't updated the spec. This doesn't track them through function calls, as right now passing ray queries as function arguments is not allowed (might be a metal requirement?).
I have also added emitting debug printf as an option if initialization fails as it could fairly difficult to debug.
Testing
Adds a test that calls the ray queries with invalid values (including NaN and Infinity)
Squash or Rebase? Squash, each of the commits don't really make sense on their own.
Checklist
cargo fmt.cargo clippy --tests. If applicable, add:--target wasm32-unknown-unknowncargo xtask testto run tests.CHANGELOG.mdentry.