Skip to content

Commit

Permalink
Expand on the documentation for ray-tracing features.
Browse files Browse the repository at this point in the history
  • Loading branch information
jimblandy committed Mar 22, 2023
1 parent 7586a9c commit 81305a2
Show file tree
Hide file tree
Showing 4 changed files with 92 additions and 8 deletions.
9 changes: 8 additions & 1 deletion src/back/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,14 @@ impl crate::Statement {
}

bitflags::bitflags! {
/// Ray flags.
/// Ray flags, for a [`RayDesc`]'s `flags` field.
///
/// Note that these exactly correspond to the SPIR-V "Ray Flags" mask, and
/// the SPIR-V backend passes them directly through to the
/// `OpRayQueryInitializeKHR` instruction. (We have to choose something, so
/// we might as well make one back end's life easier.)
///
/// [`RayDesc`]: crate::Module::generate_ray_desc_type
#[derive(Default)]
pub struct RayFlag: u32 {
const OPAQUE = 0x01;
Expand Down
29 changes: 27 additions & 2 deletions src/front/type_gen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,21 @@ Type generators.
use crate::{arena::Handle, span::Span};

impl crate::Module {
//Note: has to match `struct RayDesc`
/// Populate this module's [`SpecialTypes::ray_desc`] type.
///
/// [`SpecialTypes::ray_desc`] is the type of the [`descriptor`] operand of
/// an [`Initialize`] [`RayQuery`] statement. In WGSL, it is a struct type
/// referred to as `RayDesc`.
///
/// Backends consume values of this type to drive platform APIs, so if you
/// change any its fields, you must update the backends to match. Look for
/// backend code dealing with [`RayQueryFunction::Initialize`].
///
/// [`SpecialTypes::ray_desc`]: crate::SpecialTypes::ray_desc
/// [`descriptor`]: crate::RayQueryFunction::Initialize::descriptor
/// [`Initialize`]: crate::RayQueryFunction::Initialize
/// [`RayQuery`]: crate::Statement::RayQuery
/// [`RayQueryFunction::Initialize`]: crate::RayQueryFunction::Initialize
pub(super) fn generate_ray_desc_type(&mut self) -> Handle<crate::Type> {
if let Some(handle) = self.special_types.ray_desc {
return handle;
Expand Down Expand Up @@ -96,7 +110,18 @@ impl crate::Module {
handle
}

//Note: has to match `struct RayIntersection`
/// Populate this module's [`SpecialTypes::ray_intersection`] type.
///
/// [`SpecialTypes::ray_intersection`] is the type of a
/// `RayQueryGetIntersection` expression. In WGSL, it is a struct type
/// referred to as `RayIntersection`.
///
/// Backends construct values of this type based on platform APIs, so if you
/// change any its fields, you must update the backends to match. Look for
/// the backend's handling for [`Expression::RayQueryGetIntersection`].
///
/// [`SpecialTypes::ray_intersection`]: crate::SpecialTypes::ray_intersection
/// [`Expression::RayQueryGetIntersection`]: crate::Expression::RayQueryGetIntersection
pub(super) fn generate_ray_intersection_type(&mut self) -> Handle<crate::Type> {
if let Some(handle) = self.special_types.ray_intersection {
return handle;
Expand Down
60 changes: 56 additions & 4 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,8 +107,10 @@ Naga's rules for when `Expression`s are evaluated are as follows:
[`Atomic`] statement, representing the result of the atomic operation, is
evaluated when the `Atomic` statement is executed.
- Similarly, an [`RayQueryProceedResult`] expression, which is a boolean
indicating if the ray query is finished.
- A [`RayQueryProceedResult`] expression, which is a boolean
indicating if the ray query is finished, is evaluated when the
[`RayQuery`] statement whose [`Proceed::result`] points to it is
executed.
- All other expressions are evaluated when the (unique) [`Statement::Emit`]
statement that covers them is executed.
Expand Down Expand Up @@ -184,6 +186,9 @@ tree.
[`Call`]: Statement::Call
[`Emit`]: Statement::Emit
[`Store`]: Statement::Store
[`RayQuery`]: Statement::RayQuery
[`Proceed::result`]: RayQueryFunction::Proceed::result
[`Validator::validate`]: valid::Validator::validate
[`ModuleInfo`]: valid::ModuleInfo
Expand Down Expand Up @@ -726,6 +731,7 @@ pub enum TypeInner {

/// Opaque object representing an acceleration structure of geometry.
AccelerationStructure,

/// Locally used handle for ray queries.
RayQuery,

Expand Down Expand Up @@ -1432,9 +1438,16 @@ pub enum Expression {
/// This doesn't match the semantics of spirv's `OpArrayLength`, which must be passed
/// a pointer to a structure containing a runtime array in its' last field.
ArrayLength(Handle<Expression>),
/// Result of `rayQueryProceed`.

/// Result of a [`Proceed`] [`RayQuery`] statement.
///
/// [`Proceed`]: RayQueryFunction::Proceed
/// [`RayQuery`]: Statement::RayQuery
RayQueryProceedResult,
/// Result of `rayQueryGet*Intersection`.

/// Return an intersection found by `query`.
///
/// If `committed` is true, return the committed result available when
RayQueryGetIntersection {
query: Handle<Expression>,
committed: bool,
Expand Down Expand Up @@ -1470,18 +1483,45 @@ pub struct SwitchCase {
pub fall_through: bool,
}

/// An operation that a [`RayQuery` statement] applies to its [`query`] operand.
///
/// [`RayQuery` statement]: Statement::RayQuery
/// [`query`]: Statement::RayQuery::query
#[derive(Clone, Debug)]
#[cfg_attr(feature = "serialize", derive(Serialize))]
#[cfg_attr(feature = "deserialize", derive(Deserialize))]
#[cfg_attr(feature = "arbitrary", derive(Arbitrary))]
pub enum RayQueryFunction {
/// Initialize the `RayQuery` object.
Initialize {
/// The acceleration structure within which this query should search for hits.
///
/// The expression must be an [`AccelerationStructure`].
///
/// [`AccelerationStructure`]: TypeInner::AccelerationStructure
acceleration_structure: Handle<Expression>,

#[allow(rustdoc::private_intra_doc_links)]
/// A struct of detailed parameters for the ray query.
///
/// This expression should have the struct type given in
/// [`SpecialTypes::ray_desc`]. This is available in the WGSL
/// front end as the `RayDesc` type.
descriptor: Handle<Expression>,
},

/// Start or continue the query given by the statement's [`query`] operand.
///
/// After executing this statement, the `result` expression is a
/// [`Bool`] scalar indicating whether there are more intersection
/// candidates to consider.
///
/// [`query`]: Statement::RayQuery::query
/// [`Bool`]: ScalarKind::Bool
Proceed {
result: Handle<Expression>,
},

Terminate,
}

Expand Down Expand Up @@ -1659,7 +1699,12 @@ pub enum Statement {
result: Option<Handle<Expression>>,
},
RayQuery {
/// The [`RayQuery`] object this statement operates on.
///
/// [`RayQuery`]: TypeInner::RayQuery
query: Handle<Expression>,

/// The specific operation we're performing on `query`.
fun: RayQueryFunction,
},
}
Expand Down Expand Up @@ -1786,8 +1831,15 @@ pub struct EntryPoint {
#[cfg_attr(feature = "arbitrary", derive(Arbitrary))]
pub struct SpecialTypes {
/// Type for `RayDesc`.
///
/// Call [`Module::generate_ray_desc_type`] to populate this if
/// needed and return the handle.
ray_desc: Option<Handle<Type>>,

/// Type for `RayIntersection`.
///
/// Call [`Module::generate_ray_intersection_type`] to populate
/// this if needed and return the handle.
ray_intersection: Option<Handle<Type>>,
}

Expand Down
2 changes: 1 addition & 1 deletion src/valid/handles.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//! Implementation of [`super::Validator::validate_module_handles`].
//! Implementation of `Validator::validate_module_handles`.

use crate::{
arena::{BadHandle, BadRangeError},
Expand Down

0 comments on commit 81305a2

Please sign in to comment.