Skip to content

Commit

Permalink
spv-out: basic ray query support
Browse files Browse the repository at this point in the history
  • Loading branch information
kvark committed Feb 18, 2023
1 parent 16a293a commit 2fcb3c6
Show file tree
Hide file tree
Showing 10 changed files with 400 additions and 62 deletions.
162 changes: 153 additions & 9 deletions src/back/spv/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1069,9 +1069,9 @@ impl<'w> BlockContext<'w> {
}
}
crate::Expression::FunctionArgument(index) => self.function.parameter_id(index),
crate::Expression::CallResult(_) | crate::Expression::AtomicResult { .. } => {
self.cached[expr_handle]
}
crate::Expression::CallResult(_)
| crate::Expression::AtomicResult { .. }
| crate::Expression::RayQueryProceedResult => self.cached[expr_handle],
crate::Expression::As {
expr,
kind,
Expand Down Expand Up @@ -1364,10 +1364,61 @@ impl<'w> BlockContext<'w> {
id
}
crate::Expression::ArrayLength(expr) => self.write_runtime_array_length(expr, block)?,
//TODO
crate::Expression::RayQueryProceedResult => unreachable!(),
//TODO
crate::Expression::RayQueryGetIntersection { .. } => unreachable!(),
crate::Expression::RayQueryGetIntersection { query, committed } => {
let width = 4;
let query_id = self.cached[query];
let intersection_id = self.writer.get_constant_scalar(
crate::ScalarValue::Uint(
spirv::RayQueryIntersection::RayQueryCommittedIntersectionKHR as _,
),
width,
);
if !committed {
return Err(Error::FeatureNotImplemented("candidate intersection"));
}

let flag_type_id = self.get_type_id(LookupType::Local(LocalType::Value {
vector_size: None,
kind: crate::ScalarKind::Uint,
width,
pointer_space: None,
}));
let kind_id = self.gen_id();
block.body.push(Instruction::ray_query_get_intersection(
spirv::Op::RayQueryGetIntersectionTypeKHR,
flag_type_id,
kind_id,
query_id,
intersection_id,
));

let scalar_type_id = self.get_type_id(LookupType::Local(LocalType::Value {
vector_size: None,
kind: crate::ScalarKind::Float,
width,
pointer_space: None,
}));
let t_id = self.gen_id();
block.body.push(Instruction::ray_query_get_intersection(
spirv::Op::RayQueryGetIntersectionTKHR,
scalar_type_id,
t_id,
query_id,
intersection_id,
));

let id = self.gen_id();
let intersection_type_id = self.get_type_id(LookupType::Handle(
self.ir_module.special_types.ray_intersection.unwrap(),
));
//Note: the arguments must match `generate_ray_intersection_type` layout
block.body.push(Instruction::composite_construct(
intersection_type_id,
id,
&[kind_id, t_id],
));
id
}
};

self.cached[expr_handle] = id;
Expand Down Expand Up @@ -2181,8 +2232,101 @@ impl<'w> BlockContext<'w> {
crate::RayQueryFunction::Initialize {
acceleration_structure,
descriptor,
} => {}
crate::RayQueryFunction::Proceed => {}
} => {
//Note: composite extract indices and types must match `generate_ray_desc_type`
let desc_id = self.cached[descriptor];
let acc_struct_id = self.get_image_id(acceleration_structure);
let width = 4;

let flag_type_id =
self.get_type_id(LookupType::Local(LocalType::Value {
vector_size: None,
kind: crate::ScalarKind::Uint,
width,
pointer_space: None,
}));
let ray_flags_id = self.gen_id();
block.body.push(Instruction::composite_extract(
flag_type_id,
ray_flags_id,
desc_id,
&[0],
));
let cull_mask_id = self.gen_id();
block.body.push(Instruction::composite_extract(
flag_type_id,
cull_mask_id,
desc_id,
&[1],
));

let scalar_type_id =
self.get_type_id(LookupType::Local(LocalType::Value {
vector_size: None,
kind: crate::ScalarKind::Float,
width,
pointer_space: None,
}));
let tmin_id = self.gen_id();
block.body.push(Instruction::composite_extract(
scalar_type_id,
tmin_id,
desc_id,
&[2],
));
let tmax_id = self.gen_id();
block.body.push(Instruction::composite_extract(
scalar_type_id,
tmax_id,
desc_id,
&[3],
));

let vector_type_id =
self.get_type_id(LookupType::Local(LocalType::Value {
vector_size: Some(crate::VectorSize::Tri),
kind: crate::ScalarKind::Float,
width,
pointer_space: None,
}));
let ray_origin_id = self.gen_id();
block.body.push(Instruction::composite_extract(
vector_type_id,
ray_origin_id,
desc_id,
&[4],
));
let ray_dir_id = self.gen_id();
block.body.push(Instruction::composite_extract(
vector_type_id,
ray_dir_id,
desc_id,
&[5],
));

block.body.push(Instruction::ray_query_initialize(
query_id,
acc_struct_id,
ray_flags_id,
cull_mask_id,
ray_origin_id,
tmin_id,
ray_dir_id,
tmax_id,
));
}
crate::RayQueryFunction::Proceed { result } => {
let id = self.gen_id();
self.cached[result] = id;
let result_type_id =
self.get_expression_type_id(&self.fun_info[result].ty);

block.body.push(Instruction::ray_query_proceed(
result_type_id,
id,
query_id,
));
}
crate::RayQueryFunction::Terminate => {}
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/back/spv/image.rs
Original file line number Diff line number Diff line change
Expand Up @@ -373,7 +373,7 @@ impl<'w> BlockContext<'w> {
})
}

