1 // Copyright (c) 2017 Google Inc. 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 SOURCE_VAL_DECORATION_H_ 16 #define SOURCE_VAL_DECORATION_H_ 17 18 #include <cstdint> 19 #include <unordered_map> 20 #include <vector> 21 22 #include "source/latest_version_spirv_header.h" 23 24 namespace spvtools { 25 namespace val { 26 27 // An object of this class represents a specific decoration including its 28 // parameters (if any). Decorations are used by OpDecorate and OpMemberDecorate, 29 // and they describe certain properties that can be assigned to one or several 30 // <id>s. 31 // 32 // A Decoration object contains the decoration type (an enum), associated 33 // literal parameters, and struct member index. If the decoration does not apply 34 // to a struct member, then the index is kInvalidIndex. A Decoration object does 35 // not store the target Id, i.e. the Id to which it applies. It is 36 // possible for the same decoration to be applied to several <id>s (and they 37 // might be assigned using separate SPIR-V instructions, possibly using an 38 // assignment through GroupDecorate). 39 // 40 // Example 1: Decoration for an object<id> with no parameters: 41 // OpDecorate %obj Flat 42 // dec_type_ = spv::Decoration::Flat 43 // params_ = empty vector 44 // struct_member_index_ = kInvalidMember 45 // 46 // Example 2: Decoration for an object<id> with two parameters: 47 // OpDecorate %obj LinkageAttributes "link" Import 48 // dec_type_ = spv::Decoration::LinkageAttributes 49 // params_ = vector { link, Import } 50 // struct_member_index_ = kInvalidMember 51 // 52 // Example 3: Decoration for a member of a structure with one parameter: 53 // OpMemberDecorate %struct 2 Offset 2 54 // dec_type_ = spv::Decoration::Offset 55 // params_ = vector { 2 } 56 // struct_member_index_ = 2 57 // 58 class Decoration { 59 public: 60 enum { kInvalidMember = -1 }; 61 Decoration(spv::Decoration t, 62 const std::vector<uint32_t>& parameters = std::vector<uint32_t>(), 63 uint32_t member_index = kInvalidMember) dec_type_(t)64 : dec_type_(t), params_(parameters), struct_member_index_(member_index) {} 65 set_struct_member_index(uint32_t index)66 void set_struct_member_index(uint32_t index) { struct_member_index_ = index; } struct_member_index()67 int struct_member_index() const { return struct_member_index_; } dec_type()68 spv::Decoration dec_type() const { return dec_type_; } params()69 std::vector<uint32_t>& params() { return params_; } params()70 const std::vector<uint32_t>& params() const { return params_; } 71 72 inline bool operator<(const Decoration& rhs) const { 73 // Note: Sort by struct_member_index_ first, then type, so look up can be 74 // efficient using lower_bound() and upper_bound(). 75 if (struct_member_index_ < rhs.struct_member_index_) return true; 76 if (rhs.struct_member_index_ < struct_member_index_) return false; 77 if (dec_type_ < rhs.dec_type_) return true; 78 if (rhs.dec_type_ < dec_type_) return false; 79 return params_ < rhs.params_; 80 } 81 inline bool operator==(const Decoration& rhs) const { 82 return (dec_type_ == rhs.dec_type_ && params_ == rhs.params_ && 83 struct_member_index_ == rhs.struct_member_index_); 84 } 85 86 private: 87 spv::Decoration dec_type_; 88 std::vector<uint32_t> params_; 89 90 // If the decoration applies to a member of a structure type, then the index 91 // of the member is stored here. Otherwise, this is kInvalidIndex. 92 int struct_member_index_; 93 }; 94 95 } // namespace val 96 } // namespace spvtools 97 98 #endif // SOURCE_VAL_DECORATION_H_ 99