Skip to content

Commit

Permalink
Regenerate with final KHR Ray Tracing spec (#174)
Browse files Browse the repository at this point in the history
* Run cargo update

* Fix clippy::redundant_static_lifetimes

* Fix clippy::ptr_arg

* Fix clippy::len_zero

* Fix clippy::into_iter_on_ref

* Fix clippy::expect_fun_call

* OpTerminateRayKHR and OpIgnoreIntersectionKHR are terminal instrs

* dr: TerminateRayKHR and IgnoreIntersectionKHR are terminator instrs

* Regenerate with final KHR Ray Tracing spec

* binary/assemble: Add FragmentShadingRate operand

* grammar: Remodel terminator instruction handling after SPIRV-Tools

See:
KhronosGroup/SPIRV-Tools@94b11bc

Also add the missing TerminateInvocation instruction.
  • Loading branch information
MarijnS95 authored Dec 30, 2020
1 parent 3ba1ff4 commit b5ffcdb
Show file tree
Hide file tree
Showing 25 changed files with 1,403 additions and 621 deletions.
364 changes: 184 additions & 180 deletions Cargo.lock

Large diffs are not rendered by default.

14 changes: 6 additions & 8 deletions autogen/src/binary.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ fn get_decode_method(kind: &str) -> Ident {

/// Returns the generated operand decoding errors for binary::Decoder by
/// walking the given SPIR-V operand kinds `grammar`.
pub fn gen_operand_decode_errors(grammar: &Vec<structs::OperandKind>) -> TokenStream {
pub fn gen_operand_decode_errors(grammar: &[structs::OperandKind]) -> TokenStream {
let kinds: Vec<&str> = grammar
.iter()
.filter(|element| {
Expand Down Expand Up @@ -83,7 +83,7 @@ pub fn gen_operand_decode_errors(grammar: &Vec<structs::OperandKind>) -> TokenSt

/// Returns the generated operand decoding methods for binary::Decoder by
/// walking the given SPIR-V operand kinds `grammar.
pub fn gen_operand_decode_methods(grammar: &Vec<structs::OperandKind>) -> TokenStream {
pub fn gen_operand_decode_methods(grammar: &[structs::OperandKind]) -> TokenStream {
let methods = grammar.iter().filter(|element| {
// For kinds whose values may occupy more than one word, we need to
// implement manually.
Expand Down Expand Up @@ -124,12 +124,10 @@ pub fn gen_operand_decode_methods(grammar: &Vec<structs::OperandKind>) -> TokenS
/// Returns a vector of tuples, with the first element being the enumerant
/// symbol, and the second element being a list of parameter kinds to that
/// enumerant.
fn gen_operand_param_parse_methods(
grammar: &Vec<structs::OperandKind>,
) -> Vec<(&str, TokenStream)> {
fn gen_operand_param_parse_methods(grammar: &[structs::OperandKind]) -> Vec<(&str, TokenStream)> {
grammar.iter().filter(|element| {
// Filter out all the operand kinds without any enumerants.
element.enumerants.len() != 0
!element.enumerants.is_empty()
}).filter_map(|element| {
// Get the symbol and all the parameters for each enumerant.
let pairs: Vec<(&str, Vec<&str>)> =
Expand Down Expand Up @@ -216,7 +214,7 @@ fn gen_operand_param_parse_methods(

/// Returns the generated operand parsing methods for binary::Parser by
/// walking the given SPIR-V operand kinds `grammar`.
pub fn gen_operand_parse_methods(grammar: &Vec<structs::OperandKind>) -> TokenStream {
pub fn gen_operand_parse_methods(grammar: &[structs::OperandKind]) -> TokenStream {
// Operand kinds whose enumerants have parameters. For these kinds, we need
// to decode more than just the enumerants themselves.
let (further_parse_kinds, further_parse_methods): (Vec<_>, Vec<_>) =
Expand Down Expand Up @@ -306,7 +304,7 @@ pub fn gen_operand_parse_methods(grammar: &Vec<structs::OperandKind>) -> TokenSt
}
}

pub fn gen_disas_bit_enum_operands(grammar: &Vec<structs::OperandKind>) -> TokenStream {
pub fn gen_disas_bit_enum_operands(grammar: &[structs::OperandKind]) -> TokenStream {
let elements = grammar
.iter()
.filter(|op_kind| op_kind.category == structs::Category::BitEnum)
Expand Down
83 changes: 51 additions & 32 deletions autogen/src/dr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -372,42 +372,60 @@ pub fn gen_dr_builder_types(grammar: &structs::Grammar) -> TokenStream {
}
}

fn is_terminator_instruction(inst: &structs::Instruction) -> bool {
match inst.class {
Some(structs::Class::Reserved) => matches!(
inst.opname.as_str(),
"OpTerminateRayKHR" | "OpIgnoreIntersectionKHR"
),
Some(structs::Class::Branch) => !matches!(inst.opname.as_str(), "OpPhi" | "OpLabel"),
_ => false,
}
}

pub fn gen_dr_builder_terminator(grammar: &structs::Grammar) -> TokenStream {
let kinds = &grammar.operand_kinds;
// Generate build methods for all types.
let elements = grammar.instructions.iter().filter(|inst| {
inst.class == Some(structs::Class::Terminator) ||
(inst.class == Some(structs::Class::Branch) && inst.opname != "OpPhi" && inst.opname != "OpLabel")
}).map(|inst| {
let params = get_param_list(&inst.operands, false, kinds);
let extras = get_push_extras(&inst.operands, kinds, quote! { inst.operands });
let opcode = as_ident(&inst.opname[2..]);
let comment = format!("Appends an Op{} instruction and ends the current block.", opcode);
let insert_comment = format!("Insert an Op{} instruction and ends the current block.", opcode);
let name = get_function_name(&inst.opname);
let init = get_init_list(&inst.operands);
let insert_name = get_function_name_with_prepend("insert_", &inst.opname);
let elements = grammar
.instructions
.iter()
.filter(|inst| is_terminator_instruction(inst))
.map(|inst| {
let params = get_param_list(&inst.operands, false, kinds);
let extras = get_push_extras(&inst.operands, kinds, quote! { inst.operands });
let opcode = as_ident(&inst.opname[2..]);
let comment = format!(
"Appends an Op{} instruction and ends the current block.",
opcode
);
let insert_comment = format!(
"Insert an Op{} instruction and ends the current block.",
opcode
);
let name = get_function_name(&inst.opname);
let init = get_init_list(&inst.operands);
let insert_name = get_function_name_with_prepend("insert_", &inst.opname);

quote! {
#[doc = #comment]
pub fn #name(&mut self,#(#params),*) -> BuildResult<()> {
#[allow(unused_mut)]
let mut inst = dr::Instruction::new(
spirv::Op::#opcode, None, None, vec![#(#init),*]);
#(#extras)*
self.end_block(inst)
}
quote! {
#[doc = #comment]
pub fn #name(&mut self,#(#params),*) -> BuildResult<()> {
#[allow(unused_mut)]
let mut inst = dr::Instruction::new(
spirv::Op::#opcode, None, None, vec![#(#init),*]);
#(#extras)*
self.end_block(inst)
}

#[doc = #insert_comment]
pub fn #insert_name(&mut self, insert_point: InsertPoint, #(#params),*) -> BuildResult<()> {
#[allow(unused_mut)]
let mut inst = dr::Instruction::new(
spirv::Op::#opcode, None, None, vec![#(#init),*]);
#(#extras)*
self.insert_end_block(insert_point, inst)
#[doc = #insert_comment]
pub fn #insert_name(&mut self, insert_point: InsertPoint, #(#params),*) -> BuildResult<()> {
#[allow(unused_mut)]
let mut inst = dr::Instruction::new(
spirv::Op::#opcode, None, None, vec![#(#init),*]);
#(#extras)*
self.insert_end_block(insert_point, inst)
}
}
}
});
});
quote! {
impl Builder {
#(#elements)*
Expand All @@ -429,8 +447,9 @@ pub fn gen_dr_builder_normal_insts(grammar: &structs::Grammar) -> TokenStream {
(inst.class == Some(FunctionStruct) && inst.opname != "OpFunctionCall") ||
inst.class == Some(Debug) ||
inst.class == Some(Annotation) ||
inst.class == Some(Terminator) ||
(inst.class == Some(Branch) && inst.opname != "OpPhi") ||
is_terminator_instruction(inst) ||
// Labels should not be inserted but attached instead.
inst.opname == "OpLabel" ||
inst.class == Some(ModeSetting) ||
inst.class == Some(Exclude) ||
inst.opname == "OpTypeForwardPointer" ||
Expand Down
6 changes: 3 additions & 3 deletions autogen/src/header.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@ use proc_macro2::TokenStream;
use quote::quote;
use std::collections::BTreeMap;

static GLSL_STD_450_SPEC_LINK: &'static str = "\
static GLSL_STD_450_SPEC_LINK: &str = "\
https://www.khronos.org/registry/spir-v/specs/unified1/GLSL.std.450.html";

static OPENCL_STD_SPEC_LINK: &'static str = "\
static OPENCL_STD_SPEC_LINK: &str = "\
https://www.khronos.org/registry/spir-v/specs/unified1/OpenCL.ExtendedInstructionSet.100.html";

/// Returns the markdown string containing a link to the spec for the given
Expand Down Expand Up @@ -135,7 +135,7 @@ fn gen_value_enum_operand_kind(grammar: &structs::OperandKind) -> TokenStream {

let capabilities = capability_clauses.into_iter().map(|(k, v)| {
let kinds = std::iter::repeat(&kind);
let capabilities = k.into_iter().map(|cap| as_ident(cap));
let capabilities = k.iter().map(|cap| as_ident(cap));
quote! {
#( #kinds::#v )|* => &[#( Capability::#capabilities ),*]
}
Expand Down
2 changes: 1 addition & 1 deletion autogen/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use std::{
use utils::write_autogen_comment;

fn write(path: &PathBuf, contents: impl ToString) {
let mut f = fs::File::create(path).expect(&format!("cannot open file: {:?}", path));
let mut f = fs::File::create(path).unwrap_or_else(|_| panic!("cannot open file: {:?}", path));
write_autogen_comment(&mut f);
write!(f, "{}", contents.to_string()).unwrap()
}
Expand Down
2 changes: 1 addition & 1 deletion autogen/src/sr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -401,7 +401,7 @@ pub fn gen_sr_code_from_instruction_grammar(
});
}
}
Some(Terminator) => {
Some(Reserved) if matches!(inst_name, "TerminateRayKHR" | "IgnoreIntersectionKHR") => {
if field_names.is_empty() {
terminator_variants.push(quote! { #name_ident });
terminator_lifts.push(quote! {
Expand Down
1 change: 0 additions & 1 deletion autogen/src/structs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,6 @@ pub enum Class {
FunctionStruct,
#[serde(rename = "Mode-Setting")]
ModeSetting,
Terminator,
#[serde(rename = "Type-Declaration")]
Type,
Variable,
Expand Down
2 changes: 1 addition & 1 deletion autogen/src/table.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ fn convert_quantifier(quantifier: structs::Quantifier) -> Ident {
/// `name` is the name of the generated table.
/// `is_ext` indicates whether the grammar is for an extended instruction set.
fn gen_instruction_table(
grammar: &Vec<structs::Instruction>,
grammar: &[structs::Instruction],
name: &str,
is_ext: bool,
) -> TokenStream {
Expand Down
2 changes: 1 addition & 1 deletion autogen/src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use proc_macro2::{Ident, Span, TokenStream};
use quote::quote;

#[rustfmt::skip]
static AUTOGEN_COMMENT : &'static str = "\
static AUTOGEN_COMMENT : &str = "\
// AUTOMATICALLY GENERATED from the SPIR-V JSON grammar:
// external/spirv.core.grammar.json.
// DO NOT MODIFY!";
Expand Down
1 change: 1 addition & 0 deletions rspirv/binary/assemble.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ impl Assemble for dr::Operand {
dr::Operand::RayQueryIntersection(v) => result.push(v as u32),
dr::Operand::RayQueryCommittedIntersectionType(v) => result.push(v as u32),
dr::Operand::RayQueryCandidateIntersectionType(v) => result.push(v as u32),
dr::Operand::FragmentShadingRate(v) => result.push(v.bits()),
}
}
}
Expand Down
11 changes: 11 additions & 0 deletions rspirv/binary/autogen_decode_operand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,17 @@ impl<'a> Decoder<'a> {
Err(Error::StreamExpected(self.offset))
}
}
#[doc = "Decodes and returns the next SPIR-V word as\na SPIR-V FragmentShadingRate value."]
pub fn fragment_shading_rate(&mut self) -> Result<spirv::FragmentShadingRate> {
if let Ok(word) = self.word() {
spirv::FragmentShadingRate::from_bits(word).ok_or(Error::FragmentShadingRateUnknown(
self.offset - WORD_NUM_BYTES,
word,
))
} else {
Err(Error::StreamExpected(self.offset))
}
}
#[doc = "Decodes and returns the next SPIR-V word as\na SPIR-V SourceLanguage value."]
pub fn source_language(&mut self) -> Result<spirv::SourceLanguage> {
if let Ok(word) = self.word() {
Expand Down
42 changes: 42 additions & 0 deletions rspirv/binary/autogen_disas_operand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,27 @@ impl Disassemble for spirv::LoopControl {
if self.contains(spirv::LoopControl::PARTIAL_COUNT) {
bits.push("PartialCount")
}
if self.contains(spirv::LoopControl::INITIATION_INTERVAL_INTEL) {
bits.push("InitiationIntervalINTEL")
}
if self.contains(spirv::LoopControl::MAX_CONCURRENCY_INTEL) {
bits.push("MaxConcurrencyINTEL")
}
if self.contains(spirv::LoopControl::DEPENDENCY_ARRAY_INTEL) {
bits.push("DependencyArrayINTEL")
}
if self.contains(spirv::LoopControl::PIPELINE_ENABLE_INTEL) {
bits.push("PipelineEnableINTEL")
}
if self.contains(spirv::LoopControl::LOOP_COALESCE_INTEL) {
bits.push("LoopCoalesceINTEL")
}
if self.contains(spirv::LoopControl::MAX_INTERLEAVING_INTEL) {
bits.push("MaxInterleavingINTEL")
}
if self.contains(spirv::LoopControl::SPECULATED_ITERATIONS_INTEL) {
bits.push("SpeculatedIterationsINTEL")
}
bits.join("|")
}
}
Expand Down Expand Up @@ -308,3 +329,24 @@ impl Disassemble for spirv::RayFlags {
bits.join("|")
}
}
impl Disassemble for spirv::FragmentShadingRate {
fn disassemble(&self) -> String {
if self.is_empty() {
return "None".to_string();
}
let mut bits = vec![];
if self.contains(spirv::FragmentShadingRate::VERTICAL2_PIXELS) {
bits.push("Vertical2Pixels")
}
if self.contains(spirv::FragmentShadingRate::VERTICAL4_PIXELS) {
bits.push("Vertical4Pixels")
}
if self.contains(spirv::FragmentShadingRate::HORIZONTAL2_PIXELS) {
bits.push("Horizontal2Pixels")
}
if self.contains(spirv::FragmentShadingRate::HORIZONTAL4_PIXELS) {
bits.push("Horizontal4Pixels")
}
bits.join("|")
}
}
6 changes: 6 additions & 0 deletions rspirv/binary/autogen_error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ pub enum Error {
MemoryAccessUnknown(usize, spirv::Word),
KernelProfilingInfoUnknown(usize, spirv::Word),
RayFlagsUnknown(usize, spirv::Word),
FragmentShadingRateUnknown(usize, spirv::Word),
SourceLanguageUnknown(usize, spirv::Word),
ExecutionModelUnknown(usize, spirv::Word),
AddressingModelUnknown(usize, spirv::Word),
Expand Down Expand Up @@ -102,6 +103,11 @@ impl fmt::Display for Error {
"unknown value {} for operand kind RayFlags at index {}",
word, index
),
Error::FragmentShadingRateUnknown(index, word) => write!(
f,
"unknown value {} for operand kind FragmentShadingRate at index {}",
word, index
),
Error::SourceLanguageUnknown(index, word) => write!(
f,
"unknown value {} for operand kind SourceLanguage at index {}",
Expand Down
Loading

0 comments on commit b5ffcdb

Please sign in to comment.