1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
use crate::{ScalarKind, TypeInner, VectorSize};

#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub struct InversePolyfill {
    pub fun_name: &'static str,
    pub source: &'static str,
}

impl InversePolyfill {
    pub fn find_overload(ty: &TypeInner) -> Option<InversePolyfill> {
        let &TypeInner::Matrix {
            columns,
            rows,
            scalar,
        } = ty
        else {
            return None;
        };

        if columns != rows || scalar.kind != ScalarKind::Float {
            return None;
        };

        Self::polyfill_overload(columns, scalar.width)
    }

    const fn polyfill_overload(
        dimension: VectorSize,
        width: crate::Bytes,
    ) -> Option<InversePolyfill> {
        const INVERSE_2X2_F32: &str = include_str!("inverse/inverse_2x2_f32.wgsl");
        const INVERSE_3X3_F32: &str = include_str!("inverse/inverse_3x3_f32.wgsl");
        const INVERSE_4X4_F32: &str = include_str!("inverse/inverse_4x4_f32.wgsl");
        const INVERSE_2X2_F16: &str = include_str!("inverse/inverse_2x2_f16.wgsl");
        const INVERSE_3X3_F16: &str = include_str!("inverse/inverse_3x3_f16.wgsl");
        const INVERSE_4X4_F16: &str = include_str!("inverse/inverse_4x4_f16.wgsl");

        match (dimension, width) {
            (VectorSize::Bi, 4) => Some(InversePolyfill {
                fun_name: "_naga_inverse_2x2_f32",
                source: INVERSE_2X2_F32,
            }),
            (VectorSize::Tri, 4) => Some(InversePolyfill {
                fun_name: "_naga_inverse_3x3_f32",
                source: INVERSE_3X3_F32,
            }),
            (VectorSize::Quad, 4) => Some(InversePolyfill {
                fun_name: "_naga_inverse_4x4_f32",
                source: INVERSE_4X4_F32,
            }),
            (VectorSize::Bi, 2) => Some(InversePolyfill {
                fun_name: "_naga_inverse_2x2_f16",
                source: INVERSE_2X2_F16,
            }),
            (VectorSize::Tri, 2) => Some(InversePolyfill {
                fun_name: "_naga_inverse_3x3_f16",
                source: INVERSE_3X3_F16,
            }),
            (VectorSize::Quad, 2) => Some(InversePolyfill {
                fun_name: "_naga_inverse_4x4_f16",
                source: INVERSE_4X4_F16,
            }),
            _ => None,
        }
    }
}