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