Skip to content

Commit

Permalink
Simplify extensions. Add Debug PrintF
Browse files Browse the repository at this point in the history
  • Loading branch information
Matthias-Fauconneau committed Sep 23, 2021
1 parent ccbc13c commit ad4bf42
Show file tree
Hide file tree
Showing 7 changed files with 110 additions and 125 deletions.
62 changes: 7 additions & 55 deletions autogen/src/header.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,6 @@ use proc_macro2::TokenStream;
use quote::quote;
use std::collections::BTreeMap;

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: &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
/// operand `kind`.
fn get_spec_link(kind: &str) -> String {
Expand Down Expand Up @@ -304,48 +298,10 @@ pub fn gen_spirv_header(grammar: &structs::Grammar) -> TokenStream {
}
}

/// Returns the GLSL.std.450 extended instruction opcodes.
pub fn gen_glsl_std_450_opcodes(grammar: &structs::ExtInstSetGrammar) -> TokenStream {
// Get the instruction table.
let opcodes = grammar.instructions.iter().map(|inst| {
// Omit the "Op" prefix.
let opname = as_ident(&inst.opname);
let opcode = inst.opcode;
quote! { #opname = #opcode }
});

let from_prim_list = grammar
.instructions
.iter()
.map(|inst| {
let opname = as_ident(&inst.opname);
let opcode = inst.opcode;
quote! { #opcode => GLOp::#opname }
})
.collect::<Vec<_>>();

let comment = format!(
"[GLSL.std.450]({}) extended instruction opcode",
GLSL_STD_450_SPEC_LINK
);
let attribute = value_enum_attribute();
let from_prim_impl = from_primitive_impl(&from_prim_list, &as_ident("GLOp"));

quote! {
#[doc = #comment]
#attribute
#[allow(clippy::upper_case_acronyms)]
pub enum GLOp {
#(#opcodes),*
}

#from_prim_impl
}
}

/// Returns the OpenCL.std extended instruction opcodes.
pub fn gen_opencl_std_opcodes(grammar: &structs::ExtInstSetGrammar) -> TokenStream {
// Get the instruction table.
/// Returns extended instruction opcodes
pub fn gen_opcodes(op: &str, grammar: &structs::ExtInstSetGrammar, comment: &str) -> TokenStream {
let op = as_ident(op);
// Get the instruction table
let opcodes = grammar.instructions.iter().map(|inst| {
// Omit the "Op" prefix.
let opname = as_ident(&inst.opname);
Expand All @@ -359,22 +315,18 @@ pub fn gen_opencl_std_opcodes(grammar: &structs::ExtInstSetGrammar) -> TokenStre
.map(|inst| {
let opname = as_ident(&inst.opname);
let opcode = inst.opcode;
quote! { #opcode => CLOp::#opname }
quote! { #opcode => #op::#opname }
})
.collect::<Vec<_>>();

let comment = format!(
"[OpenCL.std]({}) extended instruction opcode",
OPENCL_STD_SPEC_LINK
);
let attribute = value_enum_attribute();
let from_prim_impl = from_primitive_impl(&from_prim_list, &as_ident("CLOp"));
let from_prim_impl = from_primitive_impl(&from_prim_list, &op);

quote! {
#[doc = #comment]
#attribute
#[allow(clippy::upper_case_acronyms)]
pub enum CLOp {
pub enum #op {
#(#opcodes),*
}

Expand Down
112 changes: 65 additions & 47 deletions autogen/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,9 @@ mod table;
mod utils;

use std::{
env, fs,
io::{Read, Write},
env,
fs,
io::Write,
path::{Path, PathBuf},
process,
};
Expand Down Expand Up @@ -61,65 +62,82 @@ fn main() {
panic!("SPIRV-Headers missing - please checkout using git submodule");
}

let mut contents = String::new();

{
let path = autogen_src_dir
.join("external/SPIRV-Headers/include/spirv/unified1/spirv.core.grammar.json");
let mut file = fs::File::open(path).unwrap();
file.read_to_string(&mut contents).unwrap();
}

let grammar: structs::Grammar = {
let mut original = serde_json::from_str(&contents).unwrap();
let mut original =
serde_json::from_str(
&std::str::from_utf8(
&fs::read(autogen_src_dir.join(
"external/SPIRV-Headers/include/spirv/unified1/spirv.core.grammar.json",
))
.unwrap(),
)
.unwrap(),
)
.unwrap();
map_reserved_instructions(&mut original);
original
};

// For GLSLstd450 extended instruction set.
{
let path = autogen_src_dir.join(
"external/SPIRV-Headers/include/spirv/unified1/extinst.glsl.std.450.grammar.json",
);
let mut file = fs::File::open(path).unwrap();
contents.clear();
file.read_to_string(&mut contents).unwrap();
}
let gl_grammar: structs::ExtInstSetGrammar = serde_json::from_str(&contents).unwrap();

// For OpenCL extended instruction set.
{
let path = autogen_src_dir.join(
"external/SPIRV-Headers/include/spirv/unified1/extinst.opencl.std.100.grammar.json",
);
let mut file = fs::File::open(path).unwrap();
contents.clear();
file.read_to_string(&mut contents).unwrap();
}
let cl_grammar: structs::ExtInstSetGrammar = serde_json::from_str(&contents).unwrap();
let extended_instruction_sets = [
("GLSL.std.450", "GLOp", "https://www.khronos.org/registry/spir-v/specs/unified1/GLSL.std.450.html"),
("OpenCL.std.100", "CLOp", "https://www.khronos.org/registry/spir-v/specs/unified1/OpenCL.ExtendedInstructionSet.100.html"),
("NonSemantic.DebugPrintF", "DebugPrintFOp", "https://github.com/KhronosGroup/Vulkan-ValidationLayers/blob/master/docs/debug_printf.md"),
];
let extended_instruction_sets = extended_instruction_sets.map(|(ext, op, url)| {
let grammar: structs::ExtInstSetGrammar = serde_json::from_str(
&std::str::from_utf8(
&fs::read(autogen_src_dir.join(format!(
"external/SPIRV-Headers/include/spirv/unified1/extinst.{}.grammar.json",
ext.to_lowercase()
)))
.unwrap(),
)
.unwrap(),
)
.unwrap();
(ext, op, url, grammar)
});

// Path to the generated SPIR-V header file.
// SPIR-V header
write_formatted(&autogen_src_dir.join("../spirv/autogen_spirv.rs"), {
let core = header::gen_spirv_header(&grammar);
let gl = header::gen_glsl_std_450_opcodes(&gl_grammar);
let cl = header::gen_opencl_std_opcodes(&cl_grammar);
format!("{}\n{}\n{}", core, gl, cl)
let extended_instruction_sets =
extended_instruction_sets
.iter()
.map(|(ext, op, url, grammar)| {
header::gen_opcodes(
op,
&grammar,
&format!("[{}]({}) extended instruction opcode", ext, url),
)
.to_string()
});
format!(
"{}\n{}",
core,
extended_instruction_sets.collect::<Box<_>>().join("\n")
)
});

// Path to the generated instruction table.
// Instruction table
write_formatted(
&autogen_src_dir.join("../rspirv/grammar/autogen_table.rs"),
table::gen_grammar_inst_table_operand_kinds(&grammar),
);
// Path to the generated GLSLstd450 extended instruction set header.
write_formatted(
&autogen_src_dir.join("../rspirv/grammar/autogen_glsl_std_450.rs"),
table::gen_glsl_std_450_inst_table(&gl_grammar),
);
write_formatted(
&autogen_src_dir.join("../rspirv/grammar/autogen_opencl_std_100.rs"),
table::gen_opencl_std_100_inst_table(&cl_grammar),
);
// Extended instruction sets
for (ext, _, _, grammar) in extended_instruction_sets {
write_formatted(
&autogen_src_dir.join(format!(
"../rspirv/grammar/autogen_{}.rs",
ext.replace(".", "_").to_lowercase()
)),
table::gen_instruction_table(
&grammar.instructions,
&format!("{}_INSTRUCTION_TABLE", ext.replace(".", "_").to_uppercase()),
true,
),
);
}

// Path to the generated operands kind in data representation.
write_formatted(
Expand Down
2 changes: 2 additions & 0 deletions autogen/src/structs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,9 @@ pub struct Grammar {

#[derive(Debug, Deserialize)]
pub struct ExtInstSetGrammar {
#[serde(default)]
pub copyright: Vec<String>,
#[serde(default)]
pub version: u32,
pub revision: u32,
pub instructions: Vec<Instruction>,
Expand Down
22 changes: 1 addition & 21 deletions autogen/src/table.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ fn convert_quantifier(quantifier: structs::Quantifier) -> Ident {
/// `grammar` is expected to be an array of SPIR-V instructions.
/// `name` is the name of the generated table.
/// `is_ext` indicates whether the grammar is for an extended instruction set.
fn gen_instruction_table(
pub(crate) fn gen_instruction_table(
grammar: &[structs::Instruction],
name: &str,
is_ext: bool,
Expand Down Expand Up @@ -82,23 +82,3 @@ pub fn gen_grammar_inst_table_operand_kinds(grammar: &structs::Grammar) -> Token
#table
}
}

/// Writes the generated instruction table for GLSLstd450 extended instruction
/// set from `grammar` to the file with the given `filename`.
pub fn gen_glsl_std_450_inst_table(grammar: &structs::ExtInstSetGrammar) -> TokenStream {
gen_instruction_table(
&grammar.instructions,
"GLSL_STD_450_INSTRUCTION_TABLE",
true,
)
}

/// Writes the generated instruction table for OpenCLstd100 extended instruction
/// set from `grammar` to the file with the given `filename`.
pub fn gen_opencl_std_100_inst_table(grammar: &structs::ExtInstSetGrammar) -> TokenStream {
gen_instruction_table(
&grammar.instructions,
"OPENCL_STD_100_INSTRUCTION_TABLE",
true,
)
}
11 changes: 11 additions & 0 deletions rspirv/grammar/autogen_nonsemantic_debugprintf.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// AUTOMATICALLY GENERATED from the SPIR-V JSON grammar:
// external/spirv.core.grammar.json.
// DO NOT MODIFY!

static NONSEMANTIC_DEBUGPRINTF_INSTRUCTION_TABLE: &[ExtendedInstruction<'static>] = &[ext_inst!(
DebugPrintf,
1u32,
[],
[],
[(IdRef, One), (IdRef, ZeroOrMore)]
)];
3 changes: 2 additions & 1 deletion rspirv/tests/spirv_blobs.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use rspirv::{
binary::{Assemble as _, Disassemble as _},
dr, lift,
dr,
lift,
};

use std::path::PathBuf;
Expand Down
23 changes: 22 additions & 1 deletion spirv/autogen_spirv.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3989,7 +3989,7 @@ impl num_traits::FromPrimitive for GLOp {
Self::from_i64(n as i64)
}
}
#[doc = "[OpenCL.std](https://www.khronos.org/registry/spir-v/specs/unified1/OpenCL.ExtendedInstructionSet.100.html) extended instruction opcode"]
#[doc = "[OpenCL.std.100](https://www.khronos.org/registry/spir-v/specs/unified1/OpenCL.ExtendedInstructionSet.100.html) extended instruction opcode"]
#[repr(u32)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[cfg_attr(feature = "serialize", derive(serde::Serialize))]
Expand Down Expand Up @@ -4332,3 +4332,24 @@ impl num_traits::FromPrimitive for CLOp {
Self::from_i64(n as i64)
}
}
#[doc = "[NonSemantic.DebugPrintF](https://github.com/KhronosGroup/Vulkan-ValidationLayers/blob/master/docs/debug_printf.md) extended instruction opcode"]
#[repr(u32)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[cfg_attr(feature = "serialize", derive(serde::Serialize))]
#[cfg_attr(feature = "deserialize", derive(serde::Deserialize))]
#[allow(clippy::upper_case_acronyms)]
pub enum DebugPrintFOp {
DebugPrintf = 1u32,
}
impl num_traits::FromPrimitive for DebugPrintFOp {
#[allow(trivial_numeric_casts)]
fn from_i64(n: i64) -> Option<Self> {
Some(match n as u32 {
1u32 => DebugPrintFOp::DebugPrintf,
_ => return None,
})
}
fn from_u64(n: u64) -> Option<Self> {
Self::from_i64(n as i64)
}
}

0 comments on commit ad4bf42

Please sign in to comment.