| // 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/reader/spirv/usage.h" | |
| #include <sstream> | |
| namespace tint { | |
| namespace reader { | |
| namespace spirv { | |
| Usage::Usage() {} | |
| Usage::Usage(const Usage& other) = default; | |
| Usage::~Usage() = default; | |
| std::ostream& Usage::operator<<(std::ostream& 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 { | |
| std::ostringstream ss; | |
| ss << *this; | |
| return ss.str(); | |
| } | |
| } // namespace spirv | |
| } // namespace reader | |
| } // namespace tint |