naga/back/spv/
f16_polyfill.rs1use crate::back::spv::{Instruction, LocalType, NumericType, Word};
13use alloc::vec::Vec;
14
15#[derive(Default)]
17pub(in crate::back::spv) struct F16IoPolyfill {
18 use_native: bool,
19 io_var_to_f32_type: crate::FastHashMap<Word, Word>,
20}
21
22impl F16IoPolyfill {
23 pub fn new(use_storage_input_output_16: bool) -> Self {
24 Self {
25 use_native: use_storage_input_output_16,
26 io_var_to_f32_type: crate::FastHashMap::default(),
27 }
28 }
29
30 pub fn needs_polyfill(&self, ty_inner: &crate::TypeInner) -> bool {
31 use crate::{ScalarKind as Sk, TypeInner};
32
33 !self.use_native
34 && match *ty_inner {
35 TypeInner::Scalar(ref s) if s.kind == Sk::Float && s.width == 2 => true,
36 TypeInner::Vector { scalar, .. }
37 if scalar.kind == Sk::Float && scalar.width == 2 =>
38 {
39 true
40 }
41 _ => false,
42 }
43 }
44
45 pub fn register_io_var(&mut self, variable_id: Word, f32_type_id: Word) {
46 self.io_var_to_f32_type.insert(variable_id, f32_type_id);
47 }
48
49 pub fn get_f32_io_type(&self, variable_id: Word) -> Option<Word> {
50 self.io_var_to_f32_type.get(&variable_id).copied()
51 }
52
53 pub fn emit_f16_to_f32_conversion(
54 f16_value_id: Word,
55 f32_type_id: Word,
56 converted_id: Word,
57 body: &mut Vec<Instruction>,
58 ) {
59 body.push(Instruction::unary(
60 spirv::Op::FConvert,
61 f32_type_id,
62 converted_id,
63 f16_value_id,
64 ));
65 }
66
67 pub fn emit_f32_to_f16_conversion(
68 f32_value_id: Word,
69 f16_type_id: Word,
70 converted_id: Word,
71 body: &mut Vec<Instruction>,
72 ) {
73 body.push(Instruction::unary(
74 spirv::Op::FConvert,
75 f16_type_id,
76 converted_id,
77 f32_value_id,
78 ));
79 }
80
81 pub fn create_polyfill_type(ty_inner: &crate::TypeInner) -> Option<LocalType> {
82 use crate::{ScalarKind as Sk, TypeInner};
83
84 match *ty_inner {
85 TypeInner::Scalar(ref s) if s.kind == Sk::Float && s.width == 2 => {
86 Some(LocalType::Numeric(NumericType::Scalar(crate::Scalar::F32)))
87 }
88 TypeInner::Vector { size, scalar } if scalar.kind == Sk::Float && scalar.width == 2 => {
89 Some(LocalType::Numeric(NumericType::Vector {
90 size,
91 scalar: crate::Scalar::F32,
92 }))
93 }
94 _ => None,
95 }
96 }
97}
98
99impl crate::back::spv::recyclable::Recyclable for F16IoPolyfill {
100 fn recycle(mut self) -> Self {
101 self.io_var_to_f32_type = self.io_var_to_f32_type.recycle();
102 self
103 }
104}