1 // Copyright 2020 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 #include "src/reader/spirv/usage.h" 16 17 #include <sstream> 18 19 namespace tint { 20 namespace reader { 21 namespace spirv { 22 Usage()23Usage::Usage() {} 24 Usage::Usage(const Usage& other) = default; 25 Usage::~Usage() = default; 26 operator <<(std::ostream & out) const27std::ostream& Usage::operator<<(std::ostream& out) const { 28 out << "Usage("; 29 if (IsSampler()) { 30 out << "Sampler("; 31 if (is_comparison_sampler_) { 32 out << " comparison"; 33 } 34 out << " )"; 35 } 36 if (IsTexture()) { 37 out << "Texture("; 38 if (is_sampled_) { 39 out << " is_sampled"; 40 } 41 if (is_multisampled_) { 42 out << " ms"; 43 } 44 if (is_depth_) { 45 out << " depth"; 46 } 47 if (is_storage_read_) { 48 out << " read"; 49 } 50 if (is_storage_write_) { 51 out << " write"; 52 } 53 out << " )"; 54 } 55 out << ")"; 56 return out; 57 } 58 IsValid() const59bool Usage::IsValid() const { 60 // Check sampler state internal consistency. 61 if (is_comparison_sampler_ && !is_sampler_) { 62 return false; 63 } 64 65 // Check texture state. 66 // |is_texture_| is implied by any of the later texture-based properties. 67 if ((IsStorageTexture() || is_sampled_ || is_multisampled_ || is_depth_) && 68 !is_texture_) { 69 return false; 70 } 71 if (is_texture_) { 72 // Multisampled implies sampled. 73 if (is_multisampled_) { 74 if (!is_sampled_) { 75 return false; 76 } 77 } 78 // Depth implies sampled. 79 if (is_depth_) { 80 if (!is_sampled_) { 81 return false; 82 } 83 } 84 85 // Sampled can't be storage. 86 if (is_sampled_) { 87 if (IsStorageTexture()) { 88 return false; 89 } 90 } 91 92 // Storage can't be sampled. 93 if (IsStorageTexture()) { 94 if (is_sampled_) { 95 return false; 96 } 97 } 98 // Storage texture can't also be a sampler. 99 if (IsStorageTexture()) { 100 if (is_sampler_) { 101 return false; 102 } 103 } 104 105 // Can't be both read and write. This is a restriction in WebGPU. 106 if (is_storage_read_ && is_storage_write_) { 107 return false; 108 } 109 } 110 return true; 111 } 112 IsComplete() const113bool Usage::IsComplete() const { 114 if (!IsValid()) { 115 return false; 116 } 117 if (IsSampler()) { 118 return true; 119 } 120 if (IsTexture()) { 121 return is_sampled_ || IsStorageTexture(); 122 } 123 return false; 124 } 125 operator ==(const Usage & other) const126bool Usage::operator==(const Usage& other) const { 127 return is_sampler_ == other.is_sampler_ && 128 is_comparison_sampler_ == other.is_comparison_sampler_ && 129 is_texture_ == other.is_texture_ && is_sampled_ == other.is_sampled_ && 130 is_multisampled_ == other.is_multisampled_ && 131 is_depth_ == other.is_depth_ && 132 is_storage_read_ == other.is_storage_read_ && 133 is_storage_write_ == other.is_storage_write_; 134 } 135 Add(const Usage & other)136void Usage::Add(const Usage& other) { 137 is_sampler_ = is_sampler_ || other.is_sampler_; 138 is_comparison_sampler_ = 139 is_comparison_sampler_ || other.is_comparison_sampler_; 140 is_texture_ = is_texture_ || other.is_texture_; 141 is_sampled_ = is_sampled_ || other.is_sampled_; 142 is_multisampled_ = is_multisampled_ || other.is_multisampled_; 143 is_depth_ = is_depth_ || other.is_depth_; 144 is_storage_read_ = is_storage_read_ || other.is_storage_read_; 145 is_storage_write_ = is_storage_write_ || other.is_storage_write_; 146 } 147 AddSampler()148void Usage::AddSampler() { 149 is_sampler_ = true; 150 } 151 AddComparisonSampler()152void Usage::AddComparisonSampler() { 153 AddSampler(); 154 is_comparison_sampler_ = true; 155 } 156 AddTexture()157void Usage::AddTexture() { 158 is_texture_ = true; 159 } 160 AddStorageReadTexture()161void Usage::AddStorageReadTexture() { 162 AddTexture(); 163 is_storage_read_ = true; 164 } 165 AddStorageWriteTexture()166void Usage::AddStorageWriteTexture() { 167 AddTexture(); 168 is_storage_write_ = true; 169 } 170 AddSampledTexture()171void Usage::AddSampledTexture() { 172 AddTexture(); 173 is_sampled_ = true; 174 } 175 AddMultisampledTexture()176void Usage::AddMultisampledTexture() { 177 AddSampledTexture(); 178 is_multisampled_ = true; 179 } 180 AddDepthTexture()181void Usage::AddDepthTexture() { 182 AddSampledTexture(); 183 is_depth_ = true; 184 } 185 to_str() const186std::string Usage::to_str() const { 187 std::ostringstream ss; 188 ss << *this; 189 return ss.str(); 190 } 191 192 } // namespace spirv 193 } // namespace reader 194 } // namespace tint 195