mirror of
https://github.com/bkaradzic/bgfx.git
synced 2026-02-17 20:52:36 +01:00
shaderc: Add WGSL support. (#3542)
This commit is contained in:
committed by
GitHub
parent
fbff26d5e5
commit
1c08bab55a
26
3rdparty/dawn/LICENSE
vendored
Normal file
26
3rdparty/dawn/LICENSE
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
// Copyright 2017-2023 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.
|
||||
85
3rdparty/dawn/include/tint/tint.h
vendored
Normal file
85
3rdparty/dawn/include/tint/tint.h
vendored
Normal file
@@ -0,0 +1,85 @@
|
||||
// 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.
|
||||
|
||||
#ifndef INCLUDE_TINT_TINT_H_
|
||||
#define INCLUDE_TINT_TINT_H_
|
||||
|
||||
// Guard for accidental includes to private headers
|
||||
#define CURRENTLY_IN_TINT_PUBLIC_HEADER
|
||||
|
||||
// TODO(tint:88): When implementing support for an install target, all of these
|
||||
// headers will need to be moved to include/tint/.
|
||||
|
||||
#include "src/tint/api/common/subgroup_matrix.h"
|
||||
#include "src/tint/api/common/substitute_overrides_config.h"
|
||||
#include "src/tint/api/common/vertex_pulling_config.h"
|
||||
#include "src/tint/api/tint.h"
|
||||
#include "src/tint/lang/core/type/manager.h"
|
||||
#include "src/tint/lang/wgsl/inspector/inspector.h"
|
||||
#include "src/tint/utils/diagnostic/formatter.h"
|
||||
#include "src/tint/utils/text/styled_text.h"
|
||||
|
||||
///////////////
|
||||
// NOTE if adding a new guard include here, it must also appear in src/tint/api/tint.cc for the
|
||||
// build to work correctly.
|
||||
///////////////
|
||||
|
||||
#if TINT_BUILD_SPV_READER
|
||||
#include "src/tint/lang/spirv/reader/reader.h"
|
||||
#endif // TINT_BUILD_SPV_READER
|
||||
|
||||
#if TINT_BUILD_WGSL_READER
|
||||
#include "src/tint/lang/wgsl/reader/reader.h"
|
||||
#endif // TINT_BUILD_WGSL_READER
|
||||
|
||||
#if TINT_BUILD_SPV_WRITER
|
||||
#include "src/tint/lang/spirv/writer/writer.h"
|
||||
#endif // TINT_BUILD_SPV_WRITER
|
||||
|
||||
#if TINT_BUILD_WGSL_WRITER
|
||||
#include "src/tint/lang/wgsl/writer/writer.h"
|
||||
#endif // TINT_BUILD_WGSL_WRITER
|
||||
|
||||
#if TINT_BUILD_MSL_WRITER
|
||||
#include "src/tint/lang/msl/writer/writer.h"
|
||||
#endif // TINT_BUILD_MSL_WRITER
|
||||
|
||||
#if TINT_BUILD_HLSL_WRITER
|
||||
#include "src/tint/lang/hlsl/writer/writer.h"
|
||||
#endif // TINT_BUILD_HLSL_WRITER
|
||||
|
||||
#if TINT_BUILD_GLSL_WRITER
|
||||
#include "src/tint/lang/glsl/writer/writer.h"
|
||||
#endif // TINT_BUILD_GLSL_WRITER
|
||||
|
||||
#if TINT_BUILD_NULL_WRITER
|
||||
#include "src/tint/lang/null/writer/writer.h"
|
||||
#endif // TINT_BUILD_NULL_WRITER
|
||||
|
||||
#undef CURRENTLY_IN_TINT_PUBLIC_HEADER
|
||||
|
||||
#endif // INCLUDE_TINT_TINT_H_
|
||||
4887
3rdparty/dawn/include/webgpu/webgpu.h
vendored
Normal file
4887
3rdparty/dawn/include/webgpu/webgpu.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
109
3rdparty/dawn/src/tint/api/common/binding_point.h
vendored
Normal file
109
3rdparty/dawn/src/tint/api/common/binding_point.h
vendored
Normal file
@@ -0,0 +1,109 @@
|
||||
// Copyright 2021 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.
|
||||
|
||||
#ifndef SRC_TINT_API_COMMON_BINDING_POINT_H_
|
||||
#define SRC_TINT_API_COMMON_BINDING_POINT_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <functional>
|
||||
|
||||
#include "src/tint/utils/math/hash.h"
|
||||
#include "src/tint/utils/reflection.h"
|
||||
#include "src/tint/utils/rtti/traits.h"
|
||||
|
||||
namespace tint {
|
||||
|
||||
/// BindingPoint holds a group and binding index.
|
||||
struct BindingPoint {
|
||||
/// The `@group` part of the binding point
|
||||
uint32_t group = 0;
|
||||
/// The `@binding` part of the binding point
|
||||
uint32_t binding = 0;
|
||||
|
||||
/// Reflect the fields of this class so that it can be used by tint::ForeachField()
|
||||
TINT_REFLECT(BindingPoint, group, binding);
|
||||
|
||||
/// @returns the hash code of the BindingPoint
|
||||
tint::HashCode HashCode() const { return tint::Hash(group, binding); }
|
||||
|
||||
/// Equality operator
|
||||
/// @param rhs the BindingPoint to compare against
|
||||
/// @returns true if this BindingPoint is equal to `rhs`
|
||||
bool operator==(const BindingPoint& rhs) const {
|
||||
return group == rhs.group && binding == rhs.binding;
|
||||
}
|
||||
|
||||
/// Inequality operator
|
||||
/// @param rhs the BindingPoint to compare against
|
||||
/// @returns true if this BindingPoint is not equal to `rhs`
|
||||
bool operator!=(const BindingPoint& rhs) const { return !(*this == rhs); }
|
||||
|
||||
/// Less-than operator
|
||||
/// @param rhs the BindingPoint to compare against
|
||||
/// @returns true if this BindingPoint comes before @p rhs
|
||||
bool operator<(const BindingPoint& rhs) const {
|
||||
if (group < rhs.group) {
|
||||
return true;
|
||||
}
|
||||
if (group > rhs.group) {
|
||||
return false;
|
||||
}
|
||||
return binding < rhs.binding;
|
||||
}
|
||||
};
|
||||
|
||||
/// Prints the BindingPoint @p bp to @p o
|
||||
/// @param o the stream to write to
|
||||
/// @param bp the BindingPoint
|
||||
/// @return the stream so calls can be chained
|
||||
template <typename STREAM>
|
||||
requires(traits::IsOStream<STREAM>)
|
||||
auto& operator<<(STREAM& o, const BindingPoint& bp) {
|
||||
return o << "[group: " << bp.group << ", binding: " << bp.binding << "]";
|
||||
}
|
||||
|
||||
} // namespace tint
|
||||
|
||||
namespace std {
|
||||
|
||||
/// Custom std::hash specialization for tint::BindingPoint so BindingPoints can be used as keys for
|
||||
/// std::unordered_map and std::unordered_set.
|
||||
template <>
|
||||
class hash<tint::BindingPoint> {
|
||||
public:
|
||||
/// @param binding_point the binding point to create a hash for
|
||||
/// @return the hash value
|
||||
size_t operator()(const tint::BindingPoint& binding_point) const {
|
||||
return (static_cast<size_t>(binding_point.group) << 16) |
|
||||
static_cast<size_t>(binding_point.binding);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace std
|
||||
|
||||
#endif // SRC_TINT_API_COMMON_BINDING_POINT_H_
|
||||
90
3rdparty/dawn/src/tint/api/common/bindings.h
vendored
Normal file
90
3rdparty/dawn/src/tint/api/common/bindings.h
vendored
Normal file
@@ -0,0 +1,90 @@
|
||||
// Copyright 2025 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.
|
||||
|
||||
#ifndef SRC_TINT_API_COMMON_BINDINGS_H_
|
||||
#define SRC_TINT_API_COMMON_BINDINGS_H_
|
||||
|
||||
#include <unordered_map>
|
||||
|
||||
#include "src/tint/api/common/binding_point.h"
|
||||
#include "src/tint/utils/reflection.h"
|
||||
|
||||
namespace tint {
|
||||
|
||||
/// An external texture
|
||||
struct ExternalTexture {
|
||||
/// Metadata
|
||||
BindingPoint metadata{};
|
||||
/// Plane0 binding data
|
||||
BindingPoint plane0{};
|
||||
/// Plane1 binding data
|
||||
BindingPoint plane1{};
|
||||
|
||||
/// Reflect the fields of this class so that it can be used by tint::ForeachField()
|
||||
TINT_REFLECT(ExternalTexture, metadata, plane0, plane1);
|
||||
|
||||
TINT_REFLECT_EQUALS(ExternalTexture);
|
||||
TINT_REFLECT_HASH_CODE(ExternalTexture);
|
||||
};
|
||||
|
||||
using BindingMap = std::unordered_map<BindingPoint, BindingPoint>;
|
||||
using ExternalTextureBindings = std::unordered_map<BindingPoint, ExternalTexture>;
|
||||
|
||||
/// Binding information
|
||||
struct Bindings {
|
||||
/// Uniform bindings
|
||||
BindingMap uniform{};
|
||||
/// Storage bindings
|
||||
BindingMap storage{};
|
||||
/// Texture bindings
|
||||
BindingMap texture{};
|
||||
/// Storage texture bindings
|
||||
BindingMap storage_texture{};
|
||||
/// Sampler bindings
|
||||
BindingMap sampler{};
|
||||
/// External bindings
|
||||
ExternalTextureBindings external_texture{};
|
||||
/// Input attachment bindings
|
||||
BindingMap input_attachment{};
|
||||
|
||||
/// Reflect the fields of this class so that it can be used by tint::ForeachField()
|
||||
TINT_REFLECT(Bindings,
|
||||
uniform,
|
||||
storage,
|
||||
texture,
|
||||
storage_texture,
|
||||
sampler,
|
||||
external_texture,
|
||||
input_attachment);
|
||||
|
||||
TINT_REFLECT_EQUALS(Bindings);
|
||||
TINT_REFLECT_HASH_CODE(Bindings);
|
||||
};
|
||||
|
||||
} // namespace tint
|
||||
|
||||
#endif // SRC_TINT_API_COMMON_BINDINGS_H_
|
||||
84
3rdparty/dawn/src/tint/api/common/override_id.h
vendored
Normal file
84
3rdparty/dawn/src/tint/api/common/override_id.h
vendored
Normal file
@@ -0,0 +1,84 @@
|
||||
// Copyright 2022 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.
|
||||
|
||||
#ifndef SRC_TINT_API_COMMON_OVERRIDE_ID_H_
|
||||
#define SRC_TINT_API_COMMON_OVERRIDE_ID_H_
|
||||
|
||||
#include <stdint.h>
|
||||
#include <functional>
|
||||
|
||||
#include "src/tint/utils/math/hash.h"
|
||||
#include "src/tint/utils/reflection.h"
|
||||
|
||||
namespace tint {
|
||||
|
||||
/// OverrideId is a numerical identifier for an override variable, unique per program.
|
||||
struct OverrideId {
|
||||
/// The identifier value
|
||||
uint16_t value = 0;
|
||||
|
||||
/// Reflect the fields of this struct so that it can be used by tint::ForeachField()
|
||||
TINT_REFLECT(OverrideId, value);
|
||||
|
||||
/// @returns the hash code of the OverrideId
|
||||
tint::HashCode HashCode() const { return Hash(value); }
|
||||
};
|
||||
|
||||
/// Equality operator for OverrideId
|
||||
/// @param lhs the OverrideId on the left of the '=' operator
|
||||
/// @param rhs the OverrideId on the right of the '=' operator
|
||||
/// @returns true if `lhs` is equal to `rhs`
|
||||
inline bool operator==(OverrideId lhs, OverrideId rhs) {
|
||||
return lhs.value == rhs.value;
|
||||
}
|
||||
|
||||
/// Less-than operator for OverrideId
|
||||
/// @param lhs the OverrideId on the left of the '<' operator
|
||||
/// @param rhs the OverrideId on the right of the '<' operator
|
||||
/// @returns true if `lhs` comes before `rhs`
|
||||
inline bool operator<(OverrideId lhs, OverrideId rhs) {
|
||||
return lhs.value < rhs.value;
|
||||
}
|
||||
|
||||
} // namespace tint
|
||||
|
||||
namespace std {
|
||||
|
||||
/// Custom std::hash specialization for tint::OverrideId.
|
||||
template <>
|
||||
class hash<tint::OverrideId> {
|
||||
public:
|
||||
/// @param id the override identifier
|
||||
/// @return the hash of the override identifier
|
||||
inline size_t operator()(tint::OverrideId id) const {
|
||||
return std::hash<decltype(tint::OverrideId::value)>()(id.value);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace std
|
||||
|
||||
#endif // SRC_TINT_API_COMMON_OVERRIDE_ID_H_
|
||||
98
3rdparty/dawn/src/tint/api/common/resource_table_config.h
vendored
Normal file
98
3rdparty/dawn/src/tint/api/common/resource_table_config.h
vendored
Normal file
@@ -0,0 +1,98 @@
|
||||
// Copyright 2025 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.
|
||||
|
||||
#ifndef SRC_TINT_API_COMMON_RESOURCE_TABLE_CONFIG_H_
|
||||
#define SRC_TINT_API_COMMON_RESOURCE_TABLE_CONFIG_H_
|
||||
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
#include "src/tint/api/common/binding_point.h"
|
||||
#include "src/tint/api/common/resource_type.h"
|
||||
#include "src/tint/utils/reflection.h"
|
||||
|
||||
namespace tint {
|
||||
|
||||
// Configuration for the resource table transform.
|
||||
//
|
||||
// The resource table transform assumes that for each resource table entry there will be an
|
||||
// entry in the `bindings` hash map. That binding will provide information on the storage buffer
|
||||
// attached for the resource table. Specifically, the storage buffer should have a format of:
|
||||
//
|
||||
// ```
|
||||
// struct SB {
|
||||
// array_length: u32,
|
||||
// bindings: array<u32>, // Has `array_length` entries (doesn't include the default bindings).
|
||||
// }
|
||||
// ```
|
||||
//
|
||||
// The values used in the `bindings` are from the `u32` conversion of the `ResourceType` enum
|
||||
// entries.
|
||||
//
|
||||
struct ResourceTableConfig {
|
||||
// The binding point for the resource_table. This is a post-remapping binding point.
|
||||
BindingPoint resource_table_binding;
|
||||
|
||||
// The binding point for the supporting storage buffer. This is a post-remapping binding point.
|
||||
BindingPoint storage_buffer_binding;
|
||||
|
||||
// The ordering of default bindings which are placed after the user bindings. These will be used
|
||||
// as the index to lookup the given `ResourceType` if the user accesses with an incorrect
|
||||
// texture type (or out of bounds).
|
||||
//
|
||||
// These `default_binding_type_order` entries will be used when we need to substitute in a
|
||||
// default binding. So, we assume that Dawn is providing the resource table memory as:
|
||||
//
|
||||
// `[user 1 (2d_i32), user 2 (3d_f32), user 3 (1d_u32), 1d_u32_default, 2d_f32_default,
|
||||
// 3d_f32_default]`
|
||||
//
|
||||
// We would then have `default_binding_type_order` entries of:
|
||||
//
|
||||
// `[1d_u32, 2d_f32, 3d_f32]`
|
||||
//
|
||||
// Then when we compile a `getResource<T>(i)` call, we will have created the storage buffer,
|
||||
// call it `metadata` in this case:
|
||||
//
|
||||
// ```
|
||||
// const len = metadata.array_length;
|
||||
// if (i < len && type_to_u32(T) == metadata.bindings[i]) {
|
||||
// return bindings[i];
|
||||
// }
|
||||
// return bindings[len + index_in_binding_order(T)];
|
||||
// ```
|
||||
//
|
||||
std::vector<ResourceType> default_binding_type_order;
|
||||
|
||||
TINT_REFLECT(ResourceTableConfig,
|
||||
resource_table_binding,
|
||||
storage_buffer_binding,
|
||||
default_binding_type_order);
|
||||
};
|
||||
|
||||
} // namespace tint
|
||||
|
||||
#endif // SRC_TINT_API_COMMON_RESOURCE_TABLE_CONFIG_H_
|
||||
71
3rdparty/dawn/src/tint/api/common/resource_type.h
vendored
Normal file
71
3rdparty/dawn/src/tint/api/common/resource_type.h
vendored
Normal file
@@ -0,0 +1,71 @@
|
||||
// Copyright 2025 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.
|
||||
|
||||
#ifndef SRC_TINT_API_COMMON_RESOURCE_TYPE_H_
|
||||
#define SRC_TINT_API_COMMON_RESOURCE_TYPE_H_
|
||||
|
||||
#include "src/tint/utils/reflection.h"
|
||||
|
||||
namespace tint {
|
||||
|
||||
enum class ResourceType : uint32_t {
|
||||
kEmpty,
|
||||
|
||||
kTexture1d_f32,
|
||||
kTexture1d_i32,
|
||||
kTexture1d_u32,
|
||||
kTexture2d_f32,
|
||||
kTexture2d_i32,
|
||||
kTexture2d_u32,
|
||||
kTexture2dArray_f32,
|
||||
kTexture2dArray_i32,
|
||||
kTexture2dArray_u32,
|
||||
kTexture3d_f32,
|
||||
kTexture3d_i32,
|
||||
kTexture3d_u32,
|
||||
kTextureCube_f32,
|
||||
kTextureCube_i32,
|
||||
kTextureCube_u32,
|
||||
kTextureCubeArray_f32,
|
||||
kTextureCubeArray_i32,
|
||||
kTextureCubeArray_u32,
|
||||
|
||||
kTextureMultisampled2d_f32,
|
||||
kTextureMultisampled2d_i32,
|
||||
kTextureMultisampled2d_u32,
|
||||
|
||||
kTextureDepth2d,
|
||||
kTextureDepth2dArray,
|
||||
kTextureDepthCube,
|
||||
kTextureDepthCubeArray,
|
||||
kTextureDepthMultisampled2d,
|
||||
};
|
||||
TINT_REFLECT_ENUM_RANGE(tint::ResourceType, kEmpty, kTextureDepthMultisampled2d);
|
||||
|
||||
} // namespace tint
|
||||
|
||||
#endif // SRC_TINT_API_COMMON_RESOURCE_TYPE_H_
|
||||
113
3rdparty/dawn/src/tint/api/common/subgroup_matrix.h
vendored
Normal file
113
3rdparty/dawn/src/tint/api/common/subgroup_matrix.h
vendored
Normal file
@@ -0,0 +1,113 @@
|
||||
// Copyright 2025 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.
|
||||
|
||||
#ifndef SRC_TINT_API_COMMON_SUBGROUP_MATRIX_H_
|
||||
#define SRC_TINT_API_COMMON_SUBGROUP_MATRIX_H_
|
||||
|
||||
#include <unordered_set>
|
||||
|
||||
#include "src/tint/utils/math/hash.h"
|
||||
|
||||
#include "src/tint/utils/reflection.h"
|
||||
|
||||
namespace tint {
|
||||
|
||||
enum class SubgroupMatrixType : uint8_t {
|
||||
kF16 = 0,
|
||||
kF32,
|
||||
kU8,
|
||||
kI8,
|
||||
kU32,
|
||||
kI32,
|
||||
};
|
||||
TINT_REFLECT_ENUM_RANGE(tint::SubgroupMatrixType, kF16, kI32);
|
||||
|
||||
struct SubgroupMatrixMultiply {
|
||||
uint32_t M;
|
||||
uint32_t N;
|
||||
uint32_t K;
|
||||
|
||||
SubgroupMatrixType input_type;
|
||||
SubgroupMatrixType output_type;
|
||||
|
||||
TINT_REFLECT(SubgroupMatrixMultiply, M, N, K, input_type, output_type);
|
||||
TINT_REFLECT_EQUALS(SubgroupMatrixMultiply);
|
||||
TINT_REFLECT_HASH_CODE(SubgroupMatrixMultiply);
|
||||
};
|
||||
|
||||
enum class SubgroupMatrixDirection : uint8_t {
|
||||
kLeft,
|
||||
kRight,
|
||||
kResult,
|
||||
};
|
||||
TINT_REFLECT_ENUM_RANGE(tint::SubgroupMatrixDirection, kLeft, kResult);
|
||||
|
||||
struct SubgroupMatrixConfig {
|
||||
uint32_t M;
|
||||
uint32_t N;
|
||||
uint32_t K;
|
||||
|
||||
SubgroupMatrixType type;
|
||||
SubgroupMatrixDirection direction;
|
||||
|
||||
TINT_REFLECT(SubgroupMatrixConfig, M, N, K, type, direction);
|
||||
TINT_REFLECT_EQUALS(SubgroupMatrixConfig);
|
||||
TINT_REFLECT_HASH_CODE(SubgroupMatrixConfig);
|
||||
};
|
||||
|
||||
} // namespace tint
|
||||
|
||||
template <>
|
||||
class std::hash<tint::SubgroupMatrixMultiply> {
|
||||
public:
|
||||
inline std::size_t operator()(const tint::SubgroupMatrixMultiply& sm) const {
|
||||
return tint::Hash(sm.M, sm.N, sm.K, sm.input_type, sm.output_type);
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
class std::hash<tint::SubgroupMatrixConfig> {
|
||||
public:
|
||||
inline std::size_t operator()(const tint::SubgroupMatrixConfig sm) const {
|
||||
return tint::Hash(sm.M, sm.N, sm.K, sm.type, sm.direction);
|
||||
}
|
||||
};
|
||||
|
||||
namespace tint {
|
||||
|
||||
struct SubgroupMatrixInfo {
|
||||
std::unordered_set<SubgroupMatrixMultiply> multiplies;
|
||||
std::unordered_set<SubgroupMatrixConfig> configs;
|
||||
|
||||
TINT_REFLECT(SubgroupMatrixInfo, multiplies, configs);
|
||||
TINT_REFLECT_EQUALS(SubgroupMatrixInfo);
|
||||
TINT_REFLECT_HASH_CODE(SubgroupMatrixInfo);
|
||||
};
|
||||
|
||||
} // namespace tint
|
||||
|
||||
#endif // SRC_TINT_API_COMMON_SUBGROUP_MATRIX_H_
|
||||
53
3rdparty/dawn/src/tint/api/common/substitute_overrides_config.h
vendored
Normal file
53
3rdparty/dawn/src/tint/api/common/substitute_overrides_config.h
vendored
Normal file
@@ -0,0 +1,53 @@
|
||||
// Copyright 2025 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.
|
||||
|
||||
#ifndef SRC_TINT_API_COMMON_SUBSTITUTE_OVERRIDES_CONFIG_H_
|
||||
#define SRC_TINT_API_COMMON_SUBSTITUTE_OVERRIDES_CONFIG_H_
|
||||
|
||||
#include <unordered_map>
|
||||
|
||||
#include "src/tint/api/common/override_id.h"
|
||||
#include "src/tint/utils/reflection.h"
|
||||
|
||||
namespace tint {
|
||||
|
||||
/// Configuration options for the transform
|
||||
struct SubstituteOverridesConfig {
|
||||
/// The map of override identifier to the override value.
|
||||
/// The value is always a double coming into the transform and will be
|
||||
/// converted to the correct type through and initializer.
|
||||
std::unordered_map<OverrideId, double> map;
|
||||
|
||||
/// Reflect the fields of this class so that it can be used by tint::ForeachField()
|
||||
TINT_REFLECT(SubstituteOverridesConfig, map);
|
||||
TINT_REFLECT_EQUALS(SubstituteOverridesConfig);
|
||||
TINT_REFLECT_HASH_CODE(SubstituteOverridesConfig);
|
||||
};
|
||||
|
||||
} // namespace tint
|
||||
|
||||
#endif // SRC_TINT_API_COMMON_SUBSTITUTE_OVERRIDES_CONFIG_H_
|
||||
44
3rdparty/dawn/src/tint/api/common/vertex_pulling_config.cc
vendored
Normal file
44
3rdparty/dawn/src/tint/api/common/vertex_pulling_config.cc
vendored
Normal file
@@ -0,0 +1,44 @@
|
||||
// Copyright 2025 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/api/common/vertex_pulling_config.h"
|
||||
|
||||
#include <utility>
|
||||
|
||||
namespace tint {
|
||||
|
||||
VertexBufferLayoutDescriptor::VertexBufferLayoutDescriptor() = default;
|
||||
|
||||
VertexBufferLayoutDescriptor::VertexBufferLayoutDescriptor(
|
||||
uint32_t in_array_stride,
|
||||
VertexStepMode in_step_mode,
|
||||
std::vector<VertexAttributeDescriptor> in_attributes)
|
||||
: array_stride(in_array_stride),
|
||||
step_mode(in_step_mode),
|
||||
attributes(std::move(in_attributes)) {}
|
||||
|
||||
} // namespace tint
|
||||
148
3rdparty/dawn/src/tint/api/common/vertex_pulling_config.h
vendored
Normal file
148
3rdparty/dawn/src/tint/api/common/vertex_pulling_config.h
vendored
Normal file
@@ -0,0 +1,148 @@
|
||||
// Copyright 2025 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.
|
||||
|
||||
#ifndef SRC_TINT_API_COMMON_VERTEX_PULLING_CONFIG_H_
|
||||
#define SRC_TINT_API_COMMON_VERTEX_PULLING_CONFIG_H_
|
||||
|
||||
#include <cstdint>
|
||||
#include <vector>
|
||||
|
||||
#include "src/tint/utils/reflection.h"
|
||||
|
||||
namespace tint {
|
||||
|
||||
/// Describes the format of data in a vertex buffer.
|
||||
enum class VertexFormat : uint8_t {
|
||||
kUint8, // uint8
|
||||
kUint8x2, // uint8x2
|
||||
kUint8x4, // uint8x4
|
||||
kSint8, // sint8
|
||||
kSint8x2, // sint8x2
|
||||
kSint8x4, // sint8x4
|
||||
kUnorm8, // unorm8
|
||||
kUnorm8x2, // unorm8x2
|
||||
kUnorm8x4, // unorm8x4
|
||||
kSnorm8, // snorm8
|
||||
kSnorm8x2, // snorm8x2
|
||||
kSnorm8x4, // snorm8x4
|
||||
kUint16, // uint16
|
||||
kUint16x2, // uint16x2
|
||||
kUint16x4, // uint16x4
|
||||
kSint16, // sint16
|
||||
kSint16x2, // sint16x2
|
||||
kSint16x4, // sint16x4
|
||||
kUnorm16, // unorm16
|
||||
kUnorm16x2, // unorm16x2
|
||||
kUnorm16x4, // unorm16x4
|
||||
kSnorm16, // snorm16
|
||||
kSnorm16x2, // snorm16x2
|
||||
kSnorm16x4, // snorm16x4
|
||||
kFloat16, // float16
|
||||
kFloat16x2, // float16x2
|
||||
kFloat16x4, // float16x4
|
||||
kFloat32, // float32
|
||||
kFloat32x2, // float32x2
|
||||
kFloat32x3, // float32x3
|
||||
kFloat32x4, // float32x4
|
||||
kUint32, // uint32
|
||||
kUint32x2, // uint32x2
|
||||
kUint32x3, // uint32x3
|
||||
kUint32x4, // uint32x4
|
||||
kSint32, // sint32
|
||||
kSint32x2, // sint32x2
|
||||
kSint32x3, // sint32x3
|
||||
kSint32x4, // sint32x4
|
||||
kUnorm10_10_10_2, // unorm10-10-10-2
|
||||
kUnorm8x4BGRA, // unorm8x4-bgra
|
||||
};
|
||||
|
||||
/// Describes if a vertex attribute increments with vertex index or instance index.
|
||||
enum class VertexStepMode : uint8_t { kVertex, kInstance };
|
||||
|
||||
/// Describes a vertex attribute within a buffer
|
||||
struct VertexAttributeDescriptor {
|
||||
/// The format of the attribute.
|
||||
VertexFormat format;
|
||||
/// The byte offset of the attribute in the buffer.
|
||||
uint32_t offset;
|
||||
/// The shader location used for the attribute.
|
||||
uint32_t shader_location;
|
||||
|
||||
/// Reflect the fields of this class so that it can be used by tint::ForeachField()
|
||||
TINT_REFLECT(VertexAttributeDescriptor, format, offset, shader_location);
|
||||
TINT_REFLECT_EQUALS(VertexAttributeDescriptor);
|
||||
TINT_REFLECT_HASH_CODE(VertexAttributeDescriptor);
|
||||
};
|
||||
|
||||
/// Describes a buffer containing multiple vertex attributes
|
||||
struct VertexBufferLayoutDescriptor {
|
||||
/// Constructor
|
||||
VertexBufferLayoutDescriptor();
|
||||
/// Constructor
|
||||
/// @param in_array_stride the array stride in bytes of the in buffer
|
||||
/// @param in_step_mode the step mode of the in buffer
|
||||
/// @param in_attributes the in attributes
|
||||
VertexBufferLayoutDescriptor(uint32_t in_array_stride,
|
||||
VertexStepMode in_step_mode,
|
||||
std::vector<VertexAttributeDescriptor> in_attributes);
|
||||
/// The array stride in bytes used in the in buffer.
|
||||
uint32_t array_stride = 0u;
|
||||
/// The input step mode used.
|
||||
VertexStepMode step_mode = VertexStepMode::kVertex;
|
||||
/// The vertex attributes.
|
||||
std::vector<VertexAttributeDescriptor> attributes;
|
||||
|
||||
/// Reflect the fields of this class so that it can be used by tint::ForeachField()
|
||||
TINT_REFLECT(VertexBufferLayoutDescriptor, array_stride, step_mode, attributes);
|
||||
TINT_REFLECT_EQUALS(VertexBufferLayoutDescriptor);
|
||||
TINT_REFLECT_HASH_CODE(VertexBufferLayoutDescriptor);
|
||||
};
|
||||
|
||||
/// Configuration options that control the vertex pulling transform.
|
||||
struct VertexPullingConfig {
|
||||
/// The vertex state descriptor, containing info about attributes.
|
||||
std::vector<VertexBufferLayoutDescriptor> vertex_state;
|
||||
|
||||
/// The "group" we will put all our vertex buffers into (as storage buffers).
|
||||
/// Default to 4 as it is past the limits of user-accessible groups.
|
||||
uint32_t pulling_group = 4u;
|
||||
|
||||
/// Reflect the fields of this class so that it can be used by tint::ForeachField()
|
||||
TINT_REFLECT(VertexPullingConfig, vertex_state, pulling_group);
|
||||
TINT_REFLECT_EQUALS(VertexPullingConfig);
|
||||
TINT_REFLECT_HASH_CODE(VertexPullingConfig);
|
||||
};
|
||||
|
||||
/// Reflection for VertexFormat.
|
||||
TINT_REFLECT_ENUM_RANGE(tint::VertexFormat, kUint8x2, kUnorm8x4BGRA);
|
||||
|
||||
/// Reflection for VertexStepMode.
|
||||
TINT_REFLECT_ENUM_RANGE(tint::VertexStepMode, kVertex, kInstance);
|
||||
|
||||
} // namespace tint
|
||||
|
||||
#endif // SRC_TINT_API_COMMON_VERTEX_PULLING_CONFIG_H_
|
||||
174
3rdparty/dawn/src/tint/api/helpers/generate_bindings.cc
vendored
Normal file
174
3rdparty/dawn/src/tint/api/helpers/generate_bindings.cc
vendored
Normal file
@@ -0,0 +1,174 @@
|
||||
/// Copyright 2025 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/api/helpers/generate_bindings.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
|
||||
#include "src/tint/api/common/binding_point.h"
|
||||
#include "src/tint/lang/core/ir/module.h"
|
||||
#include "src/tint/lang/core/ir/referenced_module_vars.h"
|
||||
#include "src/tint/lang/core/ir/var.h"
|
||||
#include "src/tint/lang/core/type/external_texture.h"
|
||||
#include "src/tint/lang/core/type/pointer.h"
|
||||
#include "src/tint/lang/core/type/storage_texture.h"
|
||||
#include "src/tint/utils/rtti/switch.h"
|
||||
|
||||
namespace tint {
|
||||
|
||||
Bindings GenerateBindings(const core::ir::Module& module,
|
||||
const std::string& ep,
|
||||
bool set_group_to_zero,
|
||||
bool flatten_bindings) {
|
||||
Bindings bindings{};
|
||||
|
||||
uint32_t next_buffer_idx = 0;
|
||||
uint32_t next_sampler_idx = 0;
|
||||
uint32_t next_texture_idx = 0;
|
||||
|
||||
// Collect next valid binding number per group
|
||||
Hashmap<uint32_t, uint32_t, 4> group_to_next_binding_number;
|
||||
Vector<tint::BindingPoint, 4> ext_tex_bps;
|
||||
|
||||
core::ir::Function* ep_func = nullptr;
|
||||
for (auto* f : module.functions) {
|
||||
if (!f->IsEntryPoint()) {
|
||||
continue;
|
||||
}
|
||||
if (module.NameOf(f).NameView() == ep) {
|
||||
ep_func = f;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// No entrypoint, so no bindings needed
|
||||
if (!ep_func) {
|
||||
return bindings;
|
||||
}
|
||||
|
||||
core::ir::ReferencedModuleVars<const core::ir::Module> referenced_module_vars{module};
|
||||
auto& refs = referenced_module_vars.TransitiveReferences(ep_func);
|
||||
|
||||
for (auto* var : refs) {
|
||||
auto bp = var->BindingPoint();
|
||||
if (!bp.has_value()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (auto val = group_to_next_binding_number.Get(bp->group)) {
|
||||
*val = std::max(*val, bp->binding + 1);
|
||||
} else {
|
||||
group_to_next_binding_number.Add(bp->group, bp->binding + 1);
|
||||
}
|
||||
|
||||
auto* ptr = var->Result()->Type()->As<core::type::Pointer>();
|
||||
|
||||
// Store up the external textures, we'll add them in the next step
|
||||
if (ptr->StoreType()->Is<core::type::ExternalTexture>()) {
|
||||
ext_tex_bps.Push(*bp);
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (ptr->AddressSpace()) {
|
||||
case core::AddressSpace::kHandle:
|
||||
Switch(
|
||||
ptr->StoreType(), //
|
||||
[&](const core::type::Sampler*) {
|
||||
tint::BindingPoint info{
|
||||
.group = set_group_to_zero ? 0 : bp->group,
|
||||
.binding = flatten_bindings ? next_sampler_idx++ : bp->binding,
|
||||
};
|
||||
bindings.sampler.emplace(*bp, info);
|
||||
},
|
||||
[&](const core::type::StorageTexture*) {
|
||||
tint::BindingPoint info{
|
||||
.group = set_group_to_zero ? 0 : bp->group,
|
||||
.binding = flatten_bindings ? next_texture_idx++ : bp->binding,
|
||||
};
|
||||
bindings.storage_texture.emplace(*bp, info);
|
||||
},
|
||||
[&](const core::type::Texture*) {
|
||||
tint::BindingPoint info{
|
||||
.group = set_group_to_zero ? 0 : bp->group,
|
||||
.binding = flatten_bindings ? next_texture_idx++ : bp->binding,
|
||||
};
|
||||
bindings.texture.emplace(*bp, info);
|
||||
});
|
||||
break;
|
||||
case core::AddressSpace::kStorage: {
|
||||
tint::BindingPoint info{
|
||||
.group = set_group_to_zero ? 0 : bp->group,
|
||||
.binding = flatten_bindings ? next_buffer_idx++ : bp->binding,
|
||||
};
|
||||
bindings.storage.emplace(*bp, info);
|
||||
break;
|
||||
}
|
||||
case core::AddressSpace::kUniform: {
|
||||
tint::BindingPoint info{
|
||||
.group = set_group_to_zero ? 0 : bp->group,
|
||||
.binding = flatten_bindings ? next_buffer_idx++ : bp->binding,
|
||||
};
|
||||
bindings.uniform.emplace(*bp, info);
|
||||
break;
|
||||
}
|
||||
case core::AddressSpace::kUndefined:
|
||||
case core::AddressSpace::kPixelLocal:
|
||||
case core::AddressSpace::kPrivate:
|
||||
case core::AddressSpace::kImmediate:
|
||||
case core::AddressSpace::kIn:
|
||||
case core::AddressSpace::kOut:
|
||||
case core::AddressSpace::kFunction:
|
||||
case core::AddressSpace::kWorkgroup:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (flatten_bindings) {
|
||||
for (auto bp : ext_tex_bps) {
|
||||
uint32_t g = set_group_to_zero ? 0 : bp.group;
|
||||
|
||||
tint::BindingPoint plane0{.group = g, .binding = next_texture_idx++};
|
||||
tint::BindingPoint plane1{.group = g, .binding = next_texture_idx++};
|
||||
tint::BindingPoint metadata{.group = g, .binding = next_buffer_idx++};
|
||||
bindings.external_texture.emplace(bp, ExternalTexture{metadata, plane0, plane1});
|
||||
}
|
||||
} else {
|
||||
for (auto bp : ext_tex_bps) {
|
||||
uint32_t& next_num = group_to_next_binding_number.GetOrAddZero(bp.group);
|
||||
uint32_t g = set_group_to_zero ? 0 : bp.group;
|
||||
|
||||
tint::BindingPoint plane0{.group = g, .binding = bp.binding};
|
||||
tint::BindingPoint plane1{.group = g, .binding = next_num++};
|
||||
tint::BindingPoint metadata{.group = g, .binding = next_num++};
|
||||
bindings.external_texture.emplace(bp, ExternalTexture{metadata, plane0, plane1});
|
||||
}
|
||||
}
|
||||
|
||||
return bindings;
|
||||
}
|
||||
|
||||
} // namespace tint
|
||||
54
3rdparty/dawn/src/tint/api/helpers/generate_bindings.h
vendored
Normal file
54
3rdparty/dawn/src/tint/api/helpers/generate_bindings.h
vendored
Normal file
@@ -0,0 +1,54 @@
|
||||
/// Copyright 2025 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.
|
||||
|
||||
#ifndef SRC_TINT_API_HELPERS_GENERATE_BINDINGS_H_
|
||||
#define SRC_TINT_API_HELPERS_GENERATE_BINDINGS_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "src/tint/api/common/bindings.h"
|
||||
|
||||
// Forward declarations
|
||||
namespace tint::core::ir {
|
||||
class Module;
|
||||
} // namespace tint::core::ir
|
||||
|
||||
namespace tint {
|
||||
|
||||
/// Generate the resource bindings
|
||||
/// @param module the module to generate from
|
||||
/// @param set_group_to_zero if true, the group used for bindings will always be zero
|
||||
/// @param flatten_bindings if true, the bindings will remap to count from 0
|
||||
/// @returns the bindings
|
||||
Bindings GenerateBindings(const core::ir::Module& module,
|
||||
const std::string& ep,
|
||||
bool set_group_to_zero,
|
||||
bool flatten_bindings);
|
||||
|
||||
} // namespace tint
|
||||
|
||||
#endif // SRC_TINT_API_HELPERS_GENERATE_BINDINGS_H_
|
||||
116
3rdparty/dawn/src/tint/api/tint.cc
vendored
Normal file
116
3rdparty/dawn/src/tint/api/tint.cc
vendored
Normal file
@@ -0,0 +1,116 @@
|
||||
// Copyright 2023 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/api/tint.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// The following includes are used by './tools/run gen' to add an implicit
|
||||
// dependency from 'tint/api' to the libraries used to make up the Tint API.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// IWYU pragma: begin_keep
|
||||
#include "src/tint/api/common/override_id.h"
|
||||
|
||||
#if TINT_BUILD_GLSL_WRITER
|
||||
#include "src/tint/lang/glsl/writer/writer.h" // nogncheck
|
||||
#endif
|
||||
|
||||
#if TINT_BUILD_HLSL_WRITER
|
||||
#include "src/tint/lang/hlsl/writer/writer.h" // nogncheck
|
||||
#endif
|
||||
|
||||
#if TINT_BUILD_MSL_WRITER
|
||||
#include "src/tint/lang/msl/writer/writer.h" // nogncheck
|
||||
#endif
|
||||
|
||||
#if TINT_BUILD_SPV_READER
|
||||
#include "src/tint/lang/spirv/reader/reader.h" // nogncheck
|
||||
#endif
|
||||
|
||||
#if TINT_BUILD_SPV_WRITER
|
||||
#include "src/tint/lang/spirv/writer/writer.h" // nogncheck
|
||||
#endif
|
||||
|
||||
#if TINT_BUILD_WGSL_READER
|
||||
#include "src/tint/lang/wgsl/inspector/inspector.h" // nogncheck
|
||||
#include "src/tint/lang/wgsl/reader/reader.h" // nogncheck
|
||||
#endif
|
||||
|
||||
#if TINT_BUILD_WGSL_WRITER
|
||||
#include "src/tint/lang/wgsl/program/program.h"
|
||||
#include "src/tint/lang/wgsl/writer/writer.h" // nogncheck
|
||||
#endif
|
||||
|
||||
#if TINT_BUILD_NULL_WRITER
|
||||
#include "src/tint/lang/null/writer/writer.h" // nogncheck
|
||||
#endif
|
||||
|
||||
// IWYU pragma: end_keep
|
||||
|
||||
#if TINT_BUILD_SPV_READER && TINT_BUILD_WGSL_WRITER
|
||||
#include "src/tint/lang/core/ir/module.h"
|
||||
#endif
|
||||
|
||||
namespace tint {
|
||||
|
||||
/// Initialize initializes the Tint library. Call before using the Tint API.
|
||||
void Initialize() {
|
||||
#if TINT_BUILD_WGSL_WRITER
|
||||
// Register the Program printer. This is used for debugging purposes.
|
||||
tint::Program::printer = [](const tint::Program& program) {
|
||||
auto result = wgsl::writer::Generate(program);
|
||||
if (result != Success) {
|
||||
return result.Failure().reason;
|
||||
}
|
||||
return result->wgsl;
|
||||
};
|
||||
#endif
|
||||
}
|
||||
|
||||
/// Shutdown uninitializes the Tint library. Call after using the Tint API.
|
||||
void Shutdown() {
|
||||
// Currently no-op, but may release tint resources in the future.
|
||||
}
|
||||
|
||||
Result<std::string> SpirvToWgsl([[maybe_unused]] const std::vector<uint32_t>& spirv,
|
||||
[[maybe_unused]] const wgsl::writer::Options& wgsl_options) {
|
||||
#if !TINT_BUILD_SPV_READER
|
||||
return Failure{"Tint SPIR-V reader is not enabled"};
|
||||
#elif !TINT_BUILD_WGSL_WRITER
|
||||
return Failure{"Tint WGSL writer is not enabled"};
|
||||
#else
|
||||
// Convert the SPIR-V program to an IR module.
|
||||
TINT_CHECK_RESULT_UNWRAP(ir_from_spirv, tint::spirv::reader::ReadIR(spirv));
|
||||
|
||||
// Convert the IR module to WGSL.
|
||||
TINT_CHECK_RESULT_UNWRAP(wgsl_from_ir,
|
||||
tint::wgsl::writer::WgslFromIR(ir_from_spirv, wgsl_options));
|
||||
|
||||
return wgsl_from_ir.wgsl;
|
||||
#endif // TINT_BUILD_SPV_READER && TINT_BUILD_WGSL_WRITER
|
||||
}
|
||||
|
||||
} // namespace tint
|
||||
55
3rdparty/dawn/src/tint/api/tint.h
vendored
Normal file
55
3rdparty/dawn/src/tint/api/tint.h
vendored
Normal file
@@ -0,0 +1,55 @@
|
||||
// Copyright 2023 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.
|
||||
|
||||
#ifndef SRC_TINT_API_TINT_H_
|
||||
#define SRC_TINT_API_TINT_H_
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "src/tint/lang/wgsl/writer/common/options.h"
|
||||
#include "src/tint/utils/result.h"
|
||||
|
||||
namespace tint {
|
||||
|
||||
/// Initialize initializes the Tint library. Call before using the Tint API.
|
||||
void Initialize();
|
||||
|
||||
/// Shutdown uninitializes the Tint library. Call after using the Tint API.
|
||||
void Shutdown();
|
||||
|
||||
/// Convert a SPIR-V binary to a WGSL shader module string.
|
||||
/// @param spirv the SPIR-V binary
|
||||
/// @param wgsl_options the options to use for generating WGSL
|
||||
/// @returns the WGSL module, or a failure
|
||||
tint::Result<std::string> SpirvToWgsl(const std::vector<uint32_t>& spirv,
|
||||
const wgsl::writer::Options& wgsl_options = {});
|
||||
|
||||
} // namespace tint
|
||||
|
||||
#endif // SRC_TINT_API_TINT_H_
|
||||
74
3rdparty/dawn/src/tint/lang/core/binary_op.cc
vendored
Normal file
74
3rdparty/dawn/src/tint/lang/core/binary_op.cc
vendored
Normal file
@@ -0,0 +1,74 @@
|
||||
// Copyright 2023 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/core/binary_op.h"
|
||||
|
||||
namespace tint::core {
|
||||
|
||||
std::string_view ToString(BinaryOp value) {
|
||||
switch (value) {
|
||||
case BinaryOp::kAnd:
|
||||
return "&";
|
||||
case BinaryOp::kOr:
|
||||
return "|";
|
||||
case BinaryOp::kXor:
|
||||
return "^";
|
||||
case BinaryOp::kLogicalAnd:
|
||||
return "&&";
|
||||
case BinaryOp::kLogicalOr:
|
||||
return "||";
|
||||
case BinaryOp::kEqual:
|
||||
return "==";
|
||||
case BinaryOp::kNotEqual:
|
||||
return "!=";
|
||||
case BinaryOp::kLessThan:
|
||||
return "<";
|
||||
case BinaryOp::kGreaterThan:
|
||||
return ">";
|
||||
case BinaryOp::kLessThanEqual:
|
||||
return "<=";
|
||||
case BinaryOp::kGreaterThanEqual:
|
||||
return ">=";
|
||||
case BinaryOp::kShiftLeft:
|
||||
return "<<";
|
||||
case BinaryOp::kShiftRight:
|
||||
return ">>";
|
||||
case BinaryOp::kAdd:
|
||||
return "+";
|
||||
case BinaryOp::kSubtract:
|
||||
return "-";
|
||||
case BinaryOp::kMultiply:
|
||||
return "*";
|
||||
case BinaryOp::kDivide:
|
||||
return "/";
|
||||
case BinaryOp::kModulo:
|
||||
return "%";
|
||||
}
|
||||
return "<unknown>";
|
||||
}
|
||||
|
||||
} // namespace tint::core
|
||||
72
3rdparty/dawn/src/tint/lang/core/binary_op.h
vendored
Normal file
72
3rdparty/dawn/src/tint/lang/core/binary_op.h
vendored
Normal file
@@ -0,0 +1,72 @@
|
||||
// Copyright 2023 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.
|
||||
|
||||
#ifndef SRC_TINT_LANG_CORE_BINARY_OP_H_
|
||||
#define SRC_TINT_LANG_CORE_BINARY_OP_H_
|
||||
|
||||
#include "src/tint/utils/rtti/traits.h"
|
||||
|
||||
namespace tint::core {
|
||||
|
||||
/// An enumerator of binary operators.
|
||||
enum class BinaryOp {
|
||||
kAnd, // &
|
||||
kOr, // |
|
||||
kXor,
|
||||
kLogicalAnd, // &&
|
||||
kLogicalOr, // ||
|
||||
kEqual,
|
||||
kNotEqual,
|
||||
kLessThan,
|
||||
kGreaterThan,
|
||||
kLessThanEqual,
|
||||
kGreaterThanEqual,
|
||||
kShiftLeft,
|
||||
kShiftRight,
|
||||
kAdd,
|
||||
kSubtract,
|
||||
kMultiply,
|
||||
kDivide,
|
||||
kModulo,
|
||||
};
|
||||
|
||||
/// @param value the enum value
|
||||
/// @returns the string for the given enum value
|
||||
std::string_view ToString(BinaryOp value);
|
||||
|
||||
/// @param out the stream to write to
|
||||
/// @param value the BinaryOp
|
||||
/// @returns @p out so calls can be chained
|
||||
template <typename STREAM>
|
||||
requires(traits::IsOStream<STREAM>)
|
||||
auto& operator<<(STREAM& out, BinaryOp value) {
|
||||
return out << ToString(value);
|
||||
}
|
||||
|
||||
} // namespace tint::core
|
||||
|
||||
#endif // SRC_TINT_LANG_CORE_BINARY_OP_H_
|
||||
51
3rdparty/dawn/src/tint/lang/core/constant/clone_context.h
vendored
Normal file
51
3rdparty/dawn/src/tint/lang/core/constant/clone_context.h
vendored
Normal file
@@ -0,0 +1,51 @@
|
||||
// Copyright 2023 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.
|
||||
|
||||
#ifndef SRC_TINT_LANG_CORE_CONSTANT_CLONE_CONTEXT_H_
|
||||
#define SRC_TINT_LANG_CORE_CONSTANT_CLONE_CONTEXT_H_
|
||||
|
||||
#include "src/tint/lang/core/type/clone_context.h"
|
||||
|
||||
// Forward declarations
|
||||
namespace tint::core::constant {
|
||||
class Manager;
|
||||
} // namespace tint::core::constant
|
||||
|
||||
namespace tint::core::constant {
|
||||
|
||||
/// Context information for cloning of constants
|
||||
struct CloneContext {
|
||||
/// The context for cloning type information
|
||||
core::type::CloneContext type_ctx;
|
||||
|
||||
/// Destination information
|
||||
constant::Manager& dst;
|
||||
};
|
||||
|
||||
} // namespace tint::core::constant
|
||||
|
||||
#endif // SRC_TINT_LANG_CORE_CONSTANT_CLONE_CONTEXT_H_
|
||||
58
3rdparty/dawn/src/tint/lang/core/constant/composite.cc
vendored
Normal file
58
3rdparty/dawn/src/tint/lang/core/constant/composite.cc
vendored
Normal file
@@ -0,0 +1,58 @@
|
||||
// Copyright 2022 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/core/constant/composite.h"
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include "src/tint/lang/core/constant/manager.h"
|
||||
|
||||
TINT_INSTANTIATE_TYPEINFO(tint::core::constant::Composite);
|
||||
|
||||
namespace tint::core::constant {
|
||||
|
||||
Composite::Composite(const core::type::Type* t, VectorRef<const Value*> els, bool all_0, bool any_0)
|
||||
: type(t), elements(std::move(els)), all_zero(all_0), any_zero(any_0), hash(CalcHash()) {
|
||||
const size_t n = elements.Length();
|
||||
TINT_ASSERT(n == t->Elements().count);
|
||||
for (size_t i = 0; i < n; i++) {
|
||||
TINT_ASSERT(t->Element(static_cast<uint32_t>(i)) == elements[i]->Type());
|
||||
}
|
||||
}
|
||||
|
||||
Composite::~Composite() = default;
|
||||
|
||||
const Composite* Composite::Clone(CloneContext& ctx) const {
|
||||
auto* ty = type->Clone(ctx.type_ctx);
|
||||
Vector<const Value*, 4> els;
|
||||
for (const auto* el : elements) {
|
||||
els.Push(el->Clone(ctx));
|
||||
}
|
||||
return ctx.dst.Get<Composite>(ty, std::move(els), all_zero, any_zero);
|
||||
}
|
||||
|
||||
} // namespace tint::core::constant
|
||||
106
3rdparty/dawn/src/tint/lang/core/constant/composite.h
vendored
Normal file
106
3rdparty/dawn/src/tint/lang/core/constant/composite.h
vendored
Normal file
@@ -0,0 +1,106 @@
|
||||
// Copyright 2022 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.
|
||||
|
||||
#ifndef SRC_TINT_LANG_CORE_CONSTANT_COMPOSITE_H_
|
||||
#define SRC_TINT_LANG_CORE_CONSTANT_COMPOSITE_H_
|
||||
|
||||
#include "src/tint/lang/core/constant/value.h"
|
||||
#include "src/tint/lang/core/number.h"
|
||||
#include "src/tint/lang/core/type/type.h"
|
||||
#include "src/tint/utils/containers/vector.h"
|
||||
#include "src/tint/utils/math/hash.h"
|
||||
#include "src/tint/utils/rtti/castable.h"
|
||||
|
||||
namespace tint::core::constant {
|
||||
|
||||
/// Composite holds a number of mixed child values.
|
||||
/// Composite may be of a vector, matrix, array or structure type.
|
||||
/// If each element is the same type and value, then a Splat would be a more efficient constant
|
||||
/// implementation. Use CreateComposite() to create the appropriate type.
|
||||
class Composite : public Castable<Composite, Value> {
|
||||
public:
|
||||
/// Constructor
|
||||
/// @param t the compsite type
|
||||
/// @param els the composite elements
|
||||
/// @param all_0 true if all elements are 0
|
||||
/// @param any_0 true if any element is 0
|
||||
Composite(const core::type::Type* t, VectorRef<const Value*> els, bool all_0, bool any_0);
|
||||
~Composite() override;
|
||||
|
||||
/// @copydoc Value::Type()
|
||||
const core::type::Type* Type() const override { return type; }
|
||||
|
||||
/// @copydoc Value::Index()
|
||||
const Value* Index(size_t i) const override {
|
||||
return i < elements.Length() ? elements[i] : nullptr;
|
||||
}
|
||||
|
||||
/// @copydoc Value::NumElements()
|
||||
size_t NumElements() const override { return elements.Length(); }
|
||||
|
||||
/// @copydoc Value::AllZero()
|
||||
bool AllZero() const override { return all_zero; }
|
||||
|
||||
/// @copydoc Value::AnyZero()
|
||||
bool AnyZero() const override { return any_zero; }
|
||||
|
||||
/// @copydoc Value::Hash()
|
||||
HashCode Hash() const override { return hash; }
|
||||
|
||||
/// Clones the constant into the provided context
|
||||
/// @param ctx the clone context
|
||||
/// @returns the cloned node
|
||||
const Composite* Clone(CloneContext& ctx) const override;
|
||||
|
||||
/// The composite type
|
||||
core::type::Type const* const type;
|
||||
/// The composite elements
|
||||
const Vector<const Value*, 4> elements;
|
||||
/// True if all elements are zero
|
||||
const bool all_zero;
|
||||
/// True if any element is zero
|
||||
const bool any_zero;
|
||||
/// The hash of the composite
|
||||
const HashCode hash;
|
||||
|
||||
protected:
|
||||
/// @copydoc Value::InternalValue()
|
||||
std::variant<std::monostate, AInt, AFloat> InternalValue() const override { return {}; }
|
||||
|
||||
private:
|
||||
HashCode CalcHash() {
|
||||
auto h = tint::Hash(type, all_zero, any_zero);
|
||||
for (auto* el : elements) {
|
||||
h = HashCombine(h, el->Hash());
|
||||
}
|
||||
return h;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace tint::core::constant
|
||||
|
||||
#endif // SRC_TINT_LANG_CORE_CONSTANT_COMPOSITE_H_
|
||||
3727
3rdparty/dawn/src/tint/lang/core/constant/eval.cc
vendored
Normal file
3727
3rdparty/dawn/src/tint/lang/core/constant/eval.cc
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1349
3rdparty/dawn/src/tint/lang/core/constant/eval.h
vendored
Normal file
1349
3rdparty/dawn/src/tint/lang/core/constant/eval.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
45
3rdparty/dawn/src/tint/lang/core/constant/invalid.cc
vendored
Normal file
45
3rdparty/dawn/src/tint/lang/core/constant/invalid.cc
vendored
Normal file
@@ -0,0 +1,45 @@
|
||||
// Copyright 2024 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/core/constant/invalid.h"
|
||||
|
||||
#include "src/tint/lang/core/constant/manager.h"
|
||||
#include "src/tint/lang/core/type/invalid.h"
|
||||
|
||||
TINT_INSTANTIATE_TYPEINFO(tint::core::constant::Invalid);
|
||||
|
||||
namespace tint::core::constant {
|
||||
|
||||
Invalid::Invalid(const core::type::Invalid* ty) : type(ty) {}
|
||||
|
||||
Invalid::~Invalid() = default;
|
||||
|
||||
const Invalid* Invalid::Clone(CloneContext& ctx) const {
|
||||
return ctx.dst.Invalid();
|
||||
}
|
||||
|
||||
} // namespace tint::core::constant
|
||||
81
3rdparty/dawn/src/tint/lang/core/constant/invalid.h
vendored
Normal file
81
3rdparty/dawn/src/tint/lang/core/constant/invalid.h
vendored
Normal file
@@ -0,0 +1,81 @@
|
||||
// Copyright 2024 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.
|
||||
|
||||
#ifndef SRC_TINT_LANG_CORE_CONSTANT_INVALID_H_
|
||||
#define SRC_TINT_LANG_CORE_CONSTANT_INVALID_H_
|
||||
|
||||
#include <variant>
|
||||
#include "src/tint/lang/core/constant/value.h"
|
||||
#include "src/tint/lang/core/number.h"
|
||||
#include "src/tint/lang/core/type/invalid.h"
|
||||
#include "src/tint/utils/rtti/castable.h"
|
||||
|
||||
namespace tint::core::constant {
|
||||
|
||||
/// Invalid represents an invalid constant, used as a placeholder in a failed parse / resolve.
|
||||
class Invalid : public Castable<Invalid, Value> {
|
||||
public:
|
||||
/// Constructor
|
||||
/// @param ty the Invalid type
|
||||
explicit Invalid(const core::type::Invalid* ty);
|
||||
~Invalid() override;
|
||||
|
||||
/// @returns the type of the Invalid
|
||||
const core::type::Type* Type() const override { return type; }
|
||||
|
||||
/// Retrieve item at index @p i
|
||||
/// @param i the index to retrieve
|
||||
/// @returns the element, or nullptr if out of bounds
|
||||
const Value* Index([[maybe_unused]] size_t i) const override { return nullptr; }
|
||||
|
||||
/// @copydoc Value::NumElements()
|
||||
size_t NumElements() const override { return 0; }
|
||||
|
||||
/// @returns true if the element is zero
|
||||
bool AllZero() const override { return false; }
|
||||
/// @returns true if the element is zero
|
||||
bool AnyZero() const override { return false; }
|
||||
|
||||
/// @returns the hash for the Invalid
|
||||
HashCode Hash() const override { return tint::Hash(type); }
|
||||
|
||||
/// Clones the constant into the provided context
|
||||
/// @param ctx the clone context
|
||||
/// @returns the cloned node
|
||||
const Invalid* Clone(CloneContext& ctx) const override;
|
||||
|
||||
/// The Invalid type
|
||||
core::type::Invalid const* const type;
|
||||
|
||||
protected:
|
||||
/// @returns a monostate variant.
|
||||
std::variant<std::monostate, AInt, AFloat> InternalValue() const override { return {}; }
|
||||
};
|
||||
|
||||
} // namespace tint::core::constant
|
||||
|
||||
#endif // SRC_TINT_LANG_CORE_CONSTANT_INVALID_H_
|
||||
197
3rdparty/dawn/src/tint/lang/core/constant/manager.cc
vendored
Normal file
197
3rdparty/dawn/src/tint/lang/core/constant/manager.cc
vendored
Normal file
@@ -0,0 +1,197 @@
|
||||
// Copyright 2023 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/core/constant/manager.h"
|
||||
|
||||
#include "src/tint/lang/core/constant/composite.h"
|
||||
#include "src/tint/lang/core/constant/invalid.h"
|
||||
#include "src/tint/lang/core/constant/scalar.h"
|
||||
#include "src/tint/lang/core/constant/splat.h"
|
||||
#include "src/tint/lang/core/constant/string.h"
|
||||
#include "src/tint/lang/core/type/abstract_float.h"
|
||||
#include "src/tint/lang/core/type/abstract_int.h"
|
||||
#include "src/tint/lang/core/type/array.h"
|
||||
#include "src/tint/lang/core/type/bool.h"
|
||||
#include "src/tint/lang/core/type/f16.h"
|
||||
#include "src/tint/lang/core/type/f32.h"
|
||||
#include "src/tint/lang/core/type/i32.h"
|
||||
#include "src/tint/lang/core/type/i8.h"
|
||||
#include "src/tint/lang/core/type/manager.h"
|
||||
#include "src/tint/lang/core/type/matrix.h"
|
||||
#include "src/tint/lang/core/type/u32.h"
|
||||
#include "src/tint/lang/core/type/u64.h"
|
||||
#include "src/tint/lang/core/type/u8.h"
|
||||
#include "src/tint/lang/core/type/vector.h"
|
||||
#include "src/tint/utils/containers/predicates.h"
|
||||
#include "src/tint/utils/rtti/switch.h"
|
||||
|
||||
namespace tint::core::constant {
|
||||
|
||||
Manager::Manager() = default;
|
||||
|
||||
Manager::Manager(Manager&&) = default;
|
||||
|
||||
Manager& Manager::operator=(Manager&& rhs) = default;
|
||||
|
||||
Manager::~Manager() = default;
|
||||
|
||||
const constant::Value* Manager::Composite(const core::type::Type* type,
|
||||
VectorRef<const constant::Value*> elements) {
|
||||
if (elements.IsEmpty()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool any_zero = false;
|
||||
bool all_zero = true;
|
||||
bool all_equal = true;
|
||||
auto* first = elements.Front();
|
||||
for (auto* el : elements) {
|
||||
if (DAWN_UNLIKELY(!el)) {
|
||||
return nullptr;
|
||||
}
|
||||
if (!any_zero && el->AnyZero()) {
|
||||
any_zero = true;
|
||||
}
|
||||
if (all_zero && !el->AllZero()) {
|
||||
all_zero = false;
|
||||
}
|
||||
if (all_equal && el != first) {
|
||||
all_equal = false;
|
||||
}
|
||||
}
|
||||
if (all_equal) {
|
||||
return Splat(type, elements.Front());
|
||||
}
|
||||
|
||||
return Get<constant::Composite>(type, std::move(elements), all_zero, any_zero);
|
||||
}
|
||||
|
||||
const constant::Splat* Manager::Splat(const core::type::Type* type,
|
||||
const constant::Value* element) {
|
||||
return Get<constant::Splat>(type, element);
|
||||
}
|
||||
|
||||
const Scalar<i32>* Manager::Get(i32 value) {
|
||||
return Get<Scalar<i32>>(types.i32(), value);
|
||||
}
|
||||
|
||||
const Scalar<u32>* Manager::Get(u32 value) {
|
||||
return Get<Scalar<u32>>(types.u32(), value);
|
||||
}
|
||||
|
||||
const Scalar<u64>* Manager::Get(u64 value) {
|
||||
return Get<Scalar<u64>>(types.u64(), value);
|
||||
}
|
||||
|
||||
const Scalar<i8>* Manager::Get(i8 value) {
|
||||
return Get<Scalar<i8>>(types.i8(), value);
|
||||
}
|
||||
|
||||
const Scalar<u8>* Manager::Get(u8 value) {
|
||||
return Get<Scalar<u8>>(types.u8(), value);
|
||||
}
|
||||
|
||||
const Scalar<f32>* Manager::Get(f32 value) {
|
||||
return Get<Scalar<f32>>(types.f32(), value);
|
||||
}
|
||||
|
||||
const Scalar<f16>* Manager::Get(f16 value) {
|
||||
return Get<Scalar<f16>>(types.f16(), value);
|
||||
}
|
||||
|
||||
const Scalar<bool>* Manager::Get(bool value) {
|
||||
return Get<Scalar<bool>>(types.bool_(), value);
|
||||
}
|
||||
|
||||
const Scalar<AFloat>* Manager::Get(AFloat value) {
|
||||
return Get<Scalar<AFloat>>(types.AFloat(), value);
|
||||
}
|
||||
|
||||
const Scalar<AInt>* Manager::Get(AInt value) {
|
||||
return Get<Scalar<AInt>>(types.AInt(), value);
|
||||
}
|
||||
|
||||
const constant::String* Manager::Get(std::string_view value) {
|
||||
return Get<String>(types.String(), value);
|
||||
}
|
||||
|
||||
const Value* Manager::Zero(const core::type::Type* type) {
|
||||
return Switch(
|
||||
type, //
|
||||
[&](const core::type::Vector* v) -> const Value* {
|
||||
auto* zero_el = Zero(v->Type());
|
||||
return Splat(type, zero_el);
|
||||
},
|
||||
[&](const core::type::Matrix* m) -> const Value* {
|
||||
auto* zero_el = Zero(m->ColumnType());
|
||||
return Splat(type, zero_el);
|
||||
},
|
||||
[&](const core::type::Array* a) -> const Value* {
|
||||
if (a->ConstantCount()) {
|
||||
if (auto* zero_el = Zero(a->ElemType())) {
|
||||
return Splat(type, zero_el);
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
},
|
||||
[&](const core::type::Struct* s) -> const Value* {
|
||||
Hashmap<const core::type::Type*, const Value*, 8> zero_by_type;
|
||||
Vector<const Value*, 4> zeros;
|
||||
zeros.Reserve(s->Members().Length());
|
||||
for (auto* member : s->Members()) {
|
||||
auto* zero =
|
||||
zero_by_type.GetOrAdd(member->Type(), [&] { return Zero(member->Type()); });
|
||||
if (!zero) {
|
||||
return nullptr;
|
||||
}
|
||||
zeros.Push(zero);
|
||||
}
|
||||
if (zero_by_type.Count() == 1) {
|
||||
// All members were of the same type, so the zero value is the same for all members.
|
||||
return Splat(type, zeros[0]);
|
||||
}
|
||||
return Composite(s, std::move(zeros));
|
||||
},
|
||||
[&](const core::type::AbstractInt*) { return Get(AInt(0)); }, //
|
||||
[&](const core::type::AbstractFloat*) { return Get(AFloat(0)); }, //
|
||||
[&](const core::type::I32*) { return Get(i32(0)); }, //
|
||||
[&](const core::type::U32*) { return Get(u32(0)); }, //
|
||||
[&](const core::type::I8*) { return Get(i8(0)); }, //
|
||||
[&](const core::type::U8*) { return Get(u8(0)); }, //
|
||||
[&](const core::type::U64*) { return Get(u64(0)); }, //
|
||||
[&](const core::type::F32*) { return Get(f32(0)); }, //
|
||||
[&](const core::type::F16*) { return Get(f16(0)); }, //
|
||||
[&](const core::type::Bool*) { return Get(false); }, //
|
||||
[&](const core::type::Invalid*) { return Invalid(); }, //
|
||||
TINT_ICE_ON_NO_MATCH);
|
||||
}
|
||||
|
||||
const constant::Invalid* Manager::Invalid() {
|
||||
return values_.Get<constant::Invalid>(types.invalid());
|
||||
}
|
||||
|
||||
} // namespace tint::core::constant
|
||||
181
3rdparty/dawn/src/tint/lang/core/constant/manager.h
vendored
Normal file
181
3rdparty/dawn/src/tint/lang/core/constant/manager.h
vendored
Normal file
@@ -0,0 +1,181 @@
|
||||
// Copyright 2023 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.
|
||||
|
||||
#ifndef SRC_TINT_LANG_CORE_CONSTANT_MANAGER_H_
|
||||
#define SRC_TINT_LANG_CORE_CONSTANT_MANAGER_H_
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include "src/tint/lang/core/constant/invalid.h"
|
||||
#include "src/tint/lang/core/constant/value.h"
|
||||
#include "src/tint/lang/core/number.h"
|
||||
#include "src/tint/lang/core/type/manager.h"
|
||||
#include "src/tint/utils/containers/unique_allocator.h"
|
||||
#include "src/tint/utils/math/hash.h"
|
||||
|
||||
namespace tint::core::constant {
|
||||
class Splat;
|
||||
class String;
|
||||
|
||||
template <typename T>
|
||||
class Scalar;
|
||||
} // namespace tint::core::constant
|
||||
|
||||
namespace tint::core::constant {
|
||||
|
||||
/// The constant manager holds a type manager and all the pointers to the known constant values.
|
||||
class Manager final {
|
||||
public:
|
||||
/// Iterator is the type returned by begin() and end()
|
||||
using TypeIterator = BlockAllocator<Value>::ConstIterator;
|
||||
|
||||
/// Constructor
|
||||
Manager();
|
||||
|
||||
/// Move constructor
|
||||
Manager(Manager&&);
|
||||
|
||||
/// Move assignment operator
|
||||
/// @param rhs the Manager to move
|
||||
/// @return this Manager
|
||||
Manager& operator=(Manager&& rhs);
|
||||
|
||||
/// Destructor
|
||||
~Manager();
|
||||
|
||||
/// @param args the arguments used to construct the type, unique node or node.
|
||||
/// @return a pointer to an instance of `T` with the provided arguments.
|
||||
/// If NODE derives from UniqueNode and an existing instance of `T` has been
|
||||
/// constructed, then the same pointer is returned.
|
||||
template <typename NODE, typename... ARGS>
|
||||
NODE* Get(ARGS&&... args) {
|
||||
return values_.Get<NODE>(std::forward<ARGS>(args)...);
|
||||
}
|
||||
|
||||
/// @returns an iterator to the beginning of the types
|
||||
TypeIterator begin() const { return values_.begin(); }
|
||||
/// @returns an iterator to the end of the types
|
||||
TypeIterator end() const { return values_.end(); }
|
||||
|
||||
/// Constructs a constant of a vector, matrix or array type.
|
||||
///
|
||||
/// Examines the element values and will return either a constant::Composite or a
|
||||
/// constant::Splat, depending on the element types and values.
|
||||
///
|
||||
/// @param type the composite type
|
||||
/// @param elements the composite elements
|
||||
/// @returns the value pointer
|
||||
const constant::Value* Composite(const core::type::Type* type,
|
||||
VectorRef<const constant::Value*> elements);
|
||||
|
||||
/// Constructs a splat constant.
|
||||
/// @param type the splat type
|
||||
/// @param element the splat element
|
||||
/// @returns the value pointer
|
||||
const constant::Splat* Splat(const core::type::Type* type, const constant::Value* element);
|
||||
|
||||
/// @param value the constant value
|
||||
/// @return a Scalar holding the i32 value @p value
|
||||
const Scalar<i32>* Get(i32 value);
|
||||
|
||||
/// @param value the constant value
|
||||
/// @return a Scalar holding the u32 value @p value
|
||||
const Scalar<u32>* Get(u32 value);
|
||||
|
||||
/// @param value the constant value
|
||||
/// @return a Scalar holding the u64 value @p value
|
||||
const Scalar<u64>* Get(u64 value);
|
||||
|
||||
/// @param value the constant value
|
||||
/// @return a Scalar holding the i8 value @p value
|
||||
const Scalar<i8>* Get(i8 value);
|
||||
|
||||
/// @param value the constant value
|
||||
/// @return a Scalar holding the u8 value @p value
|
||||
const Scalar<u8>* Get(u8 value);
|
||||
|
||||
/// @param value the constant value
|
||||
/// @return a Scalar holding the f32 value @p value
|
||||
const Scalar<f32>* Get(f32 value);
|
||||
|
||||
/// @param value the constant value
|
||||
/// @return a Scalar holding the f16 value @p value
|
||||
const Scalar<f16>* Get(f16 value);
|
||||
|
||||
/// @param value the constant value
|
||||
/// @return a Scalar holding the bool value @p value
|
||||
const Scalar<bool>* Get(bool value);
|
||||
|
||||
/// @param value the constant value
|
||||
/// @return a Scalar holding the AFloat value @p value
|
||||
const Scalar<AFloat>* Get(AFloat value);
|
||||
|
||||
/// @param value the constant value
|
||||
/// @return a Scalar holding the AInt value @p value
|
||||
const Scalar<AInt>* Get(AInt value);
|
||||
|
||||
/// @param value the string value
|
||||
/// @return a String holding the value @p value
|
||||
const String* Get(std::string_view value);
|
||||
|
||||
/// Constructs a constant zero-value of the type @p type.
|
||||
/// @param type the constant type
|
||||
/// @returns a constant zero-value for the type
|
||||
const Value* Zero(const core::type::Type* type);
|
||||
|
||||
/// Constructs an invalid constant
|
||||
/// @returns an invalid constant
|
||||
const constant::Invalid* Invalid();
|
||||
|
||||
/// The type manager
|
||||
core::type::Manager types;
|
||||
|
||||
private:
|
||||
/// A specialization of Hasher for constant::Value
|
||||
struct Hasher {
|
||||
/// @param value the value to hash
|
||||
/// @returns a hash of the value
|
||||
HashCode operator()(const constant::Value& value) const { return value.Hash(); }
|
||||
};
|
||||
|
||||
/// An equality helper for constant::Value
|
||||
struct Equal {
|
||||
/// @param a the LHS value
|
||||
/// @param b the RHS value
|
||||
/// @returns true if the two constants are equal
|
||||
bool operator()(const constant::Value& a, const constant::Value& b) const {
|
||||
return a.Equal(&b);
|
||||
}
|
||||
};
|
||||
|
||||
/// Unique types owned by the manager
|
||||
UniqueAllocator<Value, Hasher, Equal> values_;
|
||||
};
|
||||
|
||||
} // namespace tint::core::constant
|
||||
|
||||
#endif // SRC_TINT_LANG_CORE_CONSTANT_MANAGER_H_
|
||||
40
3rdparty/dawn/src/tint/lang/core/constant/node.cc
vendored
Normal file
40
3rdparty/dawn/src/tint/lang/core/constant/node.cc
vendored
Normal file
@@ -0,0 +1,40 @@
|
||||
// Copyright 2022 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/core/constant/node.h"
|
||||
|
||||
TINT_INSTANTIATE_TYPEINFO(tint::core::constant::Node);
|
||||
|
||||
namespace tint::core::constant {
|
||||
|
||||
Node::Node() = default;
|
||||
|
||||
Node::Node(const Node&) = default;
|
||||
|
||||
Node::~Node() = default;
|
||||
|
||||
} // namespace tint::core::constant
|
||||
50
3rdparty/dawn/src/tint/lang/core/constant/node.h
vendored
Normal file
50
3rdparty/dawn/src/tint/lang/core/constant/node.h
vendored
Normal file
@@ -0,0 +1,50 @@
|
||||
// Copyright 2022 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.
|
||||
|
||||
#ifndef SRC_TINT_LANG_CORE_CONSTANT_NODE_H_
|
||||
#define SRC_TINT_LANG_CORE_CONSTANT_NODE_H_
|
||||
|
||||
#include "src/tint/utils/rtti/castable.h"
|
||||
|
||||
namespace tint::core::constant {
|
||||
|
||||
/// Node is the base class for all constant nodes
|
||||
class Node : public Castable<Node> {
|
||||
public:
|
||||
/// Constructor
|
||||
Node();
|
||||
|
||||
/// Copy constructor
|
||||
Node(const Node&);
|
||||
|
||||
/// Destructor
|
||||
~Node() override;
|
||||
};
|
||||
|
||||
} // namespace tint::core::constant
|
||||
|
||||
#endif // SRC_TINT_LANG_CORE_CONSTANT_NODE_H_
|
||||
46
3rdparty/dawn/src/tint/lang/core/constant/scalar.cc
vendored
Normal file
46
3rdparty/dawn/src/tint/lang/core/constant/scalar.cc
vendored
Normal file
@@ -0,0 +1,46 @@
|
||||
// Copyright 2022 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/core/constant/scalar.h"
|
||||
|
||||
TINT_INSTANTIATE_TYPEINFO(tint::core::constant::ScalarBase);
|
||||
TINT_INSTANTIATE_TYPEINFO(tint::core::constant::Scalar<tint::core::AInt>);
|
||||
TINT_INSTANTIATE_TYPEINFO(tint::core::constant::Scalar<tint::core::AFloat>);
|
||||
TINT_INSTANTIATE_TYPEINFO(tint::core::constant::Scalar<tint::core::i32>);
|
||||
TINT_INSTANTIATE_TYPEINFO(tint::core::constant::Scalar<tint::core::i8>);
|
||||
TINT_INSTANTIATE_TYPEINFO(tint::core::constant::Scalar<tint::core::u32>);
|
||||
TINT_INSTANTIATE_TYPEINFO(tint::core::constant::Scalar<tint::core::u64>);
|
||||
TINT_INSTANTIATE_TYPEINFO(tint::core::constant::Scalar<tint::core::u8>);
|
||||
TINT_INSTANTIATE_TYPEINFO(tint::core::constant::Scalar<tint::core::f16>);
|
||||
TINT_INSTANTIATE_TYPEINFO(tint::core::constant::Scalar<tint::core::f32>);
|
||||
TINT_INSTANTIATE_TYPEINFO(tint::core::constant::Scalar<bool>);
|
||||
|
||||
namespace tint::core::constant {
|
||||
|
||||
ScalarBase::~ScalarBase() = default;
|
||||
|
||||
}
|
||||
125
3rdparty/dawn/src/tint/lang/core/constant/scalar.h
vendored
Normal file
125
3rdparty/dawn/src/tint/lang/core/constant/scalar.h
vendored
Normal file
@@ -0,0 +1,125 @@
|
||||
// Copyright 2022 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.
|
||||
|
||||
#ifndef SRC_TINT_LANG_CORE_CONSTANT_SCALAR_H_
|
||||
#define SRC_TINT_LANG_CORE_CONSTANT_SCALAR_H_
|
||||
|
||||
#include "src/tint/lang/core/constant/manager.h"
|
||||
#include "src/tint/lang/core/constant/value.h"
|
||||
#include "src/tint/lang/core/number.h"
|
||||
#include "src/tint/lang/core/type/type.h"
|
||||
#include "src/tint/utils/math/hash.h"
|
||||
#include "src/tint/utils/rtti/castable.h"
|
||||
|
||||
namespace tint::core::constant {
|
||||
|
||||
/// ScalarBase is the base class of all Scalar<T> specializations.
|
||||
/// Used for querying whether a value is a scalar type.
|
||||
class ScalarBase : public Castable<ScalarBase, Value> {
|
||||
public:
|
||||
~ScalarBase() override;
|
||||
};
|
||||
|
||||
/// Scalar holds a single scalar or abstract-numeric value.
|
||||
template <typename T>
|
||||
class Scalar : public Castable<Scalar<T>, ScalarBase> {
|
||||
public:
|
||||
static_assert(!std::is_same_v<UnwrapNumber<T>, T> || std::is_same_v<T, bool>,
|
||||
"T must be a Number or bool");
|
||||
|
||||
/// Constructor
|
||||
/// @param t the scalar type
|
||||
/// @param v the scalar value
|
||||
Scalar(const core::type::Type* t, T v) : type(t), value(v) {
|
||||
if constexpr (IsFloatingPoint<T>) {
|
||||
TINT_ASSERT(std::isfinite(v.value));
|
||||
}
|
||||
}
|
||||
~Scalar() override = default;
|
||||
|
||||
/// @copydoc Value::Type()
|
||||
const core::type::Type* Type() const override { return type; }
|
||||
|
||||
/// @return nullptr, as Scalar does not hold any elements.
|
||||
const Value* Index(size_t) const override { return nullptr; }
|
||||
|
||||
/// @copydoc Value::NumElements()
|
||||
size_t NumElements() const override { return 1; }
|
||||
|
||||
/// @copydoc Value::AllZero()
|
||||
bool AllZero() const override { return IsZero(); }
|
||||
|
||||
/// @copydoc Value::AnyZero()
|
||||
bool AnyZero() const override { return IsZero(); }
|
||||
|
||||
/// @copydoc Value::Hash()
|
||||
HashCode Hash() const override { return tint::Hash(type, ValueOf()); }
|
||||
|
||||
/// Clones the constant into the provided context
|
||||
/// @param ctx the clone context
|
||||
/// @returns the cloned node
|
||||
const Scalar* Clone(CloneContext& ctx) const override {
|
||||
auto* ty = type->Clone(ctx.type_ctx);
|
||||
return ctx.dst.Get<Scalar<T>>(ty, value);
|
||||
}
|
||||
|
||||
/// @returns `value` if `T` is not a Number, otherwise ValueOf returns the inner value of the
|
||||
/// Number.
|
||||
inline auto ValueOf() const {
|
||||
if constexpr (std::is_same_v<UnwrapNumber<T>, T>) {
|
||||
return value;
|
||||
} else {
|
||||
return value.value;
|
||||
}
|
||||
}
|
||||
|
||||
/// @returns true if `value` is zero.
|
||||
/// For floating point -0.0 equals 0.0, according to IEEE 754.
|
||||
inline bool IsZero() const {
|
||||
using N = UnwrapNumber<T>;
|
||||
return Number<N>(value) == Number<N>(0);
|
||||
}
|
||||
|
||||
/// The scalar type
|
||||
core::type::Type const* const type;
|
||||
/// The scalar value
|
||||
const T value;
|
||||
|
||||
protected:
|
||||
/// @copydoc Value::InternalValue()
|
||||
std::variant<std::monostate, AInt, AFloat> InternalValue() const override {
|
||||
if constexpr (IsFloatingPoint<UnwrapNumber<T>>) {
|
||||
return static_cast<AFloat>(value);
|
||||
} else {
|
||||
return static_cast<AInt>(value);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace tint::core::constant
|
||||
|
||||
#endif // SRC_TINT_LANG_CORE_CONSTANT_SCALAR_H_
|
||||
61
3rdparty/dawn/src/tint/lang/core/constant/splat.cc
vendored
Normal file
61
3rdparty/dawn/src/tint/lang/core/constant/splat.cc
vendored
Normal file
@@ -0,0 +1,61 @@
|
||||
// Copyright 2022 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/core/constant/splat.h"
|
||||
|
||||
#include "src/tint/lang/core/constant/manager.h"
|
||||
|
||||
TINT_INSTANTIATE_TYPEINFO(tint::core::constant::Splat);
|
||||
|
||||
namespace tint::core::constant {
|
||||
|
||||
namespace {
|
||||
|
||||
/// Asserts that the element type of @p in_type matches the type of @p value, and that the type has
|
||||
/// at least one element.
|
||||
/// @returns the number of elements in @p in_type
|
||||
inline size_t GetCountAndAssertType(const core::type::Type* in_type, const constant::Value* value) {
|
||||
auto elements = in_type->Elements();
|
||||
TINT_ASSERT(!elements.type || elements.type == value->Type());
|
||||
TINT_ASSERT(elements.count > 0);
|
||||
return elements.count;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
Splat::Splat(const core::type::Type* t, const constant::Value* e)
|
||||
: type(t), el(e), count(GetCountAndAssertType(t, e)) {}
|
||||
|
||||
Splat::~Splat() = default;
|
||||
|
||||
const Splat* Splat::Clone(CloneContext& ctx) const {
|
||||
auto* ty = type->Clone(ctx.type_ctx);
|
||||
auto* element = el->Clone(ctx);
|
||||
return ctx.dst.Splat(ty, element);
|
||||
}
|
||||
|
||||
} // namespace tint::core::constant
|
||||
88
3rdparty/dawn/src/tint/lang/core/constant/splat.h
vendored
Normal file
88
3rdparty/dawn/src/tint/lang/core/constant/splat.h
vendored
Normal file
@@ -0,0 +1,88 @@
|
||||
// Copyright 2022 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.
|
||||
|
||||
#ifndef SRC_TINT_LANG_CORE_CONSTANT_SPLAT_H_
|
||||
#define SRC_TINT_LANG_CORE_CONSTANT_SPLAT_H_
|
||||
|
||||
#include "src/tint/lang/core/constant/composite.h"
|
||||
#include "src/tint/lang/core/type/type.h"
|
||||
#include "src/tint/utils/containers/vector.h"
|
||||
#include "src/tint/utils/rtti/castable.h"
|
||||
|
||||
namespace tint::core::constant {
|
||||
|
||||
/// Splat holds a single value, duplicated as all children.
|
||||
///
|
||||
/// Splat is used for zero-initializers, 'splat' initializers, or initializers where each element is
|
||||
/// identical. Splat may be of a vector, matrix, array or structure type.
|
||||
class Splat : public Castable<Splat, Value> {
|
||||
public:
|
||||
/// Constructor
|
||||
/// @param t the splat type
|
||||
/// @param e the splat element
|
||||
Splat(const core::type::Type* t, const Value* e);
|
||||
~Splat() override;
|
||||
|
||||
/// @returns the type of the splat
|
||||
const core::type::Type* Type() const override { return type; }
|
||||
|
||||
/// Retrieve item at index @p i
|
||||
/// @param i the index to retrieve
|
||||
/// @returns the element, or nullptr if out of bounds
|
||||
const Value* Index(size_t i) const override { return i < count ? el : nullptr; }
|
||||
|
||||
/// @copydoc Value::NumElements()
|
||||
size_t NumElements() const override { return count; }
|
||||
|
||||
/// @returns true if the element is zero
|
||||
bool AllZero() const override { return el->AllZero(); }
|
||||
/// @returns true if the element is zero
|
||||
bool AnyZero() const override { return el->AnyZero(); }
|
||||
|
||||
/// @returns the hash for the splat
|
||||
HashCode Hash() const override { return tint::Hash(type, el->Hash(), count); }
|
||||
|
||||
/// Clones the constant into the provided context
|
||||
/// @param ctx the clone context
|
||||
/// @returns the cloned node
|
||||
const Splat* Clone(CloneContext& ctx) const override;
|
||||
|
||||
/// The type of the splat element
|
||||
core::type::Type const* const type;
|
||||
/// The element stored in the splat
|
||||
const Value* el;
|
||||
/// The number of items in the splat
|
||||
const size_t count;
|
||||
|
||||
protected:
|
||||
/// @returns a monostate variant.
|
||||
std::variant<std::monostate, AInt, AFloat> InternalValue() const override { return {}; }
|
||||
};
|
||||
|
||||
} // namespace tint::core::constant
|
||||
|
||||
#endif // SRC_TINT_LANG_CORE_CONSTANT_SPLAT_H_
|
||||
39
3rdparty/dawn/src/tint/lang/core/constant/string.cc
vendored
Normal file
39
3rdparty/dawn/src/tint/lang/core/constant/string.cc
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
// Copyright 2025 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/core/constant/string.h"
|
||||
|
||||
TINT_INSTANTIATE_TYPEINFO(tint::core::constant::String);
|
||||
|
||||
namespace tint::core::constant {
|
||||
|
||||
const String* String::Clone(CloneContext& ctx) const {
|
||||
auto* ty = type->Clone(ctx.type_ctx);
|
||||
return ctx.dst.Get<String>(ty, value);
|
||||
}
|
||||
|
||||
} // namespace tint::core::constant
|
||||
89
3rdparty/dawn/src/tint/lang/core/constant/string.h
vendored
Normal file
89
3rdparty/dawn/src/tint/lang/core/constant/string.h
vendored
Normal file
@@ -0,0 +1,89 @@
|
||||
// Copyright 2025 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.
|
||||
|
||||
#ifndef SRC_TINT_LANG_CORE_CONSTANT_STRING_H_
|
||||
#define SRC_TINT_LANG_CORE_CONSTANT_STRING_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "src/tint/lang/core/constant/manager.h"
|
||||
#include "src/tint/lang/core/constant/value.h"
|
||||
#include "src/tint/lang/core/type/string.h"
|
||||
#include "src/tint/lang/core/type/type.h"
|
||||
#include "src/tint/utils/math/hash.h"
|
||||
#include "src/tint/utils/rtti/castable.h"
|
||||
|
||||
namespace tint::core::constant {
|
||||
|
||||
/// String holds a constant string value.
|
||||
class String : public Castable<constant::String, Value> {
|
||||
public:
|
||||
/// Constructor
|
||||
/// @param t the scalar type
|
||||
/// @param v the scalar value
|
||||
String(const core::type::Type* t, std::string_view v) : type(t), value(v) {}
|
||||
~String() override = default;
|
||||
|
||||
/// @copydoc Value::Type()
|
||||
const core::type::Type* Type() const override { return type; }
|
||||
|
||||
/// @return nullptr, as String does not allow individual character access
|
||||
const Value* Index(size_t) const override { return nullptr; }
|
||||
|
||||
/// @copydoc Value::NumElements()
|
||||
size_t NumElements() const override { return 1; }
|
||||
|
||||
/// @copydoc Value::AllZero()
|
||||
bool AllZero() const override { return false; }
|
||||
|
||||
/// @copydoc Value::AnyZero()
|
||||
bool AnyZero() const override { return false; }
|
||||
|
||||
/// @copydoc Value::Hash()
|
||||
HashCode Hash() const override { return tint::Hash(type, Value()); }
|
||||
|
||||
/// Clones the constant into the provided context
|
||||
/// @param ctx the clone context
|
||||
/// @returns the cloned node
|
||||
const String* Clone(CloneContext& ctx) const override;
|
||||
|
||||
/// @returns the string value
|
||||
inline std::string_view Value() const { return value; }
|
||||
|
||||
/// The string type
|
||||
core::type::Type const* const type;
|
||||
/// The string value
|
||||
const std::string value;
|
||||
|
||||
protected:
|
||||
/// @copydoc Value::InternalValue()
|
||||
std::variant<std::monostate, AInt, AFloat> InternalValue() const override { return {}; }
|
||||
};
|
||||
|
||||
} // namespace tint::core::constant
|
||||
|
||||
#endif // SRC_TINT_LANG_CORE_CONSTANT_STRING_H_
|
||||
114
3rdparty/dawn/src/tint/lang/core/constant/value.cc
vendored
Normal file
114
3rdparty/dawn/src/tint/lang/core/constant/value.cc
vendored
Normal file
@@ -0,0 +1,114 @@
|
||||
// Copyright 2021 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/core/constant/value.h"
|
||||
|
||||
#include "src/tint/lang/core/constant/splat.h"
|
||||
#include "src/tint/lang/core/type/array.h"
|
||||
#include "src/tint/lang/core/type/invalid.h"
|
||||
#include "src/tint/lang/core/type/matrix.h"
|
||||
#include "src/tint/lang/core/type/struct.h"
|
||||
#include "src/tint/lang/core/type/vector.h"
|
||||
#include "src/tint/utils/rtti/switch.h"
|
||||
|
||||
TINT_INSTANTIATE_TYPEINFO(tint::core::constant::Value);
|
||||
|
||||
namespace tint::core::constant {
|
||||
|
||||
Value::Value() = default;
|
||||
|
||||
Value::~Value() = default;
|
||||
|
||||
/// Equal returns true if the constants `a` and `b` are of the same type and value.
|
||||
bool Value::Equal(const constant::Value* b) const {
|
||||
if (this == b) {
|
||||
return true;
|
||||
}
|
||||
if (Hash() != b->Hash()) {
|
||||
return false;
|
||||
}
|
||||
if (Type() != b->Type()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto elements_equal = [&](size_t count) {
|
||||
if (count == 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Avoid per-element comparisons if the constants are splats
|
||||
bool a_is_splat = Is<Splat>();
|
||||
bool b_is_splat = b->Is<Splat>();
|
||||
if (a_is_splat && b_is_splat) {
|
||||
return Index(0)->Equal(b->Index(0));
|
||||
}
|
||||
|
||||
if (a_is_splat) {
|
||||
auto* el_a = Index(0);
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
if (!el_a->Equal(b->Index(i))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if (b_is_splat) {
|
||||
auto* el_b = b->Index(0);
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
if (!Index(i)->Equal(el_b)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Per-element comparison
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
if (!Index(i)->Equal(b->Index(i))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
return Switch(
|
||||
Type(), //
|
||||
[&](const core::type::Vector* vec) { return elements_equal(vec->Width()); },
|
||||
[&](const core::type::Matrix* mat) { return elements_equal(mat->Columns()); },
|
||||
[&](const core::type::Struct* str) { return elements_equal(str->Members().Length()); },
|
||||
[&](const core::type::Array* arr) {
|
||||
if (auto n = arr->ConstantCount()) {
|
||||
return elements_equal(*n);
|
||||
}
|
||||
return false;
|
||||
},
|
||||
[&](const core::type::Invalid*) { return true; },
|
||||
[&](Default) { return InternalValue() == b->InternalValue(); });
|
||||
}
|
||||
|
||||
} // namespace tint::core::constant
|
||||
106
3rdparty/dawn/src/tint/lang/core/constant/value.h
vendored
Normal file
106
3rdparty/dawn/src/tint/lang/core/constant/value.h
vendored
Normal file
@@ -0,0 +1,106 @@
|
||||
// Copyright 2022 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.
|
||||
|
||||
#ifndef SRC_TINT_LANG_CORE_CONSTANT_VALUE_H_
|
||||
#define SRC_TINT_LANG_CORE_CONSTANT_VALUE_H_
|
||||
|
||||
#include <variant>
|
||||
|
||||
#include "src/tint/lang/core/constant/clone_context.h"
|
||||
#include "src/tint/lang/core/constant/node.h"
|
||||
#include "src/tint/lang/core/number.h"
|
||||
#include "src/tint/lang/core/type/type.h"
|
||||
#include "src/tint/utils/rtti/castable.h"
|
||||
|
||||
namespace tint::core::constant {
|
||||
|
||||
/// Value is the interface to a compile-time evaluated expression value.
|
||||
class Value : public Castable<Value, Node> {
|
||||
public:
|
||||
/// Constructor
|
||||
Value();
|
||||
|
||||
/// Destructor
|
||||
~Value() override;
|
||||
|
||||
/// @returns the type of the value
|
||||
virtual const core::type::Type* Type() const = 0;
|
||||
|
||||
/// @param i the index of the element
|
||||
/// @returns the child element with the given index, or nullptr if there are no children, or
|
||||
/// the index is out of bounds.
|
||||
///
|
||||
/// For arrays, this returns the i'th element of the array.
|
||||
/// For vectors, this returns the i'th element of the vector.
|
||||
/// For matrices, this returns the i'th column vector of the matrix.
|
||||
/// For structures, this returns the i'th member field of the structure.
|
||||
virtual const Value* Index(size_t i) const = 0;
|
||||
|
||||
/// @return the number of elements held by this Value
|
||||
virtual size_t NumElements() const = 0;
|
||||
|
||||
/// @returns true if child elements are positive-zero valued.
|
||||
virtual bool AllZero() const = 0;
|
||||
|
||||
/// @returns true if any child elements are positive-zero valued.
|
||||
virtual bool AnyZero() const = 0;
|
||||
|
||||
/// @returns a hash of the value.
|
||||
virtual HashCode Hash() const = 0;
|
||||
|
||||
/// @returns the value as the given scalar or abstract value.
|
||||
template <typename T>
|
||||
T ValueAs() const {
|
||||
return std::visit(
|
||||
[](auto v) {
|
||||
if constexpr (std::is_same_v<decltype(v), std::monostate>) {
|
||||
return T(0);
|
||||
} else {
|
||||
return static_cast<T>(v);
|
||||
}
|
||||
},
|
||||
InternalValue());
|
||||
}
|
||||
|
||||
/// @param b the value to compare too
|
||||
/// @returns true if this value is equal to @p b
|
||||
bool Equal(const Value* b) const;
|
||||
|
||||
/// Clones the constant into the provided context
|
||||
/// @param ctx the clone context
|
||||
/// @returns the cloned node
|
||||
virtual const Value* Clone(CloneContext& ctx) const = 0;
|
||||
|
||||
protected:
|
||||
/// @returns the value, if this is of a scalar value or abstract numeric, otherwise
|
||||
/// std::monostate.
|
||||
virtual std::variant<std::monostate, AInt, AFloat> InternalValue() const = 0;
|
||||
};
|
||||
|
||||
} // namespace tint::core::constant
|
||||
|
||||
#endif // SRC_TINT_LANG_CORE_CONSTANT_VALUE_H_
|
||||
2229
3rdparty/dawn/src/tint/lang/core/enums.cc
vendored
Normal file
2229
3rdparty/dawn/src/tint/lang/core/enums.cc
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1389
3rdparty/dawn/src/tint/lang/core/enums.h
vendored
Normal file
1389
3rdparty/dawn/src/tint/lang/core/enums.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
75
3rdparty/dawn/src/tint/lang/core/evaluation_stage.h
vendored
Normal file
75
3rdparty/dawn/src/tint/lang/core/evaluation_stage.h
vendored
Normal file
@@ -0,0 +1,75 @@
|
||||
// Copyright 2022 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.
|
||||
|
||||
#ifndef SRC_TINT_LANG_CORE_EVALUATION_STAGE_H_
|
||||
#define SRC_TINT_LANG_CORE_EVALUATION_STAGE_H_
|
||||
|
||||
#include <algorithm>
|
||||
#include <initializer_list>
|
||||
|
||||
namespace tint::core {
|
||||
|
||||
/// The earliest point in time that an expression can be evaluated
|
||||
enum class EvaluationStage {
|
||||
/// Expression will not be evaluated
|
||||
kNotEvaluated,
|
||||
/// Expression can be evaluated at shader creation time
|
||||
kConstant,
|
||||
/// Expression can be evaluated at pipeline creation time
|
||||
kOverride,
|
||||
/// Expression can be evaluated at runtime
|
||||
kRuntime,
|
||||
};
|
||||
|
||||
/// @returns true if stage `a` comes earlier than stage `b`
|
||||
inline bool operator<(EvaluationStage a, EvaluationStage b) {
|
||||
return static_cast<int>(a) < static_cast<int>(b);
|
||||
}
|
||||
|
||||
/// @returns true if stage `a` comes later than stage `b`
|
||||
inline bool operator>(EvaluationStage a, EvaluationStage b) {
|
||||
return static_cast<int>(a) > static_cast<int>(b);
|
||||
}
|
||||
|
||||
/// @param stages a list of EvaluationStage.
|
||||
/// @returns the earliest stage supported by all the provided stages
|
||||
inline EvaluationStage EarliestStage(std::initializer_list<EvaluationStage> stages) {
|
||||
auto earliest = EvaluationStage::kNotEvaluated;
|
||||
for (auto stage : stages) {
|
||||
earliest = std::max(stage, earliest);
|
||||
}
|
||||
return static_cast<EvaluationStage>(earliest);
|
||||
}
|
||||
|
||||
template <typename... ARGS>
|
||||
inline EvaluationStage EarliestStage(ARGS... args) {
|
||||
return EarliestStage({args...});
|
||||
}
|
||||
|
||||
} // namespace tint::core
|
||||
|
||||
#endif // SRC_TINT_LANG_CORE_EVALUATION_STAGE_H_
|
||||
294
3rdparty/dawn/src/tint/lang/core/fluent_types.h
vendored
Normal file
294
3rdparty/dawn/src/tint/lang/core/fluent_types.h
vendored
Normal file
@@ -0,0 +1,294 @@
|
||||
// Copyright 2023 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.
|
||||
|
||||
#ifndef SRC_TINT_LANG_CORE_FLUENT_TYPES_H_
|
||||
#define SRC_TINT_LANG_CORE_FLUENT_TYPES_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "src/tint/lang/core/enums.h"
|
||||
#include "src/tint/lang/core/number.h"
|
||||
|
||||
namespace tint::core::fluent_types {
|
||||
|
||||
using f16 = tint::core::f16;
|
||||
using f32 = tint::core::f32;
|
||||
using i32 = tint::core::i32;
|
||||
using i8 = tint::core::i8;
|
||||
using u32 = tint::core::u32;
|
||||
using u64 = tint::core::u64;
|
||||
using u8 = tint::core::u8;
|
||||
using AFloat = tint::core::AFloat;
|
||||
using AInt = tint::core::AInt;
|
||||
|
||||
// A sentinel type used by some template arguments to signal that the a type should be inferred.
|
||||
struct Infer {};
|
||||
|
||||
/// A 'fluent' type helper used to construct an ast::Array or type::Array.
|
||||
/// @tparam T the array element type
|
||||
/// @tparam N the array length. 0 represents a runtime-sized array.
|
||||
/// @see https://www.w3.org/TR/WGSL/#array-types
|
||||
template <typename T, uint32_t N = 0>
|
||||
struct array {
|
||||
/// the array element type
|
||||
using type = T;
|
||||
/// the array length. 0 represents a runtime-sized array.
|
||||
static constexpr uint32_t length = N;
|
||||
};
|
||||
|
||||
/// A 'fluent' type helper used to construct an ast::Atomic or type::Atomic.
|
||||
/// @tparam T the atomic element type
|
||||
/// @see https://www.w3.org/TR/WGSL/#atomic-types
|
||||
template <typename T>
|
||||
struct atomic {
|
||||
/// the atomic element type
|
||||
using type = T;
|
||||
};
|
||||
|
||||
/// A 'fluent' type helper used to construct an ast::Vector or type::Vector.
|
||||
/// @tparam N the vector width
|
||||
/// @tparam T the vector element type
|
||||
template <uint32_t N, typename T>
|
||||
struct vec {
|
||||
/// the vector width
|
||||
static constexpr uint32_t width = N;
|
||||
/// the vector element type
|
||||
using type = T;
|
||||
};
|
||||
|
||||
/// A 'fluent' type helper used to construct an ast::Matrix or type::Matrix.
|
||||
/// @tparam C the number of columns of the matrix
|
||||
/// @tparam R the number of rows of the matrix
|
||||
/// @tparam T the matrix element type
|
||||
/// @see https://www.w3.org/TR/WGSL/#matrix-types
|
||||
template <uint32_t C, uint32_t R, typename T>
|
||||
struct mat {
|
||||
/// the number of columns of the matrix
|
||||
static constexpr uint32_t columns = C;
|
||||
/// the number of rows of the matrix
|
||||
static constexpr uint32_t rows = R;
|
||||
/// the matrix element type
|
||||
using type = T;
|
||||
/// the column vector type
|
||||
using column = vec<R, T>;
|
||||
};
|
||||
|
||||
/// A 'fluent' type helper used to construct an ast::Pointer or type::Pointer.
|
||||
/// @tparam ADDRESS the pointer address space
|
||||
/// @tparam T the pointer storage type
|
||||
/// @tparam ACCESS the pointer access control
|
||||
template <core::AddressSpace ADDRESS, typename T, core::Access ACCESS = core::Access::kUndefined>
|
||||
struct ptr {
|
||||
/// the pointer address space
|
||||
static constexpr core::AddressSpace address = ADDRESS;
|
||||
/// the pointer storage type
|
||||
using type = T;
|
||||
/// the pointer access control
|
||||
static constexpr core::Access access = ACCESS;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Aliases
|
||||
//
|
||||
// Shorthand aliases for the types declared above
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//! @cond Doxygen_Suppress
|
||||
template <typename T>
|
||||
using mat2x2 = mat<2, 2, T>;
|
||||
|
||||
template <typename T>
|
||||
using mat2x3 = mat<2, 3, T>;
|
||||
|
||||
template <typename T>
|
||||
using mat2x4 = mat<2, 4, T>;
|
||||
|
||||
template <typename T>
|
||||
using mat3x2 = mat<3, 2, T>;
|
||||
|
||||
template <typename T>
|
||||
using mat3x3 = mat<3, 3, T>;
|
||||
|
||||
template <typename T>
|
||||
using mat3x4 = mat<3, 4, T>;
|
||||
|
||||
template <typename T>
|
||||
using mat4x2 = mat<4, 2, T>;
|
||||
|
||||
template <typename T>
|
||||
using mat4x3 = mat<4, 3, T>;
|
||||
|
||||
template <typename T>
|
||||
using mat4x4 = mat<4, 4, T>;
|
||||
|
||||
template <typename T>
|
||||
using vec2 = vec<2, T>;
|
||||
|
||||
template <typename T>
|
||||
using vec3 = vec<3, T>;
|
||||
|
||||
template <typename T>
|
||||
using vec4 = vec<4, T>;
|
||||
|
||||
using mat2x2f = mat<2, 2, f32>;
|
||||
using mat2x3f = mat<2, 3, f32>;
|
||||
using mat2x4f = mat<2, 4, f32>;
|
||||
using mat3x2f = mat<3, 2, f32>;
|
||||
using mat3x3f = mat<3, 3, f32>;
|
||||
using mat3x4f = mat<3, 4, f32>;
|
||||
using mat4x2f = mat<4, 2, f32>;
|
||||
using mat4x3f = mat<4, 3, f32>;
|
||||
using mat4x4f = mat<4, 4, f32>;
|
||||
|
||||
using mat2x2h = mat<2, 2, f16>;
|
||||
using mat2x3h = mat<2, 3, f16>;
|
||||
using mat2x4h = mat<2, 4, f16>;
|
||||
using mat3x2h = mat<3, 2, f16>;
|
||||
using mat3x3h = mat<3, 3, f16>;
|
||||
using mat3x4h = mat<3, 4, f16>;
|
||||
using mat4x2h = mat<4, 2, f16>;
|
||||
using mat4x3h = mat<4, 3, f16>;
|
||||
using mat4x4h = mat<4, 4, f16>;
|
||||
|
||||
using vec2f = vec<2, f32>;
|
||||
using vec3f = vec<3, f32>;
|
||||
using vec4f = vec<4, f32>;
|
||||
|
||||
using vec2h = vec<2, f16>;
|
||||
using vec3h = vec<3, f16>;
|
||||
using vec4h = vec<4, f16>;
|
||||
|
||||
using vec2i = vec<2, i32>;
|
||||
using vec3i = vec<3, i32>;
|
||||
using vec4i = vec<4, i32>;
|
||||
|
||||
using vec2u = vec<2, u32>;
|
||||
using vec3u = vec<3, u32>;
|
||||
using vec4u = vec<4, u32>;
|
||||
|
||||
//! @endcond
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Address space aliases
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
static constexpr core::AddressSpace function = core::AddressSpace::kFunction;
|
||||
static constexpr core::AddressSpace handle = core::AddressSpace::kHandle;
|
||||
static constexpr core::AddressSpace private_ = core::AddressSpace::kPrivate;
|
||||
static constexpr core::AddressSpace immediate = core::AddressSpace::kImmediate;
|
||||
static constexpr core::AddressSpace storage = core::AddressSpace::kStorage;
|
||||
static constexpr core::AddressSpace uniform = core::AddressSpace::kUniform;
|
||||
static constexpr core::AddressSpace workgroup = core::AddressSpace::kWorkgroup;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Access control aliases
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
static constexpr core::Access read = core::Access::kRead;
|
||||
static constexpr core::Access read_write = core::Access::kReadWrite;
|
||||
static constexpr core::Access write = core::Access::kWrite;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Traits
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
namespace detail {
|
||||
|
||||
//! @cond Doxygen_Suppress
|
||||
template <typename T>
|
||||
struct IsArray {
|
||||
static constexpr bool value = false;
|
||||
};
|
||||
|
||||
template <typename T, uint32_t N>
|
||||
struct IsArray<array<T, N>> {
|
||||
static constexpr bool value = true;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct IsAtomic {
|
||||
static constexpr bool value = false;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct IsAtomic<atomic<T>> {
|
||||
static constexpr bool value = true;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct IsMatrix {
|
||||
static constexpr bool value = false;
|
||||
};
|
||||
|
||||
template <uint32_t C, uint32_t R, typename T>
|
||||
struct IsMatrix<mat<C, R, T>> {
|
||||
static constexpr bool value = true;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct IsVector {
|
||||
static constexpr bool value = false;
|
||||
};
|
||||
|
||||
template <uint32_t N, typename T>
|
||||
struct IsVector<vec<N, T>> {
|
||||
static constexpr bool value = true;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct IsPointer {
|
||||
static constexpr bool value = false;
|
||||
};
|
||||
|
||||
template <core::AddressSpace ADDRESS, typename T, core::Access ACCESS>
|
||||
struct IsPointer<ptr<ADDRESS, T, ACCESS>> {
|
||||
static constexpr bool value = true;
|
||||
};
|
||||
//! @endcond
|
||||
|
||||
} // namespace detail
|
||||
|
||||
/// Evaluates to true if `T` is a array
|
||||
template <typename T>
|
||||
static constexpr bool IsArray = fluent_types::detail::IsArray<T>::value;
|
||||
|
||||
/// Evaluates to true if `T` is a atomic
|
||||
template <typename T>
|
||||
static constexpr bool IsAtomic = fluent_types::detail::IsAtomic<T>::value;
|
||||
|
||||
/// Evaluates to true if `T` is a mat
|
||||
template <typename T>
|
||||
static constexpr bool IsMatrix = fluent_types::detail::IsMatrix<T>::value;
|
||||
|
||||
/// Evaluates to true if `T` is a vec
|
||||
template <typename T>
|
||||
static constexpr bool IsVector = fluent_types::detail::IsVector<T>::value;
|
||||
|
||||
/// Evaluates to true if `T` is a ptr
|
||||
template <typename T>
|
||||
static constexpr bool IsPointer = fluent_types::detail::IsPointer<T>::value;
|
||||
|
||||
} // namespace tint::core::fluent_types
|
||||
|
||||
#endif // SRC_TINT_LANG_CORE_FLUENT_TYPES_H_
|
||||
45
3rdparty/dawn/src/tint/lang/core/interpolation.h
vendored
Normal file
45
3rdparty/dawn/src/tint/lang/core/interpolation.h
vendored
Normal file
@@ -0,0 +1,45 @@
|
||||
// Copyright 2023 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.
|
||||
|
||||
#ifndef SRC_TINT_LANG_CORE_INTERPOLATION_H_
|
||||
#define SRC_TINT_LANG_CORE_INTERPOLATION_H_
|
||||
|
||||
#include "src/tint/lang/core/enums.h"
|
||||
|
||||
namespace tint::core {
|
||||
|
||||
/// The values of an `@interpolate` attribute
|
||||
struct Interpolation {
|
||||
/// The first argument of a `@interpolate` attribute
|
||||
core::InterpolationType type = core::InterpolationType::kUndefined;
|
||||
/// The second argument of a `@interpolate` attribute
|
||||
core::InterpolationSampling sampling = core::InterpolationSampling::kUndefined;
|
||||
};
|
||||
|
||||
} // namespace tint::core
|
||||
|
||||
#endif // SRC_TINT_LANG_CORE_INTERPOLATION_H_
|
||||
93
3rdparty/dawn/src/tint/lang/core/intrinsic/ctor_conv.cc
vendored
Normal file
93
3rdparty/dawn/src/tint/lang/core/intrinsic/ctor_conv.cc
vendored
Normal file
@@ -0,0 +1,93 @@
|
||||
// Copyright 2021 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.
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// File generated by 'tools/src/cmd/gen' using the template:
|
||||
// src/tint/lang/core/intrinsic/ctor_conv.cc.tmpl
|
||||
//
|
||||
// To regenerate run: './tools/run gen'
|
||||
//
|
||||
// Do not modify this file directly
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// clang-format off
|
||||
|
||||
#include "src/tint/lang/core/intrinsic/ctor_conv.h"
|
||||
|
||||
namespace tint::core::intrinsic {
|
||||
|
||||
const char* str(CtorConv i) {
|
||||
switch (i) {
|
||||
case CtorConv::kNone:
|
||||
return "<none>";
|
||||
case CtorConv::kI32:
|
||||
return "i32";
|
||||
case CtorConv::kU32:
|
||||
return "u32";
|
||||
case CtorConv::kF32:
|
||||
return "f32";
|
||||
case CtorConv::kF16:
|
||||
return "f16";
|
||||
case CtorConv::kBool:
|
||||
return "bool";
|
||||
case CtorConv::kVec2:
|
||||
return "vec2";
|
||||
case CtorConv::kVec3:
|
||||
return "vec3";
|
||||
case CtorConv::kVec4:
|
||||
return "vec4";
|
||||
case CtorConv::kMat2x2:
|
||||
return "mat2x2";
|
||||
case CtorConv::kMat2x3:
|
||||
return "mat2x3";
|
||||
case CtorConv::kMat2x4:
|
||||
return "mat2x4";
|
||||
case CtorConv::kMat3x2:
|
||||
return "mat3x2";
|
||||
case CtorConv::kMat3x3:
|
||||
return "mat3x3";
|
||||
case CtorConv::kMat3x4:
|
||||
return "mat3x4";
|
||||
case CtorConv::kMat4x2:
|
||||
return "mat4x2";
|
||||
case CtorConv::kMat4x3:
|
||||
return "mat4x3";
|
||||
case CtorConv::kMat4x4:
|
||||
return "mat4x4";
|
||||
case CtorConv::kSubgroup_matrix_left:
|
||||
return "subgroup_matrix_left";
|
||||
case CtorConv::kSubgroup_matrix_right:
|
||||
return "subgroup_matrix_right";
|
||||
case CtorConv::kSubgroup_matrix_result:
|
||||
return "subgroup_matrix_result";
|
||||
}
|
||||
return "<unknown>";
|
||||
}
|
||||
|
||||
} // namespace tint::core::intrinsic
|
||||
|
||||
// clang-format on
|
||||
133
3rdparty/dawn/src/tint/lang/core/intrinsic/ctor_conv.h
vendored
Normal file
133
3rdparty/dawn/src/tint/lang/core/intrinsic/ctor_conv.h
vendored
Normal file
@@ -0,0 +1,133 @@
|
||||
// Copyright 2021 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.
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// File generated by 'tools/src/cmd/gen' using the template:
|
||||
// src/tint/lang/core/intrinsic/ctor_conv.h.tmpl
|
||||
//
|
||||
// To regenerate run: './tools/run gen'
|
||||
//
|
||||
// Do not modify this file directly
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef SRC_TINT_LANG_CORE_INTRINSIC_CTOR_CONV_H_
|
||||
#define SRC_TINT_LANG_CORE_INTRINSIC_CTOR_CONV_H_
|
||||
|
||||
// clang-format off
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
#include "src/tint/utils/rtti/traits.h"
|
||||
|
||||
namespace tint::core::intrinsic {
|
||||
|
||||
/// CtorConv is an enumerator of types that have a constructor or converter overload
|
||||
/// declared in the intrinsic table.
|
||||
enum class CtorConv : uint8_t {
|
||||
kI32,
|
||||
kU32,
|
||||
kF32,
|
||||
kF16,
|
||||
kBool,
|
||||
kVec2,
|
||||
kVec3,
|
||||
kVec4,
|
||||
kMat2x2,
|
||||
kMat2x3,
|
||||
kMat2x4,
|
||||
kMat3x2,
|
||||
kMat3x3,
|
||||
kMat3x4,
|
||||
kMat4x2,
|
||||
kMat4x3,
|
||||
kMat4x4,
|
||||
kSubgroup_matrix_left,
|
||||
kSubgroup_matrix_right,
|
||||
kSubgroup_matrix_result,
|
||||
kNone,
|
||||
};
|
||||
|
||||
/// @returns the name of the enumerator
|
||||
/// @param i the CtorConv enumerator
|
||||
const char* str(CtorConv i);
|
||||
|
||||
/// Prints the CtorConv @p c to @p o
|
||||
/// @param o the stream to write to
|
||||
/// @param c the CtorConv
|
||||
/// @return the stream so calls can be chained
|
||||
template <typename STREAM>
|
||||
requires(traits::IsOStream<STREAM>)
|
||||
auto& operator<<(STREAM& o, CtorConv c) {
|
||||
return o << str(c);
|
||||
}
|
||||
|
||||
/// @param n the width of the vector
|
||||
/// @return the CtorConv for a vector of width `n`
|
||||
inline CtorConv VectorCtorConv(uint32_t n) {
|
||||
switch (n) {
|
||||
case 2:
|
||||
return CtorConv::kVec2;
|
||||
case 3:
|
||||
return CtorConv::kVec3;
|
||||
case 4:
|
||||
return CtorConv::kVec4;
|
||||
}
|
||||
return CtorConv::kNone;
|
||||
}
|
||||
|
||||
/// @param c the number of columns in the matrix
|
||||
/// @param r the number of rows in the matrix
|
||||
/// @return the CtorConv for a matrix with `c` columns and `r` rows
|
||||
inline CtorConv MatrixCtorConv(uint32_t c, uint32_t r) {
|
||||
switch ((c - 2) * 3 + (r - 2)) {
|
||||
case 0:
|
||||
return CtorConv::kMat2x2;
|
||||
case 1:
|
||||
return CtorConv::kMat2x3;
|
||||
case 2:
|
||||
return CtorConv::kMat2x4;
|
||||
case 3:
|
||||
return CtorConv::kMat3x2;
|
||||
case 4:
|
||||
return CtorConv::kMat3x3;
|
||||
case 5:
|
||||
return CtorConv::kMat3x4;
|
||||
case 6:
|
||||
return CtorConv::kMat4x2;
|
||||
case 7:
|
||||
return CtorConv::kMat4x3;
|
||||
case 8:
|
||||
return CtorConv::kMat4x4;
|
||||
}
|
||||
return CtorConv::kNone;
|
||||
}
|
||||
|
||||
} // namespace tint::core::intrinsic
|
||||
|
||||
// clang-format on
|
||||
|
||||
#endif // SRC_TINT_LANG_CORE_INTRINSIC_CTOR_CONV_H_
|
||||
13850
3rdparty/dawn/src/tint/lang/core/intrinsic/data.cc
vendored
Normal file
13850
3rdparty/dawn/src/tint/lang/core/intrinsic/data.cc
vendored
Normal file
File diff suppressed because it is too large
Load Diff
59
3rdparty/dawn/src/tint/lang/core/intrinsic/dialect.h
vendored
Normal file
59
3rdparty/dawn/src/tint/lang/core/intrinsic/dialect.h
vendored
Normal file
@@ -0,0 +1,59 @@
|
||||
// Copyright 2023 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.
|
||||
|
||||
#ifndef SRC_TINT_LANG_CORE_INTRINSIC_DIALECT_H_
|
||||
#define SRC_TINT_LANG_CORE_INTRINSIC_DIALECT_H_
|
||||
|
||||
#include "src/tint/lang/core/enums.h"
|
||||
#include "src/tint/lang/core/intrinsic/ctor_conv.h"
|
||||
#include "src/tint/lang/core/intrinsic/table_data.h"
|
||||
|
||||
namespace tint::core::intrinsic {
|
||||
|
||||
/// Dialect holds the intrinsic table data and types for the core dialect
|
||||
struct Dialect {
|
||||
/// The dialect's intrinsic table data
|
||||
static const TableData kData;
|
||||
|
||||
/// The dialect's builtin function enumerator
|
||||
using BuiltinFn = core::BuiltinFn;
|
||||
|
||||
/// The dialect's type constructor / convertor enumerator
|
||||
using CtorConv = core::intrinsic::CtorConv;
|
||||
|
||||
/// @returns the name of the builtin function @p fn
|
||||
/// @param fn the builtin function
|
||||
static std::string_view ToString(BuiltinFn fn) { return str(fn); }
|
||||
|
||||
/// @returns the name of the type constructor / convertor @p ty
|
||||
/// @param ty the type constructor / convertor
|
||||
static std::string_view ToString(CtorConv ty) { return str(ty); }
|
||||
};
|
||||
|
||||
} // namespace tint::core::intrinsic
|
||||
|
||||
#endif // SRC_TINT_LANG_CORE_INTRINSIC_DIALECT_H_
|
||||
895
3rdparty/dawn/src/tint/lang/core/intrinsic/table.cc
vendored
Normal file
895
3rdparty/dawn/src/tint/lang/core/intrinsic/table.cc
vendored
Normal file
@@ -0,0 +1,895 @@
|
||||
// Copyright 2021 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/core/intrinsic/table.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <limits>
|
||||
#include <ostream>
|
||||
#include <utility>
|
||||
|
||||
#include "src/tint/lang/core/evaluation_stage.h"
|
||||
#include "src/tint/lang/core/intrinsic/table_data.h"
|
||||
#include "src/tint/lang/core/type/invalid.h"
|
||||
#include "src/tint/lang/core/type/manager.h"
|
||||
#include "src/tint/lang/core/type/void.h"
|
||||
#include "src/tint/utils/containers/slice.h"
|
||||
#include "src/tint/utils/ice/ice.h"
|
||||
#include "src/tint/utils/macros/defer.h"
|
||||
#include "src/tint/utils/text/string_stream.h"
|
||||
#include "src/tint/utils/text/styled_text.h"
|
||||
#include "src/tint/utils/text/text_style.h"
|
||||
|
||||
namespace tint::core::intrinsic {
|
||||
|
||||
const Number Number::any{Number::kAny};
|
||||
const Number Number::invalid{Number::kInvalid};
|
||||
|
||||
Any::Any() : Base(0u, core::type::Flags{}) {}
|
||||
Any::~Any() = default;
|
||||
|
||||
bool Any::Equals(const core::type::UniqueNode&) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string Any::FriendlyName() const {
|
||||
return "<any>";
|
||||
}
|
||||
|
||||
core::type::Type* Any::Clone(core::type::CloneContext&) const {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
/// The Vector `N` template argument value for arrays of parameters.
|
||||
constexpr const size_t kNumFixedParameters = Overload::kNumFixedParameters;
|
||||
|
||||
/// The Vector `N` template argument value for arrays of overload candidates.
|
||||
constexpr const size_t kNumFixedCandidates = 8;
|
||||
|
||||
/// A list of candidates
|
||||
using Candidates = Vector<Candidate, kNumFixedCandidates>;
|
||||
|
||||
/// Callback function when no overloads match.
|
||||
using OnNoMatch = std::function<StyledText(VectorRef<Candidate>)>;
|
||||
|
||||
/// Sorts the candidates based on their score, with the lowest (best-ranking) scores first.
|
||||
static inline void SortCandidates(Candidates& candidates) {
|
||||
std::stable_sort(candidates.begin(), candidates.end(),
|
||||
[&](const Candidate& a, const Candidate& b) { return a.score < b.score; });
|
||||
}
|
||||
|
||||
/// Prints a list of types.
|
||||
static void PrintTypeList(StyledText& ss, VectorRef<const core::type::Type*> types) {
|
||||
bool first = true;
|
||||
for (auto* arg : types) {
|
||||
if (!first) {
|
||||
ss << ", ";
|
||||
}
|
||||
first = false;
|
||||
ss << style::Type((arg != nullptr) ? arg->FriendlyName() : "undef");
|
||||
}
|
||||
}
|
||||
|
||||
/// Attempts to find a single intrinsic overload that matches the provided argument types.
|
||||
/// @param context the intrinsic context
|
||||
/// @param intrinsic the intrinsic being called
|
||||
/// @param intrinsic_name the name of the intrinsic
|
||||
/// @param template_args the template argument types
|
||||
/// @param args the argument types
|
||||
/// @param earliest_eval_stage the earliest evaluation stage that the call can be made
|
||||
/// @param member_function `true` if the builtin should be a member function
|
||||
/// @param on_no_match an error callback when no intrinsic overloads matched the provided
|
||||
/// arguments.
|
||||
/// @returns the matched intrinsic
|
||||
Result<Overload, StyledText> MatchIntrinsic(Context& context,
|
||||
const IntrinsicInfo& intrinsic,
|
||||
std::string_view intrinsic_name,
|
||||
VectorRef<const core::type::Type*> template_args,
|
||||
VectorRef<const core::type::Type*> args,
|
||||
EvaluationStage earliest_eval_stage,
|
||||
bool member_function,
|
||||
const OnNoMatch& on_no_match);
|
||||
|
||||
/// The scoring mode for ScoreOverload()
|
||||
enum class ScoreMode {
|
||||
/// If the overload doesn't match, then the returned Candidate will simply have a score of 1.
|
||||
/// No other fields will be populated.
|
||||
kEarlyReject,
|
||||
/// A more expensive score calculations will be made for the overload, which can be used
|
||||
/// to rank potential overloads
|
||||
kFull
|
||||
};
|
||||
|
||||
/// Evaluates the single overload for the provided argument types.
|
||||
/// @param context the intrinsic context
|
||||
/// @param overload the overload being considered
|
||||
/// @param template_args the template argument types
|
||||
/// @param args the argument types
|
||||
/// @tparam MODE the scoring mode to use. Passed as a template argument to ensure that the
|
||||
/// extremely-hot function is specialized without scoring logic for the common code path.
|
||||
/// @returns the evaluated Candidate information.
|
||||
template <ScoreMode MODE>
|
||||
Candidate ScoreOverload(Context& context,
|
||||
const OverloadInfo& overload,
|
||||
VectorRef<const core::type::Type*> template_args,
|
||||
VectorRef<const core::type::Type*> args,
|
||||
EvaluationStage earliest_eval_stage);
|
||||
|
||||
/// Performs overload resolution given the list of candidates, by ranking the conversions of
|
||||
/// arguments to the each of the candidate's parameter types.
|
||||
/// @param context the intrinsic context
|
||||
/// @param candidates the list of candidate overloads
|
||||
/// @param intrinsic_name the name of the intrinsic
|
||||
/// @param template_args the template argument types
|
||||
/// @param args the argument types
|
||||
/// @see https://www.w3.org/TR/WGSL/#overload-resolution-section
|
||||
/// @returns the resolved Candidate.
|
||||
Result<Candidate, StyledText> ResolveCandidate(Context& context,
|
||||
Candidates&& candidates,
|
||||
std::string_view intrinsic_name,
|
||||
VectorRef<const core::type::Type*> template_args,
|
||||
VectorRef<const core::type::Type*> args);
|
||||
|
||||
// Prints the list of candidates for emitting diagnostics
|
||||
void PrintCandidates(StyledText& err,
|
||||
Context& context,
|
||||
VectorRef<Candidate> candidates,
|
||||
std::string_view intrinsic_name,
|
||||
VectorRef<const core::type::Type*> template_args,
|
||||
VectorRef<const core::type::Type*> args);
|
||||
|
||||
/// Raises an ICE when no overload is a clear winner of overload resolution
|
||||
StyledText ErrAmbiguousOverload(Context& context,
|
||||
std::string_view intrinsic_name,
|
||||
VectorRef<const core::type::Type*> template_args,
|
||||
VectorRef<const core::type::Type*> args,
|
||||
VectorRef<Candidate> candidates);
|
||||
|
||||
/// @return a string representing a call to a builtin with the given argument types.
|
||||
StyledText CallSignature(std::string_view intrinsic_name,
|
||||
VectorRef<const core::type::Type*> template_args,
|
||||
VectorRef<const core::type::Type*> args) {
|
||||
StyledText out;
|
||||
out << style::Code << style::Function(intrinsic_name);
|
||||
if (!template_args.IsEmpty()) {
|
||||
out << "<";
|
||||
PrintTypeList(out, template_args);
|
||||
out << ">";
|
||||
}
|
||||
out << "(";
|
||||
PrintTypeList(out, args);
|
||||
out << ")";
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
Result<Overload, StyledText> MatchIntrinsic(Context& context,
|
||||
const IntrinsicInfo& intrinsic,
|
||||
std::string_view intrinsic_name,
|
||||
VectorRef<const core::type::Type*> template_args,
|
||||
VectorRef<const core::type::Type*> args,
|
||||
EvaluationStage earliest_eval_stage,
|
||||
bool member_function,
|
||||
const OnNoMatch& on_no_match) {
|
||||
const size_t num_overloads = static_cast<size_t>(intrinsic.num_overloads);
|
||||
size_t num_matched = 0;
|
||||
size_t match_idx = 0;
|
||||
Vector<Candidate, kNumFixedCandidates> candidates;
|
||||
candidates.Reserve(intrinsic.num_overloads);
|
||||
for (size_t overload_idx = 0; overload_idx < num_overloads; overload_idx++) {
|
||||
auto& overload = context.data[intrinsic.overloads + overload_idx];
|
||||
|
||||
// Check that the overload is a member function iff we expect one.
|
||||
if (overload.flags.Contains(OverloadFlag::kMemberFunction) != member_function) {
|
||||
continue;
|
||||
}
|
||||
|
||||
auto candidate = ScoreOverload<ScoreMode::kEarlyReject>(context, overload, template_args,
|
||||
args, earliest_eval_stage);
|
||||
if (candidate.score == 0) {
|
||||
match_idx = candidates.Length();
|
||||
num_matched++;
|
||||
}
|
||||
candidates.Push(std::move(candidate));
|
||||
}
|
||||
|
||||
// How many candidates matched?
|
||||
if (DAWN_UNLIKELY(num_matched == 0)) {
|
||||
// Perform the full scoring of each overload
|
||||
for (size_t overload_idx = 0; overload_idx < num_overloads; overload_idx++) {
|
||||
auto& overload = context.data[intrinsic.overloads + overload_idx];
|
||||
|
||||
// Check that the overload is a member function iff we expect one.
|
||||
if (overload.flags.Contains(OverloadFlag::kMemberFunction) != member_function) {
|
||||
continue;
|
||||
}
|
||||
|
||||
candidates[overload_idx] = ScoreOverload<ScoreMode::kFull>(
|
||||
context, overload, template_args, args, earliest_eval_stage);
|
||||
}
|
||||
// Sort the candidates with the most promising first
|
||||
SortCandidates(candidates);
|
||||
return on_no_match(std::move(candidates));
|
||||
}
|
||||
|
||||
Candidate match;
|
||||
|
||||
if (num_matched == 1) {
|
||||
match = std::move(candidates[match_idx]);
|
||||
} else {
|
||||
TINT_CHECK_RESULT_UNWRAP(result, ResolveCandidate(context, std::move(candidates),
|
||||
intrinsic_name, template_args, args));
|
||||
match = result;
|
||||
}
|
||||
|
||||
// Build the return type
|
||||
const core::type::Type* return_type = nullptr;
|
||||
if (auto* matcher_indices = context.data[match.overload->return_matcher_indices]) {
|
||||
Any any;
|
||||
return_type =
|
||||
context.Match(match.templates, *match.overload, matcher_indices, earliest_eval_stage)
|
||||
.Type(&any);
|
||||
if (DAWN_UNLIKELY(!return_type)) {
|
||||
StyledText err;
|
||||
err << "MatchState.MatchState() returned null";
|
||||
TINT_ICE() << err.Plain();
|
||||
}
|
||||
} else {
|
||||
return_type = context.types.void_();
|
||||
}
|
||||
|
||||
return Overload{match.overload, return_type, std::move(match.parameters),
|
||||
context.data[match.overload->const_eval_fn]};
|
||||
}
|
||||
|
||||
template <ScoreMode MODE>
|
||||
Candidate ScoreOverload(Context& context,
|
||||
const OverloadInfo& overload,
|
||||
VectorRef<const core::type::Type*> template_args,
|
||||
VectorRef<const core::type::Type*> args,
|
||||
EvaluationStage earliest_eval_stage) {
|
||||
#define MATCH_FAILURE(PENALTY) \
|
||||
do { \
|
||||
if constexpr (MODE == ScoreMode::kEarlyReject) { \
|
||||
return Candidate{1}; \
|
||||
} else { \
|
||||
score += PENALTY; \
|
||||
} \
|
||||
} while (false)
|
||||
|
||||
// Penalty weights for overload mismatching.
|
||||
// This scoring is used to order the suggested overloads in diagnostic on overload mismatch, and
|
||||
// has no impact for a correct program.
|
||||
// The overloads with the lowest score will be displayed first (top-most).
|
||||
constexpr int kMismatchedExplicitTemplateCountPenalty = 10;
|
||||
constexpr int kMismatchedParamCountPenalty = 3;
|
||||
constexpr int kMismatchedParamTypePenalty = 2;
|
||||
constexpr int kMismatchedExplicitTemplateTypePenalty = 1;
|
||||
constexpr int kMismatchedImplicitTemplateTypePenalty = 1;
|
||||
constexpr int kMismatchedImplicitTemplateNumberPenalty = 1;
|
||||
|
||||
const size_t num_parameters = static_cast<size_t>(overload.num_parameters);
|
||||
const size_t num_arguments = static_cast<size_t>(args.Length());
|
||||
|
||||
size_t score = 0;
|
||||
|
||||
if (num_parameters != num_arguments) {
|
||||
MATCH_FAILURE(kMismatchedParamCountPenalty * (std::max(num_parameters, num_arguments) -
|
||||
std::min(num_parameters, num_arguments)));
|
||||
}
|
||||
|
||||
// Check that all of the template arguments provided are actually expected by the overload.
|
||||
const size_t expected_templates = overload.num_explicit_templates;
|
||||
const size_t provided_templates = template_args.Length();
|
||||
if (provided_templates != expected_templates) {
|
||||
MATCH_FAILURE(kMismatchedExplicitTemplateCountPenalty *
|
||||
(std::max(expected_templates, provided_templates) -
|
||||
std::min(expected_templates, provided_templates)));
|
||||
}
|
||||
|
||||
TemplateState templates;
|
||||
|
||||
// Check that the explicit template arguments match the constraint if specified, otherwise
|
||||
// just set the template type.
|
||||
auto num_tmpl_args = std::min<size_t>(overload.num_explicit_templates, template_args.Length());
|
||||
for (size_t i = 0; i < num_tmpl_args; ++i) {
|
||||
auto& tmpl = context.data[overload.templates + i];
|
||||
auto* type = template_args[i];
|
||||
if (auto* matcher_indices = context.data[tmpl.matcher_indices]) {
|
||||
// Ensure type matches the template's matcher.
|
||||
type =
|
||||
context.Match(templates, overload, matcher_indices, earliest_eval_stage).Type(type);
|
||||
if (!type) {
|
||||
MATCH_FAILURE(kMismatchedExplicitTemplateTypePenalty);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
templates.SetType(i, type);
|
||||
}
|
||||
|
||||
// Invoke the matchers for each parameter <-> argument pair.
|
||||
// If any arguments cannot be matched, then `score` will be increased.
|
||||
// If the overload has any template types or numbers then these will be set based on the
|
||||
// argument types. Template types may be refined by constraining with later argument types. For
|
||||
// example calling `F<T>(T, T)` with the argument types (abstract-int, i32) will first set T to
|
||||
// abstract-int when matching the first argument, and then constrained down to i32 when matching
|
||||
// the second argument.
|
||||
// Note that inferred template types are not tested against their matchers at this point.
|
||||
auto num_params = std::min(num_parameters, num_arguments);
|
||||
for (size_t p = 0; p < num_params; p++) {
|
||||
auto& parameter = context.data[overload.parameters + p];
|
||||
auto* matcher_indices = context.data[parameter.matcher_indices];
|
||||
if (!context.Match(templates, overload, matcher_indices, earliest_eval_stage)
|
||||
.Type(args[p])) {
|
||||
MATCH_FAILURE(kMismatchedParamTypePenalty);
|
||||
}
|
||||
}
|
||||
|
||||
// Check each of the inferred types and numbers for the implicit templates match their
|
||||
// respective matcher.
|
||||
for (size_t i = overload.num_explicit_templates; i < overload.num_templates; i++) {
|
||||
auto& tmpl = context.data[overload.templates + i];
|
||||
auto* matcher_indices = context.data[tmpl.matcher_indices];
|
||||
if (!matcher_indices) {
|
||||
continue;
|
||||
}
|
||||
|
||||
auto matcher = context.Match(templates, overload, matcher_indices, earliest_eval_stage);
|
||||
|
||||
switch (tmpl.kind) {
|
||||
case TemplateInfo::Kind::kType: {
|
||||
// Check all constrained template types matched their constraint matchers.
|
||||
// If the template type *does not* match any of the types in the constraint
|
||||
// matcher, then `score` is incremented and the template is assigned an invalid
|
||||
// type. If the template type *does* match a type, then the template type is
|
||||
// replaced with the first matching type. The order of types in the template matcher
|
||||
// is important here, which can be controlled with the [[precedence(N)]] decorations
|
||||
// on the types in the def file.
|
||||
if (auto* type = templates.Type(i)) {
|
||||
if (auto* ty = matcher.Type(type)) {
|
||||
// Template type matched one of the types in the template type's
|
||||
// matcher. Replace the template type with this type.
|
||||
templates.SetType(i, ty);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
templates.SetType(i, context.types.invalid());
|
||||
MATCH_FAILURE(kMismatchedImplicitTemplateTypePenalty);
|
||||
break;
|
||||
}
|
||||
|
||||
case TemplateInfo::Kind::kNumber: {
|
||||
// Checking that the inferred number matches the constraints on the
|
||||
// template. Increments `score` and assigns the template an invalid number if the
|
||||
// template numbers do not match their constraint matchers.
|
||||
auto number = templates.Num(i);
|
||||
if (!number.IsValid() || !matcher.Num(number).IsValid()) {
|
||||
templates.SetNum(i, Number::invalid);
|
||||
MATCH_FAILURE(kMismatchedImplicitTemplateNumberPenalty);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Now that all the template types have been finalized, we can construct the parameters.
|
||||
Vector<Overload::Parameter, kNumFixedParameters> parameters;
|
||||
parameters.Reserve(num_params);
|
||||
for (size_t p = 0; p < num_params; p++) {
|
||||
auto& parameter = context.data[overload.parameters + p];
|
||||
auto* matcher_indices = context.data[parameter.matcher_indices];
|
||||
auto* ty =
|
||||
context.Match(templates, overload, matcher_indices, earliest_eval_stage).Type(args[p]);
|
||||
parameters.Emplace(ty, parameter.usage);
|
||||
}
|
||||
|
||||
return Candidate{score, &overload, templates, parameters};
|
||||
#undef MATCH_FAILURE
|
||||
}
|
||||
|
||||
Result<Candidate, StyledText> ResolveCandidate(Context& context,
|
||||
Candidates&& candidates,
|
||||
std::string_view intrinsic_name,
|
||||
VectorRef<const core::type::Type*> template_args,
|
||||
VectorRef<const core::type::Type*> args) {
|
||||
Vector<uint32_t, kNumFixedParameters> best_ranks;
|
||||
best_ranks.Resize(args.Length(), 0xffffffff);
|
||||
size_t num_matched = 0;
|
||||
Candidate* best = nullptr;
|
||||
for (auto& candidate : candidates) {
|
||||
if (candidate.score > 0) {
|
||||
continue; // Candidate has already been ruled out.
|
||||
}
|
||||
bool some_won = false; // An argument ranked less than the 'best' overload's argument
|
||||
bool some_lost = false; // An argument ranked more than the 'best' overload's argument
|
||||
for (size_t i = 0; i < args.Length(); i++) {
|
||||
auto rank = core::type::Type::ConversionRank(args[i], candidate.parameters[i].type);
|
||||
if (best_ranks[i] > rank) {
|
||||
best_ranks[i] = rank;
|
||||
some_won = true;
|
||||
} else if (best_ranks[i] < rank) {
|
||||
some_lost = true;
|
||||
}
|
||||
}
|
||||
// If no arguments of this candidate ranked worse than the previous best candidate, then
|
||||
// this candidate becomes the new best candidate.
|
||||
// If no arguments of this candidate ranked better than the previous best candidate, then
|
||||
// this candidate is removed from the list of matches.
|
||||
// If neither of the above apply, then we have two candidates with no clear winner, which
|
||||
// results in an ambiguous overload error. In this situation the loop ends with
|
||||
// `num_matched > 1`.
|
||||
if (some_won) {
|
||||
// One or more arguments of this candidate ranked better than the previous best
|
||||
// candidate's argument(s).
|
||||
num_matched++;
|
||||
if (!some_lost) {
|
||||
// All arguments were at as-good or better than the previous best.
|
||||
if (best) {
|
||||
// Mark the previous best candidate as no longer being in the running, by
|
||||
// setting its score to a non-zero value. We pick 1 as this is the closest to 0
|
||||
// (match) as we can get.
|
||||
best->score = 1;
|
||||
num_matched--;
|
||||
}
|
||||
// This candidate is the new best.
|
||||
best = &candidate;
|
||||
}
|
||||
} else {
|
||||
// No arguments ranked better than the current best.
|
||||
// Change the score of this candidate to a non-zero value, so that it's not considered a
|
||||
// match.
|
||||
candidate.score = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (num_matched > 1) {
|
||||
// Re-sort the candidates with the most promising first
|
||||
SortCandidates(candidates);
|
||||
// Raise an error
|
||||
return ErrAmbiguousOverload(context, intrinsic_name, template_args, args, candidates);
|
||||
}
|
||||
|
||||
return std::move(*best);
|
||||
}
|
||||
|
||||
void PrintCandidates(StyledText& ss,
|
||||
Context& context,
|
||||
VectorRef<Candidate> candidates,
|
||||
std::string_view intrinsic_name,
|
||||
VectorRef<const core::type::Type*> template_args,
|
||||
VectorRef<const core::type::Type*> args) {
|
||||
for (auto& candidate : candidates) {
|
||||
ss << " • ";
|
||||
PrintCandidate(ss, context, candidate, intrinsic_name, template_args, args);
|
||||
ss << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
StyledText ErrAmbiguousOverload(Context& context,
|
||||
std::string_view intrinsic_name,
|
||||
VectorRef<const core::type::Type*> template_args,
|
||||
VectorRef<const core::type::Type*> args,
|
||||
VectorRef<Candidate> candidates) {
|
||||
StyledText err;
|
||||
err << "ambiguous overload while attempting to match "
|
||||
<< CallSignature(intrinsic_name, template_args, args) << "\n";
|
||||
|
||||
for (auto& candidate : candidates) {
|
||||
if (candidate.score == 0) {
|
||||
err << " ";
|
||||
PrintCandidate(err, context, candidate, intrinsic_name, template_args, args);
|
||||
err << "\n";
|
||||
}
|
||||
}
|
||||
TINT_ICE() << err.Plain();
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
void PrintCandidate(StyledText& ss,
|
||||
Context& context,
|
||||
const Candidate& candidate,
|
||||
std::string_view intrinsic_name,
|
||||
VectorRef<const core::type::Type*> template_args,
|
||||
VectorRef<const core::type::Type*> args) {
|
||||
// Restore old style before returning.
|
||||
auto prev_style = ss.Style();
|
||||
TINT_DEFER(ss << prev_style);
|
||||
|
||||
auto& overload = *candidate.overload;
|
||||
|
||||
TemplateState templates = candidate.templates;
|
||||
|
||||
// TODO(crbug.com/tint/1730): Use input evaluation stage to output only relevant overloads.
|
||||
auto earliest_eval_stage = EvaluationStage::kConstant;
|
||||
|
||||
ss << style::Code << style::Function(intrinsic_name);
|
||||
|
||||
if (overload.num_explicit_templates > 0) {
|
||||
ss << "<";
|
||||
for (size_t i = 0; i < overload.num_explicit_templates; i++) {
|
||||
const auto& tmpl = context.data[overload.templates + i];
|
||||
|
||||
bool matched = false;
|
||||
if (i < template_args.Length()) {
|
||||
auto* matcher_indices = context.data[tmpl.matcher_indices];
|
||||
matched = (matcher_indices == nullptr) ||
|
||||
(context.Match(templates, overload, matcher_indices, earliest_eval_stage)
|
||||
.Type(template_args[i]) != nullptr);
|
||||
}
|
||||
|
||||
if (i > 0) {
|
||||
ss << ", ";
|
||||
}
|
||||
ss << style::Type(tmpl.name) << " ";
|
||||
if (matched) {
|
||||
ss << (style::Code + style::Match)(" ✓ ");
|
||||
} else {
|
||||
ss << (style::Code + style::Mismatch)(" ✗ ");
|
||||
}
|
||||
}
|
||||
ss << ">";
|
||||
}
|
||||
|
||||
bool all_params_match = true;
|
||||
ss << "(";
|
||||
for (size_t i = 0; i < overload.num_parameters; i++) {
|
||||
const auto& parameter = context.data[overload.parameters + i];
|
||||
auto* matcher_indices = context.data[parameter.matcher_indices];
|
||||
|
||||
bool matched = false;
|
||||
if (i < args.Length()) {
|
||||
matched = (context.Match(templates, overload, matcher_indices, earliest_eval_stage)
|
||||
.Type(args[i]) != nullptr);
|
||||
}
|
||||
all_params_match = all_params_match && matched;
|
||||
|
||||
if (i > 0) {
|
||||
ss << ", ";
|
||||
}
|
||||
|
||||
if (parameter.usage != ParameterUsage::kNone) {
|
||||
ss << style::Variable(parameter.usage, ": ");
|
||||
}
|
||||
context.Match(templates, overload, matcher_indices, earliest_eval_stage).PrintType(ss);
|
||||
|
||||
ss << style::Code << " ";
|
||||
if (matched) {
|
||||
ss << (style::Code + style::Match)(" ✓ ");
|
||||
} else {
|
||||
ss << (style::Code + style::Mismatch)(" ✗ ");
|
||||
}
|
||||
}
|
||||
ss << ")";
|
||||
if (overload.return_matcher_indices.IsValid()) {
|
||||
ss << " -> ";
|
||||
auto* matcher_indices = context.data[overload.return_matcher_indices];
|
||||
context.Match(templates, overload, matcher_indices, earliest_eval_stage).PrintType(ss);
|
||||
}
|
||||
|
||||
bool first = true;
|
||||
auto separator = [&] {
|
||||
ss << style::Plain(first ? " where:\n " : "\n ");
|
||||
first = false;
|
||||
};
|
||||
|
||||
if (all_params_match && args.Length() > overload.num_parameters) {
|
||||
separator();
|
||||
ss << style::Mismatch(" ✗ ")
|
||||
<< style::Plain(" overload expects ", static_cast<int>(overload.num_parameters),
|
||||
" argument", overload.num_parameters != 1 ? "s" : "", ", call passed ",
|
||||
args.Length(), " argument", args.Length() != 1 ? "s" : "");
|
||||
}
|
||||
if (all_params_match && template_args.Length() > overload.num_explicit_templates) {
|
||||
separator();
|
||||
ss << style::Mismatch(" ✗ ")
|
||||
<< style::Plain(" overload expects ", static_cast<int>(overload.num_explicit_templates),
|
||||
" template argument", overload.num_explicit_templates != 1 ? "s" : "",
|
||||
", call passed ", template_args.Length(), " argument",
|
||||
template_args.Length() != 1 ? "s" : "");
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < overload.num_templates; i++) {
|
||||
auto& tmpl = context.data[overload.templates + i];
|
||||
if (auto* matcher_indices = context.data[tmpl.matcher_indices]) {
|
||||
separator();
|
||||
bool matched = false;
|
||||
if (tmpl.kind == TemplateInfo::Kind::kType) {
|
||||
if (auto* ty = templates.Type(i)) {
|
||||
matched =
|
||||
(context.Match(templates, overload, matcher_indices, earliest_eval_stage)
|
||||
.Type(ty) != nullptr);
|
||||
}
|
||||
} else {
|
||||
matched = context.Match(templates, overload, matcher_indices, earliest_eval_stage)
|
||||
.Num(templates.Num(i))
|
||||
.IsValid();
|
||||
}
|
||||
if (matched) {
|
||||
ss << style::Match(" ✓ ") << style::Plain(" ");
|
||||
} else {
|
||||
ss << style::Mismatch(" ✗ ") << style::Plain(" ");
|
||||
}
|
||||
|
||||
ss << style::Type(tmpl.name) << style::Plain(" is ");
|
||||
if (tmpl.kind == TemplateInfo::Kind::kType) {
|
||||
context.Match(templates, overload, matcher_indices, earliest_eval_stage)
|
||||
.PrintType(ss);
|
||||
} else {
|
||||
context.Match(templates, overload, matcher_indices, earliest_eval_stage)
|
||||
.PrintNum(ss);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Result<Overload, StyledText> LookupFn(Context& context,
|
||||
std::string_view intrinsic_name,
|
||||
size_t function_id,
|
||||
VectorRef<const core::type::Type*> template_args,
|
||||
VectorRef<const core::type::Type*> args,
|
||||
EvaluationStage earliest_eval_stage) {
|
||||
// Generates an error when no overloads match the provided arguments
|
||||
auto on_no_match = [&](VectorRef<Candidate> candidates) {
|
||||
StyledText err;
|
||||
err << "no matching call to " << CallSignature(intrinsic_name, template_args, args) << "\n";
|
||||
if (!candidates.IsEmpty()) {
|
||||
err << "\n"
|
||||
<< candidates.Length() << " candidate function"
|
||||
<< (candidates.Length() > 1 ? "s:" : ":") << "\n";
|
||||
PrintCandidates(err, context, candidates, intrinsic_name, template_args, args);
|
||||
}
|
||||
return err;
|
||||
};
|
||||
|
||||
// Resolve the intrinsic overload
|
||||
return MatchIntrinsic(context, context.data.builtins[function_id], intrinsic_name,
|
||||
template_args, args, earliest_eval_stage, /* member_function */ false,
|
||||
on_no_match);
|
||||
}
|
||||
|
||||
Result<Overload, StyledText> LookupMemberFn(Context& context,
|
||||
std::string_view intrinsic_name,
|
||||
size_t function_id,
|
||||
VectorRef<const core::type::Type*> template_args,
|
||||
VectorRef<const core::type::Type*> args,
|
||||
EvaluationStage earliest_eval_stage) {
|
||||
// Generates an error when no overloads match the provided arguments
|
||||
auto on_no_match = [&](VectorRef<Candidate> candidates) {
|
||||
StyledText err;
|
||||
err << "no matching call to " << CallSignature(intrinsic_name, template_args, args) << "\n";
|
||||
if (!candidates.IsEmpty()) {
|
||||
err << "\n"
|
||||
<< candidates.Length() << " candidate function"
|
||||
<< (candidates.Length() > 1 ? "s:" : ":") << "\n";
|
||||
PrintCandidates(err, context, candidates, intrinsic_name, template_args, args);
|
||||
}
|
||||
return err;
|
||||
};
|
||||
|
||||
// Resolve the intrinsic overload
|
||||
return MatchIntrinsic(context, context.data.builtins[function_id], intrinsic_name,
|
||||
template_args, args, earliest_eval_stage, /* member_function */ true,
|
||||
on_no_match);
|
||||
}
|
||||
|
||||
Result<Overload, StyledText> LookupUnary(Context& context,
|
||||
core::UnaryOp op,
|
||||
const core::type::Type* arg,
|
||||
EvaluationStage earliest_eval_stage) {
|
||||
const IntrinsicInfo* intrinsic_info = nullptr;
|
||||
std::string_view intrinsic_name;
|
||||
switch (op) {
|
||||
case core::UnaryOp::kComplement:
|
||||
intrinsic_info = &context.data.unary_complement;
|
||||
intrinsic_name = "operator ~ ";
|
||||
break;
|
||||
case core::UnaryOp::kNegation:
|
||||
intrinsic_info = &context.data.unary_minus;
|
||||
intrinsic_name = "operator - ";
|
||||
break;
|
||||
case core::UnaryOp::kAddressOf:
|
||||
intrinsic_info = &context.data.unary_and;
|
||||
intrinsic_name = "operator & ";
|
||||
break;
|
||||
case core::UnaryOp::kIndirection:
|
||||
intrinsic_info = &context.data.unary_star;
|
||||
intrinsic_name = "operator * ";
|
||||
break;
|
||||
case core::UnaryOp::kNot:
|
||||
intrinsic_info = &context.data.unary_not;
|
||||
intrinsic_name = "operator ! ";
|
||||
break;
|
||||
}
|
||||
|
||||
Vector args{arg};
|
||||
|
||||
// Generates an error when no overloads match the provided arguments
|
||||
auto on_no_match = [&, name = intrinsic_name](VectorRef<Candidate> candidates) {
|
||||
StyledText err;
|
||||
err << "no matching overload for " << CallSignature(name, Empty, args) << "\n";
|
||||
if (!candidates.IsEmpty()) {
|
||||
err << "\n"
|
||||
<< candidates.Length() << " candidate operator"
|
||||
<< (candidates.Length() > 1 ? "s:" : ":") << "\n";
|
||||
PrintCandidates(err, context, candidates, name, Empty, Vector{arg});
|
||||
}
|
||||
return err;
|
||||
};
|
||||
|
||||
// Resolve the intrinsic overload
|
||||
return MatchIntrinsic(context, *intrinsic_info, intrinsic_name, Empty, args,
|
||||
earliest_eval_stage, /* member_function */ false, on_no_match);
|
||||
}
|
||||
|
||||
Result<Overload, StyledText> LookupBinary(Context& context,
|
||||
core::BinaryOp op,
|
||||
const core::type::Type* lhs,
|
||||
const core::type::Type* rhs,
|
||||
EvaluationStage earliest_eval_stage,
|
||||
bool is_compound) {
|
||||
const IntrinsicInfo* intrinsic_info = nullptr;
|
||||
std::string_view intrinsic_name;
|
||||
switch (op) {
|
||||
case core::BinaryOp::kAnd:
|
||||
intrinsic_info = &context.data.binary_and;
|
||||
intrinsic_name = is_compound ? "operator &= " : "operator & ";
|
||||
break;
|
||||
case core::BinaryOp::kOr:
|
||||
intrinsic_info = &context.data.binary_or;
|
||||
intrinsic_name = is_compound ? "operator |= " : "operator | ";
|
||||
break;
|
||||
case core::BinaryOp::kXor:
|
||||
intrinsic_info = &context.data.binary_xor;
|
||||
intrinsic_name = is_compound ? "operator ^= " : "operator ^ ";
|
||||
break;
|
||||
case core::BinaryOp::kLogicalAnd:
|
||||
intrinsic_info = &context.data.binary_logical_and;
|
||||
intrinsic_name = "operator && ";
|
||||
break;
|
||||
case core::BinaryOp::kLogicalOr:
|
||||
intrinsic_info = &context.data.binary_logical_or;
|
||||
intrinsic_name = "operator || ";
|
||||
break;
|
||||
case core::BinaryOp::kEqual:
|
||||
intrinsic_info = &context.data.binary_equal;
|
||||
intrinsic_name = "operator == ";
|
||||
break;
|
||||
case core::BinaryOp::kNotEqual:
|
||||
intrinsic_info = &context.data.binary_not_equal;
|
||||
intrinsic_name = "operator != ";
|
||||
break;
|
||||
case core::BinaryOp::kLessThan:
|
||||
intrinsic_info = &context.data.binary_less_than;
|
||||
intrinsic_name = "operator < ";
|
||||
break;
|
||||
case core::BinaryOp::kGreaterThan:
|
||||
intrinsic_info = &context.data.binary_greater_than;
|
||||
intrinsic_name = "operator > ";
|
||||
break;
|
||||
case core::BinaryOp::kLessThanEqual:
|
||||
intrinsic_info = &context.data.binary_less_than_equal;
|
||||
intrinsic_name = "operator <= ";
|
||||
break;
|
||||
case core::BinaryOp::kGreaterThanEqual:
|
||||
intrinsic_info = &context.data.binary_greater_than_equal;
|
||||
intrinsic_name = "operator >= ";
|
||||
break;
|
||||
case core::BinaryOp::kShiftLeft:
|
||||
intrinsic_info = &context.data.binary_shift_left;
|
||||
intrinsic_name = is_compound ? "operator <<= " : "operator << ";
|
||||
break;
|
||||
case core::BinaryOp::kShiftRight:
|
||||
intrinsic_info = &context.data.binary_shift_right;
|
||||
intrinsic_name = is_compound ? "operator >>= " : "operator >> ";
|
||||
break;
|
||||
case core::BinaryOp::kAdd:
|
||||
intrinsic_info = &context.data.binary_plus;
|
||||
intrinsic_name = is_compound ? "operator += " : "operator + ";
|
||||
break;
|
||||
case core::BinaryOp::kSubtract:
|
||||
intrinsic_info = &context.data.binary_minus;
|
||||
intrinsic_name = is_compound ? "operator -= " : "operator - ";
|
||||
break;
|
||||
case core::BinaryOp::kMultiply:
|
||||
intrinsic_info = &context.data.binary_star;
|
||||
intrinsic_name = is_compound ? "operator *= " : "operator * ";
|
||||
break;
|
||||
case core::BinaryOp::kDivide:
|
||||
intrinsic_info = &context.data.binary_divide;
|
||||
intrinsic_name = is_compound ? "operator /= " : "operator / ";
|
||||
break;
|
||||
case core::BinaryOp::kModulo:
|
||||
intrinsic_info = &context.data.binary_modulo;
|
||||
intrinsic_name = is_compound ? "operator %= " : "operator % ";
|
||||
break;
|
||||
}
|
||||
|
||||
Vector args{lhs, rhs};
|
||||
|
||||
// Generates an error when no overloads match the provided arguments
|
||||
auto on_no_match = [&, name = intrinsic_name](VectorRef<Candidate> candidates) {
|
||||
StyledText err;
|
||||
err << "no matching overload for " << CallSignature(name, Empty, args) << "\n";
|
||||
if (!candidates.IsEmpty()) {
|
||||
err << "\n"
|
||||
<< candidates.Length() << " candidate operator"
|
||||
<< (candidates.Length() > 1 ? "s:" : ":") << "\n";
|
||||
PrintCandidates(err, context, candidates, name, Empty, args);
|
||||
}
|
||||
return err;
|
||||
};
|
||||
|
||||
// Resolve the intrinsic overload
|
||||
return MatchIntrinsic(context, *intrinsic_info, intrinsic_name, Empty, args,
|
||||
earliest_eval_stage, /* member_function */ false, on_no_match);
|
||||
}
|
||||
|
||||
Result<Overload, StyledText> LookupCtorConv(Context& context,
|
||||
std::string_view type_name,
|
||||
size_t type_id,
|
||||
VectorRef<const core::type::Type*> template_args,
|
||||
VectorRef<const core::type::Type*> args,
|
||||
EvaluationStage earliest_eval_stage) {
|
||||
// Generates an error when no overloads match the provided arguments
|
||||
auto on_no_match = [&](VectorRef<Candidate> candidates) {
|
||||
StyledText err;
|
||||
err << "no matching constructor for " << CallSignature(type_name, template_args, args)
|
||||
<< "\n";
|
||||
Candidates ctor, conv;
|
||||
for (auto candidate : candidates) {
|
||||
if (candidate.overload->flags.Contains(OverloadFlag::kIsConstructor)) {
|
||||
ctor.Push(candidate);
|
||||
} else {
|
||||
conv.Push(candidate);
|
||||
}
|
||||
}
|
||||
if (!ctor.IsEmpty()) {
|
||||
err << "\n"
|
||||
<< ctor.Length() << " candidate constructor" << (ctor.Length() > 1 ? "s:" : ":")
|
||||
<< "\n";
|
||||
PrintCandidates(err, context, ctor, type_name, template_args, args);
|
||||
}
|
||||
if (!conv.IsEmpty()) {
|
||||
err << "\n"
|
||||
<< conv.Length() << " candidate conversion" << (conv.Length() > 1 ? "s:" : ":")
|
||||
<< "\n";
|
||||
PrintCandidates(err, context, conv, type_name, template_args, args);
|
||||
}
|
||||
return err;
|
||||
};
|
||||
|
||||
// Resolve the intrinsic overload
|
||||
return MatchIntrinsic(context, context.data.ctor_conv[type_id], type_name, template_args, args,
|
||||
earliest_eval_stage, /* member_function */ false, on_no_match);
|
||||
}
|
||||
|
||||
} // namespace tint::core::intrinsic
|
||||
|
||||
/// TypeInfo for the Any type declared in the anonymous namespace above
|
||||
TINT_INSTANTIATE_TYPEINFO(tint::core::intrinsic::Any);
|
||||
401
3rdparty/dawn/src/tint/lang/core/intrinsic/table.h
vendored
Normal file
401
3rdparty/dawn/src/tint/lang/core/intrinsic/table.h
vendored
Normal file
@@ -0,0 +1,401 @@
|
||||
// Copyright 2021 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.
|
||||
|
||||
#ifndef SRC_TINT_LANG_CORE_INTRINSIC_TABLE_H_
|
||||
#define SRC_TINT_LANG_CORE_INTRINSIC_TABLE_H_
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
#include "src/tint/lang/core/binary_op.h"
|
||||
#include "src/tint/lang/core/enums.h"
|
||||
#include "src/tint/lang/core/evaluation_stage.h"
|
||||
#include "src/tint/lang/core/intrinsic/ctor_conv.h"
|
||||
#include "src/tint/lang/core/intrinsic/table_data.h"
|
||||
#include "src/tint/lang/core/unary_op.h"
|
||||
#include "src/tint/utils/containers/vector.h"
|
||||
#include "src/tint/utils/text/string.h"
|
||||
#include "src/tint/utils/text/string_stream.h"
|
||||
#include "src/tint/utils/text/styled_text.h"
|
||||
|
||||
// Forward declarations
|
||||
namespace tint::diag {
|
||||
class List;
|
||||
} // namespace tint::diag
|
||||
|
||||
namespace tint::core::intrinsic {
|
||||
|
||||
/// Overload describes a fully matched builtin function overload
|
||||
struct Overload {
|
||||
static constexpr size_t kNumFixedParameters = 8;
|
||||
|
||||
/// Parameter describes a single parameter
|
||||
struct Parameter {
|
||||
/// Parameter type
|
||||
const core::type::Type* const type;
|
||||
/// Parameter usage
|
||||
core::ParameterUsage const usage = core::ParameterUsage::kNone;
|
||||
|
||||
/// Equality operator
|
||||
/// @param other the parameter to compare against
|
||||
/// @returns true if this parameter and @p other are the same
|
||||
bool operator==(const Parameter& other) const {
|
||||
return type == other.type && usage == other.usage;
|
||||
}
|
||||
|
||||
/// Inequality operator
|
||||
/// @param other the parameter to compare against
|
||||
/// @returns false if this parameter and @p other are the same
|
||||
bool operator!=(const Parameter& other) const { return !(*this == other); }
|
||||
};
|
||||
|
||||
/// The overload information
|
||||
const OverloadInfo* info = nullptr;
|
||||
|
||||
/// The resolved overload return type
|
||||
core::type::Type const* return_type = nullptr;
|
||||
|
||||
/// The resolved overload parameters
|
||||
Vector<Parameter, kNumFixedParameters> parameters;
|
||||
|
||||
/// The constant evaluation function
|
||||
constant::Eval::Function const_eval_fn = nullptr;
|
||||
|
||||
/// Equality operator
|
||||
/// @param other the overload to compare against
|
||||
/// @returns true if this overload and @p other are the same
|
||||
bool operator==(const Overload& other) const {
|
||||
return info == other.info && return_type == other.return_type &&
|
||||
parameters == other.parameters;
|
||||
}
|
||||
|
||||
/// Inequality operator
|
||||
/// @param other the overload to compare against
|
||||
/// @returns false if this overload and @p other are the same
|
||||
bool operator!=(const Overload& other) const { return !(*this == other); }
|
||||
};
|
||||
|
||||
/// The context data used to lookup intrinsic information
|
||||
struct Context {
|
||||
/// The table table
|
||||
const TableData& data;
|
||||
/// The type manager
|
||||
core::type::Manager& types;
|
||||
/// The symbol table
|
||||
SymbolTable& symbols;
|
||||
|
||||
/// @returns a MatchState from the context and arguments.
|
||||
/// @param templates the template state used for matcher evaluation
|
||||
/// @param overload the overload being evaluated
|
||||
/// @param matcher_indices pointer to a list of matcher indices
|
||||
MatchState Match(TemplateState& templates,
|
||||
const OverloadInfo& overload,
|
||||
const MatcherIndex* matcher_indices,
|
||||
EvaluationStage earliest_eval_stage) {
|
||||
return MatchState(types, symbols, templates, data, overload, matcher_indices,
|
||||
earliest_eval_stage);
|
||||
}
|
||||
};
|
||||
|
||||
/// Candidate holds information about an overload evaluated for resolution.
|
||||
struct Candidate {
|
||||
/// The match-score of the candidate overload.
|
||||
/// A score of zero indicates an exact match.
|
||||
/// Non-zero scores are used for diagnostics when no overload matches.
|
||||
/// Lower scores are displayed first (top-most).
|
||||
size_t score = 0;
|
||||
/// The candidate overload
|
||||
const OverloadInfo* overload = nullptr;
|
||||
/// The template types and numbers
|
||||
TemplateState templates{};
|
||||
/// The parameter types for the candidate overload
|
||||
Vector<Overload::Parameter, Overload::kNumFixedParameters> parameters{};
|
||||
};
|
||||
|
||||
// Prints the candidate overload for emitting diagnostics
|
||||
void PrintCandidate(StyledText& ss,
|
||||
Context& context,
|
||||
const Candidate& candidate,
|
||||
std::string_view intrinsic_name,
|
||||
VectorRef<const core::type::Type*> template_args,
|
||||
VectorRef<const core::type::Type*> args);
|
||||
|
||||
/// Lookup looks for the builtin overload with the given signature, raising an error diagnostic
|
||||
/// if the builtin was not found.
|
||||
/// @param context the intrinsic context
|
||||
/// @param function_name the name of the function
|
||||
/// @param function_id the function identifier
|
||||
/// @param template_args the optional template arguments
|
||||
/// @param args the argument types passed to the builtin function
|
||||
/// @param earliest_eval_stage the earliest evaluation stage that a call to
|
||||
/// the builtin can be made. This can alter the overloads considered.
|
||||
/// For example, if the earliest evaluation stage is `EvaluationStage::kRuntime`, then
|
||||
/// only overloads with concrete argument types will be considered, as all
|
||||
/// abstract-numerics will have been materialized after shader creation time
|
||||
/// (EvaluationStage::kConstant).
|
||||
/// @return the resolved builtin function overload
|
||||
Result<Overload, StyledText> LookupFn(Context& context,
|
||||
std::string_view function_name,
|
||||
size_t function_id,
|
||||
VectorRef<const core::type::Type*> template_args,
|
||||
VectorRef<const core::type::Type*> args,
|
||||
EvaluationStage earliest_eval_stage);
|
||||
|
||||
/// Lookup looks for the member builtin overload with the given signature, raising an error
|
||||
/// diagnostic if the builtin was not found.
|
||||
/// @param context the intrinsic context
|
||||
/// @param function_name the name of the function
|
||||
/// @param function_id the function identifier
|
||||
/// @param template_args the optional template arguments
|
||||
/// @param args the argument types passed to the builtin function
|
||||
/// @param earliest_eval_stage the earliest evaluation stage that a call to
|
||||
/// the builtin can be made. This can alter the overloads considered.
|
||||
/// For example, if the earliest evaluation stage is `EvaluationStage::kRuntime`, then
|
||||
/// only overloads with concrete argument types will be considered, as all
|
||||
/// abstract-numerics will have been materialized after shader creation time
|
||||
/// (EvaluationStage::kConstant).
|
||||
/// @return the resolved builtin function overload
|
||||
Result<Overload, StyledText> LookupMemberFn(Context& context,
|
||||
std::string_view function_name,
|
||||
size_t function_id,
|
||||
VectorRef<const core::type::Type*> template_args,
|
||||
VectorRef<const core::type::Type*> args,
|
||||
EvaluationStage earliest_eval_stage);
|
||||
|
||||
/// Lookup looks for the unary op overload with the given signature, raising an error
|
||||
/// diagnostic if the operator was not found.
|
||||
/// @param context the intrinsic context
|
||||
/// @param op the unary operator
|
||||
/// @param arg the type of the expression passed to the operator
|
||||
/// @param earliest_eval_stage the earliest evaluation stage that a call to
|
||||
/// the unary operator can be made. This can alter the overloads considered.
|
||||
/// For example, if the earliest evaluation stage is
|
||||
/// `EvaluationStage::kRuntime`, then only overloads with concrete argument types
|
||||
/// will be considered, as all abstract-numerics will have been materialized
|
||||
/// after shader creation time (EvaluationStage::kConstant).
|
||||
/// @return the resolved unary operator overload
|
||||
Result<Overload, StyledText> LookupUnary(Context& context,
|
||||
core::UnaryOp op,
|
||||
const core::type::Type* arg,
|
||||
EvaluationStage earliest_eval_stage);
|
||||
|
||||
/// Lookup looks for the binary op overload with the given signature, raising an error
|
||||
/// diagnostic if the operator was not found.
|
||||
/// @param context the intrinsic context
|
||||
/// @param op the binary operator
|
||||
/// @param lhs the LHS value type passed to the operator
|
||||
/// @param rhs the RHS value type passed to the operator
|
||||
/// @param earliest_eval_stage the earliest evaluation stage that a call to
|
||||
/// the binary operator can be made. This can alter the overloads considered.
|
||||
/// For example, if the earliest evaluation stage is
|
||||
/// `EvaluationStage::kRuntime`, then only overloads with concrete argument types
|
||||
/// will be considered, as all abstract-numerics will have been materialized
|
||||
/// after shader creation time (EvaluationStage::kConstant).
|
||||
/// @param is_compound true if the binary operator is being used as a compound assignment
|
||||
/// @return the resolved binary operator overload
|
||||
Result<Overload, StyledText> LookupBinary(Context& context,
|
||||
core::BinaryOp op,
|
||||
const core::type::Type* lhs,
|
||||
const core::type::Type* rhs,
|
||||
EvaluationStage earliest_eval_stage,
|
||||
bool is_compound);
|
||||
|
||||
/// Lookup looks for the value constructor or conversion overload for the given CtorConv.
|
||||
/// @param context the intrinsic context
|
||||
/// @param type_name the name of the type being constructed or converted
|
||||
/// @param type_id the type identifier
|
||||
/// @param template_args the optional template arguments
|
||||
/// @param args the argument types passed to the constructor / conversion call
|
||||
/// @param earliest_eval_stage the earliest evaluation stage that a call to
|
||||
/// the constructor or conversion can be made. This can alter the overloads considered.
|
||||
/// For example, if the earliest evaluation stage is
|
||||
/// `EvaluationStage::kRuntime`, then only overloads with concrete argument types
|
||||
/// will be considered, as all abstract-numerics will have been materialized
|
||||
/// after shader creation time (EvaluationStage::kConstant).
|
||||
/// @return the resolved type constructor or conversion function overload
|
||||
Result<Overload, StyledText> LookupCtorConv(Context& context,
|
||||
std::string_view type_name,
|
||||
size_t type_id,
|
||||
VectorRef<const core::type::Type*> template_args,
|
||||
VectorRef<const core::type::Type*> args,
|
||||
EvaluationStage earliest_eval_stage);
|
||||
|
||||
/// Table is a wrapper around a dialect to provide type-safe interface to the intrinsic table.
|
||||
template <typename DIALECT>
|
||||
struct Table {
|
||||
/// Alias to DIALECT::BuiltinFn
|
||||
using BuiltinFn = typename DIALECT::BuiltinFn;
|
||||
|
||||
/// Alias to DIALECT::CtorConv
|
||||
using CtorConv = typename DIALECT::CtorConv;
|
||||
|
||||
static_assert(std::is_enum_v<BuiltinFn>);
|
||||
static_assert(std::is_enum_v<CtorConv>);
|
||||
|
||||
/// @param types The type manager
|
||||
/// @param symbols The symbol table
|
||||
Table(core::type::Manager& types, SymbolTable& symbols)
|
||||
: context{DIALECT::kData, types, symbols} {}
|
||||
|
||||
/// Lookup looks for the builtin overload with the given signature, raising an error diagnostic
|
||||
/// if the builtin was not found.
|
||||
/// @param builtin_fn the builtin function
|
||||
/// @param template_args the optional template arguments
|
||||
/// @param args the argument types passed to the builtin function
|
||||
/// @param earliest_eval_stage the earliest evaluation stage that a call to
|
||||
/// the builtin can be made. This can alter the overloads considered.
|
||||
/// For example, if the earliest evaluation stage is `EvaluationStage::kRuntime`, then
|
||||
/// only overloads with concrete argument types will be considered, as all
|
||||
/// abstract-numerics will have been materialized after shader creation time
|
||||
/// (EvaluationStage::kConstant).
|
||||
/// @return the resolved builtin function overload
|
||||
Result<Overload, StyledText> Lookup(BuiltinFn builtin_fn,
|
||||
VectorRef<const core::type::Type*> template_args,
|
||||
VectorRef<const core::type::Type*> args,
|
||||
EvaluationStage earliest_eval_stage) {
|
||||
std::string_view name = DIALECT::ToString(builtin_fn);
|
||||
size_t id = static_cast<size_t>(builtin_fn);
|
||||
return LookupFn(context, name, id, std::move(template_args), std::move(args),
|
||||
earliest_eval_stage);
|
||||
}
|
||||
|
||||
/// Lookup looks for the member builtin overload with the given signature, raising an error
|
||||
/// diagnostic if the builtin was not found.
|
||||
/// @param builtin_fn the builtin function
|
||||
/// @param object the object type
|
||||
/// @param template_args the optional template arguments
|
||||
/// @param args the argument types passed to the builtin function
|
||||
/// @param earliest_eval_stage the earliest evaluation stage that a call to
|
||||
/// the builtin can be made. This can alter the overloads considered.
|
||||
/// For example, if the earliest evaluation stage is `EvaluationStage::kRuntime`, then
|
||||
/// only overloads with concrete argument types will be considered, as all
|
||||
/// abstract-numerics will have been materialized after shader creation time
|
||||
/// (EvaluationStage::kConstant).
|
||||
/// @return the resolved builtin function overload
|
||||
Result<Overload, StyledText> Lookup(BuiltinFn builtin_fn,
|
||||
const core::type::Type* object,
|
||||
VectorRef<const core::type::Type*> template_args,
|
||||
VectorRef<const core::type::Type*> args,
|
||||
EvaluationStage earliest_eval_stage) {
|
||||
// Push the object type into the argument list.
|
||||
auto full_args = Vector<const core::type::Type*, 8>({object});
|
||||
for (auto* arg : args) {
|
||||
full_args.Push(arg);
|
||||
}
|
||||
std::string_view name = DIALECT::ToString(builtin_fn);
|
||||
size_t id = static_cast<size_t>(builtin_fn);
|
||||
return LookupMemberFn(context, name, id, std::move(template_args), std::move(full_args),
|
||||
earliest_eval_stage);
|
||||
}
|
||||
|
||||
/// Lookup looks for the unary op overload with the given signature, raising an error
|
||||
/// diagnostic if the operator was not found.
|
||||
/// @param op the unary operator
|
||||
/// @param arg the type of the expression passed to the operator
|
||||
/// @param earliest_eval_stage the earliest evaluation stage that a call to
|
||||
/// the unary operator can be made. This can alter the overloads considered.
|
||||
/// For example, if the earliest evaluation stage is
|
||||
/// `EvaluationStage::kRuntime`, then only overloads with concrete argument types
|
||||
/// will be considered, as all abstract-numerics will have been materialized
|
||||
/// after shader creation time (EvaluationStage::kConstant).
|
||||
|
||||
/// @return the resolved unary operator overload
|
||||
Result<Overload, StyledText> Lookup(core::UnaryOp op,
|
||||
const core::type::Type* arg,
|
||||
EvaluationStage earliest_eval_stage) {
|
||||
return LookupUnary(context, op, arg, earliest_eval_stage);
|
||||
}
|
||||
|
||||
/// Lookup looks for the binary op overload with the given signature, raising an error
|
||||
/// diagnostic if the operator was not found.
|
||||
/// @param op the binary operator
|
||||
/// @param lhs the LHS value type passed to the operator
|
||||
/// @param rhs the RHS value type passed to the operator
|
||||
/// @param earliest_eval_stage the earliest evaluation stage that a call to
|
||||
/// the binary operator can be made. This can alter the overloads considered.
|
||||
/// For example, if the earliest evaluation stage is
|
||||
/// `EvaluationStage::kRuntime`, then only overloads with concrete argument types
|
||||
/// will be considered, as all abstract-numerics will have been materialized
|
||||
/// after shader creation time (EvaluationStage::kConstant).
|
||||
|
||||
/// @param is_compound true if the binary operator is being used as a compound assignment
|
||||
/// @return the resolved binary operator overload
|
||||
Result<Overload, StyledText> Lookup(core::BinaryOp op,
|
||||
const core::type::Type* lhs,
|
||||
const core::type::Type* rhs,
|
||||
EvaluationStage earliest_eval_stage,
|
||||
bool is_compound) {
|
||||
return LookupBinary(context, op, lhs, rhs, earliest_eval_stage, is_compound);
|
||||
}
|
||||
|
||||
/// Lookup looks for the value constructor or conversion overload for the given CtorConv.
|
||||
/// @param type the type being constructed or converted
|
||||
/// @param template_args the optional template arguments
|
||||
/// @param args the argument types passed to the constructor / conversion call
|
||||
/// @param earliest_eval_stage the earliest evaluation stage that a call to
|
||||
/// the constructor or conversion can be made. This can alter the overloads considered.
|
||||
/// For example, if the earliest evaluation stage is
|
||||
/// `EvaluationStage::kRuntime`, then only overloads with concrete argument types
|
||||
/// will be considered, as all abstract-numerics will have been materialized
|
||||
/// after shader creation time (EvaluationStage::kConstant).
|
||||
/// @return the resolved type constructor or conversion function overload
|
||||
Result<Overload, StyledText> Lookup(CtorConv type,
|
||||
VectorRef<const core::type::Type*> template_args,
|
||||
VectorRef<const core::type::Type*> args,
|
||||
EvaluationStage earliest_eval_stage) {
|
||||
std::string_view name = DIALECT::ToString(type);
|
||||
size_t id = static_cast<size_t>(type);
|
||||
return LookupCtorConv(context, name, id, std::move(template_args), std::move(args),
|
||||
earliest_eval_stage);
|
||||
}
|
||||
|
||||
/// The intrinsic context
|
||||
Context context;
|
||||
};
|
||||
|
||||
} // namespace tint::core::intrinsic
|
||||
|
||||
namespace tint {
|
||||
|
||||
/// Hasher specialization for core::intrinsic::Overload
|
||||
template <>
|
||||
struct Hasher<core::intrinsic::Overload> {
|
||||
/// @param i the core::intrinsic::Overload to create a hash for
|
||||
/// @return the hash value
|
||||
inline HashCode operator()(const core::intrinsic::Overload& i) const {
|
||||
HashCode hash = Hash(i.parameters.Length());
|
||||
for (auto& p : i.parameters) {
|
||||
hash = HashCombine(hash, p.type, p.usage);
|
||||
}
|
||||
return Hash(hash, i.info, i.return_type);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace tint
|
||||
|
||||
#endif // SRC_TINT_LANG_CORE_INTRINSIC_TABLE_H_
|
||||
678
3rdparty/dawn/src/tint/lang/core/intrinsic/table_data.h
vendored
Normal file
678
3rdparty/dawn/src/tint/lang/core/intrinsic/table_data.h
vendored
Normal file
@@ -0,0 +1,678 @@
|
||||
// Copyright 2023 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.
|
||||
|
||||
#ifndef SRC_TINT_LANG_CORE_INTRINSIC_TABLE_DATA_H_
|
||||
#define SRC_TINT_LANG_CORE_INTRINSIC_TABLE_DATA_H_
|
||||
|
||||
#include <stdint.h>
|
||||
#include <limits>
|
||||
#include <string>
|
||||
|
||||
#include "src/tint/lang/core/constant/eval.h"
|
||||
#include "src/tint/lang/core/enums.h"
|
||||
#include "src/tint/lang/core/evaluation_stage.h"
|
||||
#include "src/tint/utils/containers/enum_set.h"
|
||||
#include "src/tint/utils/containers/slice.h"
|
||||
#include "src/tint/utils/text/styled_text.h"
|
||||
#include "src/tint/utils/text/text_style.h"
|
||||
|
||||
/// Forward declaration
|
||||
namespace tint::core::intrinsic {
|
||||
struct TableData;
|
||||
} // namespace tint::core::intrinsic
|
||||
|
||||
namespace tint::core::intrinsic {
|
||||
|
||||
/// An enumerator of index namespaces.
|
||||
enum class TableIndexNamespace : uint8_t {
|
||||
kTemplate,
|
||||
kMatcher,
|
||||
kMatcherIndices,
|
||||
kTypeMatcher,
|
||||
kNumberMatcher,
|
||||
kParameter,
|
||||
kOverload,
|
||||
kConstEvalFunction,
|
||||
};
|
||||
|
||||
/// A wrapper around an integer type, used to index intrinsic table data
|
||||
/// @tparam T the index data type
|
||||
/// @tparam N the index namespace
|
||||
template <TableIndexNamespace N, typename T>
|
||||
struct TableIndex {
|
||||
static_assert(std::is_integral_v<T> && std::is_unsigned_v<T>,
|
||||
"T must be an unsigned integer type");
|
||||
|
||||
/// The value used to represent an invalid index
|
||||
static constexpr T kInvalid = std::numeric_limits<T>::max();
|
||||
|
||||
/// Constructor for invalid index
|
||||
constexpr TableIndex() : value(kInvalid) {}
|
||||
|
||||
/// Constructor
|
||||
/// @param index the index value
|
||||
constexpr explicit TableIndex(T index) : value(index) {}
|
||||
|
||||
/// @returns true if this index is not invalid
|
||||
bool IsValid() const { return value != kInvalid; }
|
||||
|
||||
/// Equality operator
|
||||
/// @param other the index to compare against
|
||||
/// @returns true if this index is equal to @p other
|
||||
bool operator==(const TableIndex& other) { return value == other.value; }
|
||||
|
||||
/// Inequality operator
|
||||
/// @param other the index to compare against
|
||||
/// @returns true if this index is equal to @p other
|
||||
bool operator!=(const TableIndex& other) { return value != other.value; }
|
||||
|
||||
/// @param offset the offset to apply to this index
|
||||
/// @returns a new index offset by @p offset
|
||||
template <typename U>
|
||||
auto operator+(U offset) const {
|
||||
static_assert(std::is_integral_v<U> && std::is_unsigned_v<U>,
|
||||
"T must be an unsigned integer type");
|
||||
using C = std::conditional_t<(sizeof(U) > sizeof(T)), U, T>;
|
||||
C new_value = static_cast<C>(value) + static_cast<C>(offset);
|
||||
return TableIndex<N, decltype(new_value)>(new_value);
|
||||
}
|
||||
|
||||
/// @param arr a C-style array
|
||||
/// @returns true if the integer type `T` has enough bits to index all the
|
||||
/// elements in the array @p arr.
|
||||
template <typename U, size_t COUNT>
|
||||
static constexpr bool CanIndex(U (&arr)[COUNT]) {
|
||||
(void)arr; // The array isn't actually used
|
||||
/// kInvalid is the largest value representable by `T`. It is not a valid index.
|
||||
return COUNT < kInvalid;
|
||||
}
|
||||
|
||||
/// The index value
|
||||
const T value = kInvalid;
|
||||
};
|
||||
|
||||
/// Index type used to index TableData::template_types
|
||||
using TemplateIndex = TableIndex<TableIndexNamespace::kTemplate, uint8_t>;
|
||||
|
||||
/// Index type used to index TableData::type_matchers or TableData::number_matchers
|
||||
using MatcherIndex = TableIndex<TableIndexNamespace::kMatcher, uint8_t>;
|
||||
|
||||
/// Index type used to index TableData::matcher_indices
|
||||
using MatcherIndicesIndex = TableIndex<TableIndexNamespace::kMatcherIndices, uint16_t>;
|
||||
|
||||
/// Index type used to index TableData::type_matchers
|
||||
using TypeMatcherIndex = TableIndex<TableIndexNamespace::kTypeMatcher, uint8_t>;
|
||||
|
||||
/// Index type used to index TableData::number_matchers
|
||||
using NumberMatcherIndex = TableIndex<TableIndexNamespace::kNumberMatcher, uint8_t>;
|
||||
|
||||
/// Index type used to index TableData::parameters
|
||||
using ParameterIndex = TableIndex<TableIndexNamespace::kParameter, uint16_t>;
|
||||
|
||||
/// Index type used to index TableData::overloads
|
||||
using OverloadIndex = TableIndex<TableIndexNamespace::kOverload, uint16_t>;
|
||||
|
||||
/// Index type used to index TableData::const_eval_functions
|
||||
using ConstEvalFunctionIndex = TableIndex<TableIndexNamespace::kConstEvalFunction, uint8_t>;
|
||||
|
||||
/// Unique flag bits for overloads
|
||||
enum class OverloadFlag : uint8_t {
|
||||
kIsBuiltin, // The overload is a builtin ('fn')
|
||||
kIsOperator, // The overload is an operator ('op')
|
||||
kIsConstructor, // The overload is a value constructor ('ctor')
|
||||
kIsConverter, // The overload is a value converter ('conv')
|
||||
kSupportsVertexPipeline, // The overload can be used in vertex shaders
|
||||
kSupportsFragmentPipeline, // The overload can be used in fragment shaders
|
||||
kSupportsComputePipeline, // The overload can be used in compute shaders
|
||||
kMustUse, // The overload cannot be called as a statement
|
||||
kMemberFunction, // The overload is a member function
|
||||
kIsDeprecated, // The overload is deprecated
|
||||
};
|
||||
|
||||
/// An enum set of OverloadFlag, used by OperatorInfo
|
||||
using OverloadFlags = tint::EnumSet<OverloadFlag>;
|
||||
|
||||
/// ParameterInfo describes a parameter
|
||||
struct ParameterInfo {
|
||||
/// The parameter usage (parameter name in definition file)
|
||||
const ParameterUsage usage;
|
||||
|
||||
/// Index of the matcher indices that are used to match the parameter types.
|
||||
/// These indices are consumed by the matchers themselves.
|
||||
const MatcherIndicesIndex matcher_indices;
|
||||
};
|
||||
|
||||
/// TemplateInfo describes an template
|
||||
struct TemplateInfo {
|
||||
/// An enumerator of template kind
|
||||
enum class Kind : uint8_t { kType, kNumber };
|
||||
|
||||
/// Name of the template type (e.g. 'T')
|
||||
const char* name;
|
||||
|
||||
/// Index of the type matcher indices that are used to match the template types.
|
||||
/// These indices are consumed by the matchers themselves.
|
||||
const MatcherIndicesIndex matcher_indices;
|
||||
|
||||
/// The template kind
|
||||
const Kind kind;
|
||||
};
|
||||
|
||||
/// OverloadInfo describes a single function overload
|
||||
struct OverloadInfo {
|
||||
/// The flags for the overload
|
||||
const OverloadFlags flags;
|
||||
/// Total number of parameters for the overload
|
||||
const uint8_t num_parameters;
|
||||
/// Total number of explicit templates for the overload
|
||||
const uint8_t num_explicit_templates;
|
||||
/// Total number of implicit and explicit templates for the overload
|
||||
const uint8_t num_templates;
|
||||
/// Index of the first template in TableData::templates
|
||||
/// This is a list of explicit template types followed by the implicit template types.
|
||||
const TemplateIndex templates;
|
||||
/// Index of the first parameter in TableData::parameters
|
||||
const ParameterIndex parameters;
|
||||
/// Index of a list of type matcher indices that are used to build the return type.
|
||||
const MatcherIndicesIndex return_matcher_indices;
|
||||
/// The function used to evaluate the overload at shader-creation time.
|
||||
const ConstEvalFunctionIndex const_eval_fn;
|
||||
};
|
||||
|
||||
/// IntrinsicInfo describes a builtin function or operator overload
|
||||
struct IntrinsicInfo {
|
||||
/// Number of overloads of the intrinsic
|
||||
const uint8_t num_overloads;
|
||||
/// Index of the first overload for the function
|
||||
const OverloadIndex overloads;
|
||||
};
|
||||
|
||||
/// A IntrinsicInfo with no overloads
|
||||
static constexpr IntrinsicInfo kNoOverloads{0, OverloadIndex(OverloadIndex::kInvalid)};
|
||||
|
||||
/// Number is an 32 bit unsigned integer, which can be in one of three states:
|
||||
/// * Invalid - Number has not been assigned a value
|
||||
/// * Valid - a fixed integer value
|
||||
/// * Any - matches any other non-invalid number
|
||||
class Number {
|
||||
enum State : uint8_t {
|
||||
kInvalid,
|
||||
kValid,
|
||||
kAny,
|
||||
};
|
||||
|
||||
constexpr explicit Number(State state) : state_(state) {}
|
||||
|
||||
public:
|
||||
/// A special number representing any number
|
||||
static const Number any;
|
||||
/// An invalid number
|
||||
static const Number invalid;
|
||||
|
||||
/// Constructed as a valid number with the value v
|
||||
/// @param v the value for the number
|
||||
explicit constexpr Number(uint32_t v) : value_(v), state_(kValid) {}
|
||||
|
||||
/// @returns the value of the number
|
||||
inline uint32_t Value() const { return value_; }
|
||||
|
||||
/// @returns the true if the number is valid
|
||||
inline bool IsValid() const { return state_ == kValid; }
|
||||
|
||||
/// @returns the true if the number is any
|
||||
inline bool IsAny() const { return state_ == kAny; }
|
||||
|
||||
/// Assignment operator.
|
||||
/// The number becomes valid, with the value n
|
||||
/// @param n the new value for the number
|
||||
/// @returns this so calls can be chained
|
||||
inline Number& operator=(uint32_t n) {
|
||||
value_ = n;
|
||||
state_ = kValid;
|
||||
return *this;
|
||||
}
|
||||
|
||||
private:
|
||||
uint32_t value_ = 0;
|
||||
State state_ = kInvalid;
|
||||
};
|
||||
|
||||
/// A special type that matches all TypeMatchers
|
||||
class Any final : public Castable<Any, core::type::Type> {
|
||||
public:
|
||||
Any();
|
||||
~Any() override;
|
||||
|
||||
/// @copydoc core::type::UniqueNode::Equals
|
||||
bool Equals(const core::type::UniqueNode& other) const override;
|
||||
/// @copydoc core::type::Type::FriendlyName
|
||||
std::string FriendlyName() const override;
|
||||
/// @copydoc core::type::Type::Clone
|
||||
core::type::Type* Clone(core::type::CloneContext& ctx) const override;
|
||||
};
|
||||
|
||||
/// TemplateState holds the state of the template numbers and types.
|
||||
/// Used by the MatchState.
|
||||
class TemplateState {
|
||||
public:
|
||||
/// If the template type with index @p idx is undefined, then it is defined with the @p ty
|
||||
/// and Type() returns @p ty. If the template type is defined, and @p ty can be converted to
|
||||
/// the template type then the template type is returned. If the template type is defined,
|
||||
/// and the template type can be converted to @p ty, then the template type is replaced with
|
||||
/// @p ty, and @p ty is returned. If none of the above applies, then @p ty is a type
|
||||
/// mismatch for the template type, and nullptr is returned.
|
||||
/// @param idx the index of the template type
|
||||
/// @param ty the type
|
||||
/// @returns true on match or newly defined
|
||||
const core::type::Type* Type(size_t idx, const core::type::Type* ty) {
|
||||
if (idx >= types_.Length()) {
|
||||
types_.Resize(idx + 1);
|
||||
}
|
||||
auto& t = types_[idx];
|
||||
if (t == nullptr) {
|
||||
t = ty;
|
||||
return ty;
|
||||
}
|
||||
ty = core::type::Type::Common(Vector{t, ty});
|
||||
if (ty) {
|
||||
t = ty;
|
||||
}
|
||||
return ty;
|
||||
}
|
||||
|
||||
/// If the number with index @p idx is undefined, then it is defined with the number
|
||||
/// `number` and Num() returns true. If the number is defined, then `Num()` returns true iff
|
||||
/// it is equal to @p ty.
|
||||
/// @param idx the index of the template number
|
||||
/// @param number the number
|
||||
/// @returns true on match or newly defined
|
||||
bool Num(size_t idx, Number number) {
|
||||
if (idx >= numbers_.Length()) {
|
||||
numbers_.Resize(idx + 1, Number::any);
|
||||
}
|
||||
auto& n = numbers_[idx];
|
||||
if (n.IsAny()) {
|
||||
n = number.Value();
|
||||
return true;
|
||||
}
|
||||
return n.Value() == number.Value();
|
||||
}
|
||||
|
||||
/// @param idx the index of the template type
|
||||
/// @returns the template type with index @p idx, or nullptr if the type was not
|
||||
/// defined.
|
||||
const core::type::Type* Type(size_t idx) const {
|
||||
if (idx >= types_.Length()) {
|
||||
return nullptr;
|
||||
}
|
||||
return types_[idx];
|
||||
}
|
||||
|
||||
/// SetType replaces the template type with index @p idx with type @p ty.
|
||||
/// @param idx the index of the template type
|
||||
/// @param ty the new type for the template
|
||||
void SetType(size_t idx, const core::type::Type* ty) {
|
||||
if (idx >= types_.Length()) {
|
||||
types_.Resize(idx + 1);
|
||||
}
|
||||
types_[idx] = ty;
|
||||
}
|
||||
|
||||
/// @returns the number type with index @p idx.
|
||||
/// @param idx the index of the template number
|
||||
Number Num(size_t idx) const {
|
||||
if (idx >= numbers_.Length()) {
|
||||
return Number::invalid;
|
||||
}
|
||||
return numbers_[idx];
|
||||
}
|
||||
|
||||
/// SetNum replaces the template number with index @p idx with number @p num.
|
||||
/// @param idx the index of the template number
|
||||
/// @param num the new number for the template
|
||||
void SetNum(size_t idx, Number num) {
|
||||
if (idx >= numbers_.Length()) {
|
||||
numbers_.Resize(idx + 1, Number::any);
|
||||
}
|
||||
numbers_[idx] = num;
|
||||
}
|
||||
|
||||
/// @return the total number of type and number templates
|
||||
size_t Count() const { return types_.Length() + numbers_.Length(); }
|
||||
|
||||
private:
|
||||
Vector<const core::type::Type*, 4> types_;
|
||||
Vector<Number, 2> numbers_;
|
||||
};
|
||||
|
||||
/// The current overload match state
|
||||
/// MatchState holds the state used to match an overload.
|
||||
class MatchState {
|
||||
public:
|
||||
/// Constructor
|
||||
/// @param ty_mgr the type manager
|
||||
/// @param syms the symbol table
|
||||
/// @param t the template state
|
||||
/// @param d the table data
|
||||
/// @param o the current overload
|
||||
/// @param matcher_indices the remaining matcher indices
|
||||
/// @param s the required evaluation stage of the overload
|
||||
MatchState(core::type::Manager& ty_mgr,
|
||||
SymbolTable& syms,
|
||||
TemplateState& t,
|
||||
const TableData& d,
|
||||
const OverloadInfo& o,
|
||||
const MatcherIndex* matcher_indices,
|
||||
EvaluationStage s)
|
||||
: types(ty_mgr),
|
||||
symbols(syms),
|
||||
templates(t),
|
||||
data(d),
|
||||
overload(o),
|
||||
earliest_eval_stage(s),
|
||||
matcher_indices_(matcher_indices) {}
|
||||
|
||||
/// The type manager
|
||||
core::type::Manager& types;
|
||||
|
||||
/// The symbol manager
|
||||
SymbolTable& symbols;
|
||||
|
||||
/// The template types and numbers
|
||||
TemplateState& templates;
|
||||
|
||||
/// The table data
|
||||
const TableData& data;
|
||||
|
||||
/// The current overload being evaluated
|
||||
const OverloadInfo& overload;
|
||||
|
||||
/// The earliest evaluation stage of the builtin call
|
||||
EvaluationStage earliest_eval_stage;
|
||||
|
||||
/// Type uses the next TypeMatcher from the matcher indices to match the type @p ty.
|
||||
/// @param ty the type to try matching
|
||||
/// @returns the canonical expected type if the type matches, otherwise nullptr.
|
||||
/// @note: The matcher indices are progressed on calling.
|
||||
inline const core::type::Type* Type(const core::type::Type* ty);
|
||||
|
||||
/// Num uses the next NumMatcher from the matcher indices to match @p number.
|
||||
/// @param number the number to try matching
|
||||
/// @returns the canonical expected number if the number matches, otherwise an invalid
|
||||
/// number.
|
||||
/// @note: The matcher indices are progressed on calling.
|
||||
inline Number Num(Number number);
|
||||
|
||||
/// Prints the type matcher representation to @p out
|
||||
/// @note: The matcher indices are progressed on calling.
|
||||
inline void PrintType(StyledText& out);
|
||||
|
||||
/// Prints the number matcher representation to @p out
|
||||
/// @note: The matcher indices are progressed on calling.
|
||||
inline void PrintNum(StyledText& out);
|
||||
|
||||
private:
|
||||
const MatcherIndex* matcher_indices_ = nullptr;
|
||||
};
|
||||
|
||||
/// A TypeMatcher is the interface used to match an type used as part of an
|
||||
/// overload's parameter or return type.
|
||||
struct TypeMatcher {
|
||||
/// Checks whether the given type matches the matcher rules, and returns the
|
||||
/// expected, canonicalized type on success.
|
||||
/// Match may define and refine the template types and numbers in state.
|
||||
/// The parameter `type` is the type to match
|
||||
/// Returns the canonicalized type on match, otherwise nullptr
|
||||
using MatchFn = const core::type::Type*(MatchState& state, const core::type::Type* type);
|
||||
|
||||
/// @see #MatchFn
|
||||
MatchFn* const match;
|
||||
|
||||
/// Prints the representation of the matcher.
|
||||
/// Used for printing error messages when no overload is found.
|
||||
using PrintFn = void(MatchState* state, StyledText& out);
|
||||
|
||||
/// @see #PrintFn
|
||||
PrintFn* const print;
|
||||
};
|
||||
|
||||
/// A NumberMatcher is the interface used to match a number or enumerator used
|
||||
/// as part of an overload's parameter or return type.
|
||||
struct NumberMatcher {
|
||||
/// Checks whether the given number matches the matcher rules.
|
||||
/// Match may define template numbers in state.
|
||||
/// The parameter `number` is the number to match
|
||||
/// Returns true if the argument type is as expected.
|
||||
using MatchFn = Number(MatchState& state, Number number);
|
||||
|
||||
/// @see #MatchFn
|
||||
MatchFn* const match;
|
||||
|
||||
/// Prints the representation of the matcher.
|
||||
/// Used for printing error messages when no overload is found.
|
||||
using PrintFn = void(MatchState* state, StyledText& out);
|
||||
|
||||
/// @see #PrintFn
|
||||
PrintFn* const print;
|
||||
};
|
||||
|
||||
/// TableData holds the immutable data that holds the intrinsic data for a language.
|
||||
struct TableData {
|
||||
/// @param idx the index of the TemplateInfo in the table data
|
||||
/// @returns the TemplateInfo with the given index
|
||||
template <typename T>
|
||||
const TemplateInfo& operator[](TableIndex<TableIndexNamespace::kTemplate, T> idx) const {
|
||||
return templates[idx.value];
|
||||
}
|
||||
|
||||
/// @param idx the index of the MatcherIndices in the table data
|
||||
/// @returns the MatcherIndices with the given index
|
||||
template <typename T>
|
||||
const MatcherIndex* operator[](TableIndex<TableIndexNamespace::kMatcherIndices, T> idx) const {
|
||||
if (idx.IsValid()) {
|
||||
return &matcher_indices[idx.value];
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/// @param idx the index of the TypeMatcher in the table data
|
||||
/// @returns the TypeMatcher with the given index
|
||||
template <typename T>
|
||||
const TypeMatcher& operator[](TableIndex<TableIndexNamespace::kTypeMatcher, T> idx) const {
|
||||
return type_matchers[idx.value];
|
||||
}
|
||||
|
||||
/// @param idx the index of the NumberMatcher in the table data
|
||||
/// @returns the NumberMatcher with the given index
|
||||
template <typename T>
|
||||
const NumberMatcher& operator[](TableIndex<TableIndexNamespace::kNumberMatcher, T> idx) const {
|
||||
return number_matchers[idx.value];
|
||||
}
|
||||
|
||||
/// @param idx the index of the ParameterInfo in the table data
|
||||
/// @returns the ParameterInfo with the given index
|
||||
template <typename T>
|
||||
const ParameterInfo& operator[](TableIndex<TableIndexNamespace::kParameter, T> idx) const {
|
||||
return parameters[idx.value];
|
||||
}
|
||||
|
||||
/// @param idx the index of the OverloadInfo in the table data
|
||||
/// @returns the OverloadInfo with the given index
|
||||
template <typename T>
|
||||
const OverloadInfo& operator[](TableIndex<TableIndexNamespace::kOverload, T> idx) const {
|
||||
return overloads[idx.value];
|
||||
}
|
||||
|
||||
/// @param idx the index of the constant::Eval::Function in the table data
|
||||
/// @returns the constant::Eval::Function with the given index
|
||||
template <typename T>
|
||||
constant::Eval::Function operator[](
|
||||
TableIndex<TableIndexNamespace::kConstEvalFunction, T> idx) const {
|
||||
return idx.IsValid() ? const_eval_functions[idx.value] : nullptr;
|
||||
}
|
||||
|
||||
/// The list of templates used by the intrinsic overloads
|
||||
const Slice<const TemplateInfo> templates;
|
||||
/// The list of type matcher indices
|
||||
const Slice<const MatcherIndex> matcher_indices;
|
||||
/// The list of type matchers used by the intrinsic overloads
|
||||
const Slice<const TypeMatcher> type_matchers;
|
||||
/// The list of number matchers used by the intrinsic overloads
|
||||
const Slice<const NumberMatcher> number_matchers;
|
||||
/// The list of parameters used by the intrinsic overloads
|
||||
const Slice<const ParameterInfo> parameters;
|
||||
/// The list of overloads used by the intrinsics
|
||||
const Slice<const OverloadInfo> overloads;
|
||||
/// The list of constant evaluation functions used by the intrinsics
|
||||
const Slice<const constant::Eval::Function> const_eval_functions;
|
||||
/// The type constructor and convertor intrinsics
|
||||
const Slice<const IntrinsicInfo> ctor_conv;
|
||||
/// The builtin function intrinsic
|
||||
const Slice<const IntrinsicInfo> builtins;
|
||||
/// The IntrinsicInfo for the binary operator 'plus'
|
||||
const IntrinsicInfo& binary_plus;
|
||||
/// The IntrinsicInfo for the binary operator 'minus'
|
||||
const IntrinsicInfo& binary_minus;
|
||||
/// The IntrinsicInfo for the binary operator 'star'
|
||||
const IntrinsicInfo& binary_star;
|
||||
/// The IntrinsicInfo for the binary operator 'divide'
|
||||
const IntrinsicInfo& binary_divide;
|
||||
/// The IntrinsicInfo for the binary operator 'modulo'
|
||||
const IntrinsicInfo& binary_modulo;
|
||||
/// The IntrinsicInfo for the binary operator 'xor'
|
||||
const IntrinsicInfo& binary_xor;
|
||||
/// The IntrinsicInfo for the binary operator 'and'
|
||||
const IntrinsicInfo& binary_and;
|
||||
/// The IntrinsicInfo for the binary operator 'or'
|
||||
const IntrinsicInfo& binary_or;
|
||||
/// The IntrinsicInfo for the binary operator 'logical_and'
|
||||
const IntrinsicInfo& binary_logical_and;
|
||||
/// The IntrinsicInfo for the binary operator 'logical_or'
|
||||
const IntrinsicInfo& binary_logical_or;
|
||||
/// The IntrinsicInfo for the binary operator 'equal'
|
||||
const IntrinsicInfo& binary_equal;
|
||||
/// The IntrinsicInfo for the binary operator 'not_equal'
|
||||
const IntrinsicInfo& binary_not_equal;
|
||||
/// The IntrinsicInfo for the binary operator 'less_than'
|
||||
const IntrinsicInfo& binary_less_than;
|
||||
/// The IntrinsicInfo for the binary operator 'greater_than'
|
||||
const IntrinsicInfo& binary_greater_than;
|
||||
/// The IntrinsicInfo for the binary operator 'less_than_equal'
|
||||
const IntrinsicInfo& binary_less_than_equal;
|
||||
/// The IntrinsicInfo for the binary operator 'greater_than_equal'
|
||||
const IntrinsicInfo& binary_greater_than_equal;
|
||||
/// The IntrinsicInfo for the binary operator 'shift_left'
|
||||
const IntrinsicInfo& binary_shift_left;
|
||||
/// The IntrinsicInfo for the binary operator 'shift_right'
|
||||
const IntrinsicInfo& binary_shift_right;
|
||||
/// The IntrinsicInfo for the unary operator 'not'
|
||||
const IntrinsicInfo& unary_not;
|
||||
/// The IntrinsicInfo for the unary operator 'complement'
|
||||
const IntrinsicInfo& unary_complement;
|
||||
/// The IntrinsicInfo for the unary operator 'minus'
|
||||
const IntrinsicInfo& unary_minus;
|
||||
/// The IntrinsicInfo for the unary operator 'star'
|
||||
const IntrinsicInfo& unary_star;
|
||||
/// The IntrinsicInfo for the unary operator 'and'
|
||||
const IntrinsicInfo& unary_and;
|
||||
};
|
||||
|
||||
TINT_BEGIN_DISABLE_WARNING(UNSAFE_BUFFER_USAGE);
|
||||
const core::type::Type* MatchState::Type(const core::type::Type* ty) {
|
||||
TypeMatcherIndex matcher_index{(*matcher_indices_++).value};
|
||||
auto& matcher = data[matcher_index];
|
||||
return matcher.match(*this, ty);
|
||||
}
|
||||
|
||||
Number MatchState::Num(Number number) {
|
||||
NumberMatcherIndex matcher_index{(*matcher_indices_++).value};
|
||||
auto& matcher = data[matcher_index];
|
||||
return matcher.match(*this, number);
|
||||
}
|
||||
|
||||
void MatchState::PrintType(StyledText& out) {
|
||||
TypeMatcherIndex matcher_index{(*matcher_indices_++).value};
|
||||
auto& matcher = data[matcher_index];
|
||||
matcher.print(this, out);
|
||||
}
|
||||
|
||||
void MatchState::PrintNum(StyledText& out) {
|
||||
NumberMatcherIndex matcher_index{(*matcher_indices_++).value};
|
||||
auto& matcher = data[matcher_index];
|
||||
matcher.print(this, out);
|
||||
}
|
||||
TINT_END_DISABLE_WARNING(UNSAFE_BUFFER_USAGE);
|
||||
|
||||
/// TemplateTypeMatcher is a Matcher for a template type.
|
||||
/// The TemplateTypeMatcher will initially match against any type, and then will only be further
|
||||
/// constrained based on the conversion rules defined at
|
||||
/// https://www.w3.org/TR/WGSL/#conversion-rank
|
||||
template <size_t INDEX>
|
||||
struct TemplateTypeMatcher {
|
||||
/// The TypeMatcher for the template type with the index `INDEX`
|
||||
static constexpr TypeMatcher matcher{
|
||||
/* match */
|
||||
[](MatchState& state, const core::type::Type* type) -> const core::type::Type* {
|
||||
if (type->Is<Any>()) {
|
||||
return state.templates.Type(INDEX);
|
||||
}
|
||||
if (auto* templates = state.templates.Type(INDEX, type)) {
|
||||
return templates;
|
||||
}
|
||||
return nullptr;
|
||||
},
|
||||
/* print */
|
||||
[](MatchState* state, StyledText& out) {
|
||||
out << style::Type(state->data[state->overload.templates + INDEX].name);
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
/// TemplateNumberMatcher is a Matcher for a template number.
|
||||
/// The TemplateNumberMatcher will match against any number (so long as it is
|
||||
/// consistent for all uses in the overload)
|
||||
template <size_t INDEX>
|
||||
struct TemplateNumberMatcher {
|
||||
/// The NumberMatcher for the template number with the index `INDEX`
|
||||
static constexpr NumberMatcher matcher{
|
||||
/* match */
|
||||
[](MatchState& state, Number number) -> Number {
|
||||
if (number.IsAny()) {
|
||||
return state.templates.Num(INDEX);
|
||||
}
|
||||
return state.templates.Num(INDEX, number) ? number : Number::invalid;
|
||||
},
|
||||
/* print */
|
||||
[](MatchState* state, StyledText& out) {
|
||||
out << style::Variable(state->data[state->overload.templates + INDEX].name);
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
} // namespace tint::core::intrinsic
|
||||
|
||||
#endif // SRC_TINT_LANG_CORE_INTRINSIC_TABLE_DATA_H_
|
||||
824
3rdparty/dawn/src/tint/lang/core/intrinsic/type_matchers.h
vendored
Normal file
824
3rdparty/dawn/src/tint/lang/core/intrinsic/type_matchers.h
vendored
Normal file
@@ -0,0 +1,824 @@
|
||||
// Copyright 2023 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.
|
||||
|
||||
#ifndef SRC_TINT_LANG_CORE_INTRINSIC_TYPE_MATCHERS_H_
|
||||
#define SRC_TINT_LANG_CORE_INTRINSIC_TYPE_MATCHERS_H_
|
||||
|
||||
#include "src/tint/lang/core/evaluation_stage.h"
|
||||
#include "src/tint/lang/core/intrinsic/table_data.h"
|
||||
#include "src/tint/lang/core/type/abstract_float.h"
|
||||
#include "src/tint/lang/core/type/abstract_int.h"
|
||||
#include "src/tint/lang/core/type/abstract_numeric.h"
|
||||
#include "src/tint/lang/core/type/array.h"
|
||||
#include "src/tint/lang/core/type/atomic.h"
|
||||
#include "src/tint/lang/core/type/binding_array.h"
|
||||
#include "src/tint/lang/core/type/bool.h"
|
||||
#include "src/tint/lang/core/type/builtin_structs.h"
|
||||
#include "src/tint/lang/core/type/depth_multisampled_texture.h"
|
||||
#include "src/tint/lang/core/type/depth_texture.h"
|
||||
#include "src/tint/lang/core/type/external_texture.h"
|
||||
#include "src/tint/lang/core/type/f16.h"
|
||||
#include "src/tint/lang/core/type/f32.h"
|
||||
#include "src/tint/lang/core/type/i32.h"
|
||||
#include "src/tint/lang/core/type/i8.h"
|
||||
#include "src/tint/lang/core/type/input_attachment.h"
|
||||
#include "src/tint/lang/core/type/manager.h"
|
||||
#include "src/tint/lang/core/type/matrix.h"
|
||||
#include "src/tint/lang/core/type/multisampled_texture.h"
|
||||
#include "src/tint/lang/core/type/pointer.h"
|
||||
#include "src/tint/lang/core/type/reference.h"
|
||||
#include "src/tint/lang/core/type/sampled_texture.h"
|
||||
#include "src/tint/lang/core/type/storage_texture.h"
|
||||
#include "src/tint/lang/core/type/string.h"
|
||||
#include "src/tint/lang/core/type/texture_dimension.h"
|
||||
#include "src/tint/lang/core/type/u32.h"
|
||||
#include "src/tint/lang/core/type/u64.h"
|
||||
#include "src/tint/lang/core/type/u8.h"
|
||||
#include "src/tint/lang/core/type/vector.h"
|
||||
|
||||
//! @cond Doxygen_Suppress
|
||||
|
||||
namespace tint::core::intrinsic {
|
||||
|
||||
inline bool MatchBool(intrinsic::MatchState&, const type::Type* ty) {
|
||||
return ty->IsAnyOf<intrinsic::Any, type::Bool>();
|
||||
}
|
||||
|
||||
inline const type::Bool* BuildBool(intrinsic::MatchState& state, const type::Type*) {
|
||||
return state.types.bool_();
|
||||
}
|
||||
|
||||
inline const type::F16* BuildF16(intrinsic::MatchState& state, const type::Type*) {
|
||||
return state.types.f16();
|
||||
}
|
||||
|
||||
inline bool MatchF16(intrinsic::MatchState&, const type::Type* ty) {
|
||||
return ty->IsAnyOf<intrinsic::Any, type::F16, type::AbstractNumeric>();
|
||||
}
|
||||
|
||||
inline const type::F32* BuildF32(intrinsic::MatchState& state, const type::Type*) {
|
||||
return state.types.f32();
|
||||
}
|
||||
|
||||
inline bool MatchF32(intrinsic::MatchState&, const type::Type* ty) {
|
||||
return ty->IsAnyOf<intrinsic::Any, type::F32, type::AbstractNumeric>();
|
||||
}
|
||||
|
||||
inline const type::I32* BuildI32(intrinsic::MatchState& state, const type::Type*) {
|
||||
return state.types.i32();
|
||||
}
|
||||
|
||||
inline bool MatchI32(intrinsic::MatchState&, const type::Type* ty) {
|
||||
return ty->IsAnyOf<intrinsic::Any, type::I32, type::AbstractInt>();
|
||||
}
|
||||
|
||||
inline const type::I8* BuildI8(intrinsic::MatchState& state, const type::Type*) {
|
||||
return state.types.i8();
|
||||
}
|
||||
|
||||
inline bool MatchI8(intrinsic::MatchState&, const type::Type* ty) {
|
||||
return ty->IsAnyOf<intrinsic::Any, type::I8, type::AbstractInt>();
|
||||
}
|
||||
|
||||
inline const type::U32* BuildU32(intrinsic::MatchState& state, const type::Type*) {
|
||||
return state.types.u32();
|
||||
}
|
||||
|
||||
inline bool MatchU32(intrinsic::MatchState&, const type::Type* ty) {
|
||||
return ty->IsAnyOf<intrinsic::Any, type::U32, type::AbstractInt>();
|
||||
}
|
||||
|
||||
inline const type::U64* BuildU64(intrinsic::MatchState& state, const type::Type*) {
|
||||
return state.types.u64();
|
||||
}
|
||||
|
||||
inline bool MatchU64(intrinsic::MatchState&, const type::Type* ty) {
|
||||
return ty->IsAnyOf<intrinsic::Any, type::U64, type::AbstractInt>();
|
||||
}
|
||||
|
||||
inline const type::U8* BuildU8(intrinsic::MatchState& state, const type::Type*) {
|
||||
return state.types.u8();
|
||||
}
|
||||
|
||||
inline bool MatchU8(intrinsic::MatchState&, const type::Type* ty) {
|
||||
return ty->IsAnyOf<intrinsic::Any, type::U8, type::AbstractInt>();
|
||||
}
|
||||
|
||||
inline bool MatchVec(intrinsic::MatchState&,
|
||||
const type::Type* ty,
|
||||
intrinsic::Number& N,
|
||||
const type::Type*& T) {
|
||||
if (ty->Is<intrinsic::Any>()) {
|
||||
N = intrinsic::Number::any;
|
||||
T = ty;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (auto* v = ty->As<type::Vector>()) {
|
||||
N = v->Width();
|
||||
T = v->Type();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
template <uint32_t N>
|
||||
inline bool MatchVec(intrinsic::MatchState&, const type::Type* ty, const type::Type*& T) {
|
||||
if (ty->Is<intrinsic::Any>()) {
|
||||
T = ty;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (auto* v = ty->As<type::Vector>()) {
|
||||
if (v->Width() == N) {
|
||||
T = v->Type();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
inline const type::Vector* BuildVec(intrinsic::MatchState& state,
|
||||
const type::Type*,
|
||||
intrinsic::Number N,
|
||||
const type::Type* el) {
|
||||
return state.types.vec(el, N.Value());
|
||||
}
|
||||
|
||||
template <uint32_t N>
|
||||
inline const type::Vector* BuildVec(intrinsic::MatchState& state,
|
||||
const type::Type*,
|
||||
const type::Type* el) {
|
||||
return state.types.vec(el, N);
|
||||
}
|
||||
|
||||
constexpr auto MatchVec2 = MatchVec<2>;
|
||||
constexpr auto MatchVec3 = MatchVec<3>;
|
||||
constexpr auto MatchVec4 = MatchVec<4>;
|
||||
|
||||
constexpr auto BuildVec2 = BuildVec<2>;
|
||||
constexpr auto BuildVec3 = BuildVec<3>;
|
||||
constexpr auto BuildVec4 = BuildVec<4>;
|
||||
|
||||
inline bool MatchPackedVec3(intrinsic::MatchState&, const type::Type* ty, const type::Type*& T) {
|
||||
if (ty->Is<intrinsic::Any>()) {
|
||||
T = ty;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (auto* v = ty->As<type::Vector>()) {
|
||||
if (v->Packed()) {
|
||||
T = v->Type();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
inline const type::Vector* BuildPackedVec3(intrinsic::MatchState& state,
|
||||
const type::Type*,
|
||||
const type::Type* el) {
|
||||
return state.types.packed_vec(el, 3u);
|
||||
}
|
||||
|
||||
inline bool MatchMat(intrinsic::MatchState&,
|
||||
const type::Type* ty,
|
||||
intrinsic::Number& M,
|
||||
intrinsic::Number& N,
|
||||
const type::Type*& T) {
|
||||
if (ty->Is<intrinsic::Any>()) {
|
||||
M = intrinsic::Number::any;
|
||||
N = intrinsic::Number::any;
|
||||
T = ty;
|
||||
return true;
|
||||
}
|
||||
if (auto* m = ty->As<type::Matrix>()) {
|
||||
M = m->Columns();
|
||||
N = m->ColumnType()->Width();
|
||||
T = m->Type();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
template <uint32_t C, uint32_t R>
|
||||
inline bool MatchMat(intrinsic::MatchState&, const type::Type* ty, const type::Type*& T) {
|
||||
if (ty->Is<intrinsic::Any>()) {
|
||||
T = ty;
|
||||
return true;
|
||||
}
|
||||
if (auto* m = ty->As<type::Matrix>()) {
|
||||
if (m->Columns() == C && m->Rows() == R) {
|
||||
T = m->Type();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
inline const type::Matrix* BuildMat(intrinsic::MatchState& state,
|
||||
const type::Type*,
|
||||
intrinsic::Number C,
|
||||
intrinsic::Number R,
|
||||
const type::Type* T) {
|
||||
auto* column_type = state.types.vec(T, R.Value());
|
||||
return state.types.mat(column_type, C.Value());
|
||||
}
|
||||
|
||||
template <uint32_t C, uint32_t R>
|
||||
inline const type::Matrix* BuildMat(intrinsic::MatchState& state,
|
||||
const type::Type*,
|
||||
const type::Type* T) {
|
||||
auto* column_type = state.types.vec(T, R);
|
||||
return state.types.mat(column_type, C);
|
||||
}
|
||||
|
||||
constexpr auto BuildMat2X2 = BuildMat<2, 2>;
|
||||
constexpr auto BuildMat2X3 = BuildMat<2, 3>;
|
||||
constexpr auto BuildMat2X4 = BuildMat<2, 4>;
|
||||
constexpr auto BuildMat3X2 = BuildMat<3, 2>;
|
||||
constexpr auto BuildMat3X3 = BuildMat<3, 3>;
|
||||
constexpr auto BuildMat3X4 = BuildMat<3, 4>;
|
||||
constexpr auto BuildMat4X2 = BuildMat<4, 2>;
|
||||
constexpr auto BuildMat4X3 = BuildMat<4, 3>;
|
||||
constexpr auto BuildMat4X4 = BuildMat<4, 4>;
|
||||
|
||||
constexpr auto MatchMat2X2 = MatchMat<2, 2>;
|
||||
constexpr auto MatchMat2X3 = MatchMat<2, 3>;
|
||||
constexpr auto MatchMat2X4 = MatchMat<2, 4>;
|
||||
constexpr auto MatchMat3X2 = MatchMat<3, 2>;
|
||||
constexpr auto MatchMat3X3 = MatchMat<3, 3>;
|
||||
constexpr auto MatchMat3X4 = MatchMat<3, 4>;
|
||||
constexpr auto MatchMat4X2 = MatchMat<4, 2>;
|
||||
constexpr auto MatchMat4X3 = MatchMat<4, 3>;
|
||||
constexpr auto MatchMat4X4 = MatchMat<4, 4>;
|
||||
|
||||
inline bool MatchSubgroupMatrix(intrinsic::MatchState&,
|
||||
const type::Type* ty,
|
||||
intrinsic::Number& S,
|
||||
const type::Type*& T,
|
||||
intrinsic::Number& A,
|
||||
intrinsic::Number& B) {
|
||||
if (ty->Is<intrinsic::Any>()) {
|
||||
A = intrinsic::Number::any;
|
||||
B = intrinsic::Number::any;
|
||||
S = intrinsic::Number::any;
|
||||
T = ty;
|
||||
return true;
|
||||
}
|
||||
if (auto* sm = ty->As<type::SubgroupMatrix>()) {
|
||||
A = sm->Columns();
|
||||
B = sm->Rows();
|
||||
S = intrinsic::Number(static_cast<uint32_t>(sm->Kind()));
|
||||
T = sm->Type();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
inline const type::SubgroupMatrix* BuildSubgroupMatrix(intrinsic::MatchState& state,
|
||||
const type::Type*,
|
||||
intrinsic::Number S,
|
||||
const type::Type* T,
|
||||
intrinsic::Number A,
|
||||
intrinsic::Number B) {
|
||||
return state.types.subgroup_matrix(static_cast<core::SubgroupMatrixKind>(S.Value()), T,
|
||||
A.Value(), B.Value());
|
||||
}
|
||||
|
||||
inline bool MatchUnsizedBuffer(intrinsic::MatchState&, const type::Type* ty) {
|
||||
if (ty->Is<intrinsic::Any>()) {
|
||||
return true;
|
||||
}
|
||||
if (auto* b = ty->As<type::Buffer>()) {
|
||||
return b->Size() == 0;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
inline const type::Buffer* BuildUnsizedBuffer(intrinsic::MatchState& state, const type::Type*) {
|
||||
return state.types.unsized_buffer();
|
||||
}
|
||||
|
||||
inline bool MatchBuffer(intrinsic::MatchState&, const type::Type* ty, intrinsic::Number& N) {
|
||||
if (ty->Is<intrinsic::Any>()) {
|
||||
N = intrinsic::Number::any;
|
||||
return true;
|
||||
}
|
||||
if (auto* b = ty->As<type::Buffer>()) {
|
||||
if (b->Size() != 0) {
|
||||
N = b->Size();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
inline const type::Buffer* BuildBuffer(intrinsic::MatchState& state,
|
||||
const type::Type*,
|
||||
intrinsic::Number N) {
|
||||
return state.types.buffer(N.Value());
|
||||
}
|
||||
|
||||
inline bool MatchArray(intrinsic::MatchState&,
|
||||
const type::Type* ty,
|
||||
const type::Type*& T,
|
||||
intrinsic::Number& C) {
|
||||
if (ty->Is<intrinsic::Any>()) {
|
||||
T = ty;
|
||||
C = intrinsic::Number::any;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (auto* a = ty->As<type::Array>()) {
|
||||
if (auto count = a->Count()->As<type::ConstantArrayCount>()) {
|
||||
T = a->ElemType();
|
||||
C = intrinsic::Number(count->value);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
inline const type::Array* BuildArray(intrinsic::MatchState& state,
|
||||
const type::Type*,
|
||||
const type::Type* el,
|
||||
intrinsic::Number C) {
|
||||
return state.types.array(el, C.Value());
|
||||
}
|
||||
|
||||
inline bool MatchRuntimeArray(intrinsic::MatchState&, const type::Type* ty, const type::Type*& T) {
|
||||
if (ty->Is<intrinsic::Any>()) {
|
||||
T = ty;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (auto* a = ty->As<type::Array>()) {
|
||||
if (a->Count()->Is<type::RuntimeArrayCount>()) {
|
||||
T = a->ElemType();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
inline const type::Array* BuildRuntimeArray(intrinsic::MatchState& state,
|
||||
const type::Type*,
|
||||
const type::Type* el) {
|
||||
return state.types.runtime_array(el);
|
||||
}
|
||||
|
||||
inline const type::BindingArray* BuildBindingArray(intrinsic::MatchState& state,
|
||||
const type::Type*,
|
||||
const type::Type* el,
|
||||
intrinsic::Number N) {
|
||||
return state.types.binding_array(el, N.Value());
|
||||
}
|
||||
|
||||
inline bool MatchBindingArray(intrinsic::MatchState&,
|
||||
const type::Type* ty,
|
||||
const type::Type*& T,
|
||||
intrinsic::Number& N) {
|
||||
if (ty->Is<intrinsic::Any>()) {
|
||||
N = intrinsic::Number::any;
|
||||
T = ty;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (auto* a = ty->As<type::BindingArray>()) {
|
||||
if (auto count = a->Count()->As<type::ConstantArrayCount>()) {
|
||||
N = intrinsic::Number(count->value);
|
||||
T = a->ElemType();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
inline bool MatchPtr(intrinsic::MatchState&,
|
||||
const type::Type* ty,
|
||||
intrinsic::Number& S,
|
||||
const type::Type*& T,
|
||||
intrinsic::Number& A) {
|
||||
if (ty->Is<intrinsic::Any>()) {
|
||||
S = intrinsic::Number::any;
|
||||
T = ty;
|
||||
A = intrinsic::Number::any;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (auto* p = ty->As<type::Pointer>()) {
|
||||
S = intrinsic::Number(static_cast<uint32_t>(p->AddressSpace()));
|
||||
T = p->StoreType();
|
||||
A = intrinsic::Number(static_cast<uint32_t>(p->Access()));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
inline const type::Pointer* BuildPtr(intrinsic::MatchState& state,
|
||||
const type::Type*,
|
||||
intrinsic::Number S,
|
||||
const type::Type* T,
|
||||
intrinsic::Number& A) {
|
||||
return state.types.ptr(static_cast<core::AddressSpace>(S.Value()), T,
|
||||
static_cast<core::Access>(A.Value()));
|
||||
}
|
||||
|
||||
inline bool MatchRef(intrinsic::MatchState&,
|
||||
const type::Type* ty,
|
||||
intrinsic::Number& S,
|
||||
const type::Type*& T,
|
||||
intrinsic::Number& A) {
|
||||
if (ty->Is<intrinsic::Any>()) {
|
||||
S = intrinsic::Number::any;
|
||||
T = ty;
|
||||
A = intrinsic::Number::any;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (auto* p = ty->As<type::Reference>()) {
|
||||
S = intrinsic::Number(static_cast<uint32_t>(p->AddressSpace()));
|
||||
T = p->StoreType();
|
||||
A = intrinsic::Number(static_cast<uint32_t>(p->Access()));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
inline const type::Reference* BuildRef(intrinsic::MatchState& state,
|
||||
const type::Type*,
|
||||
intrinsic::Number S,
|
||||
const type::Type* T,
|
||||
intrinsic::Number& A) {
|
||||
return state.types.ref(static_cast<core::AddressSpace>(S.Value()), T,
|
||||
static_cast<core::Access>(A.Value()));
|
||||
}
|
||||
|
||||
inline bool MatchAtomic(intrinsic::MatchState&, const type::Type* ty, const type::Type*& T) {
|
||||
if (ty->Is<intrinsic::Any>()) {
|
||||
T = ty;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (auto* a = ty->As<type::Atomic>()) {
|
||||
T = a->Type();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
inline const type::Atomic* BuildAtomic(intrinsic::MatchState& state,
|
||||
const type::Type*,
|
||||
const type::Type* T) {
|
||||
return state.types.atomic(T);
|
||||
}
|
||||
|
||||
inline bool MatchSampler(intrinsic::MatchState&, const type::Type* ty) {
|
||||
if (ty->Is<intrinsic::Any>()) {
|
||||
return true;
|
||||
}
|
||||
return ty->Is([](const type::Sampler* s) { return s->Kind() == type::SamplerKind::kSampler; });
|
||||
}
|
||||
|
||||
inline const type::Sampler* BuildSampler(intrinsic::MatchState& state, const type::Type*) {
|
||||
return state.types.sampler();
|
||||
}
|
||||
|
||||
inline bool MatchSamplerComparison(intrinsic::MatchState&, const type::Type* ty) {
|
||||
if (ty->Is<intrinsic::Any>()) {
|
||||
return true;
|
||||
}
|
||||
return ty->Is(
|
||||
[](const type::Sampler* s) { return s->Kind() == type::SamplerKind::kComparisonSampler; });
|
||||
}
|
||||
|
||||
inline const type::Sampler* BuildSamplerComparison(intrinsic::MatchState& state,
|
||||
const type::Type*) {
|
||||
return state.types.comparison_sampler();
|
||||
}
|
||||
|
||||
inline bool MatchTexture(intrinsic::MatchState&,
|
||||
const type::Type* ty,
|
||||
type::TextureDimension dim,
|
||||
const type::Type*& T) {
|
||||
if (ty->Is<intrinsic::Any>()) {
|
||||
T = ty;
|
||||
return true;
|
||||
}
|
||||
if (auto* v = ty->As<type::SampledTexture>()) {
|
||||
if (v->Dim() == dim) {
|
||||
T = v->Type();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
#define JOIN(a, b) a##b
|
||||
|
||||
#define DECLARE_SAMPLED_TEXTURE(suffix, dim) \
|
||||
inline bool JOIN(MatchTexture, suffix)(intrinsic::MatchState & state, const type::Type* ty, \
|
||||
const type::Type*& T) { \
|
||||
return MatchTexture(state, ty, dim, T); \
|
||||
} \
|
||||
inline const type::SampledTexture* JOIN(BuildTexture, suffix)( \
|
||||
intrinsic::MatchState & state, const type::Type*, const type::Type* T) { \
|
||||
return state.types.sampled_texture(dim, T); \
|
||||
}
|
||||
|
||||
DECLARE_SAMPLED_TEXTURE(1D, type::TextureDimension::k1d)
|
||||
DECLARE_SAMPLED_TEXTURE(2D, type::TextureDimension::k2d)
|
||||
DECLARE_SAMPLED_TEXTURE(2DArray, type::TextureDimension::k2dArray)
|
||||
DECLARE_SAMPLED_TEXTURE(3D, type::TextureDimension::k3d)
|
||||
DECLARE_SAMPLED_TEXTURE(Cube, type::TextureDimension::kCube)
|
||||
DECLARE_SAMPLED_TEXTURE(CubeArray, type::TextureDimension::kCubeArray)
|
||||
#undef DECLARE_SAMPLED_TEXTURE
|
||||
|
||||
inline bool MatchTextureMultisampled(intrinsic::MatchState&,
|
||||
const type::Type* ty,
|
||||
type::TextureDimension dim,
|
||||
const type::Type*& T) {
|
||||
if (ty->Is<intrinsic::Any>()) {
|
||||
T = ty;
|
||||
return true;
|
||||
}
|
||||
if (auto* v = ty->As<type::MultisampledTexture>()) {
|
||||
if (v->Dim() == dim) {
|
||||
T = v->Type();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
#define DECLARE_MULTISAMPLED_TEXTURE(suffix, dim) \
|
||||
inline bool JOIN(MatchTextureMultisampled, suffix)( \
|
||||
intrinsic::MatchState & state, const type::Type* ty, const type::Type*& T) { \
|
||||
return MatchTextureMultisampled(state, ty, dim, T); \
|
||||
} \
|
||||
inline const type::MultisampledTexture* JOIN(BuildTextureMultisampled, suffix)( \
|
||||
intrinsic::MatchState & state, const type::Type*, const type::Type* T) { \
|
||||
return state.types.multisampled_texture(dim, T); \
|
||||
}
|
||||
|
||||
DECLARE_MULTISAMPLED_TEXTURE(2D, type::TextureDimension::k2d)
|
||||
#undef DECLARE_MULTISAMPLED_TEXTURE
|
||||
|
||||
inline bool MatchTextureDepth(intrinsic::MatchState&,
|
||||
const type::Type* ty,
|
||||
type::TextureDimension dim) {
|
||||
if (ty->Is<intrinsic::Any>()) {
|
||||
return true;
|
||||
}
|
||||
return ty->Is([&](const type::DepthTexture* t) { return t->Dim() == dim; });
|
||||
}
|
||||
|
||||
#define DECLARE_DEPTH_TEXTURE(suffix, dim) \
|
||||
inline bool JOIN(MatchTextureDepth, suffix)(intrinsic::MatchState & state, \
|
||||
const type::Type* ty) { \
|
||||
return MatchTextureDepth(state, ty, dim); \
|
||||
} \
|
||||
inline const type::DepthTexture* JOIN(BuildTextureDepth, suffix)( \
|
||||
intrinsic::MatchState & state, const type::Type*) { \
|
||||
return state.types.depth_texture(dim); \
|
||||
}
|
||||
|
||||
DECLARE_DEPTH_TEXTURE(2D, type::TextureDimension::k2d)
|
||||
DECLARE_DEPTH_TEXTURE(2DArray, type::TextureDimension::k2dArray)
|
||||
DECLARE_DEPTH_TEXTURE(Cube, type::TextureDimension::kCube)
|
||||
DECLARE_DEPTH_TEXTURE(CubeArray, type::TextureDimension::kCubeArray)
|
||||
#undef DECLARE_DEPTH_TEXTURE
|
||||
|
||||
inline bool MatchTextureDepthMultisampled2D(intrinsic::MatchState&, const type::Type* ty) {
|
||||
if (ty->Is<intrinsic::Any>()) {
|
||||
return true;
|
||||
}
|
||||
return ty->Is([&](const type::DepthMultisampledTexture* t) {
|
||||
return t->Dim() == type::TextureDimension::k2d;
|
||||
});
|
||||
}
|
||||
|
||||
inline const type::DepthMultisampledTexture* BuildTextureDepthMultisampled2D(
|
||||
intrinsic::MatchState& state,
|
||||
const type::Type*) {
|
||||
return state.types.depth_multisampled_texture(type::TextureDimension::k2d);
|
||||
}
|
||||
|
||||
inline bool MatchTextureStorage(intrinsic::MatchState&,
|
||||
const type::Type* ty,
|
||||
type::TextureDimension dim,
|
||||
intrinsic::Number& F,
|
||||
intrinsic::Number& A) {
|
||||
if (ty->Is<intrinsic::Any>()) {
|
||||
F = intrinsic::Number::any;
|
||||
A = intrinsic::Number::any;
|
||||
return true;
|
||||
}
|
||||
if (auto* v = ty->As<type::StorageTexture>()) {
|
||||
if (v->Dim() == dim) {
|
||||
F = intrinsic::Number(static_cast<uint32_t>(v->TexelFormat()));
|
||||
A = intrinsic::Number(static_cast<uint32_t>(v->Access()));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
#define DECLARE_STORAGE_TEXTURE(suffix, dim) \
|
||||
inline bool JOIN(MatchTextureStorage, suffix)(intrinsic::MatchState & state, \
|
||||
const type::Type* ty, intrinsic::Number& F, \
|
||||
intrinsic::Number& A) { \
|
||||
return MatchTextureStorage(state, ty, dim, F, A); \
|
||||
} \
|
||||
inline const type::StorageTexture* JOIN(BuildTextureStorage, suffix)( \
|
||||
intrinsic::MatchState & state, const type::Type*, intrinsic::Number F, \
|
||||
intrinsic::Number A) { \
|
||||
auto format = static_cast<TexelFormat>(F.Value()); \
|
||||
auto access = static_cast<Access>(A.Value()); \
|
||||
return state.types.storage_texture(dim, format, access); \
|
||||
}
|
||||
|
||||
DECLARE_STORAGE_TEXTURE(1D, type::TextureDimension::k1d)
|
||||
DECLARE_STORAGE_TEXTURE(2D, type::TextureDimension::k2d)
|
||||
DECLARE_STORAGE_TEXTURE(2DArray, type::TextureDimension::k2dArray)
|
||||
DECLARE_STORAGE_TEXTURE(3D, type::TextureDimension::k3d)
|
||||
#undef DECLARE_STORAGE_TEXTURE
|
||||
|
||||
inline bool MatchTextureExternal(intrinsic::MatchState&, const type::Type* ty) {
|
||||
return ty->IsAnyOf<intrinsic::Any, type::ExternalTexture>();
|
||||
}
|
||||
|
||||
inline const type::ExternalTexture* BuildTextureExternal(intrinsic::MatchState& state,
|
||||
const type::Type*) {
|
||||
return state.types.external_texture();
|
||||
}
|
||||
|
||||
inline bool MatchTexelBuffer(intrinsic::MatchState&,
|
||||
const type::Type* ty,
|
||||
intrinsic::Number& F,
|
||||
intrinsic::Number& A) {
|
||||
if (ty->Is<intrinsic::Any>()) {
|
||||
F = intrinsic::Number::any;
|
||||
A = intrinsic::Number::any;
|
||||
return true;
|
||||
}
|
||||
if (auto* v = ty->As<type::TexelBuffer>()) {
|
||||
F = intrinsic::Number(static_cast<uint32_t>(v->TexelFormat()));
|
||||
A = intrinsic::Number(static_cast<uint32_t>(v->Access()));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
inline const type::TexelBuffer* BuildTexelBuffer(intrinsic::MatchState& state,
|
||||
const type::Type*,
|
||||
intrinsic::Number F,
|
||||
intrinsic::Number A) {
|
||||
auto format = static_cast<TexelFormat>(F.Value());
|
||||
auto access = static_cast<Access>(A.Value());
|
||||
return state.types.texel_buffer(format, access);
|
||||
}
|
||||
|
||||
inline bool MatchInputAttachment(intrinsic::MatchState&,
|
||||
const type::Type* ty,
|
||||
const type::Type*& T) {
|
||||
if (ty->Is<intrinsic::Any>()) {
|
||||
T = ty;
|
||||
return true;
|
||||
}
|
||||
if (auto* v = ty->As<type::InputAttachment>()) {
|
||||
T = v->Type();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
inline const type::InputAttachment* BuildInputAttachment(intrinsic::MatchState& state,
|
||||
const type::Type*,
|
||||
const type::Type* T) {
|
||||
return state.types.input_attachment(T);
|
||||
}
|
||||
|
||||
// Builtin types starting with a _ prefix cannot be declared in WGSL, so they
|
||||
// can only be used as return types. Because of this, they must only match Any,
|
||||
// which is used as the return type matcher.
|
||||
inline bool MatchModfResult(intrinsic::MatchState&, const type::Type* ty, const type::Type*& T) {
|
||||
if (!ty->Is<intrinsic::Any>()) {
|
||||
return false;
|
||||
}
|
||||
T = ty;
|
||||
return true;
|
||||
}
|
||||
inline bool MatchModfResultVec(intrinsic::MatchState&,
|
||||
const type::Type* ty,
|
||||
intrinsic::Number& N,
|
||||
const type::Type*& T) {
|
||||
if (!ty->Is<intrinsic::Any>()) {
|
||||
return false;
|
||||
}
|
||||
N = intrinsic::Number::any;
|
||||
T = ty;
|
||||
return true;
|
||||
}
|
||||
inline bool MatchFrexpResult(intrinsic::MatchState&, const type::Type* ty, const type::Type*& T) {
|
||||
if (!ty->Is<intrinsic::Any>()) {
|
||||
return false;
|
||||
}
|
||||
T = ty;
|
||||
return true;
|
||||
}
|
||||
inline bool MatchFrexpResultVec(intrinsic::MatchState&,
|
||||
const type::Type* ty,
|
||||
intrinsic::Number& N,
|
||||
const type::Type*& T) {
|
||||
if (!ty->Is<intrinsic::Any>()) {
|
||||
return false;
|
||||
}
|
||||
N = intrinsic::Number::any;
|
||||
T = ty;
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool MatchAtomicCompareExchangeResult(intrinsic::MatchState&,
|
||||
const type::Type* ty,
|
||||
const type::Type*& T) {
|
||||
if (ty->Is<intrinsic::Any>()) {
|
||||
T = ty;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
inline const type::Struct* BuildModfResult(intrinsic::MatchState& state,
|
||||
const type::Type*,
|
||||
const type::Type* el) {
|
||||
return type::CreateModfResult(state.types, state.symbols, el);
|
||||
}
|
||||
|
||||
inline const type::Struct* BuildModfResultVec(intrinsic::MatchState& state,
|
||||
const type::Type*,
|
||||
intrinsic::Number& n,
|
||||
const type::Type* el) {
|
||||
auto* vec = state.types.vec(el, n.Value());
|
||||
return type::CreateModfResult(state.types, state.symbols, vec);
|
||||
}
|
||||
|
||||
inline const type::Struct* BuildFrexpResult(intrinsic::MatchState& state,
|
||||
const type::Type*,
|
||||
const type::Type* el) {
|
||||
return type::CreateFrexpResult(state.types, state.symbols, el);
|
||||
}
|
||||
|
||||
inline const type::Struct* BuildFrexpResultVec(intrinsic::MatchState& state,
|
||||
const type::Type*,
|
||||
intrinsic::Number& n,
|
||||
const type::Type* el) {
|
||||
auto* vec = state.types.vec(el, n.Value());
|
||||
return type::CreateFrexpResult(state.types, state.symbols, vec);
|
||||
}
|
||||
|
||||
inline const type::Struct* BuildAtomicCompareExchangeResult(intrinsic::MatchState& state,
|
||||
const type::Type*,
|
||||
const type::Type* ty) {
|
||||
return type::CreateAtomicCompareExchangeResult(state.types, state.symbols, ty);
|
||||
}
|
||||
|
||||
inline bool MatchString(core::intrinsic::MatchState&, const core::type::Type* ty) {
|
||||
return ty->Is<type::String>();
|
||||
}
|
||||
|
||||
inline const core::type::Type* BuildString(core::intrinsic::MatchState& state,
|
||||
const core::type::Type*) {
|
||||
return state.types.String();
|
||||
}
|
||||
|
||||
} // namespace tint::core::intrinsic
|
||||
|
||||
//! @endcond
|
||||
|
||||
#endif // SRC_TINT_LANG_CORE_INTRINSIC_TYPE_MATCHERS_H_
|
||||
104
3rdparty/dawn/src/tint/lang/core/io_attributes.h
vendored
Normal file
104
3rdparty/dawn/src/tint/lang/core/io_attributes.h
vendored
Normal file
@@ -0,0 +1,104 @@
|
||||
// Copyright 2024 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.
|
||||
|
||||
#ifndef SRC_TINT_LANG_CORE_IO_ATTRIBUTES_H_
|
||||
#define SRC_TINT_LANG_CORE_IO_ATTRIBUTES_H_
|
||||
|
||||
#include <cstdint>
|
||||
#include <optional>
|
||||
|
||||
#include "src/tint/api/common/binding_point.h"
|
||||
#include "src/tint/lang/core/enums.h"
|
||||
#include "src/tint/lang/core/interpolation.h"
|
||||
|
||||
namespace tint::core {
|
||||
|
||||
/// Attributes that can be applied to an object that will be used for shader IO.
|
||||
struct IOAttributes {
|
||||
/// The value of a `@location` attribute.
|
||||
std::optional<uint32_t> location = std::nullopt;
|
||||
/// The value of a `@blend_src` attribute.
|
||||
std::optional<uint32_t> blend_src = std::nullopt;
|
||||
/// The value of a `@color` attribute.
|
||||
std::optional<uint32_t> color = std::nullopt;
|
||||
/// The value of a `@builtin` attribute.
|
||||
std::optional<core::BuiltinValue> builtin = std::nullopt;
|
||||
/// The depth mode of a `@builtin` attribute.
|
||||
std::optional<core::BuiltinDepthMode> depth_mode = std::nullopt;
|
||||
/// The values of a `@interpolate` attribute.
|
||||
std::optional<core::Interpolation> interpolation = std::nullopt;
|
||||
/// The value of an `@input_attachment_index` attribute
|
||||
std::optional<uint32_t> input_attachment_index = std::nullopt;
|
||||
/// The value of the `@binding` and `@group` attributes
|
||||
std::optional<BindingPoint> binding_point = std::nullopt;
|
||||
/// True if the object is annotated with `@invariant`.
|
||||
bool invariant = false;
|
||||
};
|
||||
|
||||
/// Used for referencing/tagging a specific IOAttribute.
|
||||
/// IOAttributes above is intentionally not a key-value map (e.g. HashSet) using this enum, since it
|
||||
/// has heterogeneous value types and would also cease to be a POD.
|
||||
enum class IOAttributeKind : uint8_t {
|
||||
kLocation,
|
||||
kBlendSrc,
|
||||
kColor,
|
||||
kBuiltin,
|
||||
kDepthMode,
|
||||
kInterpolation,
|
||||
kInputAttachmentIndex,
|
||||
kBindingPoint,
|
||||
kInvariant,
|
||||
};
|
||||
|
||||
/// @returns a human-readable string representation of @p kind
|
||||
inline std::string_view ToString(const IOAttributeKind kind) {
|
||||
switch (kind) {
|
||||
case IOAttributeKind::kLocation:
|
||||
return "location";
|
||||
case IOAttributeKind::kBlendSrc:
|
||||
return "blend src";
|
||||
case IOAttributeKind::kColor:
|
||||
return "color";
|
||||
case IOAttributeKind::kBuiltin:
|
||||
return "builtin";
|
||||
case IOAttributeKind::kDepthMode:
|
||||
return "depth mode";
|
||||
case IOAttributeKind::kInterpolation:
|
||||
return "interpolation";
|
||||
case IOAttributeKind::kInputAttachmentIndex:
|
||||
return "input attachment index";
|
||||
case IOAttributeKind::kBindingPoint:
|
||||
return "binding point";
|
||||
case IOAttributeKind::kInvariant:
|
||||
return "invariant";
|
||||
}
|
||||
TINT_ICE() << "Unknown kind passed to ToString(IOAttributeKind)";
|
||||
}
|
||||
|
||||
} // namespace tint::core
|
||||
|
||||
#endif // SRC_TINT_LANG_CORE_IO_ATTRIBUTES_H_
|
||||
59
3rdparty/dawn/src/tint/lang/core/ir/access.cc
vendored
Normal file
59
3rdparty/dawn/src/tint/lang/core/ir/access.cc
vendored
Normal file
@@ -0,0 +1,59 @@
|
||||
// Copyright 2023 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/core/ir/access.h"
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include "src/tint/lang/core/ir/clone_context.h"
|
||||
#include "src/tint/lang/core/ir/module.h"
|
||||
|
||||
TINT_INSTANTIATE_TYPEINFO(tint::core::ir::Access);
|
||||
|
||||
namespace tint::core::ir {
|
||||
|
||||
//! @cond Doxygen_Suppress
|
||||
Access::Access(Id id) : Base(id) {}
|
||||
|
||||
Access::Access(Id id, InstructionResult* result, Value* object, VectorRef<Value*> indices)
|
||||
: Base(id) {
|
||||
AddOperand(Access::kObjectOperandOffset, object);
|
||||
AddOperands(Access::kIndicesOperandOffset, std::move(indices));
|
||||
AddResult(result);
|
||||
}
|
||||
|
||||
Access::~Access() = default;
|
||||
|
||||
Access* Access::Clone(CloneContext& ctx) {
|
||||
auto new_result = ctx.Clone(Result());
|
||||
auto obj = ctx.Remap(Object());
|
||||
auto indices = ctx.Remap<Access::kDefaultNumOperands>(Indices());
|
||||
return ctx.ir.CreateInstruction<Access>(new_result, obj, indices);
|
||||
}
|
||||
//! @endcond
|
||||
|
||||
} // namespace tint::core::ir
|
||||
97
3rdparty/dawn/src/tint/lang/core/ir/access.h
vendored
Normal file
97
3rdparty/dawn/src/tint/lang/core/ir/access.h
vendored
Normal file
@@ -0,0 +1,97 @@
|
||||
// Copyright 2023 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.
|
||||
|
||||
#ifndef SRC_TINT_LANG_CORE_IR_ACCESS_H_
|
||||
#define SRC_TINT_LANG_CORE_IR_ACCESS_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "src/tint/lang/core/ir/operand_instruction.h"
|
||||
#include "src/tint/utils/rtti/castable.h"
|
||||
|
||||
namespace tint::core::ir {
|
||||
|
||||
/// An access instruction in the IR.
|
||||
class Access final : public Castable<Access, OperandInstruction<3, 1>> {
|
||||
public:
|
||||
/// The offset in Operands() for the object being accessed
|
||||
static constexpr size_t kObjectOperandOffset = 0;
|
||||
|
||||
/// The base offset in Operands() for the access indices
|
||||
static constexpr size_t kIndicesOperandOffset = 1;
|
||||
|
||||
/// The fixed number of results returned by this instruction
|
||||
static constexpr size_t kNumResults = 1;
|
||||
|
||||
/// The minimum number of operands used by this instruction
|
||||
static constexpr size_t kMinNumOperands = 2;
|
||||
|
||||
/// Constructor (no results, no operands)
|
||||
/// @param id the instruction id
|
||||
explicit Access(Instruction::Id id);
|
||||
|
||||
/// Constructor
|
||||
/// @param id the instruction id
|
||||
/// @param result the result value
|
||||
/// @param object the accessor object
|
||||
/// @param indices the indices to access
|
||||
Access(Instruction::Id id, InstructionResult* result, Value* object, VectorRef<Value*> indices);
|
||||
|
||||
~Access() override;
|
||||
|
||||
/// @copydoc Instruction::Clone()
|
||||
Access* Clone(CloneContext& ctx) override;
|
||||
|
||||
/// @returns the object used for the access
|
||||
Value* Object() { return Operand(kObjectOperandOffset); }
|
||||
|
||||
/// @returns the object used for the access
|
||||
const Value* Object() const { return Operand(kObjectOperandOffset); }
|
||||
|
||||
/// Adds the given index to the end of the access chain
|
||||
/// @param idx the index to add
|
||||
void AddIndex(Value* idx) { AddOperand(operands_.Length(), idx); }
|
||||
|
||||
/// @returns the accessor indices
|
||||
tint::Slice<Value* const> Indices() { return operands_.Slice().Offset(kIndicesOperandOffset); }
|
||||
|
||||
/// @returns the accessor indices
|
||||
tint::Slice<const Value* const> Indices() const {
|
||||
return operands_.Slice().Offset(kIndicesOperandOffset);
|
||||
}
|
||||
|
||||
/// Removes the last index from the access indices
|
||||
/// @returns the last index value
|
||||
Value* PopLastIndex() { return PopOperand(); }
|
||||
|
||||
/// @returns the friendly name for the instruction
|
||||
std::string FriendlyName() const override { return "access"; }
|
||||
};
|
||||
|
||||
} // namespace tint::core::ir
|
||||
|
||||
#endif // SRC_TINT_LANG_CORE_IR_ACCESS_H_
|
||||
124
3rdparty/dawn/src/tint/lang/core/ir/analysis/for_loop_analysis.cc
vendored
Normal file
124
3rdparty/dawn/src/tint/lang/core/ir/analysis/for_loop_analysis.cc
vendored
Normal file
@@ -0,0 +1,124 @@
|
||||
// Copyright 2025 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/core/ir/analysis/for_loop_analysis.h"
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include "src/tint/lang/core/ir/access.h"
|
||||
#include "src/tint/lang/core/ir/binary.h"
|
||||
#include "src/tint/lang/core/ir/bitcast.h"
|
||||
#include "src/tint/lang/core/ir/builtin_call.h"
|
||||
#include "src/tint/lang/core/ir/exit_if.h"
|
||||
#include "src/tint/lang/core/ir/exit_loop.h"
|
||||
#include "src/tint/lang/core/ir/function.h"
|
||||
#include "src/tint/lang/core/ir/if.h"
|
||||
#include "src/tint/lang/core/ir/let.h"
|
||||
#include "src/tint/lang/core/ir/load.h"
|
||||
#include "src/tint/lang/core/ir/load_vector_element.h"
|
||||
#include "src/tint/lang/core/ir/loop.h"
|
||||
#include "src/tint/lang/core/ir/multi_in_block.h"
|
||||
#include "src/tint/lang/core/ir/store.h"
|
||||
#include "src/tint/lang/core/ir/swizzle.h"
|
||||
#include "src/tint/lang/core/ir/traverse.h"
|
||||
#include "src/tint/lang/core/ir/unary.h"
|
||||
#include "src/tint/lang/core/ir/value.h"
|
||||
#include "src/tint/lang/core/ir/var.h"
|
||||
#include "src/tint/lang/core/type/i32.h"
|
||||
#include "src/tint/lang/core/type/pointer.h"
|
||||
#include "src/tint/lang/core/type/type.h"
|
||||
#include "src/tint/lang/core/type/u32.h"
|
||||
#include "src/tint/utils/containers/hashset.h"
|
||||
#include "src/tint/utils/rtti/switch.h"
|
||||
|
||||
namespace tint::core::ir::analysis {
|
||||
|
||||
void ForLoopAnalysis::AttemptForLoopDeduction(const Loop* loop) {
|
||||
// Find the first 'if' which should be the condition for the for-loop.
|
||||
// Order here is critical since instructions in blocks are forward dependencies.
|
||||
const core::ir::If* if_to_remove = nullptr;
|
||||
for (auto* inst : *loop->Body()) {
|
||||
if (auto* if_ = inst->As<const core::ir::If>()) {
|
||||
if (if_->Results().IsEmpty() && if_->True()->Length() == 1 &&
|
||||
if_->False()->Length() == 1 && tint::Is<core::ir::ExitIf>(if_->True()->Front()) &&
|
||||
tint::Is<core::ir::ExitLoop>(if_->False()->Front())) {
|
||||
// Matched the loop condition as it was converted from the 'for' originally.
|
||||
if_to_remove = if_;
|
||||
break;
|
||||
} else {
|
||||
// Conservatively fail to avoid the possibility of reordering instructions (when
|
||||
// moving into conditional).
|
||||
return;
|
||||
}
|
||||
} else if (inst->Is<const Binary>() || inst->Is<const BuiltinCall>() ||
|
||||
inst->Is<const Access>() || inst->Is<const Load>() ||
|
||||
inst->Is<const Swizzle>() || inst->Is<const Unary>() ||
|
||||
inst->Is<const LoadVectorElement>()) {
|
||||
// Allowed instructions since either load or operate on values (side effect free).
|
||||
continue;
|
||||
} else {
|
||||
// Conservatively fail for all other functions that could potentially store/mutate
|
||||
// memory.
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (!if_to_remove) {
|
||||
return;
|
||||
}
|
||||
|
||||
Hashset<const core::ir::Instruction*, 32> sink_chain;
|
||||
// Add the 'if' instruction to set to avoid adding it to the body.
|
||||
sink_chain.Add(if_to_remove);
|
||||
const Instruction* inst = if_to_remove->prev;
|
||||
while (inst) {
|
||||
const auto& results = inst->Results();
|
||||
if (results.Length() != 1u) {
|
||||
// We do not support more than one result for simplicity.
|
||||
return;
|
||||
}
|
||||
|
||||
for (const auto& each_usage : inst->Result()->UsagesUnsorted()) {
|
||||
// All usages must sink into the condition of the if
|
||||
if (!each_usage->instruction || !sink_chain.Contains(each_usage->instruction)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
sink_chain.Add(inst);
|
||||
inst = inst->prev;
|
||||
}
|
||||
|
||||
body_removed_instructions = std::move(sink_chain);
|
||||
// Valid condition found. Success criteria for condition hoisting.
|
||||
for_condition = if_to_remove->Condition();
|
||||
}
|
||||
|
||||
ForLoopAnalysis::ForLoopAnalysis(const Loop& loop) {
|
||||
AttemptForLoopDeduction(&loop);
|
||||
}
|
||||
ForLoopAnalysis::~ForLoopAnalysis() = default;
|
||||
|
||||
} // namespace tint::core::ir::analysis
|
||||
73
3rdparty/dawn/src/tint/lang/core/ir/analysis/for_loop_analysis.h
vendored
Normal file
73
3rdparty/dawn/src/tint/lang/core/ir/analysis/for_loop_analysis.h
vendored
Normal file
@@ -0,0 +1,73 @@
|
||||
// Copyright 2025 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.
|
||||
|
||||
#ifndef SRC_TINT_LANG_CORE_IR_ANALYSIS_FOR_LOOP_ANALYSIS_H_
|
||||
#define SRC_TINT_LANG_CORE_IR_ANALYSIS_FOR_LOOP_ANALYSIS_H_
|
||||
|
||||
#include <memory>
|
||||
#include <set>
|
||||
|
||||
#include "src/tint/lang/core/ir/if.h"
|
||||
#include "src/tint/lang/core/ir/loop.h"
|
||||
#include "src/tint/lang/core/ir/var.h"
|
||||
#include "src/tint/utils/ice/ice.h"
|
||||
|
||||
namespace tint::core::ir::analysis {
|
||||
|
||||
/// ForLoopAnalysis is a helper used to find and hoist the condition into the for loop directly.
|
||||
/// See crbug.com/429187478 for the rationale behind this analysis.
|
||||
class ForLoopAnalysis {
|
||||
public:
|
||||
/// Constructor
|
||||
/// @param loop the Loop to cache analyses for
|
||||
explicit ForLoopAnalysis(const Loop& loop);
|
||||
~ForLoopAnalysis();
|
||||
|
||||
/// Returns the condition for the loop.
|
||||
/// Otherwise if no condition can be hoisted it returns nullptr.
|
||||
/// @returns the loop condition instruction result
|
||||
const core::ir::Value* GetIfCondition() { return for_condition; }
|
||||
|
||||
/// Returns true if the instruction should be removed from the body to support condition
|
||||
/// hoisting.
|
||||
/// @param inst from the body of the loop
|
||||
/// @returns a boolean
|
||||
bool IsBodyRemovedInstruction(const core::ir::Instruction* inst) {
|
||||
TINT_ASSERT(GetIfCondition());
|
||||
return body_removed_instructions.Contains(inst);
|
||||
}
|
||||
|
||||
private:
|
||||
void AttemptForLoopDeduction(const Loop* loop);
|
||||
|
||||
Hashset<const core::ir::Instruction*, 32> body_removed_instructions;
|
||||
const core::ir::Value* for_condition = nullptr;
|
||||
};
|
||||
|
||||
} // namespace tint::core::ir::analysis
|
||||
|
||||
#endif // SRC_TINT_LANG_CORE_IR_ANALYSIS_FOR_LOOP_ANALYSIS_H_
|
||||
1472
3rdparty/dawn/src/tint/lang/core/ir/analysis/integer_range_analysis.cc
vendored
Normal file
1472
3rdparty/dawn/src/tint/lang/core/ir/analysis/integer_range_analysis.cc
vendored
Normal file
File diff suppressed because it is too large
Load Diff
196
3rdparty/dawn/src/tint/lang/core/ir/analysis/integer_range_analysis.h
vendored
Normal file
196
3rdparty/dawn/src/tint/lang/core/ir/analysis/integer_range_analysis.h
vendored
Normal file
@@ -0,0 +1,196 @@
|
||||
// Copyright 2024 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.
|
||||
|
||||
#ifndef SRC_TINT_LANG_CORE_IR_ANALYSIS_INTEGER_RANGE_ANALYSIS_H_
|
||||
#define SRC_TINT_LANG_CORE_IR_ANALYSIS_INTEGER_RANGE_ANALYSIS_H_
|
||||
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
#include <variant>
|
||||
|
||||
namespace tint::core::ir {
|
||||
class Access;
|
||||
class Binary;
|
||||
class Constant;
|
||||
class Convert;
|
||||
class CoreBuiltinCall;
|
||||
class Function;
|
||||
class FunctionParam;
|
||||
class Let;
|
||||
class Load;
|
||||
class Loop;
|
||||
class Module;
|
||||
class Value;
|
||||
class Var;
|
||||
} // namespace tint::core::ir
|
||||
|
||||
namespace tint::core::ir::analysis {
|
||||
|
||||
/// The result of a integer range analysis: the upper and lower bound of a given integer variable.
|
||||
/// The bound is inclusive, which means the value x being bound satisfies:
|
||||
/// min_bound <= x <= max_bound.
|
||||
struct IntegerRangeInfo {
|
||||
IntegerRangeInfo() = default;
|
||||
IntegerRangeInfo(int64_t min_bound, int64_t max_bound);
|
||||
IntegerRangeInfo(uint64_t min_bound, uint64_t max_bound);
|
||||
|
||||
bool IsValid() const;
|
||||
|
||||
struct SignedIntegerRange {
|
||||
int64_t min_bound;
|
||||
int64_t max_bound;
|
||||
};
|
||||
struct UnsignedIntegerRange {
|
||||
uint64_t min_bound;
|
||||
uint64_t max_bound;
|
||||
};
|
||||
std::variant<std::monostate, SignedIntegerRange, UnsignedIntegerRange> range;
|
||||
};
|
||||
|
||||
struct IntegerRangeAnalysisImpl;
|
||||
|
||||
/// IntegerRangeAnalysis is a helper used to analyze integer ranges.
|
||||
class IntegerRangeAnalysis {
|
||||
public:
|
||||
/// Constructor
|
||||
/// @module ir_module the ir module to cache analyses for
|
||||
explicit IntegerRangeAnalysis(Module* ir_module);
|
||||
|
||||
~IntegerRangeAnalysis();
|
||||
|
||||
/// Returns the integer range info of a given parameter with given index, if it is an integer
|
||||
/// or an integer vector parameter. The index must not be over the maximum size of the vector
|
||||
/// and must be 0 if the parameter is an integer.
|
||||
/// Otherwise is not analyzable and returns an invalid `IntegerRangeInfo` object. If it is the
|
||||
/// first time to query the info, the result will also be stored into a cache for future
|
||||
/// queries.
|
||||
/// @param param the variable to get information about
|
||||
/// @param index the vector component index when the parameter is a vector type. if the
|
||||
/// parameter is a scalar, then `index` must be zero.
|
||||
/// @returns the integer range info
|
||||
IntegerRangeInfo GetInfo(const FunctionParam* param, uint32_t index = 0);
|
||||
|
||||
/// Returns the integer range info of a given variable if it is an integer variable and it has a
|
||||
/// meaningful range. Returns an invalid `IntegerRangeInfo` object otherwise.
|
||||
/// @param var the variable to get information about
|
||||
/// @returns the integer range info
|
||||
IntegerRangeInfo GetInfo(const Var* var);
|
||||
|
||||
/// Returns the integer range info of a given `Load` variable if it is an integer variable and
|
||||
/// it has a meaningful range. Returns an invalid `IntegerRangeInfo` object otherwise.
|
||||
IntegerRangeInfo GetInfo(const Load* load_var);
|
||||
|
||||
/// Returns the integer range info of a given `Access` variable if it is an integer variable and
|
||||
/// it has a meaningful range. Returns an invalid `IntegerRangeInfo` object otherwise.
|
||||
IntegerRangeInfo GetInfo(const Access* access);
|
||||
|
||||
/// Returns the integer range info of a given `Let` variable if it is an integer variable and it
|
||||
/// has a meaningful range. Returns an invalid `IntegerRangeInfo` object otherwise.
|
||||
IntegerRangeInfo GetInfo(const Let* let);
|
||||
|
||||
/// Returns the integer range info of a given `Constant` if it is an integer.
|
||||
/// Returns an invalid `IntegerRangeInfo` object otherwise.
|
||||
IntegerRangeInfo GetInfo(const Constant* constant);
|
||||
|
||||
/// Returns the integer range info of a given `Value` variable if it is an integer variable and
|
||||
/// it has a meaningful range. Returns an invalid `IntegerRangeInfo` object otherwise.
|
||||
IntegerRangeInfo GetInfo(const Value* value);
|
||||
|
||||
/// Returns the integer range info of a given `Binary` variable if it is an integer variable and
|
||||
/// it has a meaningful range. Returns an invalid `IntegerRangeInfo` object otherwise.
|
||||
IntegerRangeInfo GetInfo(const Binary* binary);
|
||||
|
||||
/// Returns the integer range info of a given `Convert` variable if it is an integer variable
|
||||
/// and it has a meaningful range. Returns an invalid `IntegerRangeInfo` object otherwise.
|
||||
IntegerRangeInfo GetInfo(const Convert* convert);
|
||||
|
||||
/// Returns the integer range info of a given `CoreBuiltinCall` variable if it is an integer
|
||||
/// variable and it has a meaningful range. Returns an invalid `IntegerRangeInfo` object
|
||||
/// otherwise.
|
||||
IntegerRangeInfo GetInfo(const CoreBuiltinCall* call);
|
||||
|
||||
/// Note: This function is only for tests.
|
||||
/// Returns the pointer of the loop control variable in the given loop when its initializer
|
||||
/// meets the below requirements.
|
||||
/// - There are only two instructions in the loop initializer block.
|
||||
/// - The first instruction is to initialize the loop control variable
|
||||
/// with a constant integer (signed or unsigned) value.
|
||||
/// - The second instruction is `next_iteration`.
|
||||
/// @param loop the Loop variable to investigate
|
||||
/// @returns the pointer of the loop control variable when its loop initializer meets the
|
||||
/// requirements, return nullptr otherwise.
|
||||
const Var* GetLoopControlVariableFromConstantInitializerForTest(const Loop* loop);
|
||||
|
||||
/// Note: This function is only for tests.
|
||||
/// Returns the pointer of the binary operation that updates the loop control variable in the
|
||||
/// continuing block of the given loop if the loop meets the below requirements.
|
||||
/// - There are only 4 instructions in the loop initializer block.
|
||||
/// - The first instruction is to load the loop control variable into a temporary variable.
|
||||
/// - The second instruction is to add one or minus one to the temporary variable.
|
||||
/// - The third instruction is to store the value of the temporary variable into the loop
|
||||
/// control variable.
|
||||
/// - The fourth instruction is `next_iteration`.
|
||||
/// @param loop the Loop variable to investigate.
|
||||
/// @param loop_control_variable the loop control variable to investigate.
|
||||
/// @returns the pointer of the binary operation that updates the loop control variable in the
|
||||
/// continuing block of the given loop if the loop meets all the requirements, return nullptr
|
||||
/// otherwise.
|
||||
const Binary* GetBinaryToUpdateLoopControlVariableInContinuingBlockForTest(
|
||||
const Loop* loop,
|
||||
const Var* loop_control_variable);
|
||||
|
||||
/// Note: This function is only for tests
|
||||
/// Returns the pointer of the binary operation that compares the loop control variable with its
|
||||
/// limitations in the body block of the loop if the loop meets the below requirements:
|
||||
/// - The loop control variable is only used as the parameter of the load instruction.
|
||||
/// - The first instruction is to load the loop control variable into a temporary variable.
|
||||
/// - The second instruction is to compare the temporary variable with a constant value and save
|
||||
/// the result to a boolean variable.
|
||||
/// - The second instruction cannot be a comparison that will never return true.
|
||||
/// - The third instruction is an `ifelse` expression that uses the boolean variable got in the
|
||||
/// second instruction as the condition.
|
||||
// - The true block of the above `ifelse` expression doesn't contain `exit_loop`.
|
||||
// - The false block of the above `ifelse` expression only contains `exit_loop`.
|
||||
/// @param loop the Loop variable to investigate.
|
||||
/// @param loop_control_variable the loop control variable to investigate.
|
||||
/// @returns the pointer of the binary operation that compares the loop control variable with
|
||||
/// its limitations in the body block of the loop if the loop meets the below requirements,
|
||||
/// return nullptr otherwise.
|
||||
const Binary* GetBinaryToCompareLoopControlVariableInLoopBodyForTest(
|
||||
const Loop* loop,
|
||||
const Var* loop_control_variable);
|
||||
|
||||
private:
|
||||
IntegerRangeAnalysis(const IntegerRangeAnalysis&) = delete;
|
||||
IntegerRangeAnalysis(IntegerRangeAnalysis&&) = delete;
|
||||
|
||||
std::unique_ptr<IntegerRangeAnalysisImpl> impl_;
|
||||
};
|
||||
|
||||
} // namespace tint::core::ir::analysis
|
||||
|
||||
#endif // SRC_TINT_LANG_CORE_IR_ANALYSIS_INTEGER_RANGE_ANALYSIS_H_
|
||||
321
3rdparty/dawn/src/tint/lang/core/ir/analysis/loop_analysis.cc
vendored
Normal file
321
3rdparty/dawn/src/tint/lang/core/ir/analysis/loop_analysis.cc
vendored
Normal file
@@ -0,0 +1,321 @@
|
||||
// Copyright 2024 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/core/ir/analysis/loop_analysis.h"
|
||||
|
||||
#include "src/tint/lang/core/ir/binary.h"
|
||||
#include "src/tint/lang/core/ir/bitcast.h"
|
||||
#include "src/tint/lang/core/ir/exit_loop.h"
|
||||
#include "src/tint/lang/core/ir/function.h"
|
||||
#include "src/tint/lang/core/ir/if.h"
|
||||
#include "src/tint/lang/core/ir/let.h"
|
||||
#include "src/tint/lang/core/ir/load.h"
|
||||
#include "src/tint/lang/core/ir/loop.h"
|
||||
#include "src/tint/lang/core/ir/multi_in_block.h"
|
||||
#include "src/tint/lang/core/ir/store.h"
|
||||
#include "src/tint/lang/core/ir/traverse.h"
|
||||
#include "src/tint/lang/core/ir/value.h"
|
||||
#include "src/tint/lang/core/ir/var.h"
|
||||
#include "src/tint/lang/core/type/i32.h"
|
||||
#include "src/tint/lang/core/type/pointer.h"
|
||||
#include "src/tint/lang/core/type/type.h"
|
||||
#include "src/tint/lang/core/type/u32.h"
|
||||
#include "src/tint/utils/rtti/switch.h"
|
||||
|
||||
namespace tint::core::ir::analysis {
|
||||
|
||||
namespace {
|
||||
|
||||
/// Returns an instruction of the given kind if @p val is the result of such an instruction.
|
||||
/// Otherwise returns nullptr.
|
||||
template <typename InstClass>
|
||||
InstClass* As(Value* val) {
|
||||
if (auto* instres = val->As<InstructionResult>()) {
|
||||
return instres->Instruction()->As<InstClass>();
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/// Returns the value, after unwrapping all bitcasts.
|
||||
Value* UnwrapBitcast(Value* val) {
|
||||
while (auto* bitcast = As<Bitcast>(val)) {
|
||||
val = bitcast->Val();
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
/// Returns true if v is the integer constant 1.
|
||||
bool IsOne(Value* v) {
|
||||
if (auto* cv = v->As<Constant>()) {
|
||||
return Switch(
|
||||
cv->Type(),
|
||||
[&](const core::type::I32*) { return cv->Value()->ValueAs<int32_t>() == 1; },
|
||||
[&](const core::type::U32*) { return cv->Value()->ValueAs<uint32_t>() == 1; },
|
||||
[&](const Default) -> bool { return false; });
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// Returns `true` if `val` is definitely `var +/- 1`.
|
||||
bool IsIncrementOrDecrementOfVar(const Var& var, Value* val) {
|
||||
auto is_var_op_one = [&](Value* a, Value* b) {
|
||||
if (auto* a_load = As<Load>(a)) {
|
||||
return (a_load->From() == var.Result()) && IsOne(b);
|
||||
}
|
||||
return false;
|
||||
};
|
||||
if (auto* binary = As<Binary>(UnwrapBitcast(val))) {
|
||||
auto* lhs = UnwrapBitcast(binary->LHS());
|
||||
auto* rhs = UnwrapBitcast(binary->RHS());
|
||||
if (binary->Op() == BinaryOp::kAdd) {
|
||||
// Allow `var + 1` or `1 + var`.
|
||||
return is_var_op_one(lhs, rhs) || is_var_op_one(rhs, lhs);
|
||||
} else if (binary->Op() == BinaryOp::kSubtract) {
|
||||
// Only allow `var - 1`.
|
||||
return is_var_op_one(lhs, rhs);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
/// PIMPL class that performs the analysis and holds the analysis cache.
|
||||
struct LoopAnalysisImpl {
|
||||
explicit LoopAnalysisImpl(Function& func) {
|
||||
// Analyze all of the loops in the function.
|
||||
Traverse(func.Block(), [&](Loop* l) { AnalyzeLoop(*l); });
|
||||
}
|
||||
|
||||
/// @returns the info for a loop
|
||||
const LoopInfo* GetInfo(const Loop& loop) const { return loop_info_map_.Get(&loop).value; }
|
||||
|
||||
private:
|
||||
Hashmap<const Loop*, LoopInfo, 8> loop_info_map_;
|
||||
|
||||
/// Analyze a loop.
|
||||
void AnalyzeLoop(Loop& loop) {
|
||||
if (auto* init_block = loop.Initializer()) {
|
||||
// Look for variables that could be used as iteration indices.
|
||||
for (auto* inst : *init_block) {
|
||||
auto* var = inst->As<Var>();
|
||||
if (!var) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const auto* pty = var->Result()->Type()->As<core::type::Pointer>();
|
||||
if (!pty->StoreType()->IsIntegerScalar()) {
|
||||
break;
|
||||
}
|
||||
|
||||
// Check if the variable is an index that gives this loop a finite range.
|
||||
if (IsFiniteLoopIndex(loop, *var)) {
|
||||
loop_info_map_.Add(&loop, LoopInfo{var});
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// We could not determine that this was a finite loop.
|
||||
loop_info_map_.Add(&loop, LoopInfo{});
|
||||
}
|
||||
|
||||
/// Analyzes @p var as a candidate loop index variable for the given @p loop to see if it is
|
||||
/// used in a way that guarantees the loop will be iterating over a finite range.
|
||||
/// @returns true if @p var is an index variable for a finite ranged loop
|
||||
bool IsFiniteLoopIndex(Loop& loop, Var& index) {
|
||||
// Look for a store to the index in the continuing block.
|
||||
// Make sure there is only one, and make sure that the only other uses are loads.
|
||||
Store* single_store_in_continue_block = nullptr;
|
||||
const auto& uses = index.Result()->UsagesUnsorted();
|
||||
for (auto& use : uses) {
|
||||
if (auto* store = use->instruction->As<Store>()) {
|
||||
if (store->Block() != loop.Continuing()) {
|
||||
// Not in the continuing block, so we cannot easily prove that it will be
|
||||
// executed.
|
||||
return false;
|
||||
}
|
||||
if (single_store_in_continue_block) {
|
||||
// Found more than one store, so we cannot easily analyze this candidate.
|
||||
return false;
|
||||
}
|
||||
single_store_in_continue_block = store;
|
||||
} else if (!use->instruction->Is<Load>()) {
|
||||
// Not a store or a load, so reject this candidate.
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (!single_store_in_continue_block) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check that the store we found is either incrementing or decrementing the index by `1`.
|
||||
if (!IsIncrementOrDecrementOfVar(index, single_store_in_continue_block->From())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// We have proven that the variable increments exactly once per iteration.
|
||||
// Now check that the loop body begins with a break-if construct that will is guaranteed to
|
||||
// exit the loop if the index reaches the loop bound.
|
||||
bool has_break_if = false;
|
||||
for (auto* inst : *loop.Body()) {
|
||||
// The Switch returns `true` if more instructions should be checked, otherwise `false`.
|
||||
bool keep_going = Switch(
|
||||
inst, //
|
||||
[&](Load*) { return true; }, //
|
||||
[&](Bitcast*) { return true; }, //
|
||||
[&](Binary*) { return true; }, //
|
||||
[&](If* i) {
|
||||
if (IsBreakIfOnIndex(loop, i, index)) {
|
||||
// The loop is finite.
|
||||
has_break_if = true;
|
||||
}
|
||||
// Only look at the first 'if' we find.
|
||||
return false;
|
||||
},
|
||||
[&](Default) { return false; });
|
||||
if (!keep_going) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return has_break_if;
|
||||
}
|
||||
|
||||
/// @returns `true` if @p is a break-if construct that exits the loop based on @p index.
|
||||
bool IsBreakIfOnIndex(const Loop& loop, If* i, Var& index) {
|
||||
// Returns `true` if the given value is a load of the index variable.
|
||||
auto is_index = [&index](Value* v) {
|
||||
if (auto* load = As<Load>(UnwrapBitcast(v))) {
|
||||
return load->From() == index.Result();
|
||||
}
|
||||
return false;
|
||||
};
|
||||
// Returns `true` if the given value an immutable value declared before the loop body.
|
||||
auto is_immutable_before_body = [&loop](Value* v) {
|
||||
return tint::Switch(
|
||||
UnwrapBitcast(v), //
|
||||
[](ir::Constant*) { return true; }, //
|
||||
[](ir::FunctionParam*) { return true; }, //
|
||||
[&](ir::InstructionResult* r) {
|
||||
auto* let = r->Instruction()->As<Let>();
|
||||
return let && let->Block() != loop.Body();
|
||||
} //
|
||||
);
|
||||
};
|
||||
auto is_constant_i32_or_u32 = [](Value* v) {
|
||||
auto* constant_value = v->As<Constant>();
|
||||
if (!constant_value) {
|
||||
return false;
|
||||
}
|
||||
return constant_value->Type()->IsAnyOf<type::I32, type::U32>();
|
||||
};
|
||||
auto is_capable_binary_for_loop_exit = [&](Binary* binary) {
|
||||
switch (binary->Op()) {
|
||||
case BinaryOp::kLessThan:
|
||||
case BinaryOp::kGreaterThan: {
|
||||
return (is_index(binary->LHS()) && is_immutable_before_body(binary->RHS())) ||
|
||||
(is_index(binary->RHS()) && is_immutable_before_body(binary->LHS()));
|
||||
}
|
||||
case BinaryOp::kLessThanEqual: {
|
||||
if (is_index(binary->LHS()) && is_constant_i32_or_u32(binary->RHS())) {
|
||||
// index <= kConstantValue
|
||||
// `kConstantValue` being the highest value will cause an infinite loop.
|
||||
auto* constant_value = binary->RHS()->As<Constant>()->Value();
|
||||
if (constant_value->Type()->Is<type::I32>()) {
|
||||
return constant_value->ValueAs<int32_t>() < i32::kHighestValue;
|
||||
} else {
|
||||
TINT_ASSERT(constant_value->Type()->Is<type::U32>());
|
||||
return constant_value->ValueAs<uint32_t>() < u32::kHighestValue;
|
||||
}
|
||||
} else if (is_index(binary->RHS()) && is_constant_i32_or_u32(binary->LHS())) {
|
||||
// kConstantValue <= index
|
||||
// `kConstantValue` being the lowest value will cause an infinite loop.
|
||||
auto* constant_value = binary->LHS()->As<Constant>()->Value();
|
||||
if (constant_value->Type()->Is<type::I32>()) {
|
||||
return constant_value->ValueAs<int32_t>() > i32::kLowestValue;
|
||||
} else {
|
||||
TINT_ASSERT(constant_value->Type()->Is<type::U32>());
|
||||
return constant_value->ValueAs<uint32_t>() > u32::kLowestValue;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
case BinaryOp::kGreaterThanEqual: {
|
||||
if (is_index(binary->LHS()) && is_constant_i32_or_u32(binary->RHS())) {
|
||||
// index >= kConstantValue
|
||||
// `kConstantValue` being the lowest value will cause an infinite loop.
|
||||
auto* constant_value = binary->RHS()->As<Constant>()->Value();
|
||||
if (constant_value->Type()->Is<type::I32>()) {
|
||||
return constant_value->ValueAs<int32_t>() > i32::kLowestValue;
|
||||
} else {
|
||||
TINT_ASSERT(constant_value->Type()->Is<type::U32>());
|
||||
return constant_value->ValueAs<uint32_t>() > u32::kLowestValue;
|
||||
}
|
||||
} else if (is_index(binary->RHS()) && is_constant_i32_or_u32(binary->LHS())) {
|
||||
// kConstantValue >= index
|
||||
// `kConstantValue` being the highest value will cause an infinite loop.
|
||||
auto* constant_value = binary->LHS()->As<Constant>()->Value();
|
||||
if (constant_value->Type()->Is<type::I32>()) {
|
||||
return constant_value->ValueAs<int32_t>() < i32::kHighestValue;
|
||||
} else {
|
||||
TINT_ASSERT(constant_value->Type()->Is<type::U32>());
|
||||
return constant_value->ValueAs<uint32_t>() < u32::kHighestValue;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
// Check if the condition matches (%idx < %bound) or (%idx > %bound).
|
||||
// The value %bound can be any immutable value that was declared before the body.
|
||||
auto* binary = As<Binary>(i->Condition());
|
||||
if (!binary) {
|
||||
return false;
|
||||
}
|
||||
if (is_capable_binary_for_loop_exit(binary)) {
|
||||
// The condition matches, so now make sure that one of the branches will exit from the
|
||||
// loop and do nothing else.
|
||||
auto is_simple_loop_exit = [](Block* b) {
|
||||
return b && !b->IsEmpty() && (b->Front()->Is<ExitLoop>());
|
||||
};
|
||||
return is_simple_loop_exit(i->True()) || is_simple_loop_exit(i->False());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
LoopAnalysis::LoopAnalysis(Function& func) : impl_(new LoopAnalysisImpl(func)) {}
|
||||
LoopAnalysis::~LoopAnalysis() = default;
|
||||
|
||||
const LoopInfo* LoopAnalysis::GetInfo(const Loop& loop) const {
|
||||
return impl_->GetInfo(loop);
|
||||
}
|
||||
|
||||
} // namespace tint::core::ir::analysis
|
||||
73
3rdparty/dawn/src/tint/lang/core/ir/analysis/loop_analysis.h
vendored
Normal file
73
3rdparty/dawn/src/tint/lang/core/ir/analysis/loop_analysis.h
vendored
Normal file
@@ -0,0 +1,73 @@
|
||||
// Copyright 2024 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.
|
||||
|
||||
#ifndef SRC_TINT_LANG_CORE_IR_ANALYSIS_LOOP_ANALYSIS_H_
|
||||
#define SRC_TINT_LANG_CORE_IR_ANALYSIS_LOOP_ANALYSIS_H_
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "src/tint/lang/core/ir/function.h"
|
||||
#include "src/tint/lang/core/ir/loop.h"
|
||||
#include "src/tint/lang/core/ir/var.h"
|
||||
|
||||
namespace tint::core::ir::analysis {
|
||||
|
||||
/// The result of a loop analysis.
|
||||
struct LoopInfo {
|
||||
Var* const index_var = nullptr;
|
||||
|
||||
/// @returns `true` if the loop is definitely finite, otherwise `false`.
|
||||
bool IsFinite() const { return index_var != nullptr; }
|
||||
};
|
||||
|
||||
struct LoopAnalysisImpl;
|
||||
|
||||
/// LoopAnalysis is a helper used to analyze loops.
|
||||
/// It caches loop analyses for a function.
|
||||
class LoopAnalysis {
|
||||
public:
|
||||
/// Constructor
|
||||
/// @param func the function to cache analyses for
|
||||
explicit LoopAnalysis(ir::Function& func);
|
||||
~LoopAnalysis();
|
||||
|
||||
/// Returns the info for a given loop, if it is a loop.
|
||||
/// Otherwise is not analyzable, and returns nullptr.
|
||||
/// @param loop the loop to get information about
|
||||
/// @returns the loop info
|
||||
const LoopInfo* GetInfo(const Loop& loop) const;
|
||||
|
||||
private:
|
||||
LoopAnalysis(const LoopAnalysis&) = delete;
|
||||
LoopAnalysis(LoopAnalysis&&) = delete;
|
||||
|
||||
std::unique_ptr<LoopAnalysisImpl> impl_;
|
||||
};
|
||||
|
||||
} // namespace tint::core::ir::analysis
|
||||
|
||||
#endif // SRC_TINT_LANG_CORE_IR_ANALYSIS_LOOP_ANALYSIS_H_
|
||||
169
3rdparty/dawn/src/tint/lang/core/ir/analysis/subgroup_matrix.cc
vendored
Normal file
169
3rdparty/dawn/src/tint/lang/core/ir/analysis/subgroup_matrix.cc
vendored
Normal file
@@ -0,0 +1,169 @@
|
||||
// Copyright 2025 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/core/ir/analysis/subgroup_matrix.h"
|
||||
|
||||
#include <unordered_set>
|
||||
#include <utility>
|
||||
|
||||
#include "src/tint/lang/core/ir/core_builtin_call.h"
|
||||
#include "src/tint/lang/core/ir/module.h"
|
||||
#include "src/tint/lang/core/type/array.h"
|
||||
#include "src/tint/lang/core/type/f16.h"
|
||||
#include "src/tint/lang/core/type/f32.h"
|
||||
#include "src/tint/lang/core/type/i32.h"
|
||||
#include "src/tint/lang/core/type/i8.h"
|
||||
#include "src/tint/lang/core/type/struct.h"
|
||||
#include "src/tint/lang/core/type/subgroup_matrix.h"
|
||||
#include "src/tint/lang/core/type/u32.h"
|
||||
#include "src/tint/lang/core/type/u8.h"
|
||||
#include "src/tint/utils/rtti/switch.h"
|
||||
|
||||
namespace tint::core::ir::analysis {
|
||||
namespace {
|
||||
|
||||
struct State {
|
||||
/// The IR module.
|
||||
core::ir::Module& ir;
|
||||
|
||||
SubgroupMatrixInfo info{};
|
||||
|
||||
/// Process the module.
|
||||
SubgroupMatrixInfo Process() {
|
||||
for (const auto* inst : ir.Instructions()) {
|
||||
if (auto* call = inst->As<core::ir::CoreBuiltinCall>()) {
|
||||
GatherCall(call);
|
||||
}
|
||||
|
||||
for (auto* res : inst->Results()) {
|
||||
GatherType(res->Type()->UnwrapPtr());
|
||||
}
|
||||
}
|
||||
|
||||
return std::move(info);
|
||||
}
|
||||
|
||||
SubgroupMatrixType TypeToSMType(const core::type::Type* ty) {
|
||||
return tint::Switch(
|
||||
ty, //
|
||||
[&](const core::type::F16*) { return SubgroupMatrixType::kF16; },
|
||||
[&](const core::type::F32*) { return SubgroupMatrixType::kF32; },
|
||||
[&](const core::type::U8*) { return SubgroupMatrixType::kU8; },
|
||||
[&](const core::type::I8*) { return SubgroupMatrixType::kI8; },
|
||||
[&](const core::type::U32*) { return SubgroupMatrixType::kU32; },
|
||||
[&](const core::type::I32*) { return SubgroupMatrixType::kI32; }, //
|
||||
TINT_ICE_ON_NO_MATCH);
|
||||
}
|
||||
|
||||
void GatherCall(const core::ir::CoreBuiltinCall* call) {
|
||||
if (call->Func() != BuiltinFn::kSubgroupMatrixMultiply &&
|
||||
call->Func() != BuiltinFn::kSubgroupMatrixMultiplyAccumulate) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto* result_ty = call->Result()->Type()->As<core::type::SubgroupMatrix>();
|
||||
TINT_ASSERT(result_ty);
|
||||
|
||||
auto* left_ty = call->Args()[0]->Type()->As<core::type::SubgroupMatrix>();
|
||||
TINT_ASSERT(left_ty);
|
||||
|
||||
auto* right_ty = call->Args()[1]->Type()->As<core::type::SubgroupMatrix>();
|
||||
TINT_ASSERT(right_ty);
|
||||
|
||||
SubgroupMatrixMultiply cfg{
|
||||
.M = left_ty->Rows(),
|
||||
.N = right_ty->Columns(),
|
||||
.K = right_ty->Rows(),
|
||||
.input_type = TypeToSMType(left_ty->Type()),
|
||||
.output_type = TypeToSMType(result_ty->Type()),
|
||||
};
|
||||
|
||||
info.multiplies.insert(cfg);
|
||||
}
|
||||
|
||||
void GatherType(const core::type::Type* ty) {
|
||||
if (auto* str = ty->As<core::type::Struct>()) {
|
||||
for (auto* mem : str->Members()) {
|
||||
GatherType(mem->Type());
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (auto* arr = ty->As<core::type::Array>()) {
|
||||
GatherType(arr->ElemType());
|
||||
return;
|
||||
}
|
||||
|
||||
auto* sm = ty->As<core::type::SubgroupMatrix>();
|
||||
if (!sm) {
|
||||
return;
|
||||
}
|
||||
|
||||
SubgroupMatrixDirection dir = SubgroupMatrixDirection::kResult;
|
||||
|
||||
uint32_t M = 0;
|
||||
uint32_t N = 0;
|
||||
uint32_t K = 0;
|
||||
|
||||
switch (sm->Kind()) {
|
||||
case SubgroupMatrixKind::kResult:
|
||||
dir = SubgroupMatrixDirection::kResult;
|
||||
M = sm->Rows();
|
||||
N = sm->Columns();
|
||||
break;
|
||||
case SubgroupMatrixKind::kLeft:
|
||||
dir = SubgroupMatrixDirection::kLeft;
|
||||
M = sm->Rows();
|
||||
K = sm->Columns();
|
||||
break;
|
||||
case SubgroupMatrixKind::kRight:
|
||||
dir = SubgroupMatrixDirection::kRight;
|
||||
K = sm->Rows();
|
||||
N = sm->Columns();
|
||||
break;
|
||||
case SubgroupMatrixKind::kUndefined:
|
||||
TINT_UNREACHABLE();
|
||||
}
|
||||
|
||||
SubgroupMatrixConfig cfg{
|
||||
.M = M,
|
||||
.N = N,
|
||||
.K = K,
|
||||
.type = TypeToSMType(sm->Type()),
|
||||
.direction = dir,
|
||||
};
|
||||
|
||||
info.configs.insert(cfg);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
SubgroupMatrixInfo GatherSubgroupMatrixInfo(core::ir::Module& ir) {
|
||||
return State{ir}.Process();
|
||||
}
|
||||
|
||||
} // namespace tint::core::ir::analysis
|
||||
60
3rdparty/dawn/src/tint/lang/core/ir/analysis/subgroup_matrix.h
vendored
Normal file
60
3rdparty/dawn/src/tint/lang/core/ir/analysis/subgroup_matrix.h
vendored
Normal file
@@ -0,0 +1,60 @@
|
||||
// Copyright 2025 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.
|
||||
|
||||
#ifndef SRC_TINT_LANG_CORE_IR_ANALYSIS_SUBGROUP_MATRIX_H_
|
||||
#define SRC_TINT_LANG_CORE_IR_ANALYSIS_SUBGROUP_MATRIX_H_
|
||||
|
||||
#include "src/tint/api/common/subgroup_matrix.h"
|
||||
|
||||
// Forward declarations.
|
||||
namespace tint::core::ir {
|
||||
class Module;
|
||||
} // namespace tint::core::ir
|
||||
|
||||
namespace tint::core::ir::analysis {
|
||||
|
||||
/// Gathers information about the subgroup matrix configurations used in the module.
|
||||
///
|
||||
/// This returns two fundamental types of information on the subgroup matrix uses.
|
||||
///
|
||||
/// 1. The Matrix multiply configurations
|
||||
/// * This provides the `M`, `N`, `K`, input and output types for the
|
||||
/// `subgroupMatrixMultiply` and `subgroupMatrtixMultiplyAccumulate` calls in the
|
||||
/// module. (The configs are de-duplicated so each combination is only returned once.)
|
||||
///
|
||||
/// 2. The used matrix configurations
|
||||
/// * This provides the `C`, `R`, type and if it's left/right (input) or result usage for
|
||||
/// every subgroup matrix seen in the file. (The configs are de-duplicated so each
|
||||
/// combination is only returned once.)
|
||||
///
|
||||
/// @param module the module to transform
|
||||
/// @returns the subgroup matrix information
|
||||
SubgroupMatrixInfo GatherSubgroupMatrixInfo(core::ir::Module& module);
|
||||
|
||||
} // namespace tint::core::ir::analysis
|
||||
|
||||
#endif // SRC_TINT_LANG_CORE_IR_ANALYSIS_SUBGROUP_MATRIX_H_
|
||||
48
3rdparty/dawn/src/tint/lang/core/ir/binary.cc
vendored
Normal file
48
3rdparty/dawn/src/tint/lang/core/ir/binary.cc
vendored
Normal file
@@ -0,0 +1,48 @@
|
||||
// Copyright 2022 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/core/ir/binary.h"
|
||||
|
||||
#include "src/tint/lang/core/ir/clone_context.h"
|
||||
#include "src/tint/lang/core/ir/module.h"
|
||||
|
||||
TINT_INSTANTIATE_TYPEINFO(tint::core::ir::Binary);
|
||||
|
||||
namespace tint::core::ir {
|
||||
|
||||
Binary::Binary(Id id) : Base(id) {}
|
||||
|
||||
Binary::Binary(Id id, InstructionResult* result, BinaryOp op, Value* lhs, Value* rhs)
|
||||
: Base(id), op_(op) {
|
||||
AddOperand(Binary::kLhsOperandOffset, lhs);
|
||||
AddOperand(Binary::kRhsOperandOffset, rhs);
|
||||
AddResult(result);
|
||||
}
|
||||
|
||||
Binary::~Binary() = default;
|
||||
|
||||
} // namespace tint::core::ir
|
||||
101
3rdparty/dawn/src/tint/lang/core/ir/binary.h
vendored
Normal file
101
3rdparty/dawn/src/tint/lang/core/ir/binary.h
vendored
Normal file
@@ -0,0 +1,101 @@
|
||||
// Copyright 2022 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.
|
||||
|
||||
#ifndef SRC_TINT_LANG_CORE_IR_BINARY_H_
|
||||
#define SRC_TINT_LANG_CORE_IR_BINARY_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "src/tint/lang/core/binary_op.h"
|
||||
#include "src/tint/lang/core/ir/operand_instruction.h"
|
||||
|
||||
// Forward declarations
|
||||
namespace tint::core::intrinsic {
|
||||
struct TableData;
|
||||
}
|
||||
|
||||
namespace tint::core::ir {
|
||||
|
||||
/// The abstract base class for dialect-specific binary-op instructions in the IR.
|
||||
class Binary : public Castable<Binary, OperandInstruction<2, 1>> {
|
||||
public:
|
||||
/// The offset in Operands() for the LHS
|
||||
static constexpr size_t kLhsOperandOffset = 0;
|
||||
|
||||
/// The offset in Operands() for the RHS
|
||||
static constexpr size_t kRhsOperandOffset = 1;
|
||||
|
||||
/// The fixed number of results returned by binary instructions
|
||||
static constexpr size_t kNumResults = 1;
|
||||
|
||||
/// The fixed number of operands expected for binary instructions
|
||||
static constexpr size_t kNumOperands = 2;
|
||||
|
||||
/// Constructor (no results, no operands)
|
||||
/// @param id the instruction id
|
||||
explicit Binary(Id id);
|
||||
|
||||
/// Constructor
|
||||
/// @param id the instruction id
|
||||
/// @param result the result value
|
||||
/// @param op the binary operator
|
||||
/// @param lhs the lhs of the instruction
|
||||
/// @param rhs the rhs of the instruction
|
||||
Binary(Id id, InstructionResult* result, BinaryOp op, Value* lhs, Value* rhs);
|
||||
~Binary() override;
|
||||
|
||||
/// @returns the binary operator
|
||||
BinaryOp Op() const { return op_; }
|
||||
|
||||
/// @param op the new binary operator
|
||||
void SetOp(BinaryOp op) { op_ = op; }
|
||||
|
||||
/// @returns the left-hand-side value for the instruction
|
||||
Value* LHS() { return Operand(kLhsOperandOffset); }
|
||||
|
||||
/// @returns the left-hand-side value for the instruction
|
||||
const Value* LHS() const { return Operand(kLhsOperandOffset); }
|
||||
|
||||
/// @returns the right-hand-side value for the instruction
|
||||
Value* RHS() { return Operand(kRhsOperandOffset); }
|
||||
|
||||
/// @returns the right-hand-side value for the instruction
|
||||
const Value* RHS() const { return Operand(kRhsOperandOffset); }
|
||||
|
||||
/// @returns the friendly name for the instruction
|
||||
std::string FriendlyName() const override { return "binary"; }
|
||||
|
||||
/// @returns the table data to validate this builtin
|
||||
virtual const core::intrinsic::TableData& TableData() const = 0;
|
||||
|
||||
private:
|
||||
BinaryOp op_ = BinaryOp::kAdd;
|
||||
};
|
||||
|
||||
} // namespace tint::core::ir
|
||||
|
||||
#endif // SRC_TINT_LANG_CORE_IR_BINARY_H_
|
||||
2097
3rdparty/dawn/src/tint/lang/core/ir/binary/decode.cc
vendored
Normal file
2097
3rdparty/dawn/src/tint/lang/core/ir/binary/decode.cc
vendored
Normal file
File diff suppressed because it is too large
Load Diff
53
3rdparty/dawn/src/tint/lang/core/ir/binary/decode.h
vendored
Normal file
53
3rdparty/dawn/src/tint/lang/core/ir/binary/decode.h
vendored
Normal file
@@ -0,0 +1,53 @@
|
||||
// Copyright 2023 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.
|
||||
|
||||
#ifndef SRC_TINT_LANG_CORE_IR_BINARY_DECODE_H_
|
||||
#define SRC_TINT_LANG_CORE_IR_BINARY_DECODE_H_
|
||||
|
||||
#include <span>
|
||||
|
||||
#include "src/tint/utils/result.h"
|
||||
|
||||
// Forward declarations
|
||||
namespace tint::core::ir {
|
||||
class Module;
|
||||
} // namespace tint::core::ir
|
||||
namespace tint::core::ir::binary::pb {
|
||||
class Module;
|
||||
} // namespace tint::core::ir::binary::pb
|
||||
|
||||
namespace tint::core::ir::binary {
|
||||
|
||||
/// @returns the decoded Module from the serialized protobuf.
|
||||
Result<Module> Decode(std::span<const std::byte> encoded);
|
||||
|
||||
/// @returns the decoded Module from the protobuf.
|
||||
Result<Module> Decode(const pb::Module& module);
|
||||
|
||||
} // namespace tint::core::ir::binary
|
||||
|
||||
#endif // SRC_TINT_LANG_CORE_IR_BINARY_DECODE_H_
|
||||
1462
3rdparty/dawn/src/tint/lang/core/ir/binary/encode.cc
vendored
Normal file
1462
3rdparty/dawn/src/tint/lang/core/ir/binary/encode.cc
vendored
Normal file
File diff suppressed because it is too large
Load Diff
55
3rdparty/dawn/src/tint/lang/core/ir/binary/encode.h
vendored
Normal file
55
3rdparty/dawn/src/tint/lang/core/ir/binary/encode.h
vendored
Normal file
@@ -0,0 +1,55 @@
|
||||
// Copyright 2023 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.
|
||||
|
||||
#ifndef SRC_TINT_LANG_CORE_IR_BINARY_ENCODE_H_
|
||||
#define SRC_TINT_LANG_CORE_IR_BINARY_ENCODE_H_
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "src/tint/utils/containers/vector.h"
|
||||
#include "src/tint/utils/result.h"
|
||||
|
||||
// Forward declarations
|
||||
namespace tint::core::ir {
|
||||
class Module;
|
||||
} // namespace tint::core::ir
|
||||
|
||||
namespace tint::core::ir::binary::pb {
|
||||
class Module;
|
||||
}
|
||||
|
||||
namespace tint::core::ir::binary {
|
||||
|
||||
// Encode the module into a proto representation.
|
||||
Result<std::unique_ptr<pb::Module>> EncodeToProto(const Module& module);
|
||||
|
||||
// Encode the module into a binary representation.
|
||||
Result<Vector<std::byte, 0>> EncodeToBinary(const Module& module);
|
||||
|
||||
} // namespace tint::core::ir::binary
|
||||
|
||||
#endif // SRC_TINT_LANG_CORE_IR_BINARY_ENCODE_H_
|
||||
52
3rdparty/dawn/src/tint/lang/core/ir/bitcast.cc
vendored
Normal file
52
3rdparty/dawn/src/tint/lang/core/ir/bitcast.cc
vendored
Normal file
@@ -0,0 +1,52 @@
|
||||
// Copyright 2023 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/core/ir/bitcast.h"
|
||||
|
||||
#include "src/tint/lang/core/ir/clone_context.h"
|
||||
#include "src/tint/lang/core/ir/module.h"
|
||||
|
||||
TINT_INSTANTIATE_TYPEINFO(tint::core::ir::Bitcast);
|
||||
|
||||
namespace tint::core::ir {
|
||||
|
||||
Bitcast::Bitcast(Id id) : Base(id) {}
|
||||
|
||||
Bitcast::Bitcast(Id id, InstructionResult* result, Value* val) : Base(id) {
|
||||
AddOperand(Bitcast::kValueOperandOffset, val);
|
||||
AddResult(result);
|
||||
}
|
||||
|
||||
Bitcast::~Bitcast() = default;
|
||||
|
||||
Bitcast* Bitcast::Clone(CloneContext& ctx) {
|
||||
auto* new_result = ctx.Clone(Result());
|
||||
auto* val = ctx.Remap(Val());
|
||||
return ctx.ir.CreateInstruction<Bitcast>(new_result, val);
|
||||
}
|
||||
|
||||
} // namespace tint::core::ir
|
||||
80
3rdparty/dawn/src/tint/lang/core/ir/bitcast.h
vendored
Normal file
80
3rdparty/dawn/src/tint/lang/core/ir/bitcast.h
vendored
Normal file
@@ -0,0 +1,80 @@
|
||||
// Copyright 2023 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.
|
||||
|
||||
#ifndef SRC_TINT_LANG_CORE_IR_BITCAST_H_
|
||||
#define SRC_TINT_LANG_CORE_IR_BITCAST_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "src/tint/lang/core/ir/call.h"
|
||||
#include "src/tint/utils/rtti/castable.h"
|
||||
|
||||
namespace tint::core::ir {
|
||||
|
||||
/// A bitcast instruction in the IR.
|
||||
class Bitcast final : public Castable<Bitcast, Call> {
|
||||
public:
|
||||
/// The offset in Operands() for the value
|
||||
static constexpr size_t kValueOperandOffset = 0;
|
||||
|
||||
/// The fixed number of results returned by this instruction
|
||||
static constexpr size_t kNumResults = 1;
|
||||
|
||||
/// The fixed number of operands expected for this instruction
|
||||
static constexpr size_t kNumOperands = 1;
|
||||
|
||||
/// Constructor (no results, no operands)
|
||||
/// @param id the instruction id
|
||||
explicit Bitcast(Id id);
|
||||
|
||||
/// Constructor
|
||||
/// @param id the instruction id
|
||||
/// @param result the result value
|
||||
/// @param val the value being bitcast
|
||||
Bitcast(Id id, InstructionResult* result, Value* val);
|
||||
|
||||
~Bitcast() override;
|
||||
|
||||
/// @copydoc Instruction::Clone()
|
||||
Bitcast* Clone(CloneContext& ctx) override;
|
||||
|
||||
/// @returns the operand value
|
||||
Value* Val() { return Operand(kValueOperandOffset); }
|
||||
|
||||
/// @returns the operand value
|
||||
const Value* Val() const { return Operand(kValueOperandOffset); }
|
||||
|
||||
/// @returns the friendly name for the instruction
|
||||
std::string FriendlyName() const override { return "bitcast"; }
|
||||
|
||||
/// @returns an empty access as the bitcast neither loads nor stores.
|
||||
Accesses GetSideEffects() const override { return Accesses{}; }
|
||||
};
|
||||
|
||||
} // namespace tint::core::ir
|
||||
|
||||
#endif // SRC_TINT_LANG_CORE_IR_BITCAST_H_
|
||||
207
3rdparty/dawn/src/tint/lang/core/ir/block.cc
vendored
Normal file
207
3rdparty/dawn/src/tint/lang/core/ir/block.cc
vendored
Normal file
@@ -0,0 +1,207 @@
|
||||
// Copyright 2022 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/core/ir/block.h"
|
||||
|
||||
#include "src/tint/lang/core/ir/clone_context.h"
|
||||
#include "src/tint/lang/core/ir/control_instruction.h"
|
||||
#include "src/tint/lang/core/ir/module.h"
|
||||
#include "src/tint/utils/ice/ice.h"
|
||||
|
||||
TINT_INSTANTIATE_TYPEINFO(tint::core::ir::Block);
|
||||
|
||||
namespace tint::core::ir {
|
||||
|
||||
Block::Block() : Base() {}
|
||||
|
||||
Block::~Block() = default;
|
||||
|
||||
Block* Block::Clone(CloneContext&) {
|
||||
TINT_UNREACHABLE() << "blocks must be cloned with CloneInto";
|
||||
}
|
||||
|
||||
void Block::CloneInto(CloneContext& ctx, Block* out) {
|
||||
// Note, the `parent_` is not cloned here. Doing so can end up in infinite loops as we try to
|
||||
// clone a control instruction and the blocks inside of it. The `parent_` pointer should be set
|
||||
// by the control instructions constructor.
|
||||
|
||||
for (auto* inst_in : *this) {
|
||||
auto* inst_out = inst_in->Clone(ctx);
|
||||
auto results_out = inst_out->Results();
|
||||
auto results_in = inst_in->Results();
|
||||
TINT_ASSERT(results_out.Length() == results_in.Length());
|
||||
|
||||
size_t len = results_out.Length();
|
||||
for (size_t i = 0; i < len; ++i) {
|
||||
ctx.Replace(results_in[i], results_out[i]);
|
||||
}
|
||||
out->Append(inst_out);
|
||||
}
|
||||
}
|
||||
|
||||
Instruction* Block::Prepend(Instruction* inst) {
|
||||
TINT_ASSERT(inst);
|
||||
TINT_ASSERT(inst->Block() == nullptr);
|
||||
|
||||
inst->SetBlock(this);
|
||||
instructions_.count += 1;
|
||||
|
||||
if (instructions_.first == nullptr) {
|
||||
instructions_.first = inst;
|
||||
instructions_.last = inst;
|
||||
} else {
|
||||
inst->next = instructions_.first;
|
||||
instructions_.first->prev = inst;
|
||||
instructions_.first = inst;
|
||||
}
|
||||
|
||||
return inst;
|
||||
}
|
||||
|
||||
Instruction* Block::Append(Instruction* inst) {
|
||||
TINT_ASSERT(inst);
|
||||
TINT_ASSERT(inst->Block() == nullptr);
|
||||
|
||||
inst->SetBlock(this);
|
||||
instructions_.count += 1;
|
||||
|
||||
if (instructions_.first == nullptr) {
|
||||
instructions_.first = inst;
|
||||
instructions_.last = inst;
|
||||
} else {
|
||||
inst->prev = instructions_.last;
|
||||
instructions_.last->next = inst;
|
||||
instructions_.last = inst;
|
||||
}
|
||||
|
||||
return inst;
|
||||
}
|
||||
|
||||
void Block::InsertBefore(Instruction* before, Instruction* inst) {
|
||||
TINT_ASSERT(before);
|
||||
TINT_ASSERT(inst);
|
||||
TINT_ASSERT(before->Block() == this);
|
||||
TINT_ASSERT(inst->Block() == nullptr);
|
||||
|
||||
inst->SetBlock(this);
|
||||
instructions_.count += 1;
|
||||
|
||||
inst->next = before;
|
||||
inst->prev = before->prev;
|
||||
before->prev = inst;
|
||||
|
||||
if (inst->prev) {
|
||||
inst->prev->next = inst;
|
||||
}
|
||||
|
||||
if (before == instructions_.first) {
|
||||
instructions_.first = inst;
|
||||
}
|
||||
}
|
||||
|
||||
void Block::InsertAfter(Instruction* after, Instruction* inst) {
|
||||
TINT_ASSERT(after);
|
||||
TINT_ASSERT(inst);
|
||||
TINT_ASSERT(after->Block() == this);
|
||||
TINT_ASSERT(inst->Block() == nullptr);
|
||||
|
||||
inst->SetBlock(this);
|
||||
instructions_.count += 1;
|
||||
|
||||
inst->prev = after;
|
||||
inst->next = after->next;
|
||||
after->next = inst;
|
||||
|
||||
if (inst->next) {
|
||||
inst->next->prev = inst;
|
||||
}
|
||||
if (after == instructions_.last) {
|
||||
instructions_.last = inst;
|
||||
}
|
||||
}
|
||||
|
||||
void Block::Replace(Instruction* target, Instruction* inst) {
|
||||
TINT_ASSERT(target);
|
||||
TINT_ASSERT(inst);
|
||||
TINT_ASSERT(target->Block() == this);
|
||||
TINT_ASSERT(inst->Block() == nullptr);
|
||||
|
||||
inst->SetBlock(this);
|
||||
target->SetBlock(nullptr);
|
||||
|
||||
inst->next = target->next;
|
||||
inst->prev = target->prev;
|
||||
|
||||
target->next = nullptr;
|
||||
target->prev = nullptr;
|
||||
|
||||
if (inst->next) {
|
||||
inst->next->prev = inst;
|
||||
}
|
||||
if (inst->prev) {
|
||||
inst->prev->next = inst;
|
||||
}
|
||||
|
||||
if (target == instructions_.first) {
|
||||
instructions_.first = inst;
|
||||
}
|
||||
if (target == instructions_.last) {
|
||||
instructions_.last = inst;
|
||||
}
|
||||
}
|
||||
|
||||
void Block::Remove(Instruction* inst) {
|
||||
TINT_ASSERT(inst);
|
||||
TINT_ASSERT(inst->Block() == this);
|
||||
|
||||
inst->SetBlock(nullptr);
|
||||
instructions_.count -= 1;
|
||||
|
||||
if (inst->prev) {
|
||||
inst->prev->next = inst->next;
|
||||
}
|
||||
if (inst->next) {
|
||||
inst->next->prev = inst->prev;
|
||||
}
|
||||
if (inst == instructions_.first) {
|
||||
instructions_.first = inst->next;
|
||||
}
|
||||
if (inst == instructions_.last) {
|
||||
instructions_.last = inst->prev;
|
||||
}
|
||||
|
||||
inst->prev = nullptr;
|
||||
inst->next = nullptr;
|
||||
}
|
||||
|
||||
void Block::Destroy() {
|
||||
while (instructions_.first) {
|
||||
instructions_.first->Destroy();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace tint::core::ir
|
||||
194
3rdparty/dawn/src/tint/lang/core/ir/block.h
vendored
Normal file
194
3rdparty/dawn/src/tint/lang/core/ir/block.h
vendored
Normal file
@@ -0,0 +1,194 @@
|
||||
// Copyright 2022 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.
|
||||
|
||||
#ifndef SRC_TINT_LANG_CORE_IR_BLOCK_H_
|
||||
#define SRC_TINT_LANG_CORE_IR_BLOCK_H_
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include "src/tint/lang/core/ir/instruction.h"
|
||||
#include "src/tint/lang/core/ir/terminator.h"
|
||||
#include "src/tint/utils/containers/vector.h"
|
||||
|
||||
// Forward declarations
|
||||
namespace tint::core::ir {
|
||||
class ControlInstruction;
|
||||
} // namespace tint::core::ir
|
||||
|
||||
namespace tint::core::ir {
|
||||
|
||||
/// A block of statements. The instructions in the block are a linear list of instructions to
|
||||
/// execute. The block will terminate with a Terminator instruction at the end.
|
||||
/// The instructions are held in a doubly-linked list with explicit first and last pointer,
|
||||
/// and with an explicit count.
|
||||
class Block : public Castable<Block> {
|
||||
public:
|
||||
/// Constructor
|
||||
Block();
|
||||
~Block() override;
|
||||
|
||||
/// @param ctx the CloneContext used to clone this block
|
||||
/// @returns a clone of this block
|
||||
virtual Block* Clone(CloneContext& ctx);
|
||||
|
||||
/// Clones the block contents into the given block
|
||||
/// @param ctx the CloneContext used to clone
|
||||
/// @param out the block to clone into
|
||||
virtual void CloneInto(CloneContext& ctx, Block* out);
|
||||
|
||||
/// @return the terminator instruction for this block, or nullptr if this block does not end in
|
||||
/// a terminator.
|
||||
ir::Terminator* Terminator() { return tint::As<ir::Terminator>(instructions_.last); }
|
||||
|
||||
/// @return the terminator instruction for this block, or nullptr if this block does not end in
|
||||
/// a terminator.
|
||||
const ir::Terminator* Terminator() const {
|
||||
return tint::As<ir::Terminator>(instructions_.last);
|
||||
}
|
||||
|
||||
/// @returns the instructions in the block
|
||||
Instruction* Instructions() { return instructions_.first; }
|
||||
|
||||
/// @returns the instructions in the block
|
||||
const Instruction* Instructions() const { return instructions_.first; }
|
||||
|
||||
/// Iterator for the instructions inside a block
|
||||
template <typename T>
|
||||
class Iterator {
|
||||
public:
|
||||
/// Constructor
|
||||
/// @param inst the instruction to start iterating from
|
||||
explicit Iterator(T* inst) : inst_(inst) {}
|
||||
~Iterator() = default;
|
||||
|
||||
/// Dereference operator
|
||||
/// @returns the instruction for this iterator
|
||||
T* operator*() const { return inst_; }
|
||||
|
||||
/// Comparison operator
|
||||
/// @param itr to compare against
|
||||
/// @returns true if this iterator and @p itr point to the same instruction
|
||||
bool operator==(const Iterator& itr) const { return itr.inst_ == inst_; }
|
||||
|
||||
/// Not equal operator
|
||||
/// @param itr to compare against
|
||||
/// @returns true if this iterator and @p itr point to different instructions
|
||||
bool operator!=(const Iterator& itr) const { return !(*this == itr); }
|
||||
|
||||
/// Increment operator
|
||||
/// @returns this iterator advanced to the next element
|
||||
Iterator& operator++() {
|
||||
inst_ = inst_->next;
|
||||
return *this;
|
||||
}
|
||||
|
||||
private:
|
||||
T* inst_ = nullptr;
|
||||
};
|
||||
|
||||
/// @returns the iterator pointing to the start of the instruction list
|
||||
Iterator<Instruction> begin() { return Iterator<Instruction>{instructions_.first}; }
|
||||
|
||||
/// @returns the ending iterator
|
||||
Iterator<Instruction> end() { return Iterator<Instruction>{nullptr}; }
|
||||
|
||||
/// @returns the iterator pointing to the start of the instruction list
|
||||
Iterator<const Instruction> begin() const {
|
||||
return Iterator<const Instruction>{instructions_.first};
|
||||
}
|
||||
|
||||
/// @returns the ending iterator
|
||||
Iterator<const Instruction> end() const { return Iterator<const Instruction>{nullptr}; }
|
||||
|
||||
/// @returns the first instruction in the instruction list
|
||||
Instruction* Front() { return instructions_.first; }
|
||||
|
||||
/// @returns the first instruction in the instruction list
|
||||
const Instruction* Front() const { return instructions_.first; }
|
||||
|
||||
/// @returns the last instruction in the instruction list
|
||||
Instruction* Back() { return instructions_.last; }
|
||||
|
||||
/// @returns the last instruction in the instruction list
|
||||
const Instruction* Back() const { return instructions_.last; }
|
||||
|
||||
/// Adds the instruction to the beginning of the block
|
||||
/// @param inst the instruction to add
|
||||
/// @returns the instruction to allow calls to be chained
|
||||
Instruction* Prepend(Instruction* inst);
|
||||
/// Adds the instruction to the end of the block
|
||||
/// @param inst the instruction to add
|
||||
/// @returns the instruction to allow calls to be chained
|
||||
Instruction* Append(Instruction* inst);
|
||||
/// Adds the new instruction before the given instruction
|
||||
/// @param before the instruction to insert before
|
||||
/// @param inst the instruction to insert
|
||||
void InsertBefore(Instruction* before, Instruction* inst);
|
||||
/// Adds the new instruction after the given instruction
|
||||
/// @param after the instruction to insert after
|
||||
/// @param inst the instruction to insert
|
||||
void InsertAfter(Instruction* after, Instruction* inst);
|
||||
/// Replaces the target instruction with the new instruction
|
||||
/// @param target the instruction to replace
|
||||
/// @param inst the instruction to insert
|
||||
void Replace(Instruction* target, Instruction* inst);
|
||||
/// Removes the target instruction
|
||||
/// @param inst the instruction to remove
|
||||
void Remove(Instruction* inst);
|
||||
|
||||
/// @returns true if the block contains no instructions
|
||||
bool IsEmpty() const { return Length() == 0; }
|
||||
|
||||
/// @returns the number of instructions in the block
|
||||
size_t Length() const { return instructions_.count; }
|
||||
|
||||
/// @return the parent instruction that owns this block
|
||||
ControlInstruction* Parent() { return parent_; }
|
||||
|
||||
/// @return the parent instruction that owns this block
|
||||
const ControlInstruction* Parent() const { return parent_; }
|
||||
|
||||
/// @param parent the parent instruction that owns this block
|
||||
void SetParent(ControlInstruction* parent) { parent_ = parent; }
|
||||
|
||||
/// Destroys the block and all of its instructions.
|
||||
void Destroy();
|
||||
|
||||
private:
|
||||
// The first and last pointers are null if and only if the list is empty.
|
||||
struct {
|
||||
Instruction* first = nullptr;
|
||||
Instruction* last = nullptr;
|
||||
size_t count = 0;
|
||||
} instructions_;
|
||||
|
||||
ControlInstruction* parent_ = nullptr;
|
||||
};
|
||||
|
||||
} // namespace tint::core::ir
|
||||
|
||||
#endif // SRC_TINT_LANG_CORE_IR_BLOCK_H_
|
||||
54
3rdparty/dawn/src/tint/lang/core/ir/block_param.cc
vendored
Normal file
54
3rdparty/dawn/src/tint/lang/core/ir/block_param.cc
vendored
Normal file
@@ -0,0 +1,54 @@
|
||||
// Copyright 2023 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/core/ir/block_param.h"
|
||||
|
||||
#include "src/tint/lang/core/ir/clone_context.h"
|
||||
#include "src/tint/lang/core/ir/module.h"
|
||||
#include "src/tint/utils/ice/ice.h"
|
||||
|
||||
TINT_INSTANTIATE_TYPEINFO(tint::core::ir::BlockParam);
|
||||
|
||||
namespace tint::core::ir {
|
||||
|
||||
BlockParam::BlockParam(const core::type::Type* ty) : Base(ty) {
|
||||
TINT_ASSERT(ty != nullptr);
|
||||
}
|
||||
|
||||
BlockParam::~BlockParam() = default;
|
||||
|
||||
BlockParam* BlockParam::Clone(CloneContext& ctx) {
|
||||
auto* new_bp = ctx.ir.CreateValue<BlockParam>(Type());
|
||||
|
||||
auto name = ctx.ir.NameOf(this);
|
||||
if (name.IsValid()) {
|
||||
ctx.ir.SetName(new_bp, ctx.ir.NameOf(this).Name());
|
||||
}
|
||||
return new_bp;
|
||||
}
|
||||
|
||||
} // namespace tint::core::ir
|
||||
69
3rdparty/dawn/src/tint/lang/core/ir/block_param.h
vendored
Normal file
69
3rdparty/dawn/src/tint/lang/core/ir/block_param.h
vendored
Normal file
@@ -0,0 +1,69 @@
|
||||
// Copyright 2023 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.
|
||||
|
||||
#ifndef SRC_TINT_LANG_CORE_IR_BLOCK_PARAM_H_
|
||||
#define SRC_TINT_LANG_CORE_IR_BLOCK_PARAM_H_
|
||||
|
||||
#include "src/tint/lang/core/ir/value.h"
|
||||
#include "src/tint/utils/rtti/castable.h"
|
||||
|
||||
// Forward declarations
|
||||
namespace tint::core::ir {
|
||||
class MultiInBlock;
|
||||
} // namespace tint::core::ir
|
||||
|
||||
namespace tint::core::ir {
|
||||
|
||||
/// A block parameter in the IR.
|
||||
class BlockParam : public Castable<BlockParam, Value> {
|
||||
public:
|
||||
/// Constructor
|
||||
/// @param type the type of the parameter
|
||||
explicit BlockParam(const core::type::Type* type);
|
||||
~BlockParam() override;
|
||||
|
||||
/// Sets the block that this parameter belongs to.
|
||||
/// @param block the block
|
||||
void SetBlock(MultiInBlock* block) { block_ = block; }
|
||||
|
||||
/// @returns the block that this parameter belongs to, or nullptr
|
||||
MultiInBlock* Block() { return block_; }
|
||||
|
||||
/// @returns the block that this parameter belongs to, or nullptr
|
||||
const MultiInBlock* Block() const { return block_; }
|
||||
|
||||
/// @copydoc Instruction::Clone()
|
||||
BlockParam* Clone(CloneContext& ctx) override;
|
||||
|
||||
private:
|
||||
/// the block that the parameter belongs to
|
||||
MultiInBlock* block_ = nullptr;
|
||||
};
|
||||
|
||||
} // namespace tint::core::ir
|
||||
|
||||
#endif // SRC_TINT_LANG_CORE_IR_BLOCK_PARAM_H_
|
||||
90
3rdparty/dawn/src/tint/lang/core/ir/break_if.cc
vendored
Normal file
90
3rdparty/dawn/src/tint/lang/core/ir/break_if.cc
vendored
Normal file
@@ -0,0 +1,90 @@
|
||||
// Copyright 2023 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/core/ir/break_if.h"
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include "src/tint/lang/core/ir/block.h"
|
||||
#include "src/tint/lang/core/ir/clone_context.h"
|
||||
#include "src/tint/lang/core/ir/loop.h"
|
||||
#include "src/tint/lang/core/ir/module.h"
|
||||
#include "src/tint/lang/core/ir/multi_in_block.h"
|
||||
#include "src/tint/utils/ice/ice.h"
|
||||
|
||||
TINT_INSTANTIATE_TYPEINFO(tint::core::ir::BreakIf);
|
||||
|
||||
namespace tint::core::ir {
|
||||
|
||||
BreakIf::BreakIf(Id id) : Base(id) {}
|
||||
|
||||
BreakIf::BreakIf(Id id,
|
||||
Value* condition,
|
||||
ir::Loop* loop,
|
||||
VectorRef<Value*> next_iter_values /* = tint::Empty */,
|
||||
VectorRef<Value*> exit_values /* = tint::Empty */)
|
||||
: Base(id), loop_(loop), num_next_iter_values_(next_iter_values.Length()) {
|
||||
TINT_ASSERT(loop_);
|
||||
|
||||
AddOperand(BreakIf::kConditionOperandOffset, condition);
|
||||
AddOperands(BreakIf::kArgsOperandOffset, std::move(next_iter_values));
|
||||
AddOperands(BreakIf::kArgsOperandOffset + num_next_iter_values_, std::move(exit_values));
|
||||
|
||||
if (loop_) {
|
||||
loop_->Body()->AddInboundSiblingBranch(this);
|
||||
SetControlInstruction(loop_);
|
||||
}
|
||||
}
|
||||
|
||||
BreakIf::~BreakIf() = default;
|
||||
|
||||
void BreakIf::Destroy() {
|
||||
if (loop_) {
|
||||
loop_->Body()->RemoveInboundSiblingBranch(this);
|
||||
}
|
||||
Instruction::Destroy();
|
||||
}
|
||||
|
||||
BreakIf* BreakIf::Clone(CloneContext& ctx) {
|
||||
auto* loop = ctx.Remap(loop_);
|
||||
auto* cond = ctx.Remap(Condition());
|
||||
auto args = ctx.Remap<BreakIf::kDefaultNumOperands>(Args());
|
||||
return ctx.ir.CreateInstruction<BreakIf>(cond, loop, args);
|
||||
}
|
||||
|
||||
void BreakIf::SetLoop(ir::Loop* loop) {
|
||||
if (loop_ && loop_->Body()) {
|
||||
loop_->Body()->RemoveInboundSiblingBranch(this);
|
||||
}
|
||||
loop_ = loop;
|
||||
SetControlInstruction(loop);
|
||||
if (loop) {
|
||||
loop->Body()->AddInboundSiblingBranch(this);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace tint::core::ir
|
||||
138
3rdparty/dawn/src/tint/lang/core/ir/break_if.h
vendored
Normal file
138
3rdparty/dawn/src/tint/lang/core/ir/break_if.h
vendored
Normal file
@@ -0,0 +1,138 @@
|
||||
// Copyright 2023 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.
|
||||
|
||||
#ifndef SRC_TINT_LANG_CORE_IR_BREAK_IF_H_
|
||||
#define SRC_TINT_LANG_CORE_IR_BREAK_IF_H_
|
||||
|
||||
#include <span>
|
||||
#include <string>
|
||||
|
||||
#include "src/tint/lang/core/ir/exit.h"
|
||||
#include "src/tint/lang/core/ir/value.h"
|
||||
#include "src/tint/utils/rtti/castable.h"
|
||||
|
||||
// Forward declarations
|
||||
namespace tint::core::ir {
|
||||
class Loop;
|
||||
} // namespace tint::core::ir
|
||||
|
||||
namespace tint::core::ir {
|
||||
|
||||
/// A break-if terminator instruction.
|
||||
class BreakIf final : public Castable<BreakIf, Exit> {
|
||||
public:
|
||||
/// The offset in Operands() for the condition
|
||||
static constexpr size_t kConditionOperandOffset = 0;
|
||||
|
||||
/// The base offset in Operands() for the arguments
|
||||
static constexpr size_t kArgsOperandOffset = 1;
|
||||
|
||||
/// Constructor (no operands, no loop)
|
||||
/// @param id the instruction id
|
||||
explicit BreakIf(Id id);
|
||||
|
||||
/// Constructor
|
||||
/// @param id the instruction id
|
||||
/// @param condition the break condition
|
||||
/// @param loop the loop containing the break-if
|
||||
/// @param next_iter_values the arguments passed to the loop body MultiInBlock, if the break
|
||||
/// condition evaluates to `false`.
|
||||
/// @param exit_values the values returned by the loop, if the break condition evaluates to
|
||||
/// `true`.
|
||||
BreakIf(Id id,
|
||||
Value* condition,
|
||||
ir::Loop* loop,
|
||||
VectorRef<Value*> next_iter_values = tint::Empty,
|
||||
VectorRef<Value*> exit_values = tint::Empty);
|
||||
|
||||
~BreakIf() override;
|
||||
|
||||
/// @copydoc Instruction::Destroy()
|
||||
void Destroy() override;
|
||||
|
||||
/// @copydoc Instruction::Clone()
|
||||
BreakIf* Clone(CloneContext& ctx) override;
|
||||
|
||||
/// @returns the offset of the arguments in Operands()
|
||||
size_t ArgsOperandOffset() const override { return kArgsOperandOffset; }
|
||||
|
||||
/// @returns the break condition
|
||||
Value* Condition() { return Operand(kConditionOperandOffset); }
|
||||
|
||||
/// @returns the break condition
|
||||
const Value* Condition() const { return Operand(kConditionOperandOffset); }
|
||||
|
||||
/// @returns the loop containing the break-if
|
||||
ir::Loop* Loop() { return loop_; }
|
||||
|
||||
/// @returns the loop containing the break-if
|
||||
const ir::Loop* Loop() const { return loop_; }
|
||||
|
||||
/// @param loop the new loop containing the continue
|
||||
void SetLoop(ir::Loop* loop);
|
||||
|
||||
/// @returns the friendly name for the instruction
|
||||
std::string FriendlyName() const override { return "break_if"; }
|
||||
|
||||
/// @returns the arguments passed to the loop body MultiInBlock, if the break condition
|
||||
/// evaluates to `false`.
|
||||
std::span<Value* const> NextIterValues() {
|
||||
return operands_.AsSpan().subspan(kArgsOperandOffset, num_next_iter_values_);
|
||||
}
|
||||
|
||||
/// @returns the arguments passed to the loop body MultiInBlock, if the break condition
|
||||
/// evaluates to `false`.
|
||||
std::span<const Value* const> NextIterValues() const {
|
||||
return operands_.AsSpan().subspan(kArgsOperandOffset, num_next_iter_values_);
|
||||
}
|
||||
|
||||
/// @returns the values returned by the loop, if the break condition evaluates to `true`.
|
||||
std::span<Value* const> ExitValues() {
|
||||
return operands_.AsSpan().subspan(kArgsOperandOffset + num_next_iter_values_);
|
||||
}
|
||||
|
||||
/// @returns the values returned by the loop, if the break condition evaluates to `true`.
|
||||
std::span<const Value* const> ExitValues() const {
|
||||
return operands_.AsSpan().subspan(kArgsOperandOffset + num_next_iter_values_);
|
||||
}
|
||||
|
||||
/// Sets the number of operands used as the next iterator values.
|
||||
/// The first @p num operands after kArgsOperandOffset are used as next iterator values,
|
||||
/// subsequent operators are used as exit values.
|
||||
void SetNumNextIterValues(size_t num) {
|
||||
TINT_ASSERT(operands_.Length() >= num + kArgsOperandOffset);
|
||||
num_next_iter_values_ = num;
|
||||
}
|
||||
|
||||
private:
|
||||
ir::Loop* loop_ = nullptr;
|
||||
size_t num_next_iter_values_ = 0;
|
||||
};
|
||||
|
||||
} // namespace tint::core::ir
|
||||
|
||||
#endif // SRC_TINT_LANG_CORE_IR_BREAK_IF_H_
|
||||
154
3rdparty/dawn/src/tint/lang/core/ir/builder.cc
vendored
Normal file
154
3rdparty/dawn/src/tint/lang/core/ir/builder.cc
vendored
Normal file
@@ -0,0 +1,154 @@
|
||||
// Copyright 2022 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/core/ir/builder.h"
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include "src/tint/lang/core/constant/scalar.h"
|
||||
#include "src/tint/lang/core/type/function.h"
|
||||
#include "src/tint/lang/core/type/pointer.h"
|
||||
#include "src/tint/lang/core/type/reference.h"
|
||||
#include "src/tint/utils/ice/ice.h"
|
||||
|
||||
namespace tint::core::ir {
|
||||
|
||||
Builder::Builder(Module& mod) : ir(mod) {}
|
||||
|
||||
Builder::Builder(Module& mod, ir::Block* block)
|
||||
: insertion_point_(InsertionPoints::AppendToBlock{block}), ir(mod) {}
|
||||
|
||||
Builder::~Builder() = default;
|
||||
|
||||
Block* Builder::Block() {
|
||||
return ir.blocks.Create<ir::Block>();
|
||||
}
|
||||
|
||||
MultiInBlock* Builder::MultiInBlock() {
|
||||
return ir.blocks.Create<ir::MultiInBlock>();
|
||||
}
|
||||
|
||||
Function* Builder::Function(const core::type::Type* return_type, Function::PipelineStage stage) {
|
||||
auto* ir_func = ir.CreateValue<ir::Function>(ir.Types().function(), return_type, stage);
|
||||
ir_func->SetBlock(Block());
|
||||
ir.functions.Push(ir_func);
|
||||
return ir_func;
|
||||
}
|
||||
|
||||
Function* Builder::Function(std::string_view name,
|
||||
const core::type::Type* return_type,
|
||||
Function::PipelineStage stage) {
|
||||
auto* ir_func = Function(return_type, stage);
|
||||
ir.SetName(ir_func, name);
|
||||
return ir_func;
|
||||
}
|
||||
|
||||
ir::Loop* Builder::Loop() {
|
||||
return Append(ir.CreateInstruction<ir::Loop>(Block(), MultiInBlock(), MultiInBlock()));
|
||||
}
|
||||
|
||||
Block* Builder::Case(ir::Switch* s, VectorRef<ir::Constant*> values) {
|
||||
auto* block = Block();
|
||||
|
||||
Switch::Case c;
|
||||
c.block = block;
|
||||
for (auto* value : values) {
|
||||
c.selectors.Push(Switch::CaseSelector{value});
|
||||
}
|
||||
s->Cases().Push(std::move(c));
|
||||
block->SetParent(s);
|
||||
return block;
|
||||
}
|
||||
|
||||
Block* Builder::DefaultCase(ir::Switch* s) {
|
||||
return Case(s, Vector<ir::Constant*, 1>{nullptr});
|
||||
}
|
||||
|
||||
Block* Builder::Case(ir::Switch* s, std::initializer_list<ir::Constant*> selectors) {
|
||||
return Case(s, Vector<ir::Constant*, 4>(selectors));
|
||||
}
|
||||
|
||||
ir::Discard* Builder::Discard() {
|
||||
return Append(ir.CreateInstruction<ir::Discard>());
|
||||
}
|
||||
|
||||
ir::Var* Builder::Var(const core::type::MemoryView* type) {
|
||||
return Append(ir.CreateInstruction<ir::Var>(InstructionResult(type)));
|
||||
}
|
||||
|
||||
ir::Var* Builder::Var(std::string_view name, const core::type::MemoryView* type) {
|
||||
auto* var = Var(type);
|
||||
ir.SetName(var, name);
|
||||
return var;
|
||||
}
|
||||
|
||||
ir::BlockParam* Builder::BlockParam(const core::type::Type* type) {
|
||||
return ir.CreateValue<ir::BlockParam>(type);
|
||||
}
|
||||
|
||||
ir::BlockParam* Builder::BlockParam(std::string_view name, const core::type::Type* type) {
|
||||
auto* param = ir.CreateValue<ir::BlockParam>(type);
|
||||
ir.SetName(param, name);
|
||||
return param;
|
||||
}
|
||||
|
||||
ir::FunctionParam* Builder::FunctionParam(const core::type::Type* type) {
|
||||
return ir.CreateValue<ir::FunctionParam>(type);
|
||||
}
|
||||
|
||||
ir::FunctionParam* Builder::FunctionParam(std::string_view name, const core::type::Type* type) {
|
||||
auto* param = ir.CreateValue<ir::FunctionParam>(type);
|
||||
ir.SetName(param, name);
|
||||
return param;
|
||||
}
|
||||
|
||||
ir::TerminateInvocation* Builder::TerminateInvocation() {
|
||||
return Append(ir.CreateInstruction<ir::TerminateInvocation>());
|
||||
}
|
||||
|
||||
ir::Unreachable* Builder::Unreachable() {
|
||||
return Append(ir.CreateInstruction<ir::Unreachable>());
|
||||
}
|
||||
|
||||
ir::Unused* Builder::Unused() {
|
||||
return ir.CreateValue<ir::Unused>();
|
||||
}
|
||||
|
||||
const core::type::Type* Builder::VectorPtrElementType(const core::type::Type* type) {
|
||||
auto* vec_ptr_ty = type->As<core::type::Pointer>();
|
||||
TINT_ASSERT(vec_ptr_ty);
|
||||
if (DAWN_LIKELY(vec_ptr_ty)) {
|
||||
auto* vec_ty = vec_ptr_ty->StoreType()->As<core::type::Vector>();
|
||||
TINT_ASSERT(vec_ty);
|
||||
if (DAWN_LIKELY(vec_ty)) {
|
||||
return vec_ty->Type();
|
||||
}
|
||||
}
|
||||
return ir.Types().i32();
|
||||
}
|
||||
|
||||
} // namespace tint::core::ir
|
||||
1978
3rdparty/dawn/src/tint/lang/core/ir/builder.h
vendored
Normal file
1978
3rdparty/dawn/src/tint/lang/core/ir/builder.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
48
3rdparty/dawn/src/tint/lang/core/ir/builtin_call.cc
vendored
Normal file
48
3rdparty/dawn/src/tint/lang/core/ir/builtin_call.cc
vendored
Normal file
@@ -0,0 +1,48 @@
|
||||
// Copyright 2023 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/core/ir/builtin_call.h"
|
||||
|
||||
#include <utility>
|
||||
|
||||
TINT_INSTANTIATE_TYPEINFO(tint::core::ir::BuiltinCall);
|
||||
|
||||
namespace tint::core::ir {
|
||||
|
||||
BuiltinCall::BuiltinCall(Id id) : Base(id) {
|
||||
flags_.Add(Flag::kSequenced);
|
||||
}
|
||||
|
||||
BuiltinCall::BuiltinCall(Id id, InstructionResult* result, VectorRef<Value*> arguments) : Base(id) {
|
||||
flags_.Add(Flag::kSequenced);
|
||||
AddOperands(BuiltinCall::kArgsOperandOffset, std::move(arguments));
|
||||
AddResult(result);
|
||||
}
|
||||
|
||||
BuiltinCall::~BuiltinCall() = default;
|
||||
|
||||
} // namespace tint::core::ir
|
||||
67
3rdparty/dawn/src/tint/lang/core/ir/builtin_call.h
vendored
Normal file
67
3rdparty/dawn/src/tint/lang/core/ir/builtin_call.h
vendored
Normal file
@@ -0,0 +1,67 @@
|
||||
// Copyright 2023 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.
|
||||
|
||||
#ifndef SRC_TINT_LANG_CORE_IR_BUILTIN_CALL_H_
|
||||
#define SRC_TINT_LANG_CORE_IR_BUILTIN_CALL_H_
|
||||
|
||||
#include "src/tint/lang/core/intrinsic/table_data.h"
|
||||
#include "src/tint/lang/core/ir/call.h"
|
||||
#include "src/tint/utils/rtti/castable.h"
|
||||
|
||||
namespace tint::core::ir {
|
||||
|
||||
/// The base class for builtin call instructions in the IR.
|
||||
class BuiltinCall : public Castable<BuiltinCall, Call> {
|
||||
public:
|
||||
/// The fixed number of results returned by this instruction
|
||||
static constexpr size_t kNumResults = 1;
|
||||
|
||||
/// The base offset in Operands() for the args
|
||||
static constexpr size_t kArgsOperandOffset = 0;
|
||||
|
||||
/// Constructor (no results, no operands)
|
||||
/// @param id the instruction id
|
||||
explicit BuiltinCall(Id id);
|
||||
|
||||
/// Constructor
|
||||
/// @param id the instruction id
|
||||
/// @param result the result value
|
||||
/// @param args the conversion arguments
|
||||
BuiltinCall(Id id, InstructionResult* result, VectorRef<Value*> args = tint::Empty);
|
||||
|
||||
~BuiltinCall() override;
|
||||
|
||||
/// @returns the identifier for the function
|
||||
virtual size_t FuncId() const = 0;
|
||||
|
||||
/// @returns the table data to validate this builtin
|
||||
virtual const core::intrinsic::TableData& TableData() const = 0;
|
||||
};
|
||||
|
||||
} // namespace tint::core::ir
|
||||
|
||||
#endif // SRC_TINT_LANG_CORE_IR_BUILTIN_CALL_H_
|
||||
38
3rdparty/dawn/src/tint/lang/core/ir/call.cc
vendored
Normal file
38
3rdparty/dawn/src/tint/lang/core/ir/call.cc
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
// Copyright 2023 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/core/ir/call.h"
|
||||
|
||||
TINT_INSTANTIATE_TYPEINFO(tint::core::ir::Call);
|
||||
|
||||
namespace tint::core::ir {
|
||||
|
||||
Call::Call(Id id) : Base(id) {}
|
||||
|
||||
Call::~Call() = default;
|
||||
|
||||
} // namespace tint::core::ir
|
||||
84
3rdparty/dawn/src/tint/lang/core/ir/call.h
vendored
Normal file
84
3rdparty/dawn/src/tint/lang/core/ir/call.h
vendored
Normal file
@@ -0,0 +1,84 @@
|
||||
// Copyright 2023 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.
|
||||
|
||||
#ifndef SRC_TINT_LANG_CORE_IR_CALL_H_
|
||||
#define SRC_TINT_LANG_CORE_IR_CALL_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "src/tint/lang/core/ir/operand_instruction.h"
|
||||
#include "src/tint/lang/core/type/type.h"
|
||||
#include "src/tint/utils/rtti/castable.h"
|
||||
|
||||
namespace tint::core::ir {
|
||||
|
||||
/// A Call instruction in the IR.
|
||||
class Call : public Castable<Call, OperandInstruction<4, 1>> {
|
||||
public:
|
||||
~Call() override;
|
||||
|
||||
/// @returns the offset of the arguments in Operands()
|
||||
virtual size_t ArgsOperandOffset() const { return 0; }
|
||||
|
||||
/// Sets the explicit template params for the call
|
||||
void SetExplicitTemplateParams(VectorRef<const core::type::Type*> params) {
|
||||
explicit_template_params_ = params;
|
||||
}
|
||||
/// Retrieves the explicit template params for the call
|
||||
tint::VectorRef<const core::type::Type*> ExplicitTemplateParams() const {
|
||||
return explicit_template_params_;
|
||||
}
|
||||
|
||||
/// @returns the call arguments
|
||||
tint::Slice<Value* const> Args() { return operands_.Slice().Offset(ArgsOperandOffset()); }
|
||||
|
||||
/// @returns the call arguments
|
||||
tint::Slice<const Value* const> Args() const {
|
||||
return operands_.Slice().Offset(ArgsOperandOffset());
|
||||
}
|
||||
|
||||
/// Sets the argument at `idx` of `arg`. `idx` must be within bounds of the current argument
|
||||
/// set.
|
||||
void SetArg(size_t idx, ir::Value* arg) { SetOperand(ArgsOperandOffset() + idx, arg); }
|
||||
|
||||
/// Append a new argument to the argument list for this call instruction.
|
||||
/// @param arg the argument value to append
|
||||
void AppendArg(ir::Value* arg) { AddOperand(operands_.Length(), arg); }
|
||||
|
||||
/// @returns the side effects for this instruction
|
||||
Accesses GetSideEffects() const override { return Accesses{Access::kLoad, Access::kStore}; }
|
||||
|
||||
protected:
|
||||
/// Constructor
|
||||
explicit Call(Id id);
|
||||
|
||||
Vector<const core::type::Type*, 1> explicit_template_params_;
|
||||
};
|
||||
|
||||
} // namespace tint::core::ir
|
||||
|
||||
#endif // SRC_TINT_LANG_CORE_IR_CALL_H_
|
||||
37
3rdparty/dawn/src/tint/lang/core/ir/clone_context.cc
vendored
Normal file
37
3rdparty/dawn/src/tint/lang/core/ir/clone_context.cc
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
// Copyright 2023 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/core/ir/clone_context.h"
|
||||
|
||||
#include "src/tint/lang/core/ir/builder.h"
|
||||
#include "src/tint/lang/core/ir/let.h"
|
||||
|
||||
namespace tint::core::ir {
|
||||
|
||||
CloneContext::CloneContext(Module& module) : ir(module) {}
|
||||
|
||||
} // namespace tint::core::ir
|
||||
143
3rdparty/dawn/src/tint/lang/core/ir/clone_context.h
vendored
Normal file
143
3rdparty/dawn/src/tint/lang/core/ir/clone_context.h
vendored
Normal file
@@ -0,0 +1,143 @@
|
||||
// Copyright 2023 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.
|
||||
|
||||
#ifndef SRC_TINT_LANG_CORE_IR_CLONE_CONTEXT_H_
|
||||
#define SRC_TINT_LANG_CORE_IR_CLONE_CONTEXT_H_
|
||||
|
||||
#include "src/tint/utils/containers/hashmap.h"
|
||||
#include "src/tint/utils/containers/transform.h"
|
||||
#include "src/tint/utils/rtti/traits.h"
|
||||
|
||||
namespace tint::core::ir {
|
||||
class Block;
|
||||
class Instruction;
|
||||
class Module;
|
||||
class Value;
|
||||
} // namespace tint::core::ir
|
||||
|
||||
namespace tint::core::ir {
|
||||
|
||||
/// Constant in the IR.
|
||||
class CloneContext {
|
||||
public:
|
||||
/// @param module the IR module
|
||||
explicit CloneContext(Module& module);
|
||||
|
||||
/// The IR module
|
||||
Module& ir;
|
||||
|
||||
/// Performs a clone of @p what.
|
||||
/// @param what the item to clone
|
||||
/// @return the cloned item
|
||||
template <typename T>
|
||||
T* Clone(T* what) {
|
||||
if (auto replacement = replacements_.Get(what)) {
|
||||
return (*replacement)->template As<T>();
|
||||
}
|
||||
T* result = what->Clone(*this);
|
||||
Replace(what, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
/// Performs a clone of all the elements in @p what.
|
||||
/// @param what the elements to clone
|
||||
/// @return the cloned elements
|
||||
template <size_t N, typename T>
|
||||
Vector<T*, N> Clone(Slice<T* const> what) {
|
||||
return Transform<N>(what, [&](T* const p) { return Clone(p); });
|
||||
}
|
||||
|
||||
/// Performs a clone of all the elements in @p what.
|
||||
/// @param what the elements to clone
|
||||
/// @return the cloned elements
|
||||
template <size_t N, typename T>
|
||||
Vector<T*, N> Clone(Slice<T*> what) {
|
||||
return Transform<N>(what, [&](T* p) { return Clone(p); });
|
||||
}
|
||||
|
||||
/// Performs a clone of all the elements in @p what.
|
||||
/// @param what the elements to clone
|
||||
/// @return the cloned elements
|
||||
template <size_t N, typename T>
|
||||
Vector<T*, N> Clone(Vector<T*, N> what) {
|
||||
return Transform(what, [&](T* p) { return Clone(p); });
|
||||
}
|
||||
|
||||
/// Obtains the (potentially) remapped pointer to @p what
|
||||
/// @param what the item
|
||||
/// @return the cloned item for @p what, or the original pointer if @p what has not been cloned.
|
||||
template <typename T>
|
||||
T* Remap(T* what) {
|
||||
if (auto replacement = replacements_.Get(what)) {
|
||||
return (*replacement)->template As<T>();
|
||||
}
|
||||
return what;
|
||||
}
|
||||
|
||||
/// Obtains the (potentially) remapped pointer of all the elements in @p what.
|
||||
/// @param what the item
|
||||
/// @return the remapped elements
|
||||
template <size_t N, typename T>
|
||||
Vector<T*, N> Remap(Slice<T* const> what) {
|
||||
return Transform<N>(what, [&](T* const p) { return Remap(p); });
|
||||
}
|
||||
|
||||
/// Obtains the (potentially) remapped pointer of all the elements in @p what.
|
||||
/// @param what the item
|
||||
/// @return the remapped elements
|
||||
template <size_t N, typename T>
|
||||
Vector<T*, N> Remap(Slice<T*> what) {
|
||||
return Transform<N>(what, [&](T* p) { return Remap(p); });
|
||||
}
|
||||
|
||||
/// Obtains the (potentially) remapped pointer of all the elements in @p what.
|
||||
/// @param what the item
|
||||
/// @return the remapped elements
|
||||
template <size_t N, typename T>
|
||||
Vector<T*, N> Remap(Vector<T*, N> what) {
|
||||
return Transform(what, [&](T* p) { return Remap(p); });
|
||||
}
|
||||
|
||||
/// Registers the replacement of `what` with `with`
|
||||
/// @param what the value or instruction to replace
|
||||
/// @param with a pointer to a replacement value or instruction
|
||||
template <typename WHAT, typename WITH>
|
||||
void Replace(WHAT* what, WITH* with) {
|
||||
static_assert(traits::IsTypeOrDerived<WHAT, ir::Instruction> ||
|
||||
traits::IsTypeOrDerived<WHAT, ir::Value>);
|
||||
static_assert(traits::IsTypeOrDerived<WITH, WHAT>);
|
||||
TINT_ASSERT(with);
|
||||
replacements_.Add(what, with);
|
||||
}
|
||||
|
||||
private:
|
||||
Hashmap<CastableBase*, CastableBase*, 8> replacements_;
|
||||
};
|
||||
|
||||
} // namespace tint::core::ir
|
||||
|
||||
#endif // SRC_TINT_LANG_CORE_IR_CLONE_CONTEXT_H_
|
||||
318
3rdparty/dawn/src/tint/lang/core/ir/const_param_validator.cc
vendored
Normal file
318
3rdparty/dawn/src/tint/lang/core/ir/const_param_validator.cc
vendored
Normal file
@@ -0,0 +1,318 @@
|
||||
// Copyright 2024 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/core/ir/const_param_validator.h"
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
#include "src/tint/lang/core/enums.h"
|
||||
#include "src/tint/lang/core/intrinsic/table.h"
|
||||
#include "src/tint/lang/core/ir/constant.h"
|
||||
#include "src/tint/lang/core/ir/core_binary.h"
|
||||
#include "src/tint/lang/core/ir/core_builtin_call.h"
|
||||
#include "src/tint/lang/core/ir/instruction.h"
|
||||
#include "src/tint/lang/core/ir/instruction_result.h"
|
||||
#include "src/tint/lang/core/ir/module.h"
|
||||
#include "src/tint/lang/core/ir/switch.h"
|
||||
#include "src/tint/lang/core/ir/type/array_count.h"
|
||||
#include "src/tint/lang/core/ir/value.h"
|
||||
#include "src/tint/lang/core/number.h"
|
||||
#include "src/tint/lang/core/type/type.h"
|
||||
#include "src/tint/utils/diagnostic/diagnostic.h"
|
||||
#include "src/tint/utils/internal_limits.h"
|
||||
#include "src/tint/utils/rtti/switch.h"
|
||||
|
||||
namespace tint::core::ir {
|
||||
|
||||
namespace {
|
||||
|
||||
/// The core IR const param validator.
|
||||
class ConstParamValidator {
|
||||
public:
|
||||
/// Create a core const param validator
|
||||
/// @param mod the module to be validated
|
||||
explicit ConstParamValidator(Module& mod);
|
||||
|
||||
/// Destructor
|
||||
~ConstParamValidator();
|
||||
|
||||
/// Runs the const param validator over the module provided during construction
|
||||
/// @returns success or failure
|
||||
Result<SuccessType> Run();
|
||||
|
||||
void CheckSubgroupCall(const CoreBuiltinCall* call);
|
||||
void CheckBuiltinCall(const BuiltinCall* call);
|
||||
void CheckCoreBinaryCall(const CoreBinary* inst);
|
||||
void CheckExtractBitsCall(const CoreBuiltinCall* call);
|
||||
void CheckInsertBitsCall(const CoreBuiltinCall* call);
|
||||
void CheckLdexpCall(const CoreBuiltinCall* call);
|
||||
void CheckQuantizeToF16(const CoreBuiltinCall* call);
|
||||
void CheckClampCall(const CoreBuiltinCall* call);
|
||||
void CheckPack2x16float(const CoreBuiltinCall* call);
|
||||
void CheckSmoothstepCall(const CoreBuiltinCall* call);
|
||||
void CheckBinaryDivModCall(const CoreBinary* call);
|
||||
void CheckBinaryShiftCall(const CoreBinary* call);
|
||||
|
||||
diag::Diagnostic& AddError(const Instruction& inst);
|
||||
|
||||
private:
|
||||
Module& mod_;
|
||||
constant::Eval const_eval_;
|
||||
diag::List diagnostics_;
|
||||
};
|
||||
|
||||
ConstParamValidator::ConstParamValidator(Module& mod)
|
||||
: mod_(mod), const_eval_(mod.constant_values, diagnostics_) {}
|
||||
|
||||
ConstParamValidator::~ConstParamValidator() = default;
|
||||
|
||||
diag::Diagnostic& ConstParamValidator::AddError(const Instruction& inst) {
|
||||
auto src = mod_.SourceOf(&inst);
|
||||
return diagnostics_.AddError(src);
|
||||
}
|
||||
|
||||
const constant::Value* GetConstArg(const CoreBuiltinCall* call, uint32_t param_index) {
|
||||
if (call->Args().Length() <= param_index) {
|
||||
return nullptr;
|
||||
}
|
||||
if (call->Args()[param_index] == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
if (!call->Args()[param_index]->Is<ir::Constant>()) {
|
||||
return nullptr;
|
||||
}
|
||||
return call->Args()[param_index]->As<ir::Constant>()->Value();
|
||||
}
|
||||
|
||||
void ConstParamValidator::CheckExtractBitsCall(const CoreBuiltinCall* call) {
|
||||
// This can be u32/i32 or vector of those types.
|
||||
auto* param0 = call->Args()[0];
|
||||
auto* const_val_offset = GetConstArg(call, 1);
|
||||
auto* const_val_count = GetConstArg(call, 2);
|
||||
if (const_val_count && const_val_offset) {
|
||||
auto* zero = const_eval_.Zero(param0->Type(), {}, Source{}).Get();
|
||||
auto fakeArgs = Vector{zero, const_val_offset, const_val_count};
|
||||
[[maybe_unused]] auto result =
|
||||
const_eval_.extractBits(param0->Type(), fakeArgs, mod_.SourceOf(call));
|
||||
}
|
||||
}
|
||||
|
||||
void ConstParamValidator::CheckInsertBitsCall(const CoreBuiltinCall* call) {
|
||||
// This can be u32/i32 or vector of those types.
|
||||
auto* param0 = call->Args()[0];
|
||||
auto* const_val_offset = GetConstArg(call, 2);
|
||||
auto* const_val_count = GetConstArg(call, 3);
|
||||
if (const_val_count && const_val_offset) {
|
||||
auto* zero = const_eval_.Zero(param0->Type(), {}, Source{}).Get();
|
||||
auto fakeArgs = Vector{zero, zero, const_val_offset, const_val_count};
|
||||
[[maybe_unused]] auto result =
|
||||
const_eval_.insertBits(param0->Type(), fakeArgs, mod_.SourceOf(call));
|
||||
}
|
||||
}
|
||||
|
||||
void ConstParamValidator::CheckLdexpCall(const CoreBuiltinCall* call) {
|
||||
auto* param0 = call->Args()[0];
|
||||
if (auto const_val = GetConstArg(call, 1)) {
|
||||
auto* zero = const_eval_.Zero(param0->Type(), {}, Source{}).Get();
|
||||
auto fakeArgs = Vector{zero, const_val};
|
||||
[[maybe_unused]] auto result =
|
||||
const_eval_.ldexp(param0->Type(), fakeArgs, mod_.SourceOf(call));
|
||||
}
|
||||
}
|
||||
|
||||
void ConstParamValidator::CheckQuantizeToF16(const CoreBuiltinCall* call) {
|
||||
if (auto const_val = GetConstArg(call, 0)) {
|
||||
[[maybe_unused]] auto result = const_eval_.quantizeToF16(
|
||||
call->Result()->Type(), Vector{const_val}, mod_.SourceOf(call));
|
||||
}
|
||||
}
|
||||
|
||||
void ConstParamValidator::CheckPack2x16float(const CoreBuiltinCall* call) {
|
||||
if (auto const_val = GetConstArg(call, 0)) {
|
||||
[[maybe_unused]] auto result = const_eval_.pack2x16float(
|
||||
call->Result()->Type(), Vector{const_val}, mod_.SourceOf(call));
|
||||
}
|
||||
}
|
||||
|
||||
void ConstParamValidator::CheckSubgroupCall(const CoreBuiltinCall* call) {
|
||||
if (auto const_val = GetConstArg(call, 1)) {
|
||||
auto as_aint = const_val->ValueAs<AInt>();
|
||||
// User friendly param name.
|
||||
std::string paramName = "sourceLaneIndex";
|
||||
switch (call->Func()) {
|
||||
case core::BuiltinFn::kSubgroupShuffleXor:
|
||||
paramName = "mask";
|
||||
break;
|
||||
case core::BuiltinFn::kSubgroupShuffleUp:
|
||||
case core::BuiltinFn::kSubgroupShuffleDown:
|
||||
paramName = "delta";
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (as_aint >= tint::internal_limits::kMaxSubgroupSize) {
|
||||
AddError(*call) << "The " << paramName << " argument of " << call->FriendlyName()
|
||||
<< " must be less than " << tint::internal_limits::kMaxSubgroupSize;
|
||||
} else if (as_aint < 0) {
|
||||
AddError(*call) << "The " << paramName << " argument of " << call->FriendlyName()
|
||||
<< " must be greater than or equal to zero";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ConstParamValidator::CheckClampCall(const CoreBuiltinCall* call) {
|
||||
auto* const_val_low = GetConstArg(call, 1);
|
||||
auto* const_val_high = GetConstArg(call, 2);
|
||||
if (const_val_low && const_val_high) {
|
||||
auto fakeArgs = Vector{const_val_low, const_val_low, const_val_high};
|
||||
[[maybe_unused]] auto result =
|
||||
const_eval_.clamp(call->Result()->Type(), fakeArgs, mod_.SourceOf(call));
|
||||
}
|
||||
}
|
||||
|
||||
void ConstParamValidator::CheckSmoothstepCall(const CoreBuiltinCall* call) {
|
||||
auto* const_val_low = GetConstArg(call, 0);
|
||||
auto* const_val_high = GetConstArg(call, 1);
|
||||
if (const_val_low && const_val_high) {
|
||||
auto fakeArgs = Vector{const_val_low, const_val_high, const_val_high};
|
||||
[[maybe_unused]] auto result =
|
||||
const_eval_.smoothstep(call->Result()->Type(), fakeArgs, mod_.SourceOf(call));
|
||||
}
|
||||
}
|
||||
|
||||
void ConstParamValidator::CheckBuiltinCall(const BuiltinCall* inst) {
|
||||
if (auto* call = inst->As<core::ir::CoreBuiltinCall>()) {
|
||||
switch (call->Func()) {
|
||||
case core::BuiltinFn::kSubgroupShuffle:
|
||||
case core::BuiltinFn::kSubgroupShuffleXor:
|
||||
case core::BuiltinFn::kSubgroupShuffleUp:
|
||||
case core::BuiltinFn::kSubgroupShuffleDown:
|
||||
CheckSubgroupCall(call);
|
||||
break;
|
||||
case core::BuiltinFn::kExtractBits:
|
||||
CheckExtractBitsCall(call);
|
||||
break;
|
||||
case core::BuiltinFn::kInsertBits:
|
||||
CheckInsertBitsCall(call);
|
||||
break;
|
||||
case core::BuiltinFn::kLdexp:
|
||||
CheckLdexpCall(call);
|
||||
break;
|
||||
case core::BuiltinFn::kClamp:
|
||||
CheckClampCall(call);
|
||||
break;
|
||||
case core::BuiltinFn::kSmoothstep:
|
||||
CheckSmoothstepCall(call);
|
||||
break;
|
||||
case core::BuiltinFn::kQuantizeToF16:
|
||||
CheckQuantizeToF16(call);
|
||||
break;
|
||||
case core::BuiltinFn::kPack2X16Float:
|
||||
CheckPack2x16float(call);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ConstParamValidator::CheckBinaryDivModCall(const CoreBinary* call) {
|
||||
// Integer division by zero should be checked for the partial evaluation case (only rhs
|
||||
// is const). FP division by zero is only invalid when the whole expression is
|
||||
// constant-evaluated.
|
||||
if (call->RHS()->Type()->IsIntegerScalarOrVector()) {
|
||||
auto rhs_constant = call->RHS()->As<ir::Constant>();
|
||||
if (rhs_constant && rhs_constant->Value()->AnyZero()) {
|
||||
AddError(*call) << "integer division by zero is invalid";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ConstParamValidator::CheckBinaryShiftCall(const CoreBinary* call) {
|
||||
// If lhs value is a concrete type, and rhs is a const-expression greater than or equal
|
||||
// to the bit width of lhs, then it is a shader-creation error.
|
||||
const auto* elem_type = call->LHS()->Type()->DeepestElement();
|
||||
const uint32_t bit_width = elem_type->Size() * 8;
|
||||
if (auto* rhs_val_as_const = call->RHS()->As<ir::Constant>()) {
|
||||
auto* rhs_as_value = rhs_val_as_const->Value();
|
||||
for (size_t i = 0, n = rhs_as_value->NumElements(); i < n; i++) {
|
||||
auto* shift_val = n == 1 ? rhs_as_value : rhs_as_value->Index(i);
|
||||
if (shift_val->ValueAs<u32>() >= bit_width) {
|
||||
AddError(*call) << "shift "
|
||||
<< (call->Op() == core::BinaryOp::kShiftLeft ? "left" : "right")
|
||||
<< " value must be less than the bit width of the lhs, which is "
|
||||
<< bit_width;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ConstParamValidator::CheckCoreBinaryCall(const CoreBinary* call) {
|
||||
switch (call->Op()) {
|
||||
case core::BinaryOp::kDivide:
|
||||
case core::BinaryOp::kModulo:
|
||||
CheckBinaryDivModCall(call);
|
||||
break;
|
||||
case core::BinaryOp::kShiftLeft:
|
||||
case core::BinaryOp::kShiftRight:
|
||||
CheckBinaryShiftCall(call);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Result<SuccessType> ConstParamValidator::Run() {
|
||||
auto instructions = this->mod_.Instructions();
|
||||
|
||||
for (auto inst : instructions) {
|
||||
tint::Switch(
|
||||
inst, //
|
||||
[&](const BuiltinCall* c) { CheckBuiltinCall(c); }, //
|
||||
[&](const CoreBinary* c) { CheckCoreBinaryCall(c); }, //
|
||||
[&](Default) {});
|
||||
}
|
||||
|
||||
if (diagnostics_.ContainsErrors()) {
|
||||
return Failure{diagnostics_.Str()};
|
||||
}
|
||||
|
||||
return Success;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
Result<SuccessType> ValidateConstParam(Module& mod) {
|
||||
ConstParamValidator v(mod);
|
||||
return v.Run();
|
||||
}
|
||||
|
||||
} // namespace tint::core::ir
|
||||
47
3rdparty/dawn/src/tint/lang/core/ir/const_param_validator.h
vendored
Normal file
47
3rdparty/dawn/src/tint/lang/core/ir/const_param_validator.h
vendored
Normal file
@@ -0,0 +1,47 @@
|
||||
// Copyright 2024 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.
|
||||
|
||||
#ifndef SRC_TINT_LANG_CORE_IR_CONST_PARAM_VALIDATOR_H_
|
||||
#define SRC_TINT_LANG_CORE_IR_CONST_PARAM_VALIDATOR_H_
|
||||
|
||||
#include "src/tint/utils/result.h"
|
||||
|
||||
// Forward declarations
|
||||
namespace tint::core::ir {
|
||||
class Module;
|
||||
} // namespace tint::core::ir
|
||||
|
||||
namespace tint::core::ir {
|
||||
|
||||
/// Validates the constant params for all instructions in the IR.
|
||||
/// @param mod the module to validate
|
||||
/// @returns success or failure
|
||||
Result<SuccessType> ValidateConstParam(Module& mod);
|
||||
|
||||
} // namespace tint::core::ir
|
||||
|
||||
#endif // SRC_TINT_LANG_CORE_IR_CONST_PARAM_VALIDATOR_H_
|
||||
46
3rdparty/dawn/src/tint/lang/core/ir/constant.cc
vendored
Normal file
46
3rdparty/dawn/src/tint/lang/core/ir/constant.cc
vendored
Normal file
@@ -0,0 +1,46 @@
|
||||
// Copyright 2022 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/core/ir/constant.h"
|
||||
#include "src/tint/utils/ice/ice.h"
|
||||
|
||||
TINT_INSTANTIATE_TYPEINFO(tint::core::ir::Constant);
|
||||
|
||||
namespace tint::core::ir {
|
||||
|
||||
Constant::Constant(const core::constant::Value* val) : Base(nullptr), value_(val) {
|
||||
TINT_ASSERT(value_);
|
||||
SetType(val->Type());
|
||||
}
|
||||
|
||||
Constant::~Constant() = default;
|
||||
|
||||
Constant* Constant::Clone(CloneContext&) {
|
||||
return this; // Constants are immutable so can just return ourselves.
|
||||
}
|
||||
|
||||
} // namespace tint::core::ir
|
||||
56
3rdparty/dawn/src/tint/lang/core/ir/constant.h
vendored
Normal file
56
3rdparty/dawn/src/tint/lang/core/ir/constant.h
vendored
Normal file
@@ -0,0 +1,56 @@
|
||||
// Copyright 2022 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.
|
||||
|
||||
#ifndef SRC_TINT_LANG_CORE_IR_CONSTANT_H_
|
||||
#define SRC_TINT_LANG_CORE_IR_CONSTANT_H_
|
||||
|
||||
#include "src/tint/lang/core/constant/value.h"
|
||||
#include "src/tint/lang/core/ir/value.h"
|
||||
|
||||
namespace tint::core::ir {
|
||||
|
||||
/// Constant in the IR.
|
||||
class Constant : public Castable<Constant, Value> {
|
||||
public:
|
||||
/// Constructor
|
||||
/// @param val the value stored in the constant
|
||||
explicit Constant(const core::constant::Value* val);
|
||||
~Constant() override;
|
||||
|
||||
/// @returns the constants value
|
||||
const core::constant::Value* Value() const { return value_; }
|
||||
|
||||
/// @copydoc Value::Clone()
|
||||
Constant* Clone(CloneContext& ctx) override;
|
||||
|
||||
private:
|
||||
const core::constant::Value* const value_ = nullptr;
|
||||
};
|
||||
|
||||
} // namespace tint::core::ir
|
||||
|
||||
#endif // SRC_TINT_LANG_CORE_IR_CONSTANT_H_
|
||||
57
3rdparty/dawn/src/tint/lang/core/ir/constexpr_if.cc
vendored
Normal file
57
3rdparty/dawn/src/tint/lang/core/ir/constexpr_if.cc
vendored
Normal file
@@ -0,0 +1,57 @@
|
||||
// Copyright 2025 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/core/ir/constexpr_if.h"
|
||||
|
||||
#include "src/tint/lang/core/ir/clone_context.h"
|
||||
#include "src/tint/lang/core/ir/module.h"
|
||||
|
||||
TINT_INSTANTIATE_TYPEINFO(tint::core::ir::ConstExprIf);
|
||||
|
||||
namespace tint::core::ir {
|
||||
|
||||
ConstExprIf::ConstExprIf(Id id) : Base(id) {}
|
||||
|
||||
ConstExprIf::ConstExprIf(Id id, Value* cond, ir::Block* t, ir::Block* f) : Base(id, cond, t, f) {}
|
||||
|
||||
ConstExprIf* ConstExprIf::Clone(CloneContext& ctx) {
|
||||
auto* cond = ctx.Remap(Condition());
|
||||
auto* new_true = ctx.ir.blocks.Create<ir::Block>();
|
||||
auto* new_false = ctx.ir.blocks.Create<ir::Block>();
|
||||
|
||||
auto* new_if = ctx.ir.CreateInstruction<ConstExprIf>(cond, new_true, new_false);
|
||||
ctx.Replace(this, new_if);
|
||||
|
||||
True()->CloneInto(ctx, new_true);
|
||||
False()->CloneInto(ctx, new_false);
|
||||
|
||||
new_if->SetResults(ctx.Clone(results_));
|
||||
|
||||
return new_if;
|
||||
}
|
||||
|
||||
} // namespace tint::core::ir
|
||||
61
3rdparty/dawn/src/tint/lang/core/ir/constexpr_if.h
vendored
Normal file
61
3rdparty/dawn/src/tint/lang/core/ir/constexpr_if.h
vendored
Normal file
@@ -0,0 +1,61 @@
|
||||
// Copyright 2025 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.
|
||||
|
||||
#ifndef SRC_TINT_LANG_CORE_IR_CONSTEXPR_IF_H_
|
||||
#define SRC_TINT_LANG_CORE_IR_CONSTEXPR_IF_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "src/tint/lang/core/ir/if.h"
|
||||
|
||||
namespace tint::core::ir {
|
||||
|
||||
/// A `constexpr-if` is an `if` instruction which will always be evaluated during
|
||||
/// const-eval processing. The `condition` must be a `const` or `override`
|
||||
/// expression.
|
||||
class ConstExprIf final : public Castable<ConstExprIf, If> {
|
||||
public:
|
||||
/// Constructor (no results, no operands, no blocks)
|
||||
/// @param id the instruction id
|
||||
explicit ConstExprIf(Id id);
|
||||
|
||||
/// Constructor
|
||||
/// @param cond the if condition
|
||||
/// @param t the true block
|
||||
/// @param f the false block
|
||||
ConstExprIf(Id id, Value* cond, ir::Block* t, ir::Block* f);
|
||||
|
||||
/// @copydoc Instruction::Clone()
|
||||
ConstExprIf* Clone(CloneContext& ctx) override;
|
||||
|
||||
/// @returns the friendly name for the instruction
|
||||
std::string FriendlyName() const override { return "constexpr_if"; }
|
||||
};
|
||||
|
||||
} // namespace tint::core::ir
|
||||
|
||||
#endif // SRC_TINT_LANG_CORE_IR_CONSTEXPR_IF_H_
|
||||
54
3rdparty/dawn/src/tint/lang/core/ir/construct.cc
vendored
Normal file
54
3rdparty/dawn/src/tint/lang/core/ir/construct.cc
vendored
Normal file
@@ -0,0 +1,54 @@
|
||||
// Copyright 2023 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/core/ir/construct.h"
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include "src/tint/lang/core/ir/clone_context.h"
|
||||
#include "src/tint/lang/core/ir/module.h"
|
||||
|
||||
TINT_INSTANTIATE_TYPEINFO(tint::core::ir::Construct);
|
||||
|
||||
namespace tint::core::ir {
|
||||
|
||||
Construct::Construct(Id id) : Base(id) {}
|
||||
|
||||
Construct::Construct(Id id, InstructionResult* result, VectorRef<Value*> arguments) : Base(id) {
|
||||
AddOperands(Construct::kArgsOperandOffset, std::move(arguments));
|
||||
AddResult(result);
|
||||
}
|
||||
|
||||
Construct::~Construct() = default;
|
||||
|
||||
Construct* Construct::Clone(CloneContext& ctx) {
|
||||
auto* new_result = ctx.Clone(Result());
|
||||
auto args = ctx.Remap<Construct::kDefaultNumOperands>(Args());
|
||||
return ctx.ir.CreateInstruction<Construct>(new_result, args);
|
||||
}
|
||||
|
||||
} // namespace tint::core::ir
|
||||
71
3rdparty/dawn/src/tint/lang/core/ir/construct.h
vendored
Normal file
71
3rdparty/dawn/src/tint/lang/core/ir/construct.h
vendored
Normal file
@@ -0,0 +1,71 @@
|
||||
// Copyright 2023 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.
|
||||
|
||||
#ifndef SRC_TINT_LANG_CORE_IR_CONSTRUCT_H_
|
||||
#define SRC_TINT_LANG_CORE_IR_CONSTRUCT_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "src/tint/lang/core/ir/call.h"
|
||||
#include "src/tint/utils/rtti/castable.h"
|
||||
|
||||
namespace tint::core::ir {
|
||||
|
||||
/// A constructor instruction in the IR.
|
||||
class Construct final : public Castable<Construct, Call> {
|
||||
public:
|
||||
/// The base offset in Operands() for the args
|
||||
static constexpr size_t kArgsOperandOffset = 0;
|
||||
|
||||
/// The fixed number of results returned by this instruction
|
||||
static constexpr size_t kNumResults = 1;
|
||||
|
||||
/// The minimum number of operands expected for this instruction
|
||||
static constexpr size_t kMinOperands = 0;
|
||||
|
||||
/// Constructor (no result, no operands)
|
||||
/// @param id the instruction id
|
||||
explicit Construct(Id id);
|
||||
|
||||
/// Constructor
|
||||
/// @param id the instruction id
|
||||
/// @param result the result value
|
||||
/// @param args the constructor arguments
|
||||
Construct(Id id, InstructionResult* result, VectorRef<Value*> args = tint::Empty);
|
||||
|
||||
~Construct() override;
|
||||
|
||||
/// @copydoc Instruction::Clone()
|
||||
Construct* Clone(CloneContext& ctx) override;
|
||||
|
||||
/// @returns the friendly name for the instruction
|
||||
std::string FriendlyName() const override { return "construct"; }
|
||||
};
|
||||
|
||||
} // namespace tint::core::ir
|
||||
|
||||
#endif // SRC_TINT_LANG_CORE_IR_CONSTRUCT_H_
|
||||
81
3rdparty/dawn/src/tint/lang/core/ir/continue.cc
vendored
Normal file
81
3rdparty/dawn/src/tint/lang/core/ir/continue.cc
vendored
Normal file
@@ -0,0 +1,81 @@
|
||||
// Copyright 2023 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/core/ir/continue.h"
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include "src/tint/lang/core/ir/block.h"
|
||||
#include "src/tint/lang/core/ir/clone_context.h"
|
||||
#include "src/tint/lang/core/ir/loop.h"
|
||||
#include "src/tint/lang/core/ir/module.h"
|
||||
#include "src/tint/lang/core/ir/multi_in_block.h"
|
||||
#include "src/tint/utils/ice/ice.h"
|
||||
|
||||
TINT_INSTANTIATE_TYPEINFO(tint::core::ir::Continue);
|
||||
|
||||
namespace tint::core::ir {
|
||||
|
||||
Continue::Continue(Id id) : Base(id) {}
|
||||
|
||||
Continue::Continue(Id id, ir::Loop* loop, VectorRef<Value*> args) : Base(id), loop_(loop) {
|
||||
TINT_ASSERT(loop_);
|
||||
|
||||
AddOperands(Continue::kArgsOperandOffset, std::move(args));
|
||||
|
||||
if (loop_) {
|
||||
loop_->Continuing()->AddInboundSiblingBranch(this);
|
||||
}
|
||||
}
|
||||
|
||||
Continue::~Continue() = default;
|
||||
|
||||
void Continue::Destroy() {
|
||||
if (loop_) {
|
||||
loop_->Continuing()->RemoveInboundSiblingBranch(this);
|
||||
}
|
||||
Instruction::Destroy();
|
||||
}
|
||||
|
||||
Continue* Continue::Clone(CloneContext& ctx) {
|
||||
auto* loop = ctx.Remap(Loop());
|
||||
auto args = ctx.Remap<Continue::kDefaultNumOperands>(Args());
|
||||
|
||||
return ctx.ir.CreateInstruction<Continue>(loop, args);
|
||||
}
|
||||
|
||||
void Continue::SetLoop(ir::Loop* loop) {
|
||||
if (loop_ && loop_->Body()) {
|
||||
loop_->Continuing()->RemoveInboundSiblingBranch(this);
|
||||
}
|
||||
loop_ = loop;
|
||||
if (loop) {
|
||||
loop->Continuing()->AddInboundSiblingBranch(this);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace tint::core::ir
|
||||
84
3rdparty/dawn/src/tint/lang/core/ir/continue.h
vendored
Normal file
84
3rdparty/dawn/src/tint/lang/core/ir/continue.h
vendored
Normal file
@@ -0,0 +1,84 @@
|
||||
// Copyright 2023 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.
|
||||
|
||||
#ifndef SRC_TINT_LANG_CORE_IR_CONTINUE_H_
|
||||
#define SRC_TINT_LANG_CORE_IR_CONTINUE_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "src/tint/lang/core/ir/terminator.h"
|
||||
#include "src/tint/utils/rtti/castable.h"
|
||||
|
||||
// Forward declarations
|
||||
namespace tint::core::ir {
|
||||
class Loop;
|
||||
} // namespace tint::core::ir
|
||||
|
||||
namespace tint::core::ir {
|
||||
|
||||
/// A continue instruction.
|
||||
class Continue final : public Castable<Continue, Terminator> {
|
||||
public:
|
||||
/// The base offset in Operands() for the args
|
||||
static constexpr size_t kArgsOperandOffset = 0;
|
||||
|
||||
/// Constructor (no operands, no loop)
|
||||
/// @param id the instruction id
|
||||
explicit Continue(Id id);
|
||||
|
||||
/// Constructor
|
||||
/// @param id the instruction id
|
||||
/// @param loop the loop owning the continue block
|
||||
/// @param args the arguments for the MultiInBlock
|
||||
Continue(Id id, ir::Loop* loop, VectorRef<Value*> args = tint::Empty);
|
||||
~Continue() override;
|
||||
|
||||
/// @copydoc Instruction::Clone()
|
||||
Continue* Clone(CloneContext& ctx) override;
|
||||
|
||||
/// @copydoc Instruction::Destroy()
|
||||
void Destroy() override;
|
||||
|
||||
/// @returns the loop owning the continue block
|
||||
ir::Loop* Loop() { return loop_; }
|
||||
|
||||
/// @returns the loop owning the continue block
|
||||
const ir::Loop* Loop() const { return loop_; }
|
||||
|
||||
/// @param loop the new loop owning the continue block
|
||||
void SetLoop(ir::Loop* loop);
|
||||
|
||||
/// @returns the friendly name for the instruction
|
||||
std::string FriendlyName() const override { return "continue"; }
|
||||
|
||||
private:
|
||||
ir::Loop* loop_ = nullptr;
|
||||
};
|
||||
|
||||
} // namespace tint::core::ir
|
||||
|
||||
#endif // SRC_TINT_LANG_CORE_IR_CONTINUE_H_
|
||||
55
3rdparty/dawn/src/tint/lang/core/ir/control_instruction.cc
vendored
Normal file
55
3rdparty/dawn/src/tint/lang/core/ir/control_instruction.cc
vendored
Normal file
@@ -0,0 +1,55 @@
|
||||
// Copyright 2023 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/core/ir/control_instruction.h"
|
||||
|
||||
#include "src/tint/lang/core/ir/block.h"
|
||||
|
||||
TINT_INSTANTIATE_TYPEINFO(tint::core::ir::ControlInstruction);
|
||||
|
||||
namespace tint::core::ir {
|
||||
|
||||
ControlInstruction::ControlInstruction(Id id) : Base(id) {
|
||||
flags_.Add(Flag::kSequenced);
|
||||
}
|
||||
|
||||
ControlInstruction::~ControlInstruction() = default;
|
||||
|
||||
void ControlInstruction::AddExit(Exit* exit) {
|
||||
exits_.Add(exit);
|
||||
}
|
||||
|
||||
void ControlInstruction::RemoveExit(Exit* exit) {
|
||||
exits_.Remove(exit);
|
||||
}
|
||||
|
||||
void ControlInstruction::Destroy() {
|
||||
Base::Destroy();
|
||||
ForeachBlock([](ir::Block* blk) { blk->Destroy(); });
|
||||
}
|
||||
|
||||
} // namespace tint::core::ir
|
||||
83
3rdparty/dawn/src/tint/lang/core/ir/control_instruction.h
vendored
Normal file
83
3rdparty/dawn/src/tint/lang/core/ir/control_instruction.h
vendored
Normal file
@@ -0,0 +1,83 @@
|
||||
// Copyright 2023 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.
|
||||
|
||||
#ifndef SRC_TINT_LANG_CORE_IR_CONTROL_INSTRUCTION_H_
|
||||
#define SRC_TINT_LANG_CORE_IR_CONTROL_INSTRUCTION_H_
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include "src/tint/lang/core/ir/operand_instruction.h"
|
||||
|
||||
// Forward declarations
|
||||
namespace tint::core::ir {
|
||||
class Block;
|
||||
class Exit;
|
||||
} // namespace tint::core::ir
|
||||
|
||||
namespace tint::core::ir {
|
||||
|
||||
/// Base class of instructions that perform control flow to two or more blocks, owned by the
|
||||
/// ControlInstruction.
|
||||
class ControlInstruction : public Castable<ControlInstruction, OperandInstruction<1, 1>> {
|
||||
public:
|
||||
/// Constructor
|
||||
/// @param id the instruction id
|
||||
explicit ControlInstruction(Id id);
|
||||
|
||||
/// Destructor
|
||||
~ControlInstruction() override;
|
||||
|
||||
/// Calls @p cb for each block owned by this control instruction
|
||||
/// @param cb the function to call once for each block
|
||||
virtual void ForeachBlock(const std::function<void(ir::Block*)>& cb) = 0;
|
||||
|
||||
/// Calls @p cb for each block owned by this control instruction
|
||||
/// @param cb the function to call once for each block
|
||||
virtual void ForeachBlock(const std::function<void(const ir::Block*)>& cb) const = 0;
|
||||
|
||||
/// @return All the exits for the flow control instruction
|
||||
const Hashset<Exit*, 2>& Exits() const { return exits_; }
|
||||
|
||||
/// Adds the exit to the flow control instruction
|
||||
/// @param exit the exit instruction
|
||||
void AddExit(Exit* exit);
|
||||
|
||||
/// Removes the exit to the flow control instruction
|
||||
/// @param exit the exit instruction
|
||||
void RemoveExit(Exit* exit);
|
||||
|
||||
/// @copydoc Instruction::Destroy
|
||||
void Destroy() override;
|
||||
|
||||
protected:
|
||||
/// The flow control exits
|
||||
Hashset<Exit*, 2> exits_;
|
||||
};
|
||||
|
||||
} // namespace tint::core::ir
|
||||
|
||||
#endif // SRC_TINT_LANG_CORE_IR_CONTROL_INSTRUCTION_H_
|
||||
54
3rdparty/dawn/src/tint/lang/core/ir/convert.cc
vendored
Normal file
54
3rdparty/dawn/src/tint/lang/core/ir/convert.cc
vendored
Normal file
@@ -0,0 +1,54 @@
|
||||
// Copyright 2023 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/core/ir/convert.h"
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include "src/tint/lang/core/ir/clone_context.h"
|
||||
#include "src/tint/lang/core/ir/module.h"
|
||||
|
||||
TINT_INSTANTIATE_TYPEINFO(tint::core::ir::Convert);
|
||||
|
||||
namespace tint::core::ir {
|
||||
|
||||
Convert::Convert(Id id) : Base(id) {}
|
||||
|
||||
Convert::Convert(Id id, InstructionResult* result, Value* value) : Base(id) {
|
||||
AddOperand(Convert::kValueOperandOffset, value);
|
||||
AddResult(result);
|
||||
}
|
||||
|
||||
Convert::~Convert() = default;
|
||||
|
||||
Convert* Convert::Clone(CloneContext& ctx) {
|
||||
auto* new_result = ctx.Clone(Result());
|
||||
auto* val = ctx.Remap(Args()[0]);
|
||||
return ctx.ir.CreateInstruction<Convert>(new_result, val);
|
||||
}
|
||||
|
||||
} // namespace tint::core::ir
|
||||
72
3rdparty/dawn/src/tint/lang/core/ir/convert.h
vendored
Normal file
72
3rdparty/dawn/src/tint/lang/core/ir/convert.h
vendored
Normal file
@@ -0,0 +1,72 @@
|
||||
// Copyright 2023 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.
|
||||
|
||||
#ifndef SRC_TINT_LANG_CORE_IR_CONVERT_H_
|
||||
#define SRC_TINT_LANG_CORE_IR_CONVERT_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "src/tint/lang/core/ir/call.h"
|
||||
#include "src/tint/lang/core/type/type.h"
|
||||
#include "src/tint/utils/rtti/castable.h"
|
||||
|
||||
namespace tint::core::ir {
|
||||
|
||||
/// A value conversion instruction in the IR.
|
||||
class Convert final : public Castable<Convert, Call> {
|
||||
public:
|
||||
/// The offset in Operands() for the value
|
||||
static constexpr size_t kValueOperandOffset = 0;
|
||||
|
||||
/// The fixed number of results returned by this instruction
|
||||
static constexpr size_t kNumResults = 1;
|
||||
|
||||
/// The fixed number of operands expected for this instruction
|
||||
static constexpr size_t kNumOperands = 1;
|
||||
|
||||
/// Constructor (no results, no operands)
|
||||
/// @param id the instruction id
|
||||
explicit Convert(Id id);
|
||||
|
||||
/// Constructor
|
||||
/// @param id the instruction id
|
||||
/// @param result the result value
|
||||
/// @param value the value to convert
|
||||
Convert(Id id, InstructionResult* result, Value* value);
|
||||
|
||||
~Convert() override;
|
||||
|
||||
/// @copydoc Instruction::Clone()
|
||||
Convert* Clone(CloneContext& ctx) override;
|
||||
|
||||
/// @returns the friendly name for the instruction
|
||||
std::string FriendlyName() const override { return "convert"; }
|
||||
};
|
||||
|
||||
} // namespace tint::core::ir
|
||||
|
||||
#endif // SRC_TINT_LANG_CORE_IR_CONVERT_H_
|
||||
56
3rdparty/dawn/src/tint/lang/core/ir/core_binary.cc
vendored
Normal file
56
3rdparty/dawn/src/tint/lang/core/ir/core_binary.cc
vendored
Normal file
@@ -0,0 +1,56 @@
|
||||
// Copyright 2024 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/core/ir/core_binary.h"
|
||||
|
||||
#include "src/tint/lang/core/intrinsic/dialect.h"
|
||||
#include "src/tint/lang/core/ir/clone_context.h"
|
||||
#include "src/tint/lang/core/ir/module.h"
|
||||
|
||||
TINT_INSTANTIATE_TYPEINFO(tint::core::ir::CoreBinary);
|
||||
|
||||
namespace tint::core::ir {
|
||||
|
||||
CoreBinary::CoreBinary(Id id) : Base(id) {}
|
||||
|
||||
CoreBinary::CoreBinary(Id id, InstructionResult* result, BinaryOp op, Value* lhs, Value* rhs)
|
||||
: Base(id, result, op, lhs, rhs) {}
|
||||
|
||||
CoreBinary::~CoreBinary() = default;
|
||||
|
||||
CoreBinary* CoreBinary::Clone(CloneContext& ctx) {
|
||||
auto* new_result = ctx.Clone(Result());
|
||||
auto* lhs = ctx.Remap(LHS());
|
||||
auto* rhs = ctx.Remap(RHS());
|
||||
return ctx.ir.CreateInstruction<CoreBinary>(new_result, Op(), lhs, rhs);
|
||||
}
|
||||
|
||||
const core::intrinsic::TableData& CoreBinary::TableData() const {
|
||||
return core::intrinsic::Dialect::kData;
|
||||
}
|
||||
|
||||
} // namespace tint::core::ir
|
||||
64
3rdparty/dawn/src/tint/lang/core/ir/core_binary.h
vendored
Normal file
64
3rdparty/dawn/src/tint/lang/core/ir/core_binary.h
vendored
Normal file
@@ -0,0 +1,64 @@
|
||||
// Copyright 2024 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.
|
||||
|
||||
#ifndef SRC_TINT_LANG_CORE_IR_CORE_BINARY_H_
|
||||
#define SRC_TINT_LANG_CORE_IR_CORE_BINARY_H_
|
||||
|
||||
#include "src/tint/lang/core/ir/binary.h"
|
||||
|
||||
namespace tint::core::ir {
|
||||
|
||||
/// A core-dialect binary-op instruction in the IR.
|
||||
class CoreBinary final : public Castable<CoreBinary, Binary> {
|
||||
public:
|
||||
/// The offset in Operands() for the value
|
||||
static constexpr size_t kValueOperandOffset = 0;
|
||||
|
||||
/// Constructor (no results, no operands)
|
||||
/// @param id the instruction id
|
||||
explicit CoreBinary(Id id);
|
||||
|
||||
/// Constructor
|
||||
/// @param id the instruction id
|
||||
/// @param result the result value
|
||||
/// @param op the Binary operator
|
||||
/// @param lhs the lhs of the instruction
|
||||
/// @param rhs the rhs of the instruction
|
||||
CoreBinary(Id id, InstructionResult* result, BinaryOp op, Value* lhs, Value* rhs);
|
||||
|
||||
~CoreBinary() override;
|
||||
|
||||
/// @copydoc Instruction::Clone()
|
||||
CoreBinary* Clone(CloneContext& ctx) override;
|
||||
|
||||
/// @returns the table data to validate this builtin
|
||||
const core::intrinsic::TableData& TableData() const override;
|
||||
};
|
||||
|
||||
} // namespace tint::core::ir
|
||||
|
||||
#endif // SRC_TINT_LANG_CORE_IR_CORE_BINARY_H_
|
||||
229
3rdparty/dawn/src/tint/lang/core/ir/core_builtin_call.cc
vendored
Normal file
229
3rdparty/dawn/src/tint/lang/core/ir/core_builtin_call.cc
vendored
Normal file
@@ -0,0 +1,229 @@
|
||||
// Copyright 2023 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/core/ir/core_builtin_call.h"
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include "src/tint/lang/core/ir/clone_context.h"
|
||||
#include "src/tint/lang/core/ir/module.h"
|
||||
#include "src/tint/utils/ice/ice.h"
|
||||
|
||||
TINT_INSTANTIATE_TYPEINFO(tint::core::ir::CoreBuiltinCall);
|
||||
|
||||
namespace tint::core::ir {
|
||||
|
||||
CoreBuiltinCall::CoreBuiltinCall(Id id) : Base(id) {}
|
||||
|
||||
CoreBuiltinCall::CoreBuiltinCall(Id id,
|
||||
InstructionResult* result,
|
||||
core::BuiltinFn func,
|
||||
VectorRef<Value*> arguments)
|
||||
: Base(id, result, arguments), func_(func) {
|
||||
TINT_ASSERT(func != core::BuiltinFn::kNone);
|
||||
}
|
||||
|
||||
CoreBuiltinCall::~CoreBuiltinCall() = default;
|
||||
|
||||
CoreBuiltinCall* CoreBuiltinCall::Clone(CloneContext& ctx) {
|
||||
auto* new_result = ctx.Clone(Result());
|
||||
auto args = ctx.Remap<CoreBuiltinCall::kDefaultNumOperands>(Args());
|
||||
return ctx.ir.CreateInstruction<CoreBuiltinCall>(new_result, func_, args);
|
||||
}
|
||||
|
||||
tint::core::ir::Instruction::Accesses CoreBuiltinCall::GetSideEffects() const {
|
||||
switch (func_) {
|
||||
case BuiltinFn::kAtomicLoad:
|
||||
case BuiltinFn::kInputAttachmentLoad:
|
||||
case BuiltinFn::kSubgroupMatrixLoad:
|
||||
case BuiltinFn::kTextureSample:
|
||||
case BuiltinFn::kTextureSampleBias:
|
||||
case BuiltinFn::kTextureSampleCompare:
|
||||
case BuiltinFn::kTextureSampleCompareLevel:
|
||||
case BuiltinFn::kTextureSampleGrad:
|
||||
case BuiltinFn::kTextureSampleLevel:
|
||||
case BuiltinFn::kTextureSampleBaseClampToEdge:
|
||||
case BuiltinFn::kTextureLoad:
|
||||
case BuiltinFn::kGetResource:
|
||||
return Accesses{Access::kLoad};
|
||||
|
||||
case BuiltinFn::kSubgroupMatrixStore:
|
||||
case BuiltinFn::kTextureStore:
|
||||
return Accesses{Access::kStore};
|
||||
|
||||
case BuiltinFn::kAtomicStore:
|
||||
case BuiltinFn::kAtomicAdd:
|
||||
case BuiltinFn::kAtomicSub:
|
||||
case BuiltinFn::kAtomicMax:
|
||||
case BuiltinFn::kAtomicMin:
|
||||
case BuiltinFn::kAtomicAnd:
|
||||
case BuiltinFn::kAtomicOr:
|
||||
case BuiltinFn::kAtomicXor:
|
||||
case BuiltinFn::kAtomicExchange:
|
||||
case BuiltinFn::kAtomicCompareExchangeWeak:
|
||||
case BuiltinFn::kDpdx:
|
||||
case BuiltinFn::kDpdxCoarse:
|
||||
case BuiltinFn::kDpdxFine:
|
||||
case BuiltinFn::kDpdy:
|
||||
case BuiltinFn::kDpdyCoarse:
|
||||
case BuiltinFn::kDpdyFine:
|
||||
case BuiltinFn::kFwidth:
|
||||
case BuiltinFn::kFwidthCoarse:
|
||||
case BuiltinFn::kFwidthFine:
|
||||
case BuiltinFn::kSubgroupBallot:
|
||||
case BuiltinFn::kSubgroupElect:
|
||||
case BuiltinFn::kSubgroupBroadcast:
|
||||
case BuiltinFn::kSubgroupBroadcastFirst:
|
||||
case BuiltinFn::kSubgroupShuffle:
|
||||
case BuiltinFn::kSubgroupShuffleXor:
|
||||
case BuiltinFn::kSubgroupShuffleUp:
|
||||
case BuiltinFn::kSubgroupShuffleDown:
|
||||
case BuiltinFn::kSubgroupAdd:
|
||||
case BuiltinFn::kSubgroupInclusiveAdd:
|
||||
case BuiltinFn::kSubgroupExclusiveAdd:
|
||||
case BuiltinFn::kSubgroupMul:
|
||||
case BuiltinFn::kSubgroupInclusiveMul:
|
||||
case BuiltinFn::kSubgroupExclusiveMul:
|
||||
case BuiltinFn::kSubgroupAnd:
|
||||
case BuiltinFn::kSubgroupOr:
|
||||
case BuiltinFn::kSubgroupXor:
|
||||
case BuiltinFn::kSubgroupMin:
|
||||
case BuiltinFn::kSubgroupMax:
|
||||
case BuiltinFn::kSubgroupAll:
|
||||
case BuiltinFn::kSubgroupAny:
|
||||
case BuiltinFn::kQuadBroadcast:
|
||||
case BuiltinFn::kQuadSwapX:
|
||||
case BuiltinFn::kQuadSwapY:
|
||||
case BuiltinFn::kQuadSwapDiagonal:
|
||||
case BuiltinFn::kStorageBarrier:
|
||||
case BuiltinFn::kWorkgroupBarrier:
|
||||
case BuiltinFn::kTextureBarrier:
|
||||
case BuiltinFn::kPrint:
|
||||
return Accesses{Access::kLoad, Access::kStore};
|
||||
|
||||
case BuiltinFn::kAbs:
|
||||
case BuiltinFn::kAcos:
|
||||
case BuiltinFn::kAcosh:
|
||||
case BuiltinFn::kAll:
|
||||
case BuiltinFn::kAny:
|
||||
case BuiltinFn::kArrayLength:
|
||||
case BuiltinFn::kAsin:
|
||||
case BuiltinFn::kAsinh:
|
||||
case BuiltinFn::kAtan:
|
||||
case BuiltinFn::kAtan2:
|
||||
case BuiltinFn::kAtanh:
|
||||
case BuiltinFn::kCeil:
|
||||
case BuiltinFn::kClamp:
|
||||
case BuiltinFn::kCos:
|
||||
case BuiltinFn::kCosh:
|
||||
case BuiltinFn::kCountLeadingZeros:
|
||||
case BuiltinFn::kCountOneBits:
|
||||
case BuiltinFn::kCountTrailingZeros:
|
||||
case BuiltinFn::kCross:
|
||||
case BuiltinFn::kDegrees:
|
||||
case BuiltinFn::kDeterminant:
|
||||
case BuiltinFn::kDistance:
|
||||
case BuiltinFn::kDot:
|
||||
case BuiltinFn::kDot4I8Packed:
|
||||
case BuiltinFn::kDot4U8Packed:
|
||||
case BuiltinFn::kExp:
|
||||
case BuiltinFn::kExp2:
|
||||
case BuiltinFn::kExtractBits:
|
||||
case BuiltinFn::kFaceForward:
|
||||
case BuiltinFn::kFirstLeadingBit:
|
||||
case BuiltinFn::kFirstTrailingBit:
|
||||
case BuiltinFn::kFloor:
|
||||
case BuiltinFn::kFma:
|
||||
case BuiltinFn::kFract:
|
||||
case BuiltinFn::kFrexp:
|
||||
case BuiltinFn::kInsertBits:
|
||||
case BuiltinFn::kInverseSqrt:
|
||||
case BuiltinFn::kLdexp:
|
||||
case BuiltinFn::kLength:
|
||||
case BuiltinFn::kLog:
|
||||
case BuiltinFn::kLog2:
|
||||
case BuiltinFn::kMax:
|
||||
case BuiltinFn::kMin:
|
||||
case BuiltinFn::kMix:
|
||||
case BuiltinFn::kModf:
|
||||
case BuiltinFn::kNormalize:
|
||||
case BuiltinFn::kPack2X16Float:
|
||||
case BuiltinFn::kPack2X16Snorm:
|
||||
case BuiltinFn::kPack2X16Unorm:
|
||||
case BuiltinFn::kPack4X8Snorm:
|
||||
case BuiltinFn::kPack4X8Unorm:
|
||||
case BuiltinFn::kPack4XI8:
|
||||
case BuiltinFn::kPack4XU8:
|
||||
case BuiltinFn::kPack4XI8Clamp:
|
||||
case BuiltinFn::kPack4XU8Clamp:
|
||||
case BuiltinFn::kPow:
|
||||
case BuiltinFn::kQuantizeToF16:
|
||||
case BuiltinFn::kRadians:
|
||||
case BuiltinFn::kReflect:
|
||||
case BuiltinFn::kRefract:
|
||||
case BuiltinFn::kReverseBits:
|
||||
case BuiltinFn::kRound:
|
||||
case BuiltinFn::kSaturate:
|
||||
case BuiltinFn::kSelect:
|
||||
case BuiltinFn::kSign:
|
||||
case BuiltinFn::kSin:
|
||||
case BuiltinFn::kSinh:
|
||||
case BuiltinFn::kSmoothstep:
|
||||
case BuiltinFn::kSqrt:
|
||||
case BuiltinFn::kStep:
|
||||
case BuiltinFn::kTan:
|
||||
case BuiltinFn::kTanh:
|
||||
case BuiltinFn::kTextureDimensions:
|
||||
case BuiltinFn::kTextureGather:
|
||||
case BuiltinFn::kTextureGatherCompare:
|
||||
case BuiltinFn::kTextureNumLayers:
|
||||
case BuiltinFn::kTextureNumLevels:
|
||||
case BuiltinFn::kTextureNumSamples:
|
||||
case BuiltinFn::kTranspose:
|
||||
case BuiltinFn::kTrunc:
|
||||
case BuiltinFn::kUnpack2X16Float:
|
||||
case BuiltinFn::kUnpack2X16Snorm:
|
||||
case BuiltinFn::kUnpack2X16Unorm:
|
||||
case BuiltinFn::kUnpack4X8Snorm:
|
||||
case BuiltinFn::kUnpack4X8Unorm:
|
||||
case BuiltinFn::kUnpack4XI8:
|
||||
case BuiltinFn::kUnpack4XU8:
|
||||
case BuiltinFn::kSubgroupMatrixMultiply:
|
||||
case BuiltinFn::kSubgroupMatrixMultiplyAccumulate:
|
||||
case BuiltinFn::kSubgroupMatrixScalarAdd:
|
||||
case BuiltinFn::kSubgroupMatrixScalarSubtract:
|
||||
case BuiltinFn::kSubgroupMatrixScalarMultiply:
|
||||
case BuiltinFn::kHasResource:
|
||||
case BuiltinFn::kBufferView:
|
||||
case BuiltinFn::kBufferLength:
|
||||
case BuiltinFn::kNone:
|
||||
break;
|
||||
}
|
||||
return Accesses{};
|
||||
}
|
||||
|
||||
} // namespace tint::core::ir
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user