naga/front/spv/
convert.rs

1use core::convert::TryInto;
2
3use super::error::Error;
4
5pub(super) const fn map_binary_operator(word: spirv::Op) -> Result<crate::BinaryOperator, Error> {
6    use crate::BinaryOperator;
7    use spirv::Op;
8
9    match word {
10        // Arithmetic Instructions +, -, *, /, %
11        Op::IAdd | Op::FAdd => Ok(BinaryOperator::Add),
12        Op::ISub | Op::FSub => Ok(BinaryOperator::Subtract),
13        Op::IMul | Op::FMul => Ok(BinaryOperator::Multiply),
14        Op::UDiv | Op::SDiv | Op::FDiv => Ok(BinaryOperator::Divide),
15        Op::SRem => Ok(BinaryOperator::Modulo),
16        // Relational and Logical Instructions
17        Op::IEqual | Op::FOrdEqual | Op::FUnordEqual | Op::LogicalEqual => {
18            Ok(BinaryOperator::Equal)
19        }
20        Op::INotEqual | Op::FOrdNotEqual | Op::FUnordNotEqual | Op::LogicalNotEqual => {
21            Ok(BinaryOperator::NotEqual)
22        }
23        Op::ULessThan | Op::SLessThan | Op::FOrdLessThan | Op::FUnordLessThan => {
24            Ok(BinaryOperator::Less)
25        }
26        Op::ULessThanEqual
27        | Op::SLessThanEqual
28        | Op::FOrdLessThanEqual
29        | Op::FUnordLessThanEqual => Ok(BinaryOperator::LessEqual),
30        Op::UGreaterThan | Op::SGreaterThan | Op::FOrdGreaterThan | Op::FUnordGreaterThan => {
31            Ok(BinaryOperator::Greater)
32        }
33        Op::UGreaterThanEqual
34        | Op::SGreaterThanEqual
35        | Op::FOrdGreaterThanEqual
36        | Op::FUnordGreaterThanEqual => Ok(BinaryOperator::GreaterEqual),
37        Op::BitwiseOr => Ok(BinaryOperator::InclusiveOr),
38        Op::BitwiseXor => Ok(BinaryOperator::ExclusiveOr),
39        Op::BitwiseAnd => Ok(BinaryOperator::And),
40        _ => Err(Error::UnknownBinaryOperator(word)),
41    }
42}
43
44pub(super) const fn map_relational_fun(
45    word: spirv::Op,
46) -> Result<crate::RelationalFunction, Error> {
47    use crate::RelationalFunction as Rf;
48    use spirv::Op;
49
50    match word {
51        Op::All => Ok(Rf::All),
52        Op::Any => Ok(Rf::Any),
53        Op::IsNan => Ok(Rf::IsNan),
54        Op::IsInf => Ok(Rf::IsInf),
55        _ => Err(Error::UnknownRelationalFunction(word)),
56    }
57}
58
59pub(super) const fn map_vector_size(word: spirv::Word) -> Result<crate::VectorSize, Error> {
60    match word {
61        2 => Ok(crate::VectorSize::Bi),
62        3 => Ok(crate::VectorSize::Tri),
63        4 => Ok(crate::VectorSize::Quad),
64        _ => Err(Error::InvalidVectorSize(word)),
65    }
66}
67
68pub(super) fn map_image_dim(word: spirv::Word) -> Result<crate::ImageDimension, Error> {
69    use spirv::Dim as D;
70    match D::from_u32(word) {
71        Some(D::Dim1D) => Ok(crate::ImageDimension::D1),
72        Some(D::Dim2D) => Ok(crate::ImageDimension::D2),
73        Some(D::Dim3D) => Ok(crate::ImageDimension::D3),
74        Some(D::DimCube) => Ok(crate::ImageDimension::Cube),
75        _ => Err(Error::UnsupportedImageDim(word)),
76    }
77}
78
79pub(super) fn map_image_format(word: spirv::Word) -> Result<crate::StorageFormat, Error> {
80    match spirv::ImageFormat::from_u32(word) {
81        Some(spirv::ImageFormat::R8) => Ok(crate::StorageFormat::R8Unorm),
82        Some(spirv::ImageFormat::R8Snorm) => Ok(crate::StorageFormat::R8Snorm),
83        Some(spirv::ImageFormat::R8ui) => Ok(crate::StorageFormat::R8Uint),
84        Some(spirv::ImageFormat::R8i) => Ok(crate::StorageFormat::R8Sint),
85        Some(spirv::ImageFormat::R16) => Ok(crate::StorageFormat::R16Unorm),
86        Some(spirv::ImageFormat::R16Snorm) => Ok(crate::StorageFormat::R16Snorm),
87        Some(spirv::ImageFormat::R16ui) => Ok(crate::StorageFormat::R16Uint),
88        Some(spirv::ImageFormat::R16i) => Ok(crate::StorageFormat::R16Sint),
89        Some(spirv::ImageFormat::R16f) => Ok(crate::StorageFormat::R16Float),
90        Some(spirv::ImageFormat::Rg8) => Ok(crate::StorageFormat::Rg8Unorm),
91        Some(spirv::ImageFormat::Rg8Snorm) => Ok(crate::StorageFormat::Rg8Snorm),
92        Some(spirv::ImageFormat::Rg8ui) => Ok(crate::StorageFormat::Rg8Uint),
93        Some(spirv::ImageFormat::Rg8i) => Ok(crate::StorageFormat::Rg8Sint),
94        Some(spirv::ImageFormat::R32ui) => Ok(crate::StorageFormat::R32Uint),
95        Some(spirv::ImageFormat::R32i) => Ok(crate::StorageFormat::R32Sint),
96        Some(spirv::ImageFormat::R32f) => Ok(crate::StorageFormat::R32Float),
97        Some(spirv::ImageFormat::Rg16) => Ok(crate::StorageFormat::Rg16Unorm),
98        Some(spirv::ImageFormat::Rg16Snorm) => Ok(crate::StorageFormat::Rg16Snorm),
99        Some(spirv::ImageFormat::Rg16ui) => Ok(crate::StorageFormat::Rg16Uint),
100        Some(spirv::ImageFormat::Rg16i) => Ok(crate::StorageFormat::Rg16Sint),
101        Some(spirv::ImageFormat::Rg16f) => Ok(crate::StorageFormat::Rg16Float),
102        Some(spirv::ImageFormat::Rgba8) => Ok(crate::StorageFormat::Rgba8Unorm),
103        Some(spirv::ImageFormat::Rgba8Snorm) => Ok(crate::StorageFormat::Rgba8Snorm),
104        Some(spirv::ImageFormat::Rgba8ui) => Ok(crate::StorageFormat::Rgba8Uint),
105        Some(spirv::ImageFormat::Rgba8i) => Ok(crate::StorageFormat::Rgba8Sint),
106        Some(spirv::ImageFormat::Rgb10a2ui) => Ok(crate::StorageFormat::Rgb10a2Uint),
107        Some(spirv::ImageFormat::Rgb10A2) => Ok(crate::StorageFormat::Rgb10a2Unorm),
108        Some(spirv::ImageFormat::R11fG11fB10f) => Ok(crate::StorageFormat::Rg11b10Ufloat),
109        Some(spirv::ImageFormat::R64ui) => Ok(crate::StorageFormat::R64Uint),
110        Some(spirv::ImageFormat::Rg32ui) => Ok(crate::StorageFormat::Rg32Uint),
111        Some(spirv::ImageFormat::Rg32i) => Ok(crate::StorageFormat::Rg32Sint),
112        Some(spirv::ImageFormat::Rg32f) => Ok(crate::StorageFormat::Rg32Float),
113        Some(spirv::ImageFormat::Rgba16) => Ok(crate::StorageFormat::Rgba16Unorm),
114        Some(spirv::ImageFormat::Rgba16Snorm) => Ok(crate::StorageFormat::Rgba16Snorm),
115        Some(spirv::ImageFormat::Rgba16ui) => Ok(crate::StorageFormat::Rgba16Uint),
116        Some(spirv::ImageFormat::Rgba16i) => Ok(crate::StorageFormat::Rgba16Sint),
117        Some(spirv::ImageFormat::Rgba16f) => Ok(crate::StorageFormat::Rgba16Float),
118        Some(spirv::ImageFormat::Rgba32ui) => Ok(crate::StorageFormat::Rgba32Uint),
119        Some(spirv::ImageFormat::Rgba32i) => Ok(crate::StorageFormat::Rgba32Sint),
120        Some(spirv::ImageFormat::Rgba32f) => Ok(crate::StorageFormat::Rgba32Float),
121        _ => Err(Error::UnsupportedImageFormat(word)),
122    }
123}
124
125pub(super) fn map_width(word: spirv::Word) -> Result<crate::Bytes, Error> {
126    (word >> 3) // bits to bytes
127        .try_into()
128        .map_err(|_| Error::InvalidTypeWidth(word))
129}
130
131pub(super) fn map_builtin(word: spirv::Word, invariant: bool) -> Result<crate::BuiltIn, Error> {
132    use spirv::BuiltIn as Bi;
133    Ok(match spirv::BuiltIn::from_u32(word) {
134        Some(Bi::Position | Bi::FragCoord) => crate::BuiltIn::Position { invariant },
135        Some(Bi::ViewIndex) => crate::BuiltIn::ViewIndex,
136        // vertex
137        Some(Bi::BaseInstance) => crate::BuiltIn::BaseInstance,
138        Some(Bi::BaseVertex) => crate::BuiltIn::BaseVertex,
139        Some(Bi::ClipDistance) => crate::BuiltIn::ClipDistance,
140        Some(Bi::CullDistance) => crate::BuiltIn::CullDistance,
141        Some(Bi::InstanceIndex) => crate::BuiltIn::InstanceIndex,
142        Some(Bi::PointSize) => crate::BuiltIn::PointSize,
143        Some(Bi::VertexIndex) => crate::BuiltIn::VertexIndex,
144        Some(Bi::DrawIndex) => crate::BuiltIn::DrawID,
145        // fragment
146        Some(Bi::FragDepth) => crate::BuiltIn::FragDepth,
147        Some(Bi::PointCoord) => crate::BuiltIn::PointCoord,
148        Some(Bi::FrontFacing) => crate::BuiltIn::FrontFacing,
149        Some(Bi::PrimitiveId) => crate::BuiltIn::PrimitiveIndex,
150        Some(Bi::SampleId) => crate::BuiltIn::SampleIndex,
151        Some(Bi::SampleMask) => crate::BuiltIn::SampleMask,
152        // compute
153        Some(Bi::GlobalInvocationId) => crate::BuiltIn::GlobalInvocationId,
154        Some(Bi::LocalInvocationId) => crate::BuiltIn::LocalInvocationId,
155        Some(Bi::LocalInvocationIndex) => crate::BuiltIn::LocalInvocationIndex,
156        Some(Bi::WorkgroupId) => crate::BuiltIn::WorkGroupId,
157        Some(Bi::WorkgroupSize) => crate::BuiltIn::WorkGroupSize,
158        Some(Bi::NumWorkgroups) => crate::BuiltIn::NumWorkGroups,
159        // subgroup
160        Some(Bi::NumSubgroups) => crate::BuiltIn::NumSubgroups,
161        Some(Bi::SubgroupId) => crate::BuiltIn::SubgroupId,
162        Some(Bi::SubgroupSize) => crate::BuiltIn::SubgroupSize,
163        Some(Bi::SubgroupLocalInvocationId) => crate::BuiltIn::SubgroupInvocationId,
164        _ => return Err(Error::UnsupportedBuiltIn(word)),
165    })
166}
167
168pub(super) fn map_storage_class(word: spirv::Word) -> Result<super::ExtendedClass, Error> {
169    use super::ExtendedClass as Ec;
170    use spirv::StorageClass as Sc;
171    Ok(match Sc::from_u32(word) {
172        Some(Sc::Function) => Ec::Global(crate::AddressSpace::Function),
173        Some(Sc::Input) => Ec::Input,
174        Some(Sc::Output) => Ec::Output,
175        Some(Sc::Private) => Ec::Global(crate::AddressSpace::Private),
176        Some(Sc::UniformConstant) => Ec::Global(crate::AddressSpace::Handle),
177        Some(Sc::StorageBuffer) => Ec::Global(crate::AddressSpace::Storage {
178            //Note: this is restricted by decorations later
179            access: crate::StorageAccess::LOAD | crate::StorageAccess::STORE,
180        }),
181        // we expect the `Storage` case to be filtered out before calling this function.
182        Some(Sc::Uniform) => Ec::Global(crate::AddressSpace::Uniform),
183        Some(Sc::Workgroup) => Ec::Global(crate::AddressSpace::WorkGroup),
184        Some(Sc::PushConstant) => Ec::Global(crate::AddressSpace::PushConstant),
185        _ => return Err(Error::UnsupportedStorageClass(word)),
186    })
187}