mirror of
https://github.com/encounter/dawn-cmake.git
synced 2025-12-17 00:47:13 +00:00
tint/intrinsics.def: Implement saturate()
Fixed: tint:1591 Change-Id: I0b1397d74abd49cd44caf326a2063e50c5cf07de Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/101480 Reviewed-by: Dan Sinclair <dsinclair@chromium.org> Auto-Submit: Ben Clayton <bclayton@google.com> Commit-Queue: Ben Clayton <bclayton@google.com> Kokoro: Kokoro <noreply+kokoro@google.com>
This commit is contained in:
committed by
Dawn LUCI CQ
parent
f3d9ea4bea
commit
751e6686aa
@@ -508,6 +508,8 @@ fn reverseBits<T: iu32>(T) -> T
|
||||
fn reverseBits<N: num, T: iu32>(vec<N, T>) -> vec<N, T>
|
||||
fn round<T: f32_f16>(T) -> T
|
||||
fn round<N: num, T: f32_f16>(vec<N, T>) -> vec<N, T>
|
||||
fn saturate<T: f32_f16>(T) -> T
|
||||
fn saturate<T: f32_f16, N: num>(vec<N, T>) -> vec<N, T>
|
||||
fn select<T: scalar>(T, T, bool) -> T
|
||||
fn select<T: scalar, N: num>(vec<N, T>, vec<N, T>, bool) -> vec<N, T>
|
||||
fn select<N: num, T: scalar>(vec<N, T>, vec<N, T>, vec<N, bool>) -> vec<N, T>
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -225,6 +225,9 @@ BuiltinType ParseBuiltinType(const std::string& name) {
|
||||
if (name == "round") {
|
||||
return BuiltinType::kRound;
|
||||
}
|
||||
if (name == "saturate") {
|
||||
return BuiltinType::kSaturate;
|
||||
}
|
||||
if (name == "select") {
|
||||
return BuiltinType::kSelect;
|
||||
}
|
||||
@@ -493,6 +496,8 @@ const char* str(BuiltinType i) {
|
||||
return "reverseBits";
|
||||
case BuiltinType::kRound:
|
||||
return "round";
|
||||
case BuiltinType::kSaturate:
|
||||
return "saturate";
|
||||
case BuiltinType::kSelect:
|
||||
return "select";
|
||||
case BuiltinType::kSign:
|
||||
|
||||
@@ -97,6 +97,7 @@ enum class BuiltinType {
|
||||
kRefract,
|
||||
kReverseBits,
|
||||
kRound,
|
||||
kSaturate,
|
||||
kSelect,
|
||||
kSign,
|
||||
kSin,
|
||||
|
||||
@@ -495,6 +495,23 @@ struct BuiltinPolyfill::State {
|
||||
return name;
|
||||
}
|
||||
|
||||
/// Builds the polyfill function for the `saturate` builtin
|
||||
/// @param ty the parameter and return type for the function
|
||||
/// @return the polyfill function name
|
||||
Symbol saturate(const sem::Type* ty) {
|
||||
auto name = b.Symbols().New("tint_saturate");
|
||||
auto body = utils::Vector{
|
||||
b.Return(b.Call("clamp", "v", b.Construct(T(ty), 0_a), b.Construct(T(ty), 1_a))),
|
||||
};
|
||||
b.Func(name,
|
||||
utils::Vector{
|
||||
b.Param("v", T(ty)),
|
||||
},
|
||||
T(ty), body);
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
private:
|
||||
/// @returns the AST type for the given sem type
|
||||
const ast::Type* T(const sem::Type* ty) const { return CreateASTTypeFor(ctx, ty); }
|
||||
@@ -575,6 +592,11 @@ bool BuiltinPolyfill::ShouldRun(const Program* program, const DataMap& data) con
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case sem::BuiltinType::kSaturate:
|
||||
if (builtins.saturate) {
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -661,6 +683,13 @@ void BuiltinPolyfill::Run(CloneContext& ctx, const DataMap& data, DataMap&) cons
|
||||
});
|
||||
}
|
||||
break;
|
||||
case sem::BuiltinType::kSaturate:
|
||||
if (builtins.saturate) {
|
||||
polyfill = utils::GetOrCreate(polyfills, builtin, [&] {
|
||||
return s.saturate(builtin->ReturnType());
|
||||
});
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -59,6 +59,8 @@ class BuiltinPolyfill final : public Castable<BuiltinPolyfill, Transform> {
|
||||
bool first_trailing_bit = false;
|
||||
/// Should `insertBits()` be polyfilled?
|
||||
Level insert_bits = Level::kNone;
|
||||
/// Should `saturate()` be polyfilled?
|
||||
bool saturate = false;
|
||||
};
|
||||
|
||||
/// Config is consumed by the BuiltinPolyfill transform.
|
||||
|
||||
@@ -1387,5 +1387,167 @@ fn f() {
|
||||
EXPECT_EQ(expect, str(got));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// saturate
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
DataMap polyfillSaturate() {
|
||||
BuiltinPolyfill::Builtins builtins;
|
||||
builtins.saturate = true;
|
||||
DataMap data;
|
||||
data.Add<BuiltinPolyfill::Config>(builtins);
|
||||
return data;
|
||||
}
|
||||
|
||||
TEST_F(BuiltinPolyfillTest, ShouldRunSaturate) {
|
||||
auto* src = R"(
|
||||
fn f() {
|
||||
saturate(0.5);
|
||||
}
|
||||
)";
|
||||
|
||||
EXPECT_FALSE(ShouldRun<BuiltinPolyfill>(src));
|
||||
EXPECT_TRUE(ShouldRun<BuiltinPolyfill>(src, polyfillSaturate()));
|
||||
}
|
||||
|
||||
TEST_F(BuiltinPolyfillTest, Saturate_f32) {
|
||||
auto* src = R"(
|
||||
fn f() {
|
||||
let r : f32 = saturate(0.5f);
|
||||
}
|
||||
)";
|
||||
|
||||
auto* expect = R"(
|
||||
fn tint_saturate(v : f32) -> f32 {
|
||||
return clamp(v, f32(0), f32(1));
|
||||
}
|
||||
|
||||
fn f() {
|
||||
let r : f32 = tint_saturate(0.5f);
|
||||
}
|
||||
)";
|
||||
|
||||
auto got = Run<BuiltinPolyfill>(src, polyfillSaturate());
|
||||
|
||||
EXPECT_EQ(expect, str(got));
|
||||
}
|
||||
|
||||
TEST_F(BuiltinPolyfillTest, Saturate_f32_from_abstract_float) {
|
||||
auto* src = R"(
|
||||
fn f() {
|
||||
let r : f32 = saturate(0.5);
|
||||
}
|
||||
)";
|
||||
|
||||
auto* expect = R"(
|
||||
fn tint_saturate(v : f32) -> f32 {
|
||||
return clamp(v, f32(0), f32(1));
|
||||
}
|
||||
|
||||
fn f() {
|
||||
let r : f32 = tint_saturate(0.5);
|
||||
}
|
||||
)";
|
||||
|
||||
auto got = Run<BuiltinPolyfill>(src, polyfillSaturate());
|
||||
|
||||
EXPECT_EQ(expect, str(got));
|
||||
}
|
||||
|
||||
TEST_F(BuiltinPolyfillTest, Saturate_f16) {
|
||||
auto* src = R"(
|
||||
enable f16;
|
||||
|
||||
fn f() {
|
||||
let r : f16 = saturate(0.5h);
|
||||
}
|
||||
)";
|
||||
|
||||
auto* expect = R"(
|
||||
enable f16;
|
||||
|
||||
fn tint_saturate(v : f16) -> f16 {
|
||||
return clamp(v, f16(0), f16(1));
|
||||
}
|
||||
|
||||
fn f() {
|
||||
let r : f16 = tint_saturate(0.5h);
|
||||
}
|
||||
)";
|
||||
|
||||
auto got = Run<BuiltinPolyfill>(src, polyfillSaturate());
|
||||
|
||||
EXPECT_EQ(expect, str(got));
|
||||
}
|
||||
|
||||
TEST_F(BuiltinPolyfillTest, Saturate_vec3_f32) {
|
||||
auto* src = R"(
|
||||
fn f() {
|
||||
let r : vec3<f32> = saturate(vec3<f32>(0.5f));
|
||||
}
|
||||
)";
|
||||
|
||||
auto* expect = R"(
|
||||
fn tint_saturate(v : vec3<f32>) -> vec3<f32> {
|
||||
return clamp(v, vec3<f32>(0), vec3<f32>(1));
|
||||
}
|
||||
|
||||
fn f() {
|
||||
let r : vec3<f32> = tint_saturate(vec3<f32>(0.5f));
|
||||
}
|
||||
)";
|
||||
|
||||
auto got = Run<BuiltinPolyfill>(src, polyfillSaturate());
|
||||
|
||||
EXPECT_EQ(expect, str(got));
|
||||
}
|
||||
|
||||
TEST_F(BuiltinPolyfillTest, Saturate_vec3_f32_from_abstract_float) {
|
||||
auto* src = R"(
|
||||
fn f() {
|
||||
let r : vec3<f32> = saturate(vec3(0.5));
|
||||
}
|
||||
)";
|
||||
|
||||
auto* expect = R"(
|
||||
fn tint_saturate(v : vec3<f32>) -> vec3<f32> {
|
||||
return clamp(v, vec3<f32>(0), vec3<f32>(1));
|
||||
}
|
||||
|
||||
fn f() {
|
||||
let r : vec3<f32> = tint_saturate(vec3(0.5));
|
||||
}
|
||||
)";
|
||||
|
||||
auto got = Run<BuiltinPolyfill>(src, polyfillSaturate());
|
||||
|
||||
EXPECT_EQ(expect, str(got));
|
||||
}
|
||||
|
||||
TEST_F(BuiltinPolyfillTest, Saturate_vec3_f16) {
|
||||
auto* src = R"(
|
||||
enable f16;
|
||||
|
||||
fn f() {
|
||||
let r : vec3<f16> = saturate(vec3<f16>(0.5h));
|
||||
}
|
||||
)";
|
||||
|
||||
auto* expect = R"(
|
||||
enable f16;
|
||||
|
||||
fn tint_saturate(v : vec3<f16>) -> vec3<f16> {
|
||||
return clamp(v, vec3<f16>(0), vec3<f16>(1));
|
||||
}
|
||||
|
||||
fn f() {
|
||||
let r : vec3<f16> = tint_saturate(vec3<f16>(0.5h));
|
||||
}
|
||||
)";
|
||||
|
||||
auto got = Run<BuiltinPolyfill>(src, polyfillSaturate());
|
||||
|
||||
EXPECT_EQ(expect, str(got));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace tint::transform
|
||||
|
||||
@@ -194,6 +194,7 @@ SanitizedResult Sanitize(const Program* in,
|
||||
polyfills.first_leading_bit = true;
|
||||
polyfills.first_trailing_bit = true;
|
||||
polyfills.insert_bits = transform::BuiltinPolyfill::Level::kClampParameters;
|
||||
polyfills.saturate = true;
|
||||
data.Add<transform::BuiltinPolyfill::Config>(polyfills);
|
||||
manager.Add<transform::BuiltinPolyfill>();
|
||||
}
|
||||
|
||||
@@ -2510,6 +2510,7 @@ std::string GeneratorImpl::generate_builtin_name(const sem::Builtin* builtin) {
|
||||
case sem::BuiltinType::kReflect:
|
||||
case sem::BuiltinType::kRefract:
|
||||
case sem::BuiltinType::kRound:
|
||||
case sem::BuiltinType::kSaturate:
|
||||
case sem::BuiltinType::kSign:
|
||||
case sem::BuiltinType::kSin:
|
||||
case sem::BuiltinType::kSinh:
|
||||
|
||||
@@ -1400,6 +1400,7 @@ std::string GeneratorImpl::generate_builtin_name(const sem::Builtin* builtin) {
|
||||
case sem::BuiltinType::kPow:
|
||||
case sem::BuiltinType::kReflect:
|
||||
case sem::BuiltinType::kRefract:
|
||||
case sem::BuiltinType::kSaturate:
|
||||
case sem::BuiltinType::kSelect:
|
||||
case sem::BuiltinType::kSin:
|
||||
case sem::BuiltinType::kSinh:
|
||||
|
||||
@@ -57,6 +57,7 @@ SanitizedResult Sanitize(const Program* in, const Options& options) {
|
||||
polyfills.first_leading_bit = true;
|
||||
polyfills.first_trailing_bit = true;
|
||||
polyfills.insert_bits = transform::BuiltinPolyfill::Level::kClampParameters;
|
||||
polyfills.saturate = true;
|
||||
data.Add<transform::BuiltinPolyfill::Config>(polyfills);
|
||||
manager.Add<transform::BuiltinPolyfill>();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user