rustc_codegen_spirv/builder/
ext_inst.rs1use super::Builder;
2use crate::builder_spirv::{SpirvValue, SpirvValueExt};
3use crate::custom_insts;
4use rspirv::dr::Operand;
5use rspirv::spirv::{GLOp, Word};
6
7const GLSL_STD_450: &str = "GLSL.std.450";
8
9#[derive(Default)]
11pub struct ExtInst {
12 custom: Option<Word>,
14
15 glsl: Option<Word>,
16}
17
18impl ExtInst {
19 pub fn import_custom(&mut self, bx: &Builder<'_, '_>) -> Word {
20 if let Some(id) = self.custom {
21 id
22 } else {
23 let id = bx
24 .emit_global()
25 .ext_inst_import(custom_insts::CUSTOM_EXT_INST_SET.clone());
26 self.custom = Some(id);
27 id
28 }
29 }
30
31 pub fn import_glsl(&mut self, bx: &Builder<'_, '_>) -> Word {
32 if let Some(id) = self.glsl {
33 id
34 } else {
35 let id = bx.emit_global().ext_inst_import(GLSL_STD_450);
36 self.glsl = Some(id);
37 id
38 }
39 }
40}
41
42impl<'a, 'tcx> Builder<'a, 'tcx> {
43 pub fn custom_inst(
44 &mut self,
45 result_type: Word,
46 inst: custom_insts::CustomInst<Operand>,
47 ) -> SpirvValue {
48 let custom_ext_inst_set = self.ext_inst.borrow_mut().import_custom(self);
49 self.emit()
50 .ext_inst(
51 result_type,
52 None,
53 custom_ext_inst_set,
54 inst.op() as u32,
55 inst.into_operands(),
56 )
57 .unwrap()
58 .with_type(result_type)
59 }
60
61 pub fn gl_op(
62 &mut self,
63 op: GLOp,
64 result_type: Word,
65 args: impl AsRef<[SpirvValue]>,
66 ) -> SpirvValue {
67 let args = args.as_ref();
68 let glsl = self.ext_inst.borrow_mut().import_glsl(self);
69 self.emit()
70 .ext_inst(
71 result_type,
72 None,
73 glsl,
74 op as u32,
75 args.iter().map(|a| Operand::IdRef(a.def(self))),
76 )
77 .unwrap()
78 .with_type(result_type)
79 }
80}