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 &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(&self, op: GLOp, result_type: Word, args: impl AsRef<[SpirvValue]>) -> SpirvValue {
62 let args = args.as_ref();
63 let glsl = self.ext_inst.borrow_mut().import_glsl(self);
64 self.emit()
65 .ext_inst(
66 result_type,
67 None,
68 glsl,
69 op as u32,
70 args.iter().map(|a| Operand::IdRef(a.def(self))),
71 )
72 .unwrap()
73 .with_type(result_type)
74 }
75}