Address Jim's review notes, use typegen module for atomic struct

This commit is contained in:
Dzmitry Malyshau 2023-03-21 22:47:53 -07:00
parent 024c197cc8
commit c34eed5e47
9 changed files with 92 additions and 68 deletions

View File

@ -254,19 +254,25 @@ impl StatementGraph {
}
S::RayQuery { query, ref fun } => {
self.dependencies.push((id, query, "query"));
if let crate::RayQueryFunction::Initialize {
acceleration_structure,
descriptor,
} = *fun
{
self.dependencies.push((
id,
match *fun {
crate::RayQueryFunction::Initialize {
acceleration_structure,
"acceleration_structure",
));
self.dependencies.push((id, descriptor, "descriptor"));
descriptor,
} => {
self.dependencies.push((
id,
acceleration_structure,
"acceleration_structure",
));
self.dependencies.push((id, descriptor, "descriptor"));
"RayQueryInitialize"
}
crate::RayQueryFunction::Proceed { result } => {
self.emits.push((id, result));
"RayQueryProceed"
}
crate::RayQueryFunction::Terminate => "RayQueryTerminate",
}
"RayQuery"
}
};
// Set the last node to the merge node

View File

@ -234,8 +234,8 @@ bitflags::bitflags! {
const NO_OPAQUE = 0x02;
const TERMINATE_ON_FIRST_HIT = 0x04;
const SKIP_CLOSEST_HIT_SHADER = 0x08;
const CULL_FRONT_FACING = 0x10;
const CULL_BACK_FACING = 0x20;
const CULL_BACK_FACING = 0x10;
const CULL_FRONT_FACING = 0x20;
const CULL_OPAQUE = 0x40;
const CULL_NO_OPAQUE = 0x80;
const SKIP_TRIANGLES = 0x100;

View File

@ -973,7 +973,7 @@ impl Writer {
self.write_type_declaration_local(id, local);
// If it's an type that needs SPIR-V capabilities, request them now,
// If it's a type that needs SPIR-V capabilities, request them now,
// so write_type_declaration_local can stay infallible.
self.request_type_capabilities(&ty.inner)?;

View File

@ -5,6 +5,55 @@ Type generators.
use crate::{arena::Handle, span::Span};
impl crate::Module {
pub fn generate_atomic_compare_exchange_result(
&mut self,
kind: crate::ScalarKind,
width: crate::Bytes,
) -> Handle<crate::Type> {
let bool_ty = self.types.insert(
crate::Type {
name: None,
inner: crate::TypeInner::Scalar {
kind: crate::ScalarKind::Bool,
width: crate::BOOL_WIDTH,
},
},
Span::UNDEFINED,
);
let scalar_ty = self.types.insert(
crate::Type {
name: None,
inner: crate::TypeInner::Scalar { kind, width },
},
Span::UNDEFINED,
);
self.types.insert(
crate::Type {
name: Some(format!(
"__atomic_compare_exchange_result<{kind:?},{width}>"
)),
inner: crate::TypeInner::Struct {
members: vec![
crate::StructMember {
name: Some("old_value".to_string()),
ty: scalar_ty,
binding: None,
offset: 0,
},
crate::StructMember {
name: Some("exchanged".to_string()),
ty: bool_ty,
binding: None,
offset: 4,
},
],
span: 8,
},
},
Span::UNDEFINED,
)
}
/// Populate this module's [`SpecialTypes::ray_desc`] type.
///
/// [`SpecialTypes::ray_desc`] is the type of the [`descriptor`] operand of
@ -20,7 +69,7 @@ impl crate::Module {
/// [`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> {
pub fn generate_ray_desc_type(&mut self) -> Handle<crate::Type> {
if let Some(handle) = self.special_types.ray_desc {
return handle;
}
@ -122,7 +171,7 @@ impl crate::Module {
///
/// [`SpecialTypes::ray_intersection`]: crate::SpecialTypes::ray_intersection
/// [`Expression::RayQueryGetIntersection`]: crate::Expression::RayQueryGetIntersection
pub(super) fn generate_ray_intersection_type(&mut self) -> Handle<crate::Type> {
pub fn generate_ray_intersection_type(&mut self) -> Handle<crate::Type> {
if let Some(handle) = self.special_types.ray_intersection {
return handle;
}

View File

@ -188,6 +188,7 @@ pub enum Error<'a> {
MissingAttribute(&'static str, Span),
InvalidAtomicPointer(Span),
InvalidAtomicOperandType(Span),
InvalidRayQueryPointer(Span),
Pointer(&'static str, Span),
NotPointer(Span),
NotReference(&'static str, Span),
@ -526,6 +527,11 @@ impl<'a> Error<'a> {
labels: vec![(span, "atomic operand type is invalid".into())],
notes: vec![],
},
Error::InvalidRayQueryPointer(span) => ParseError {
message: "ray query operation is done on a pointer to a non-ray-query".to_string(),
labels: vec![(span, "ray query pointer is invalid".into())],
notes: vec![],
},
Error::NotPointer(span) => ParseError {
message: "the operand of the `*` operator must be a pointer".to_string(),
labels: vec![(span, "expression is not a pointer".into())],

View File

@ -641,6 +641,8 @@ impl<'source, 'temp> Lowerer<'source, 'temp> {
let span = tu.decls.get_span(decl_handle);
let decl = &tu.decls[decl_handle];
//NOTE: This is done separately from `resolve_ast_type` because `RayDesc` may be
// first encountered in a local constructor invocation.
//TODO: find a nicer way?
if let Some(dep) = decl.dependencies.iter().find(|dep| dep.ident == "RayDesc") {
let ty_handle = ctx.module.generate_ray_desc_type();
@ -1733,50 +1735,11 @@ impl<'source, 'temp> Lowerer<'source, 'temp> {
let expression = match *ctx.resolved_inner(value) {
crate::TypeInner::Scalar { kind, width } => {
let bool_ty = ctx.module.types.insert(
crate::Type {
name: None,
inner: crate::TypeInner::Scalar {
kind: crate::ScalarKind::Bool,
width: crate::BOOL_WIDTH,
},
},
Span::UNDEFINED,
);
let scalar_ty = ctx.module.types.insert(
crate::Type {
name: None,
inner: crate::TypeInner::Scalar { kind, width },
},
Span::UNDEFINED,
);
let struct_ty = ctx.module.types.insert(
crate::Type {
name: Some(
"__atomic_compare_exchange_result".to_string(),
),
inner: crate::TypeInner::Struct {
members: vec![
crate::StructMember {
name: Some("old_value".to_string()),
ty: scalar_ty,
binding: None,
offset: 0,
},
crate::StructMember {
name: Some("exchanged".to_string()),
ty: bool_ty,
binding: None,
offset: 4,
},
],
span: 8,
},
},
Span::UNDEFINED,
);
crate::Expression::AtomicResult {
ty: struct_ty,
//TODO: cache this to avoid generating duplicate types
ty: ctx
.module
.generate_atomic_compare_exchange_result(kind, width),
comparison: true,
}
}
@ -2449,12 +2412,12 @@ impl<'source, 'temp> Lowerer<'source, 'temp> {
crate::TypeInner::RayQuery => Ok(pointer),
ref other => {
log::error!("Pointer type to {:?} passed to ray query op", other);
Err(Error::InvalidAtomicPointer(span))
Err(Error::InvalidRayQueryPointer(span))
}
},
ref other => {
log::error!("Type {:?} passed to ray query op", other);
Err(Error::InvalidAtomicPointer(span))
Err(Error::InvalidRayQueryPointer(span))
}
}
}

View File

@ -1460,7 +1460,7 @@ pub enum Expression {
/// Return an intersection found by `query`.
///
/// If `committed` is true, return the committed result available when
/// If `committed` is true, return the committed result available when
RayQueryGetIntersection {
query: Handle<Expression>,
committed: bool,
@ -1848,13 +1848,13 @@ pub struct SpecialTypes {
///
/// Call [`Module::generate_ray_desc_type`] to populate this if
/// needed and return the handle.
ray_desc: Option<Handle<Type>>,
pub 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>>,
pub ray_intersection: Option<Handle<Type>>,
}
/// Shader module.

View File

@ -7,8 +7,8 @@ let RAY_FLAG_OPAQUE = 0x01u;
let RAY_FLAG_NO_OPAQUE = 0x02u;
let RAY_FLAG_TERMINATE_ON_FIRST_HIT = 0x04u;
let RAY_FLAG_SKIP_CLOSEST_HIT_SHADER = 0x08u;
let RAY_FLAG_CULL_FRONT_FACING = 0x10u;
let RAY_FLAG_CULL_BACK_FACING = 0x20u;
let RAY_FLAG_CULL_BACK_FACING = 0x10u;
let RAY_FLAG_CULL_FRONT_FACING = 0x20u;
let RAY_FLAG_CULL_OPAQUE = 0x40u;
let RAY_FLAG_CULL_NO_OPAQUE = 0x80u;
let RAY_FLAG_SKIP_TRIANGLES = 0x100u;

View File

@ -1,9 +1,9 @@
struct gen___atomic_compare_exchange_result {
struct gen___atomic_compare_exchange_resultSint4_ {
old_value: i32,
exchanged: bool,
}
struct gen___atomic_compare_exchange_result_1 {
struct gen___atomic_compare_exchange_resultUint4_ {
old_value: u32,
exchanged: bool,
}