mirror of
https://github.com/encounter/dawn-cmake.git
synced 2025-12-16 16:37:08 +00:00
intrinsics: Add scalar overload of all() & any()
Fixed: tint:1253 Change-Id: I0bdc865a9df9e0171c09daa9918b25bba033ba3b Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/67061 Kokoro: Kokoro <noreply+kokoro@google.com> Reviewed-by: David Neto <dneto@google.com> Reviewed-by: James Price <jrprice@google.com> Commit-Queue: Ben Clayton <bclayton@chromium.org>
This commit is contained in:
committed by
Tint LUCI CQ
parent
347c74e671
commit
8cab28c9f9
File diff suppressed because it is too large
Load Diff
@@ -267,7 +267,9 @@ fn abs<T: fiu32>(T) -> T
|
||||
fn abs<N: num, T: fiu32>(vec<N, T>) -> vec<N, T>
|
||||
fn acos(f32) -> f32
|
||||
fn acos<N: num>(vec<N, f32>) -> vec<N, f32>
|
||||
fn all(bool) -> bool
|
||||
fn all<N: num>(vec<N, bool>) -> bool
|
||||
fn any(bool) -> bool
|
||||
fn any<N: num>(vec<N, bool>) -> bool
|
||||
fn arrayLength<T, A: access>(ptr<storage, array<T>, A>) -> u32
|
||||
fn asin(f32) -> f32
|
||||
|
||||
@@ -107,8 +107,21 @@ INSTANTIATE_TEST_SUITE_P(ResolverTest,
|
||||
"fwidthCoarse",
|
||||
"fwidthFine"));
|
||||
|
||||
using ResolverIntrinsic = ResolverTestWithParam<std::string>;
|
||||
TEST_P(ResolverIntrinsic, Test) {
|
||||
using ResolverIntrinsicTest_BoolMethod = ResolverTestWithParam<std::string>;
|
||||
TEST_P(ResolverIntrinsicTest_BoolMethod, Scalar) {
|
||||
auto name = GetParam();
|
||||
|
||||
Global("my_var", ty.bool_(), ast::StorageClass::kPrivate);
|
||||
|
||||
auto* expr = Call(name, "my_var");
|
||||
WrapInFunction(expr);
|
||||
|
||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||
|
||||
ASSERT_NE(TypeOf(expr), nullptr);
|
||||
EXPECT_TRUE(TypeOf(expr)->Is<sem::Bool>());
|
||||
}
|
||||
TEST_P(ResolverIntrinsicTest_BoolMethod, Vector) {
|
||||
auto name = GetParam();
|
||||
|
||||
Global("my_var", ty.vec3<bool>(), ast::StorageClass::kPrivate);
|
||||
@@ -122,7 +135,7 @@ TEST_P(ResolverIntrinsic, Test) {
|
||||
EXPECT_TRUE(TypeOf(expr)->Is<sem::Bool>());
|
||||
}
|
||||
INSTANTIATE_TEST_SUITE_P(ResolverTest,
|
||||
ResolverIntrinsic,
|
||||
ResolverIntrinsicTest_BoolMethod,
|
||||
testing::Values("any", "all"));
|
||||
|
||||
using ResolverIntrinsicTest_FloatMethod = ResolverTestWithParam<std::string>;
|
||||
|
||||
@@ -2307,10 +2307,10 @@ uint32_t Builder::GenerateIntrinsic(const ast::CallExpression* call,
|
||||
return result_id;
|
||||
}
|
||||
|
||||
// Generates the SPIR-V ID for the expression for the indexed call parameter,
|
||||
// Generates the SPIR-V ID for the expression for the indexed call argument,
|
||||
// and loads it if necessary. Returns 0 on error.
|
||||
auto get_param_as_value_id = [&](size_t i,
|
||||
bool generate_load = true) -> uint32_t {
|
||||
auto get_arg_as_value_id = [&](size_t i,
|
||||
bool generate_load = true) -> uint32_t {
|
||||
auto* arg = call->args[i];
|
||||
auto* param = intrinsic->Parameters()[i];
|
||||
auto val_id = GenerateExpression(arg);
|
||||
@@ -2327,7 +2327,7 @@ uint32_t Builder::GenerateIntrinsic(const ast::CallExpression* call,
|
||||
OperandList params = {Operand::Int(result_type_id), result};
|
||||
spv::Op op = spv::Op::OpNop;
|
||||
|
||||
// Pushes the parameters for a GlslStd450 extended instruction, and sets op
|
||||
// Pushes the arguments for a GlslStd450 extended instruction, and sets op
|
||||
// to OpExtInst.
|
||||
auto glsl_std450 = [&](uint32_t inst_id) {
|
||||
auto set_id = GetGLSLstd450Import();
|
||||
@@ -2338,9 +2338,17 @@ uint32_t Builder::GenerateIntrinsic(const ast::CallExpression* call,
|
||||
|
||||
switch (intrinsic->Type()) {
|
||||
case IntrinsicType::kAny:
|
||||
if (intrinsic->Parameters()[0]->Type()->Is<sem::Bool>()) {
|
||||
// any(v: bool) just resolves to v.
|
||||
return get_arg_as_value_id(0);
|
||||
}
|
||||
op = spv::Op::OpAny;
|
||||
break;
|
||||
case IntrinsicType::kAll:
|
||||
if (intrinsic->Parameters()[0]->Type()->Is<sem::Bool>()) {
|
||||
// all(v: bool) just resolves to v.
|
||||
return get_arg_as_value_id(0);
|
||||
}
|
||||
op = spv::Op::OpAll;
|
||||
break;
|
||||
case IntrinsicType::kArrayLength: {
|
||||
@@ -2424,7 +2432,7 @@ uint32_t Builder::GenerateIntrinsic(const ast::CallExpression* call,
|
||||
// Evaluate the single argument, return the non-zero result_id which isn't
|
||||
// associated with any op (ignore returns void, so this cannot be used in
|
||||
// an expression).
|
||||
if (!get_param_as_value_id(0, false)) {
|
||||
if (!get_arg_as_value_id(0, false)) {
|
||||
return 0;
|
||||
}
|
||||
return result_id;
|
||||
@@ -2436,7 +2444,7 @@ uint32_t Builder::GenerateIntrinsic(const ast::CallExpression* call,
|
||||
break;
|
||||
case IntrinsicType::kIsFinite: {
|
||||
// Implemented as: not(IsInf or IsNan)
|
||||
auto val_id = get_param_as_value_id(0);
|
||||
auto val_id = get_arg_as_value_id(0);
|
||||
if (!val_id) {
|
||||
return 0;
|
||||
}
|
||||
@@ -2468,7 +2476,7 @@ uint32_t Builder::GenerateIntrinsic(const ast::CallExpression* call,
|
||||
// clamped = uclamp(1,254,exponent_bits);
|
||||
// result = (clamped == exponent_bits);
|
||||
//
|
||||
auto val_id = get_param_as_value_id(0);
|
||||
auto val_id = get_arg_as_value_id(0);
|
||||
if (!val_id) {
|
||||
return 0;
|
||||
}
|
||||
@@ -2541,9 +2549,9 @@ uint32_t Builder::GenerateIntrinsic(const ast::CallExpression* call,
|
||||
case IntrinsicType::kMix: {
|
||||
auto std450 = Operand::Int(GetGLSLstd450Import());
|
||||
|
||||
auto a_id = get_param_as_value_id(0);
|
||||
auto b_id = get_param_as_value_id(1);
|
||||
auto f_id = get_param_as_value_id(2);
|
||||
auto a_id = get_arg_as_value_id(0);
|
||||
auto b_id = get_arg_as_value_id(1);
|
||||
auto f_id = get_arg_as_value_id(2);
|
||||
if (!a_id || !b_id || !f_id) {
|
||||
return 0;
|
||||
}
|
||||
@@ -2572,9 +2580,9 @@ uint32_t Builder::GenerateIntrinsic(const ast::CallExpression* call,
|
||||
break;
|
||||
case IntrinsicType::kSelect: {
|
||||
// Note: Argument order is different in WGSL and SPIR-V
|
||||
auto cond_id = get_param_as_value_id(2);
|
||||
auto true_id = get_param_as_value_id(1);
|
||||
auto false_id = get_param_as_value_id(0);
|
||||
auto cond_id = get_arg_as_value_id(2);
|
||||
auto true_id = get_arg_as_value_id(1);
|
||||
auto false_id = get_arg_as_value_id(0);
|
||||
if (!cond_id || !true_id || !false_id) {
|
||||
return 0;
|
||||
}
|
||||
@@ -2611,7 +2619,7 @@ uint32_t Builder::GenerateIntrinsic(const ast::CallExpression* call,
|
||||
if (intrinsic->ReturnType()->is_unsigned_scalar_or_vector()) {
|
||||
// abs() only operates on *signed* integers.
|
||||
// This is a no-op for unsigned integers.
|
||||
return get_param_as_value_id(0);
|
||||
return get_arg_as_value_id(0);
|
||||
}
|
||||
if (intrinsic->ReturnType()->is_float_scalar_or_vector()) {
|
||||
glsl_std450(GLSLstd450FAbs);
|
||||
@@ -2637,7 +2645,7 @@ uint32_t Builder::GenerateIntrinsic(const ast::CallExpression* call,
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < call->args.size(); i++) {
|
||||
if (auto val_id = get_param_as_value_id(i)) {
|
||||
if (auto val_id = get_arg_as_value_id(i)) {
|
||||
params.emplace_back(Operand::Int(val_id));
|
||||
} else {
|
||||
return 0;
|
||||
|
||||
@@ -39,7 +39,32 @@ inline std::ostream& operator<<(std::ostream& out, IntrinsicData data) {
|
||||
}
|
||||
|
||||
using IntrinsicBoolTest = IntrinsicBuilderTestWithParam<IntrinsicData>;
|
||||
TEST_P(IntrinsicBoolTest, Call_Bool) {
|
||||
TEST_P(IntrinsicBoolTest, Call_Bool_Scalar) {
|
||||
auto param = GetParam();
|
||||
|
||||
auto* var = Global("v", ty.bool_(), ast::StorageClass::kPrivate);
|
||||
|
||||
auto* expr = Call(param.name, "v");
|
||||
WrapInFunction(expr);
|
||||
|
||||
spirv::Builder& b = Build();
|
||||
|
||||
b.push_function(Function{});
|
||||
ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
|
||||
|
||||
EXPECT_EQ(b.GenerateCallExpression(expr), 6u) << b.error();
|
||||
EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeBool
|
||||
%2 = OpTypePointer Private %3
|
||||
%4 = OpConstantNull %3
|
||||
%1 = OpVariable %2 Private %4
|
||||
)");
|
||||
|
||||
// both any and all are 'passthrough' for scalar booleans
|
||||
EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
|
||||
"%6 = OpLoad %3 %1\n");
|
||||
}
|
||||
|
||||
TEST_P(IntrinsicBoolTest, Call_Bool_Vector) {
|
||||
auto param = GetParam();
|
||||
|
||||
auto* var = Global("v", ty.vec3<bool>(), ast::StorageClass::kPrivate);
|
||||
|
||||
Reference in New Issue
Block a user