spirq/
reflect_cfg.rs

1use fnv::FnvHashMap as HashMap;
2
3use crate::{
4    constant::ConstantValue,
5    entry_point::EntryPoint,
6    error::Result,
7    inspect::{FnInspector, Inspector},
8    parse::{Instr, SpirvBinary},
9    reflect::{reflect, FunctionInspector, ReflectIntermediate},
10    var::SpecId,
11};
12
13/// Reflection configuration builder.
14#[derive(Default, Clone)]
15pub struct ReflectConfig {
16    pub(crate) spv: Option<SpirvBinary>,
17    pub(crate) ref_all_rscs: bool,
18    pub(crate) combine_img_samplers: bool,
19    pub(crate) gen_unique_names: bool,
20    pub(crate) spec_values: HashMap<SpecId, ConstantValue>,
21}
22impl ReflectConfig {
23    pub fn new() -> Self {
24        Default::default()
25    }
26
27    /// SPIR-V binary to be reflected.
28    pub fn spv<Spv: Into<SpirvBinary>>(&mut self, x: Spv) -> &mut Self {
29        self.spv = Some(x.into());
30        self
31    }
32    /// Reference all defined resources even the resource is not used by an
33    /// entry point. Otherwise and by default, only the referenced resources are
34    /// assigned to entry points.
35    ///
36    /// Can be faster for modules with only entry point; slower for multiple
37    /// entry points.
38    pub fn ref_all_rscs(&mut self, x: bool) -> &mut Self {
39        self.ref_all_rscs = x;
40        self
41    }
42    /// Combine images and samplers sharing a same binding point to combined
43    /// image sampler descriptors.
44    ///
45    /// Faster when disabled, but useful for modules derived from HLSL.
46    pub fn combine_img_samplers(&mut self, x: bool) -> &mut Self {
47        self.combine_img_samplers = x;
48        self
49    }
50    /// Generate unique names for types and struct fields to help further
51    /// processing of the reflection data. Otherwise, the debug names are
52    /// assigned.
53    pub fn gen_unique_names(&mut self, x: bool) -> &mut Self {
54        self.gen_unique_names = x;
55        self
56    }
57    /// Use the provided value for specialization constant at `spec_id`.
58    pub fn specialize(&mut self, spec_id: SpecId, value: ConstantValue) -> &mut Self {
59        self.spec_values.insert(spec_id, value);
60        self
61    }
62
63    /// Reflect the SPIR-V binary and extract all entry points.
64    pub fn reflect(&mut self) -> Result<Vec<EntryPoint>> {
65        let spv = self.spv.take().unwrap_or_default();
66        let mut itm = ReflectIntermediate::new(self)?;
67        let inspector = FunctionInspector::new();
68        reflect(&mut itm, &mut spv.instrs()?, inspector)
69    }
70    /// Reflect the SPIR-V binary and extract all entry points with an inspector
71    /// for customized reflection subroutines.
72    pub fn reflect_inspect<I: Inspector>(&mut self, inspector: &mut I) -> Result<Vec<EntryPoint>> {
73        let spv = self.spv.take().unwrap_or_default();
74        let mut itm = ReflectIntermediate::new(self)?;
75        let mut func_inspector = FunctionInspector::new();
76        reflect(
77            &mut itm,
78            &mut spv.instrs()?,
79            func_inspector.chain(inspector),
80        )
81    }
82    /// Reflect the SPIR-V binary and extract all entry points with an inspector
83    /// function for customized reflection subroutines.
84    pub fn reflect_inspect_by<F: FnMut(&mut ReflectIntermediate<'_>, &Instr)>(
85        &mut self,
86        inspector: F,
87    ) -> Result<Vec<EntryPoint>> {
88        let mut inspector = FnInspector::<F>(inspector);
89        self.reflect_inspect(&mut inspector)
90    }
91}