spirv_utils/
instruction.rs

1// Copyright 2016 James Miller
2//
3// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
4// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
5// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
6// option. This file may not be copied, modified, or distributed
7// except according to those terms.
8
9use desc::{self, Id, TypeId, ValueId, ResultId};
10
11include!(concat!(env!("OUT_DIR"), "/insts.rs"));
12
13impl Instruction {
14    #[inline(always)]
15    pub fn defines_value(&self) -> Option<ValueId> {
16        self.defines_value_inner().map(|r| r.to_value_id())
17    }
18}
19
20#[derive(Clone, Debug)]
21pub enum ExecutionMode {
22    Invocations(u32),
23    SpacingEqual,
24    SpacingFractionalEven,
25    SpacingFractionalOdd,
26    VertexOrderCw,
27    VertexOrderCcw,
28    PixelCenterInteger,
29    OriginUpperLeft,
30    OriginLowerLeft,
31    EarlyFragmentTests,
32    PointMode,
33    Xfb,
34    DepthReplacing,
35    DepthGreater,
36    DepthLess,
37    DepthUnchanged,
38    LocalSize(u32, u32, u32),
39    LocalSizeHint(u32, u32, u32),
40    InputPoints,
41    InputLines,
42    InputLinesAdjacency,
43    Triangles,
44    InputTrianglesAdjacency,
45    Quads,
46    IsoLines,
47    OutputVertices(u32),
48    OutputPoints,
49    OutputLineStrip,
50    OutputTriangleStrip,
51    VecTypeHint(u32),
52    ContractionOff
53}
54
55impl ExecutionMode {
56    pub fn to_desc(&self) -> desc::ExecutionMode {
57        match self {
58            &ExecutionMode::Invocations(_) => desc::ExecutionMode::Invocations,
59            &ExecutionMode::SpacingEqual => desc::ExecutionMode::SpacingEqual,
60            &ExecutionMode::SpacingFractionalEven => desc::ExecutionMode::SpacingFractionalEven,
61            &ExecutionMode::SpacingFractionalOdd => desc::ExecutionMode::SpacingFractionalOdd,
62            &ExecutionMode::VertexOrderCw => desc::ExecutionMode::VertexOrderCw,
63            &ExecutionMode::VertexOrderCcw => desc::ExecutionMode::VertexOrderCcw,
64            &ExecutionMode::PixelCenterInteger => desc::ExecutionMode::PixelCenterInteger,
65            &ExecutionMode::OriginUpperLeft => desc::ExecutionMode::OriginUpperLeft,
66            &ExecutionMode::OriginLowerLeft => desc::ExecutionMode::OriginLowerLeft,
67            &ExecutionMode::EarlyFragmentTests => desc::ExecutionMode::EarlyFragmentTests,
68            &ExecutionMode::PointMode => desc::ExecutionMode::PointMode,
69            &ExecutionMode::Xfb => desc::ExecutionMode::Xfb,
70            &ExecutionMode::DepthReplacing => desc::ExecutionMode::DepthReplacing,
71            &ExecutionMode::DepthGreater => desc::ExecutionMode::DepthGreater,
72            &ExecutionMode::DepthLess => desc::ExecutionMode::DepthLess,
73            &ExecutionMode::DepthUnchanged => desc::ExecutionMode::DepthUnchanged,
74            &ExecutionMode::LocalSize(_, _, _) => desc::ExecutionMode::LocalSize,
75            &ExecutionMode::LocalSizeHint(_, _, _) => desc::ExecutionMode::LocalSizeHint,
76            &ExecutionMode::InputPoints => desc::ExecutionMode::InputPoints,
77            &ExecutionMode::InputLines => desc::ExecutionMode::InputLines,
78            &ExecutionMode::InputLinesAdjacency => desc::ExecutionMode::InputLinesAdjacency,
79            &ExecutionMode::Triangles => desc::ExecutionMode::Triangles,
80            &ExecutionMode::InputTrianglesAdjacency => desc::ExecutionMode::InputTrianglesAdjacency,
81            &ExecutionMode::Quads => desc::ExecutionMode::Quads,
82            &ExecutionMode::IsoLines => desc::ExecutionMode::IsoLines,
83            &ExecutionMode::OutputVertices(_) => desc::ExecutionMode::OutputVertices,
84            &ExecutionMode::OutputPoints => desc::ExecutionMode::OutputPoints,
85            &ExecutionMode::OutputLineStrip => desc::ExecutionMode::OutputLineStrip,
86            &ExecutionMode::OutputTriangleStrip => desc::ExecutionMode::OutputTriangleStrip,
87            &ExecutionMode::VecTypeHint(_) => desc::ExecutionMode::VecTypeHint,
88            &ExecutionMode::ContractionOff => desc::ExecutionMode::ContractionOff
89        }
90    }
91}
92
93#[derive(Clone, Debug)]
94pub enum Decoration {
95    RelaxedPrecision,
96    SpecId(u32),
97    Block,
98    BufferBlock,
99    RowMajor,
100    ColMajor,
101    ArrayStride(u32),
102    MatrixStride(u32),
103    GLSLShared,
104    GLSLPacked,
105    CPacked,
106    BuiltIn(desc::BuiltIn),
107    NoPerspective,
108    Flat,
109    Patch,
110    Centroid,
111    Sample,
112    Invariant,
113    Restrict,
114    Aliased,
115    Volatile,
116    Constant,
117    Coherent,
118    NonWritable,
119    NonReadable,
120    Uniform,
121    SaturatedConversion,
122    Stream(u32),
123    Location(u32),
124    Component(u32),
125    Index(u32),
126    Binding(u32),
127    DescriptorSet(u32),
128    Offset(u32),
129    XfbBuffer(u32),
130    XfbStride(u32),
131    FuncParamAttr(desc::FuncParamAttr),
132    FPRoundingMode(desc::FPRoundingMode),
133    FPFastMathMode(desc::FPFastMathMode),
134    LinkageAttributes(String, desc::LinkageType),
135    NoContraction,
136    InputAttachmentIndex(u32),
137    Alignment(u32),
138}
139
140impl Decoration {
141    pub fn to_desc(&self) -> desc::Decoration {
142        match self {
143            &Decoration::RelaxedPrecision => desc::Decoration::RelaxedPrecision,
144            &Decoration::SpecId(_) => desc::Decoration::SpecId,
145            &Decoration::Block => desc::Decoration::Block,
146            &Decoration::BufferBlock => desc::Decoration::BufferBlock,
147            &Decoration::RowMajor => desc::Decoration::RowMajor,
148            &Decoration::ColMajor => desc::Decoration::ColMajor,
149            &Decoration::ArrayStride(_) => desc::Decoration::ArrayStride,
150            &Decoration::MatrixStride(_) => desc::Decoration::MatrixStride,
151            &Decoration::GLSLShared => desc::Decoration::GLSLShared,
152            &Decoration::GLSLPacked => desc::Decoration::GLSLPacked,
153            &Decoration::CPacked => desc::Decoration::CPacked,
154            &Decoration::BuiltIn(_) => desc::Decoration::BuiltIn,
155            &Decoration::NoPerspective => desc::Decoration::NoPerspective,
156            &Decoration::Flat => desc::Decoration::Flat,
157            &Decoration::Patch => desc::Decoration::Patch,
158            &Decoration::Centroid => desc::Decoration::Centroid,
159            &Decoration::Sample => desc::Decoration::Sample,
160            &Decoration::Invariant => desc::Decoration::Invariant,
161            &Decoration::Restrict => desc::Decoration::Restrict,
162            &Decoration::Aliased => desc::Decoration::Aliased,
163            &Decoration::Volatile => desc::Decoration::Volatile,
164            &Decoration::Constant => desc::Decoration::Constant,
165            &Decoration::Coherent => desc::Decoration::Coherent,
166            &Decoration::NonWritable => desc::Decoration::NonWritable,
167            &Decoration::NonReadable => desc::Decoration::NonReadable,
168            &Decoration::Uniform => desc::Decoration::Uniform,
169            &Decoration::SaturatedConversion => desc::Decoration::SaturatedConversion,
170            &Decoration::Stream(_) => desc::Decoration::Stream,
171            &Decoration::Location(_) => desc::Decoration::Location,
172            &Decoration::Component(_) => desc::Decoration::Component,
173            &Decoration::Index(_) => desc::Decoration::Index,
174            &Decoration::Binding(_) => desc::Decoration::Binding,
175            &Decoration::DescriptorSet(_) => desc::Decoration::DescriptorSet,
176            &Decoration::Offset(_) => desc::Decoration::Offset,
177            &Decoration::XfbBuffer(_) => desc::Decoration::XfbBuffer,
178            &Decoration::XfbStride(_) => desc::Decoration::XfbStride,
179            &Decoration::FuncParamAttr(_) => desc::Decoration::FuncParamAttr,
180            &Decoration::FPRoundingMode(_) => desc::Decoration::FPRoundingMode,
181            &Decoration::FPFastMathMode(_) => desc::Decoration::FPFastMathMode,
182            &Decoration::LinkageAttributes(_, _) => desc::Decoration::LinkageAttributes,
183            &Decoration::NoContraction => desc::Decoration::NoContraction,
184            &Decoration::InputAttachmentIndex(_) => desc::Decoration::InputAttachmentIndex,
185            &Decoration::Alignment(_) => desc::Decoration::Alignment,
186        }
187    }
188}
189
190#[derive(Clone, Debug)]
191pub struct ImageOperands {
192    set: desc::ImageOperands,
193    values: Vec<ValueId>
194}
195
196const ALL_OPERANDS : [desc::ImageOperands; 8] = [
197    desc::ImgOpBias, desc::ImgOpLod, desc::ImgOpGrad,
198    desc::ImgOpConstOffset, desc::ImgOpOffset,
199    desc::ImgOpConstOffsets, desc::ImgOpSample,
200    desc::ImgOpMinLod
201];
202
203impl ImageOperands {
204    #[inline]
205    pub fn new() -> ImageOperands {
206        ImageOperands {
207            set: desc::ImageOperands::empty(),
208            values: Vec::new()
209        }
210    }
211
212    pub fn get(&mut self, op: desc::ImageOperands) -> Option<ValueId> {
213        assert!(op.count() == 1, "`op` must be single entry, got {:?}", op);
214
215        if self.set.contains(op) {
216            let idx = self.idx_of(op);
217            Some(self.values[idx])
218        } else {
219            None
220        }
221    }
222
223    pub fn set(&mut self, op: desc::ImageOperands, value: ValueId) {
224        assert!(op.count() == 1, "`op` must be single entry, got {:?}", op);
225
226        let idx = self.idx_of(op);
227        assert!(idx <= self.values.len());
228
229        // If it's already set, replace the existing value, otherwise
230        // insert into the new position
231        if self.set.contains(op) {
232            self.values[idx] = value;
233        } else {
234            self.values.insert(idx, value);
235            self.set.insert(op);
236        }
237    }
238
239    fn idx_of(&self, op: desc::ImageOperands) -> usize {
240        assert!(op.count() == 1, "`op` must be single entry, got {:?}", op);
241        // Get the index where the value for this operand is/should be
242        // this is effectively done by counting the set bits that are
243        // lower than the operand we're checking
244        let mut idx = 0;
245        for &o in ALL_OPERANDS.iter() {
246            // Stop once we reach this operand
247            if o.bits() >= op.bits() {
248                break;
249            }
250            // If the operand we're checking is in the set, bump the
251            // index
252            if self.set.contains(o) {
253                idx += 1;
254            }
255        }
256
257        idx
258    }
259}