• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2021 The Tint Authors.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #ifndef SRC_WRITER_SPIRV_SCALAR_CONSTANT_H_
16 #define SRC_WRITER_SPIRV_SCALAR_CONSTANT_H_
17 
18 #include <stdint.h>
19 
20 #include <cstring>
21 #include <functional>
22 
23 #include "src/utils/hash.h"
24 
25 namespace tint {
26 
27 // Forward declarations
28 namespace sem {
29 class Call;
30 }  // namespace sem
31 
32 namespace writer {
33 namespace spirv {
34 
35 /// ScalarConstant represents a scalar constant value
36 struct ScalarConstant {
37   /// The constant value
38   union Value {
39     /// The value as a bool
40     bool b;
41     /// The value as a uint32_t
42     uint32_t u32;
43     /// The value as a int32_t
44     int32_t i32;
45     /// The value as a float
46     float f32;
47 
48     /// The value that is wide enough to encompass all other types (including
49     /// future 64-bit data types).
50     uint64_t u64;
51   };
52 
53   /// The kind of constant
54   enum class Kind { kBool, kU32, kI32, kF32 };
55 
56   /// Constructor
ScalarConstantScalarConstant57   inline ScalarConstant() { value.u64 = 0; }
58 
59   /// @param value the value of the constant
60   /// @returns a new ScalarConstant with the provided value and kind Kind::kU32
U32ScalarConstant61   static inline ScalarConstant U32(uint32_t value) {
62     ScalarConstant c;
63     c.value.u32 = value;
64     c.kind = Kind::kU32;
65     return c;
66   }
67 
68   /// @param value the value of the constant
69   /// @returns a new ScalarConstant with the provided value and kind Kind::kI32
I32ScalarConstant70   static inline ScalarConstant I32(int32_t value) {
71     ScalarConstant c;
72     c.value.i32 = value;
73     c.kind = Kind::kI32;
74     return c;
75   }
76 
77   /// @param value the value of the constant
78   /// @returns a new ScalarConstant with the provided value and kind Kind::kI32
F32ScalarConstant79   static inline ScalarConstant F32(float value) {
80     ScalarConstant c;
81     c.value.f32 = value;
82     c.kind = Kind::kF32;
83     return c;
84   }
85 
86   /// @param value the value of the constant
87   /// @returns a new ScalarConstant with the provided value and kind Kind::kBool
BoolScalarConstant88   static inline ScalarConstant Bool(bool value) {
89     ScalarConstant c;
90     c.value.b = value;
91     c.kind = Kind::kBool;
92     return c;
93   }
94 
95   /// Equality operator
96   /// @param rhs the ScalarConstant to compare against
97   /// @returns true if this ScalarConstant is equal to `rhs`
98   inline bool operator==(const ScalarConstant& rhs) const {
99     return value.u64 == rhs.value.u64 && kind == rhs.kind &&
100            is_spec_op == rhs.is_spec_op && constant_id == rhs.constant_id;
101   }
102 
103   /// Inequality operator
104   /// @param rhs the ScalarConstant to compare against
105   /// @returns true if this ScalarConstant is not equal to `rhs`
106   inline bool operator!=(const ScalarConstant& rhs) const {
107     return !(*this == rhs);
108   }
109 
110   /// @returns this ScalarConstant as a specialization op with the given
111   /// specialization constant identifier
112   /// @param id the constant identifier
AsSpecOpScalarConstant113   ScalarConstant AsSpecOp(uint32_t id) const {
114     auto ret = *this;
115     ret.is_spec_op = true;
116     ret.constant_id = id;
117     return ret;
118   }
119 
120   /// The constant value
121   Value value;
122   /// The constant value kind
123   Kind kind = Kind::kBool;
124   /// True if the constant is a specialization op
125   bool is_spec_op = false;
126   /// The identifier if a specialization op
127   uint32_t constant_id = 0;
128 };
129 
130 }  // namespace spirv
131 }  // namespace writer
132 }  // namespace tint
133 
134 namespace std {
135 
136 /// Custom std::hash specialization for tint::Symbol so symbols can be used as
137 /// keys for std::unordered_map and std::unordered_set.
138 template <>
139 class hash<tint::writer::spirv::ScalarConstant> {
140  public:
141   /// @param c the ScalarConstant
142   /// @return the Symbol internal value
operator()143   inline std::size_t operator()(
144       const tint::writer::spirv::ScalarConstant& c) const {
145     uint32_t value = 0;
146     std::memcpy(&value, &c.value, sizeof(value));
147     return tint::utils::Hash(value, c.kind);
148   }
149 };
150 
151 }  // namespace std
152 
153 #endif  // SRC_WRITER_SPIRV_SCALAR_CONSTANT_H_
154