blob: 1f927a8775ef7d362ee1d87d6abffd353445046f [file] [log] [blame]
// Copyright 2020 The Dawn & Tint Authors
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this
// list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "src/tint/lang/spirv/reader/ast_parser/usage.h"
#include "src/tint/utils/text/string_stream.h"
namespace tint::spirv::reader::ast_parser {
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;
}
}
}
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::ast_parser