Skip to content

Commit

Permalink
[msl-out] add min version check for ray tracing
Browse files Browse the repository at this point in the history
  • Loading branch information
teoxoy authored and jimblandy committed Oct 17, 2023
1 parent 89ab590 commit ea83f62
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 30 deletions.
2 changes: 2 additions & 0 deletions src/back/msl/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,8 @@ pub enum Error {
UnsupportedArrayOf(String),
#[error("array of type '{0:?}' is not supported")]
UnsupportedArrayOfType(Handle<crate::Type>),
#[error("ray tracing is not supported prior to MSL 2.3")]
UnsupportedRayTracing,
}

#[derive(Clone, Debug, PartialEq, thiserror::Error)]
Expand Down
97 changes: 67 additions & 30 deletions src/back/msl/writer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1961,6 +1961,10 @@ impl<W: Write> Writer<W> {
}
}
crate::Expression::RayQueryGetIntersection { query, committed } => {
if context.lang_version < (2, 4) {
return Err(Error::UnsupportedRayTracing);
}

if !committed {
unimplemented!()
}
Expand All @@ -1971,16 +1975,16 @@ impl<W: Write> Writer<W> {
write!(self.out, ".{RAY_QUERY_FIELD_INTERSECTION}.type)")?;
let fields = [
"distance",
"user_instance_id",
"user_instance_id", // req Metal 2.4
"instance_id",
"", // SBT offset
"geometry_id",
"primitive_id",
"triangle_barycentric_coord",
"triangle_front_facing",
"", // padding
"object_to_world_transform",
"world_to_object_transform",
"", // padding
"object_to_world_transform", // req Metal 2.4
"world_to_object_transform", // req Metal 2.4
];
for field in fields {
write!(self.out, ", ")?;
Expand Down Expand Up @@ -2913,6 +2917,10 @@ impl<W: Write> Writer<W> {
self.write_barrier(crate::Barrier::WORK_GROUP, level)?;
}
crate::Statement::RayQuery { query, ref fun } => {
if context.expression.lang_version < (2, 4) {
return Err(Error::UnsupportedRayTracing);
}

match *fun {
crate::RayQueryFunction::Initialize {
acceleration_structure,
Expand Down Expand Up @@ -3104,33 +3112,36 @@ impl<W: Write> Writer<W> {
// Work around Metal bug where `uint` is not available by default
writeln!(self.out, "using {NAMESPACE}::uint;")?;

if module.types.iter().any(|(_, t)| match t.inner {
crate::TypeInner::RayQuery => true,
_ => false,
}) {
let tab = back::INDENT;
writeln!(self.out, "struct {RAY_QUERY_TYPE} {{")?;
let full_type = format!("{RT_NAMESPACE}::intersector<{RT_NAMESPACE}::instancing, {RT_NAMESPACE}::triangle_data, {RT_NAMESPACE}::world_space_data>");
writeln!(self.out, "{tab}{full_type} {RAY_QUERY_FIELD_INTERSECTOR};")?;
writeln!(
self.out,
"{tab}{full_type}::result_type {RAY_QUERY_FIELD_INTERSECTION};"
)?;
writeln!(self.out, "{tab}bool {RAY_QUERY_FIELD_READY} = false;")?;
writeln!(self.out, "}};")?;
writeln!(self.out, "constexpr {NAMESPACE}::uint {RAY_QUERY_FUN_MAP_INTERSECTION}(const {RT_NAMESPACE}::intersection_type ty) {{")?;
let v_triangle = back::RayIntersectionType::Triangle as u32;
let v_bbox = back::RayIntersectionType::BoundingBox as u32;
writeln!(
self.out,
"{tab}return ty=={RT_NAMESPACE}::intersection_type::triangle ? {v_triangle} : "
)?;
writeln!(
self.out,
"{tab}{tab}ty=={RT_NAMESPACE}::intersection_type::bounding_box ? {v_bbox} : 0;"
)?;
writeln!(self.out, "}}")?;
let mut uses_ray_query = false;
for (_, ty) in module.types.iter() {
match ty.inner {
crate::TypeInner::AccelerationStructure => {
if options.lang_version < (2, 4) {
return Err(Error::UnsupportedRayTracing);
}
}
crate::TypeInner::RayQuery => {
if options.lang_version < (2, 4) {
return Err(Error::UnsupportedRayTracing);
}
uses_ray_query = true;
}
_ => (),
}
}

if module.special_types.ray_desc.is_some()
|| module.special_types.ray_intersection.is_some()
{
if options.lang_version < (2, 4) {
return Err(Error::UnsupportedRayTracing);
}
}

if uses_ray_query {
self.put_ray_query_type()?;
}

if options
.bounds_check_policies
.contains(index::BoundsCheckPolicy::ReadZeroSkipWrite)
Expand Down Expand Up @@ -3188,6 +3199,32 @@ impl<W: Write> Writer<W> {
Ok(())
}

fn put_ray_query_type(&mut self) -> BackendResult {
let tab = back::INDENT;
writeln!(self.out, "struct {RAY_QUERY_TYPE} {{")?;
let full_type = format!("{RT_NAMESPACE}::intersector<{RT_NAMESPACE}::instancing, {RT_NAMESPACE}::triangle_data, {RT_NAMESPACE}::world_space_data>");
writeln!(self.out, "{tab}{full_type} {RAY_QUERY_FIELD_INTERSECTOR};")?;
writeln!(
self.out,
"{tab}{full_type}::result_type {RAY_QUERY_FIELD_INTERSECTION};"
)?;
writeln!(self.out, "{tab}bool {RAY_QUERY_FIELD_READY} = false;")?;
writeln!(self.out, "}};")?;
writeln!(self.out, "constexpr {NAMESPACE}::uint {RAY_QUERY_FUN_MAP_INTERSECTION}(const {RT_NAMESPACE}::intersection_type ty) {{")?;
let v_triangle = back::RayIntersectionType::Triangle as u32;
let v_bbox = back::RayIntersectionType::BoundingBox as u32;
writeln!(
self.out,
"{tab}return ty=={RT_NAMESPACE}::intersection_type::triangle ? {v_triangle} : "
)?;
writeln!(
self.out,
"{tab}{tab}ty=={RT_NAMESPACE}::intersection_type::bounding_box ? {v_bbox} : 0;"
)?;
writeln!(self.out, "}}")?;
Ok(())
}

fn write_type_defs(&mut self, module: &crate::Module) -> BackendResult {
for (handle, ty) in module.types.iter() {
if !ty.needs_alias() {
Expand Down

0 comments on commit ea83f62

Please sign in to comment.