fn get_image_id(&mut self, expr_handle: Handle<crate::Expression>) -> Word {
pub(super) fn get_image_id(&mut self, expr_handle: Handle<crate::Expression>) -> Word {
let id = match self.ir_function.expressions[expr_handle] {
crate::Expression::GlobalVariable(handle) => {
self.writer.global_variables[handle.index()].handle_id
Expand Down
60 changes: 60 additions & 0 deletions src/back/spv/instructions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,18 @@ impl super::Instruction {
instruction
}

pub(super) fn type_acceleration_structure(id: Word) -> Self {
let mut instruction = Self::new(Op::TypeAccelerationStructureKHR);
instruction.set_result(id);
instruction
}

pub(super) fn type_ray_query(id: Word) -> Self {
let mut instruction = Self::new(Op::TypeRayQueryKHR);
instruction.set_result(id);
instruction
}

pub(super) fn type_sampled_image(id: Word, image_type_id: Word) -> Self {
let mut instruction = Self::new(Op::TypeSampledImage);
instruction.set_result(id);
Expand Down Expand Up @@ -627,6 +639,54 @@ impl super::Instruction {
instruction
}

//
// Ray Query Instructions
//
pub(super) fn ray_query_initialize(
query: Word,
acceleration_structure: Word,
ray_flags: Word,
cull_mask: Word,
ray_origin: Word,
ray_tmin: Word,
ray_dir: Word,
ray_tmax: Word,
) -> Self {
let mut instruction = Self::new(Op::RayQueryInitializeKHR);
instruction.add_operand(query);
instruction.add_operand(acceleration_structure);
instruction.add_operand(ray_flags);
instruction.add_operand(cull_mask);
instruction.add_operand(ray_origin);
instruction.add_operand(ray_tmin);
instruction.add_operand(ray_dir);
instruction.add_operand(ray_tmax);
instruction
}

pub(super) fn ray_query_proceed(result_type_id: Word, id: Word, query: Word) -> Self {
let mut instruction = Self::new(Op::RayQueryProceedKHR);
instruction.set_type(result_type_id);
instruction.set_result(id);
instruction.add_operand(query);
instruction
}

pub(super) fn ray_query_get_intersection(
op: Op,
result_type_id: Word,
id: Word,
query: Word,
intersection: Word,
) -> Self {
let mut instruction = Self::new(op);
instruction.set_type(result_type_id);
instruction.set_result(id);
instruction.add_operand(query);
instruction.add_operand(intersection);
instruction
}

//
// Conversion Instructions
//
Expand Down
8 changes: 7 additions & 1 deletion src/back/spv/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,8 @@ enum LocalType {
base: Handle<crate::Type>,
size: u64,
},
AccelerationStructure,
RayQuery,
}

/// A type encountered during SPIR-V generation.
Expand Down Expand Up @@ -383,7 +385,11 @@ fn make_local(inner: &crate::TypeInner) -> Option<LocalType> {
class,
} => LocalType::Image(LocalImageType::from_inner(dim, arrayed, class)),
crate::TypeInner::Sampler { comparison: _ } => LocalType::Sampler,
_ => return None,
crate::TypeInner::AccelerationStructure => LocalType::AccelerationStructure,
crate::TypeInner::RayQuery => LocalType::RayQuery,
crate::TypeInner::Array { .. }
| crate::TypeInner::Struct { .. }
| crate::TypeInner::BindingArray { .. } => return None,
})
}

Expand Down
Loading

0 comments on commit 2fcb3c6

Please sign in to comment.