| // Copyright 2020 The Tint Authors. |
| // |
| // Licensed under the Apache License, Version 2.0 (the "License"); |
| // you may not use this file except in compliance with the License. |
| // You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| |
| #include "src/tint/lang/spirv/reader/ast_parser/usage.h" |
| |
| #include "src/tint/utils/text/string_stream.h" |
| |
| namespace tint::spirv::reader { |
| |
| Usage::Usage() {} |
| Usage::Usage(const Usage& other) = default; |
| Usage::~Usage() = default; |
| |
| StringStream& Usage::operator<<(StringStream& out) const { |
| out << "Usage("; |
| if (IsSampler()) { |
| out << "Sampler("; |
| if (is_comparison_sampler_) { |
| out << " comparison"; |
| } |
| out << " )"; |
| } |
| if (IsTexture()) { |
| out << "Texture("; |
| if (is_sampled_) { |
| out << " is_sampled"; |
| } |
| if (is_multisampled_) { |
| out << " ms"; |
| } |
| if (is_depth_) { |
| out << " depth"; |
| } |
| if (is_storage_read_) { |
| out << " read"; |
| } |
| if (is_storage_write_) { |
| out << " write"; |
| } |
| out << " )"; |
| } |
| out << ")"; |
| return out; |
| } |
| |
| bool Usage::IsValid() const { |
| // Check sampler state internal consistency. |
| if (is_comparison_sampler_ && !is_sampler_) { |
| return false; |
| } |
| |
| // Check texture state. |
| // |is_texture_| is implied by any of the later texture-based properties. |
| if ((IsStorageTexture() || is_sampled_ || is_multisampled_ || is_depth_) && !is_texture_) { |
| return false; |
| } |
| if (is_texture_) { |
| // Multisampled implies sampled. |
| if (is_multisampled_) { |
| if (!is_sampled_) { |
| return false; |
| } |
| } |
| // Depth implies sampled. |
| if (is_depth_) { |
| if (!is_sampled_) { |
| return false; |
| } |
| } |
| |
| // Sampled can't be storage. |
| if (is_sampled_) { |
| if (IsStorageTexture()) { |
| return false; |
| } |
| } |
| |
| // Storage can't be sampled. |
| if (IsStorageTexture()) { |
| if (is_sampled_) { |
| return false; |
| } |
| } |
| // Storage texture can't also be a sampler. |
| if (IsStorageTexture()) { |
| if (is_sampler_) { |
| return false; |
| } |
| } |
| |
| // Can't be both read and write. This is a restriction in WebGPU. |
| if (is_storage_read_ && is_storage_write_) { |
| return false; |
| } |
| } |
| return true; |
| } |
| |
| bool Usage::IsComplete() const { |
| if (!IsValid()) { |
| return false; |
| } |
| if (IsSampler()) { |
| return true; |
| } |
| if (IsTexture()) { |
| return is_sampled_ || IsStorageTexture(); |
| } |
| return false; |
| } |
| |
| bool Usage::operator==(const Usage& other) const { |
| return is_sampler_ == other.is_sampler_ && |
| is_comparison_sampler_ == other.is_comparison_sampler_ && |
| is_texture_ == other.is_texture_ && is_sampled_ == other.is_sampled_ && |
| is_multisampled_ == other.is_multisampled_ && is_depth_ == other.is_depth_ && |
| is_storage_read_ == other.is_storage_read_ && |
| is_storage_write_ == other.is_storage_write_; |
| } |
| |
| void Usage::Add(const Usage& other) { |
| is_sampler_ = is_sampler_ || other.is_sampler_; |
| is_comparison_sampler_ = is_comparison_sampler_ || other.is_comparison_sampler_; |
| is_texture_ = is_texture_ || other.is_texture_; |
| is_sampled_ = is_sampled_ || other.is_sampled_; |
| is_multisampled_ = is_multisampled_ || other.is_multisampled_; |
| is_depth_ = is_depth_ || other.is_depth_; |
| is_storage_read_ = is_storage_read_ || other.is_storage_read_; |
| is_storage_write_ = is_storage_write_ || other.is_storage_write_; |
| } |
| |
| void Usage::AddSampler() { |
| is_sampler_ = true; |
| } |
| |
| void Usage::AddComparisonSampler() { |
| AddSampler(); |
| is_comparison_sampler_ = true; |
| } |
| |
| void Usage::AddTexture() { |
| is_texture_ = true; |
| } |
| |
| void Usage::AddStorageReadTexture() { |
| AddTexture(); |
| is_storage_read_ = true; |
| } |
| |
| void Usage::AddStorageWriteTexture() { |
| AddTexture(); |
| is_storage_write_ = true; |
| } |
| |
| void Usage::AddSampledTexture() { |
| AddTexture(); |
| is_sampled_ = true; |
| } |
| |
| void Usage::AddMultisampledTexture() { |
| AddSampledTexture(); |
| is_multisampled_ = true; |
| } |
| |
| void Usage::AddDepthTexture() { |
| AddSampledTexture(); |
| is_depth_ = true; |
| } |
| |
| std::string Usage::to_str() const { |
| StringStream ss; |
| ss << *this; |
| return ss.str(); |
| } |
| |
| } // namespace tint::spirv::reader |