mirror of
https://github.com/encounter/dawn-cmake.git
synced 2025-12-12 14:46:08 +00:00
intrinsics: Remove deprecated modf & frexp overloads
These have been deprecated for multiple chrome releases. Change-Id: I4cc05a74ff8f085e6d13f93aefb93077480e52f5 Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/66261 Kokoro: Kokoro <noreply+kokoro@google.com> Reviewed-by: James Price <jrprice@google.com> Commit-Queue: Ben Clayton <bclayton@google.com>
This commit is contained in:
committed by
Tint LUCI CQ
parent
d57a129810
commit
2aa6855914
File diff suppressed because it is too large
Load Diff
@@ -16,6 +16,7 @@
|
||||
|
||||
#include "gmock/gmock.h"
|
||||
#include "src/program_builder.h"
|
||||
#include "src/sem/atomic_type.h"
|
||||
#include "src/sem/depth_multisampled_texture_type.h"
|
||||
#include "src/sem/depth_texture_type.h"
|
||||
#include "src/sem/external_texture_type.h"
|
||||
@@ -211,22 +212,24 @@ TEST_F(IntrinsicTableTest, MismatchBool) {
|
||||
}
|
||||
|
||||
TEST_F(IntrinsicTableTest, MatchPointer) {
|
||||
auto* f32 = create<sem::F32>();
|
||||
auto* ptr = create<sem::Pointer>(f32, ast::StorageClass::kFunction,
|
||||
auto* i32 = create<sem::I32>();
|
||||
auto* atomicI32 = create<sem::Atomic>(i32);
|
||||
auto* ptr = create<sem::Pointer>(atomicI32, ast::StorageClass::kWorkgroup,
|
||||
ast::Access::kReadWrite);
|
||||
auto* result = table->Lookup(IntrinsicType::kModf, {f32, ptr}, Source{});
|
||||
auto* result = table->Lookup(IntrinsicType::kAtomicLoad, {ptr}, Source{});
|
||||
ASSERT_NE(result, nullptr) << Diagnostics().str();
|
||||
ASSERT_EQ(Diagnostics().str(), "");
|
||||
EXPECT_THAT(result->Type(), IntrinsicType::kModf);
|
||||
EXPECT_THAT(result->ReturnType(), f32);
|
||||
ASSERT_EQ(result->Parameters().size(), 2u);
|
||||
EXPECT_EQ(result->Parameters()[0]->Type(), f32);
|
||||
EXPECT_EQ(result->Parameters()[1]->Type(), ptr);
|
||||
EXPECT_THAT(result->Type(), IntrinsicType::kAtomicLoad);
|
||||
EXPECT_THAT(result->ReturnType(), i32);
|
||||
ASSERT_EQ(result->Parameters().size(), 1u);
|
||||
EXPECT_EQ(result->Parameters()[0]->Type(), ptr);
|
||||
}
|
||||
|
||||
TEST_F(IntrinsicTableTest, MismatchPointer) {
|
||||
auto* f32 = create<sem::F32>();
|
||||
auto* result = table->Lookup(IntrinsicType::kModf, {f32, f32}, Source{});
|
||||
auto* i32 = create<sem::I32>();
|
||||
auto* atomicI32 = create<sem::Atomic>(i32);
|
||||
auto* result =
|
||||
table->Lookup(IntrinsicType::kAtomicLoad, {atomicI32}, Source{});
|
||||
ASSERT_EQ(result, nullptr);
|
||||
ASSERT_THAT(Diagnostics().str(), HasSubstr("no matching call"));
|
||||
}
|
||||
|
||||
@@ -314,8 +314,6 @@ fn fma(f32, f32, f32) -> f32
|
||||
fn fma<N: num>(vec<N, f32>, vec<N, f32>, vec<N, f32>) -> vec<N, f32>
|
||||
fn fract(f32) -> f32
|
||||
fn fract<N: num>(vec<N, f32>) -> vec<N, f32>
|
||||
[[deprecated]] fn frexp<S: function_private_workgroup, A: access>(f32, ptr<S, i32, A>) -> f32
|
||||
[[deprecated]] fn frexp<N: num, S: function_private_workgroup, A: access>(vec<N, f32>, ptr<S, vec<N, i32>, A>) -> vec<N, f32>
|
||||
fn frexp(f32) -> _frexp_result
|
||||
fn frexp<N: num>(vec<N, f32>) -> _frexp_result_vec<N>
|
||||
[[stage("fragment")]] fn fwidth(f32) -> f32
|
||||
@@ -350,8 +348,6 @@ fn min<N: num, T: fiu32>(vec<N, T>, vec<N, T>) -> vec<N, T>
|
||||
fn mix(f32, f32, f32) -> f32
|
||||
fn mix<N: num>(vec<N, f32>, vec<N, f32>, vec<N, f32>) -> vec<N, f32>
|
||||
fn mix<N: num>(vec<N, f32>, vec<N, f32>, f32) -> vec<N, f32>
|
||||
[[deprecated]] fn modf<S: function_private_workgroup, A: access>(f32, ptr<S, f32, A>) -> f32
|
||||
[[deprecated]] fn modf<N: num, S: function_private_workgroup, A: access>(vec<N, f32>, ptr<S, vec<N, f32>, A>) -> vec<N, f32>
|
||||
fn modf(f32) -> _modf_result
|
||||
fn modf<N: num>(vec<N, f32>) -> _modf_result_vec<N>
|
||||
fn normalize<N: num>(vec<N, f32>) -> vec<N, f32>
|
||||
|
||||
@@ -766,87 +766,131 @@ TEST_F(ResolverBuiltinsValidationTest, Determinant_Mat4x4) {
|
||||
}
|
||||
|
||||
TEST_F(ResolverBuiltinsValidationTest, Frexp_Scalar) {
|
||||
auto* a = Var("a", ty.i32());
|
||||
auto* builtin = Call("frexp", 1.0f, AddressOf(Expr("a")));
|
||||
WrapInFunction(Decl(a), builtin);
|
||||
auto* builtin = Call("frexp", 1.0f);
|
||||
WrapInFunction(builtin);
|
||||
|
||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||
EXPECT_TRUE(TypeOf(builtin)->Is<sem::F32>());
|
||||
EXPECT_TRUE(TypeOf(builtin->params()[1])->Is<sem::Pointer>());
|
||||
auto* res_ty = TypeOf(builtin)->As<sem::Struct>();
|
||||
ASSERT_TRUE(res_ty != nullptr);
|
||||
auto& members = res_ty->Members();
|
||||
ASSERT_EQ(members.size(), 2u);
|
||||
EXPECT_TRUE(members[0]->Type()->Is<sem::F32>());
|
||||
EXPECT_TRUE(members[1]->Type()->Is<sem::I32>());
|
||||
}
|
||||
|
||||
TEST_F(ResolverBuiltinsValidationTest, Frexp_Vec2) {
|
||||
auto* a = Var("a", ty.vec2<int>());
|
||||
auto* builtin = Call("frexp", vec2<f32>(1.0f, 1.0f), AddressOf(Expr("a")));
|
||||
WrapInFunction(Decl(a), builtin);
|
||||
auto* builtin = Call("frexp", vec2<f32>(1.0f, 1.0f));
|
||||
WrapInFunction(builtin);
|
||||
|
||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||
EXPECT_TRUE(TypeOf(builtin)->is_float_vector());
|
||||
EXPECT_TRUE(TypeOf(builtin->params()[1])->Is<sem::Pointer>());
|
||||
auto* res_ty = TypeOf(builtin)->As<sem::Struct>();
|
||||
ASSERT_TRUE(res_ty != nullptr);
|
||||
auto& members = res_ty->Members();
|
||||
ASSERT_EQ(members.size(), 2u);
|
||||
ASSERT_TRUE(members[0]->Type()->Is<sem::Vector>());
|
||||
ASSERT_TRUE(members[1]->Type()->Is<sem::Vector>());
|
||||
EXPECT_EQ(members[0]->Type()->As<sem::Vector>()->Width(), 2u);
|
||||
EXPECT_TRUE(members[0]->Type()->As<sem::Vector>()->type()->Is<sem::F32>());
|
||||
EXPECT_EQ(members[1]->Type()->As<sem::Vector>()->Width(), 2u);
|
||||
EXPECT_TRUE(members[1]->Type()->As<sem::Vector>()->type()->Is<sem::I32>());
|
||||
}
|
||||
|
||||
TEST_F(ResolverBuiltinsValidationTest, Frexp_Vec3) {
|
||||
auto* a = Var("a", ty.vec3<int>());
|
||||
auto* builtin =
|
||||
Call("frexp", vec3<f32>(1.0f, 1.0f, 1.0f), AddressOf(Expr("a")));
|
||||
WrapInFunction(Decl(a), builtin);
|
||||
auto* builtin = Call("frexp", vec3<f32>(1.0f, 1.0f, 1.0f));
|
||||
WrapInFunction(builtin);
|
||||
|
||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||
EXPECT_TRUE(TypeOf(builtin)->is_float_vector());
|
||||
EXPECT_TRUE(TypeOf(builtin->params()[1])->Is<sem::Pointer>());
|
||||
auto* res_ty = TypeOf(builtin)->As<sem::Struct>();
|
||||
ASSERT_TRUE(res_ty != nullptr);
|
||||
auto& members = res_ty->Members();
|
||||
ASSERT_EQ(members.size(), 2u);
|
||||
ASSERT_TRUE(members[0]->Type()->Is<sem::Vector>());
|
||||
ASSERT_TRUE(members[1]->Type()->Is<sem::Vector>());
|
||||
EXPECT_EQ(members[0]->Type()->As<sem::Vector>()->Width(), 3u);
|
||||
EXPECT_TRUE(members[0]->Type()->As<sem::Vector>()->type()->Is<sem::F32>());
|
||||
EXPECT_EQ(members[1]->Type()->As<sem::Vector>()->Width(), 3u);
|
||||
EXPECT_TRUE(members[1]->Type()->As<sem::Vector>()->type()->Is<sem::I32>());
|
||||
}
|
||||
|
||||
TEST_F(ResolverBuiltinsValidationTest, Frexp_Vec4) {
|
||||
auto* a = Var("a", ty.vec4<int>());
|
||||
auto* builtin =
|
||||
Call("frexp", vec4<f32>(1.0f, 1.0f, 1.0f, 1.0f), AddressOf(Expr("a")));
|
||||
WrapInFunction(Decl(a), builtin);
|
||||
auto* builtin = Call("frexp", vec4<f32>(1.0f, 1.0f, 1.0f, 1.0f));
|
||||
WrapInFunction(builtin);
|
||||
|
||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||
EXPECT_TRUE(TypeOf(builtin)->is_float_vector());
|
||||
EXPECT_TRUE(TypeOf(builtin->params()[1])->Is<sem::Pointer>());
|
||||
auto* res_ty = TypeOf(builtin)->As<sem::Struct>();
|
||||
ASSERT_TRUE(res_ty != nullptr);
|
||||
auto& members = res_ty->Members();
|
||||
ASSERT_EQ(members.size(), 2u);
|
||||
ASSERT_TRUE(members[0]->Type()->Is<sem::Vector>());
|
||||
ASSERT_TRUE(members[1]->Type()->Is<sem::Vector>());
|
||||
EXPECT_EQ(members[0]->Type()->As<sem::Vector>()->Width(), 4u);
|
||||
EXPECT_TRUE(members[0]->Type()->As<sem::Vector>()->type()->Is<sem::F32>());
|
||||
EXPECT_EQ(members[1]->Type()->As<sem::Vector>()->Width(), 4u);
|
||||
EXPECT_TRUE(members[1]->Type()->As<sem::Vector>()->type()->Is<sem::I32>());
|
||||
}
|
||||
|
||||
TEST_F(ResolverBuiltinsValidationTest, Modf_Scalar) {
|
||||
auto* a = Var("a", ty.f32());
|
||||
auto* builtin = Call("modf", 1.0f, AddressOf(Expr("a")));
|
||||
WrapInFunction(Decl(a), builtin);
|
||||
auto* builtin = Call("modf", 1.0f);
|
||||
WrapInFunction(builtin);
|
||||
|
||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||
EXPECT_TRUE(TypeOf(builtin)->Is<sem::F32>());
|
||||
EXPECT_TRUE(TypeOf(builtin->params()[1])->Is<sem::Pointer>());
|
||||
auto* res_ty = TypeOf(builtin)->As<sem::Struct>();
|
||||
ASSERT_TRUE(res_ty != nullptr);
|
||||
auto& members = res_ty->Members();
|
||||
ASSERT_EQ(members.size(), 2u);
|
||||
EXPECT_TRUE(members[0]->Type()->Is<sem::F32>());
|
||||
EXPECT_TRUE(members[1]->Type()->Is<sem::F32>());
|
||||
}
|
||||
|
||||
TEST_F(ResolverBuiltinsValidationTest, Modf_Vec2) {
|
||||
auto* a = Var("a", ty.vec2<f32>());
|
||||
auto* builtin = Call("modf", vec2<f32>(1.0f, 1.0f), AddressOf(Expr("a")));
|
||||
WrapInFunction(Decl(a), builtin);
|
||||
auto* builtin = Call("modf", vec2<f32>(1.0f, 1.0f));
|
||||
WrapInFunction(builtin);
|
||||
|
||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||
EXPECT_TRUE(TypeOf(builtin)->is_float_vector());
|
||||
EXPECT_TRUE(TypeOf(builtin->params()[1])->Is<sem::Pointer>());
|
||||
auto* res_ty = TypeOf(builtin)->As<sem::Struct>();
|
||||
ASSERT_TRUE(res_ty != nullptr);
|
||||
auto& members = res_ty->Members();
|
||||
ASSERT_EQ(members.size(), 2u);
|
||||
ASSERT_TRUE(members[0]->Type()->Is<sem::Vector>());
|
||||
ASSERT_TRUE(members[1]->Type()->Is<sem::Vector>());
|
||||
EXPECT_EQ(members[0]->Type()->As<sem::Vector>()->Width(), 2u);
|
||||
EXPECT_TRUE(members[0]->Type()->As<sem::Vector>()->type()->Is<sem::F32>());
|
||||
EXPECT_EQ(members[1]->Type()->As<sem::Vector>()->Width(), 2u);
|
||||
EXPECT_TRUE(members[1]->Type()->As<sem::Vector>()->type()->Is<sem::F32>());
|
||||
}
|
||||
|
||||
TEST_F(ResolverBuiltinsValidationTest, Modf_Vec3) {
|
||||
auto* a = Var("a", ty.vec3<f32>());
|
||||
auto* builtin =
|
||||
Call("modf", vec3<f32>(1.0f, 1.0f, 1.0f), AddressOf(Expr("a")));
|
||||
WrapInFunction(Decl(a), builtin);
|
||||
auto* builtin = Call("modf", vec3<f32>(1.0f, 1.0f, 1.0f));
|
||||
WrapInFunction(builtin);
|
||||
|
||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||
EXPECT_TRUE(TypeOf(builtin)->is_float_vector());
|
||||
EXPECT_TRUE(TypeOf(builtin->params()[1])->Is<sem::Pointer>());
|
||||
auto* res_ty = TypeOf(builtin)->As<sem::Struct>();
|
||||
ASSERT_TRUE(res_ty != nullptr);
|
||||
auto& members = res_ty->Members();
|
||||
ASSERT_EQ(members.size(), 2u);
|
||||
ASSERT_TRUE(members[0]->Type()->Is<sem::Vector>());
|
||||
ASSERT_TRUE(members[1]->Type()->Is<sem::Vector>());
|
||||
EXPECT_EQ(members[0]->Type()->As<sem::Vector>()->Width(), 3u);
|
||||
EXPECT_TRUE(members[0]->Type()->As<sem::Vector>()->type()->Is<sem::F32>());
|
||||
EXPECT_EQ(members[1]->Type()->As<sem::Vector>()->Width(), 3u);
|
||||
EXPECT_TRUE(members[1]->Type()->As<sem::Vector>()->type()->Is<sem::F32>());
|
||||
}
|
||||
|
||||
TEST_F(ResolverBuiltinsValidationTest, Modf_Vec4) {
|
||||
auto* a = Var("a", ty.vec4<f32>());
|
||||
auto* builtin =
|
||||
Call("modf", vec4<f32>(1.0f, 1.0f, 1.0f, 1.0f), AddressOf(Expr("a")));
|
||||
WrapInFunction(Decl(a), builtin);
|
||||
auto* builtin = Call("modf", vec4<f32>(1.0f, 1.0f, 1.0f, 1.0f));
|
||||
WrapInFunction(builtin);
|
||||
|
||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||
EXPECT_TRUE(TypeOf(builtin)->is_float_vector());
|
||||
EXPECT_TRUE(TypeOf(builtin->params()[1])->Is<sem::Pointer>());
|
||||
auto* res_ty = TypeOf(builtin)->As<sem::Struct>();
|
||||
ASSERT_TRUE(res_ty != nullptr);
|
||||
auto& members = res_ty->Members();
|
||||
ASSERT_EQ(members.size(), 2u);
|
||||
ASSERT_TRUE(members[0]->Type()->Is<sem::Vector>());
|
||||
ASSERT_TRUE(members[1]->Type()->Is<sem::Vector>());
|
||||
EXPECT_EQ(members[0]->Type()->As<sem::Vector>()->Width(), 4u);
|
||||
EXPECT_TRUE(members[0]->Type()->As<sem::Vector>()->type()->Is<sem::F32>());
|
||||
EXPECT_EQ(members[1]->Type()->As<sem::Vector>()->Width(), 4u);
|
||||
EXPECT_TRUE(members[1]->Type()->As<sem::Vector>()->type()->Is<sem::F32>());
|
||||
}
|
||||
|
||||
TEST_F(ResolverBuiltinsValidationTest, Cross_Float_Vec3) {
|
||||
|
||||
@@ -828,29 +828,6 @@ TEST_F(ResolverIntrinsicDataTest, Normalize_Error_NoParams) {
|
||||
)");
|
||||
}
|
||||
|
||||
TEST_F(ResolverIntrinsicDataTest, DEPRECATED_FrexpScalar) {
|
||||
Global("exp", ty.i32(), ast::StorageClass::kWorkgroup);
|
||||
auto* call = Call("frexp", 1.0f, AddressOf("exp"));
|
||||
WrapInFunction(call);
|
||||
|
||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||
|
||||
ASSERT_NE(TypeOf(call), nullptr);
|
||||
EXPECT_TRUE(TypeOf(call)->Is<sem::F32>());
|
||||
}
|
||||
|
||||
TEST_F(ResolverIntrinsicDataTest, DEPRECATED_FrexpVector) {
|
||||
Global("exp", ty.vec3<i32>(), ast::StorageClass::kWorkgroup);
|
||||
auto* call = Call("frexp", vec3<f32>(1.0f, 2.0f, 3.0f), AddressOf("exp"));
|
||||
WrapInFunction(call);
|
||||
|
||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||
|
||||
ASSERT_NE(TypeOf(call), nullptr);
|
||||
EXPECT_TRUE(TypeOf(call)->Is<sem::Vector>());
|
||||
EXPECT_TRUE(TypeOf(call)->As<sem::Vector>()->type()->Is<sem::F32>());
|
||||
}
|
||||
|
||||
TEST_F(ResolverIntrinsicDataTest, FrexpScalar) {
|
||||
auto* call = Call("frexp", 1.0f);
|
||||
WrapInFunction(call);
|
||||
@@ -924,9 +901,7 @@ TEST_F(ResolverIntrinsicDataTest, Frexp_Error_FirstParamInt) {
|
||||
r()->error(),
|
||||
R"(error: no matching call to frexp(i32, ptr<workgroup, i32, read_write>)
|
||||
|
||||
4 candidate functions:
|
||||
frexp(f32, ptr<S, i32, A>) -> f32 where: S is function, private or workgroup
|
||||
frexp(vecN<f32>, ptr<S, vecN<i32>, A>) -> vecN<f32> where: S is function, private or workgroup
|
||||
2 candidate functions:
|
||||
frexp(f32) -> _frexp_result
|
||||
frexp(vecN<f32>) -> _frexp_result_vecN
|
||||
)");
|
||||
@@ -943,10 +918,8 @@ TEST_F(ResolverIntrinsicDataTest, Frexp_Error_SecondParamFloatPtr) {
|
||||
r()->error(),
|
||||
R"(error: no matching call to frexp(f32, ptr<workgroup, f32, read_write>)
|
||||
|
||||
4 candidate functions:
|
||||
frexp(f32, ptr<S, i32, A>) -> f32 where: S is function, private or workgroup
|
||||
2 candidate functions:
|
||||
frexp(f32) -> _frexp_result
|
||||
frexp(vecN<f32>, ptr<S, vecN<i32>, A>) -> vecN<f32> where: S is function, private or workgroup
|
||||
frexp(vecN<f32>) -> _frexp_result_vecN
|
||||
)");
|
||||
}
|
||||
@@ -959,10 +932,8 @@ TEST_F(ResolverIntrinsicDataTest, Frexp_Error_SecondParamNotAPointer) {
|
||||
|
||||
EXPECT_EQ(r()->error(), R"(error: no matching call to frexp(f32, i32)
|
||||
|
||||
4 candidate functions:
|
||||
frexp(f32, ptr<S, i32, A>) -> f32 where: S is function, private or workgroup
|
||||
2 candidate functions:
|
||||
frexp(f32) -> _frexp_result
|
||||
frexp(vecN<f32>, ptr<S, vecN<i32>, A>) -> vecN<f32> where: S is function, private or workgroup
|
||||
frexp(vecN<f32>) -> _frexp_result_vecN
|
||||
)");
|
||||
}
|
||||
@@ -978,37 +949,12 @@ TEST_F(ResolverIntrinsicDataTest, Frexp_Error_VectorSizesDontMatch) {
|
||||
r()->error(),
|
||||
R"(error: no matching call to frexp(vec2<f32>, ptr<workgroup, vec4<i32>, read_write>)
|
||||
|
||||
4 candidate functions:
|
||||
frexp(vecN<f32>, ptr<S, vecN<i32>, A>) -> vecN<f32> where: S is function, private or workgroup
|
||||
2 candidate functions:
|
||||
frexp(vecN<f32>) -> _frexp_result_vecN
|
||||
frexp(f32, ptr<S, i32, A>) -> f32 where: S is function, private or workgroup
|
||||
frexp(f32) -> _frexp_result
|
||||
)");
|
||||
}
|
||||
|
||||
TEST_F(ResolverIntrinsicDataTest, DEPRECATED_ModfScalar) {
|
||||
Global("whole", ty.f32(), ast::StorageClass::kWorkgroup);
|
||||
auto* call = Call("modf", 1.0f, AddressOf("whole"));
|
||||
WrapInFunction(call);
|
||||
|
||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||
|
||||
ASSERT_NE(TypeOf(call), nullptr);
|
||||
EXPECT_TRUE(TypeOf(call)->Is<sem::F32>());
|
||||
}
|
||||
|
||||
TEST_F(ResolverIntrinsicDataTest, DEPRECATED_ModfVector) {
|
||||
Global("whole", ty.vec3<f32>(), ast::StorageClass::kWorkgroup);
|
||||
auto* call = Call("modf", vec3<f32>(1.0f, 2.0f, 3.0f), AddressOf("whole"));
|
||||
WrapInFunction(call);
|
||||
|
||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||
|
||||
ASSERT_NE(TypeOf(call), nullptr);
|
||||
EXPECT_TRUE(TypeOf(call)->Is<sem::Vector>());
|
||||
EXPECT_TRUE(TypeOf(call)->As<sem::Vector>()->type()->Is<sem::F32>());
|
||||
}
|
||||
|
||||
TEST_F(ResolverIntrinsicDataTest, ModfScalar) {
|
||||
auto* call = Call("modf", 1.0f);
|
||||
WrapInFunction(call);
|
||||
@@ -1082,9 +1028,7 @@ TEST_F(ResolverIntrinsicDataTest, Modf_Error_FirstParamInt) {
|
||||
r()->error(),
|
||||
R"(error: no matching call to modf(i32, ptr<workgroup, f32, read_write>)
|
||||
|
||||
4 candidate functions:
|
||||
modf(f32, ptr<S, f32, A>) -> f32 where: S is function, private or workgroup
|
||||
modf(vecN<f32>, ptr<S, vecN<f32>, A>) -> vecN<f32> where: S is function, private or workgroup
|
||||
2 candidate functions:
|
||||
modf(f32) -> _modf_result
|
||||
modf(vecN<f32>) -> _modf_result_vecN
|
||||
)");
|
||||
@@ -1101,10 +1045,8 @@ TEST_F(ResolverIntrinsicDataTest, Modf_Error_SecondParamIntPtr) {
|
||||
r()->error(),
|
||||
R"(error: no matching call to modf(f32, ptr<workgroup, i32, read_write>)
|
||||
|
||||
4 candidate functions:
|
||||
modf(f32, ptr<S, f32, A>) -> f32 where: S is function, private or workgroup
|
||||
2 candidate functions:
|
||||
modf(f32) -> _modf_result
|
||||
modf(vecN<f32>, ptr<S, vecN<f32>, A>) -> vecN<f32> where: S is function, private or workgroup
|
||||
modf(vecN<f32>) -> _modf_result_vecN
|
||||
)");
|
||||
}
|
||||
@@ -1117,10 +1059,8 @@ TEST_F(ResolverIntrinsicDataTest, Modf_Error_SecondParamNotAPointer) {
|
||||
|
||||
EXPECT_EQ(r()->error(), R"(error: no matching call to modf(f32, f32)
|
||||
|
||||
4 candidate functions:
|
||||
modf(f32, ptr<S, f32, A>) -> f32 where: S is function, private or workgroup
|
||||
2 candidate functions:
|
||||
modf(f32) -> _modf_result
|
||||
modf(vecN<f32>, ptr<S, vecN<f32>, A>) -> vecN<f32> where: S is function, private or workgroup
|
||||
modf(vecN<f32>) -> _modf_result_vecN
|
||||
)");
|
||||
}
|
||||
@@ -1136,10 +1076,8 @@ TEST_F(ResolverIntrinsicDataTest, Modf_Error_VectorSizesDontMatch) {
|
||||
r()->error(),
|
||||
R"(error: no matching call to modf(vec2<f32>, ptr<workgroup, vec4<f32>, read_write>)
|
||||
|
||||
4 candidate functions:
|
||||
modf(vecN<f32>, ptr<S, vecN<f32>, A>) -> vecN<f32> where: S is function, private or workgroup
|
||||
2 candidate functions:
|
||||
modf(vecN<f32>) -> _modf_result_vecN
|
||||
modf(f32, ptr<S, f32, A>) -> f32 where: S is function, private or workgroup
|
||||
modf(f32) -> _modf_result
|
||||
)");
|
||||
}
|
||||
|
||||
@@ -297,6 +297,7 @@ TEST_F(GlslGeneratorImplTest_Intrinsic, Select_Vector) {
|
||||
EXPECT_EQ(out.str(), "(bvec2(true, false) ? ivec2(3, 4) : ivec2(1, 2))");
|
||||
}
|
||||
|
||||
#if 0
|
||||
TEST_F(GlslGeneratorImplTest_Intrinsic, Modf_Scalar) {
|
||||
auto* res = Var("res", ty.f32());
|
||||
auto* call = Call("modf", 1.0f, AddressOf(res));
|
||||
@@ -319,7 +320,6 @@ TEST_F(GlslGeneratorImplTest_Intrinsic, Modf_Vector) {
|
||||
EXPECT_THAT(gen.result(), HasSubstr("modf(vec3(0.0f, 0.0f, 0.0f), res)"));
|
||||
}
|
||||
|
||||
#if 0
|
||||
TEST_F(GlslGeneratorImplTest_Intrinsic, Frexp_Scalar_i32) {
|
||||
auto* exp = Var("exp", ty.i32());
|
||||
auto* call = Call("frexp", 1.0f, AddressOf(exp));
|
||||
|
||||
@@ -1366,120 +1366,71 @@ bool GeneratorImpl::EmitSelectCall(std::ostream& out,
|
||||
bool GeneratorImpl::EmitModfCall(std::ostream& out,
|
||||
ast::CallExpression* expr,
|
||||
const sem::Intrinsic* intrinsic) {
|
||||
if (expr->params().size() == 1) {
|
||||
return CallIntrinsicHelper(
|
||||
out, expr, intrinsic,
|
||||
[&](TextBuffer* b, const std::vector<std::string>& params) {
|
||||
auto* ty = intrinsic->Parameters()[0]->Type();
|
||||
auto in = params[0];
|
||||
return CallIntrinsicHelper(
|
||||
out, expr, intrinsic,
|
||||
[&](TextBuffer* b, const std::vector<std::string>& params) {
|
||||
auto* ty = intrinsic->Parameters()[0]->Type();
|
||||
auto in = params[0];
|
||||
|
||||
std::string width;
|
||||
if (auto* vec = ty->As<sem::Vector>()) {
|
||||
width = std::to_string(vec->Width());
|
||||
}
|
||||
std::string width;
|
||||
if (auto* vec = ty->As<sem::Vector>()) {
|
||||
width = std::to_string(vec->Width());
|
||||
}
|
||||
|
||||
// Emit the builtin return type unique to this overload. This does not
|
||||
// exist in the AST, so it will not be generated in Generate().
|
||||
if (!EmitStructType(&helpers_,
|
||||
intrinsic->ReturnType()->As<sem::Struct>())) {
|
||||
// Emit the builtin return type unique to this overload. This does not
|
||||
// exist in the AST, so it will not be generated in Generate().
|
||||
if (!EmitStructType(&helpers_,
|
||||
intrinsic->ReturnType()->As<sem::Struct>())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
line(b) << "float" << width << " whole;";
|
||||
line(b) << "float" << width << " fract = modf(" << in << ", whole);";
|
||||
{
|
||||
auto l = line(b);
|
||||
if (!EmitType(l, intrinsic->ReturnType(), ast::StorageClass::kNone,
|
||||
ast::Access::kUndefined, "")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
line(b) << "float" << width << " whole;";
|
||||
line(b) << "float" << width << " fract = modf(" << in << ", whole);";
|
||||
{
|
||||
auto l = line(b);
|
||||
if (!EmitType(l, intrinsic->ReturnType(), ast::StorageClass::kNone,
|
||||
ast::Access::kUndefined, "")) {
|
||||
return false;
|
||||
}
|
||||
l << " result = {fract, whole};";
|
||||
}
|
||||
line(b) << "return result;";
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
// DEPRECATED
|
||||
out << "modf";
|
||||
ScopedParen sp(out);
|
||||
if (!EmitExpression(out, expr->params()[0])) {
|
||||
return false;
|
||||
}
|
||||
out << ", ";
|
||||
if (!EmitExpression(out, expr->params()[1])) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
l << " result = {fract, whole};";
|
||||
}
|
||||
line(b) << "return result;";
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
bool GeneratorImpl::EmitFrexpCall(std::ostream& out,
|
||||
ast::CallExpression* expr,
|
||||
const sem::Intrinsic* intrinsic) {
|
||||
if (expr->params().size() == 1) {
|
||||
return CallIntrinsicHelper(
|
||||
out, expr, intrinsic,
|
||||
[&](TextBuffer* b, const std::vector<std::string>& params) {
|
||||
auto* ty = intrinsic->Parameters()[0]->Type();
|
||||
auto in = params[0];
|
||||
|
||||
std::string width;
|
||||
if (auto* vec = ty->As<sem::Vector>()) {
|
||||
width = std::to_string(vec->Width());
|
||||
}
|
||||
|
||||
// Emit the builtin return type unique to this overload. This does not
|
||||
// exist in the AST, so it will not be generated in Generate().
|
||||
if (!EmitStructType(&helpers_,
|
||||
intrinsic->ReturnType()->As<sem::Struct>())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
line(b) << "float" << width << " exp;";
|
||||
line(b) << "float" << width << " sig = frexp(" << in << ", exp);";
|
||||
{
|
||||
auto l = line(b);
|
||||
if (!EmitType(l, intrinsic->ReturnType(), ast::StorageClass::kNone,
|
||||
ast::Access::kUndefined, "")) {
|
||||
return false;
|
||||
}
|
||||
l << " result = {sig, int" << width << "(exp)};";
|
||||
}
|
||||
line(b) << "return result;";
|
||||
return true;
|
||||
});
|
||||
}
|
||||
// DEPRECATED
|
||||
// Exponent is an integer in WGSL, but HLSL wants a float.
|
||||
// We need to make the call with a temporary float, and then cast.
|
||||
return CallIntrinsicHelper(
|
||||
out, expr, intrinsic,
|
||||
[&](TextBuffer* b, const std::vector<std::string>& params) {
|
||||
auto* significand_ty = intrinsic->Parameters()[0]->Type();
|
||||
auto significand = params[0];
|
||||
auto* exponent_ty = intrinsic->Parameters()[1]->Type();
|
||||
auto exponent = params[1];
|
||||
auto* ty = intrinsic->Parameters()[0]->Type();
|
||||
auto in = params[0];
|
||||
|
||||
std::string width;
|
||||
if (auto* vec = significand_ty->As<sem::Vector>()) {
|
||||
if (auto* vec = ty->As<sem::Vector>()) {
|
||||
width = std::to_string(vec->Width());
|
||||
}
|
||||
|
||||
// Exponent is an integer, which HLSL does not have an overload for.
|
||||
// We need to cast from a float.
|
||||
line(b) << "float" << width << " float_exp;";
|
||||
line(b) << "float" << width << " significand = frexp(" << significand
|
||||
<< ", float_exp);";
|
||||
// Emit the builtin return type unique to this overload. This does not
|
||||
// exist in the AST, so it will not be generated in Generate().
|
||||
if (!EmitStructType(&helpers_,
|
||||
intrinsic->ReturnType()->As<sem::Struct>())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
line(b) << "float" << width << " exp;";
|
||||
line(b) << "float" << width << " sig = frexp(" << in << ", exp);";
|
||||
{
|
||||
auto l = line(b);
|
||||
l << exponent << " = ";
|
||||
if (!EmitType(l, exponent_ty->UnwrapPtr(), ast::StorageClass::kNone,
|
||||
if (!EmitType(l, intrinsic->ReturnType(), ast::StorageClass::kNone,
|
||||
ast::Access::kUndefined, "")) {
|
||||
return false;
|
||||
}
|
||||
l << "(float_exp);";
|
||||
l << " result = {sig, int" << width << "(exp)};";
|
||||
}
|
||||
line(b) << "return significand;";
|
||||
line(b) << "return result;";
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
@@ -298,72 +298,104 @@ TEST_F(HlslGeneratorImplTest_Intrinsic, Select_Vector) {
|
||||
}
|
||||
|
||||
TEST_F(HlslGeneratorImplTest_Intrinsic, Modf_Scalar) {
|
||||
auto* res = Var("res", ty.f32());
|
||||
auto* call = Call("modf", 1.0f, AddressOf(res));
|
||||
WrapInFunction(res, call);
|
||||
auto* call = Call("modf", 1.0f);
|
||||
WrapInFunction(call);
|
||||
|
||||
GeneratorImpl& gen = SanitizeAndBuild();
|
||||
|
||||
ASSERT_TRUE(gen.Generate()) << gen.error();
|
||||
EXPECT_THAT(gen.result(), HasSubstr("modf(1.0f, res)"));
|
||||
}
|
||||
|
||||
TEST_F(HlslGeneratorImplTest_Intrinsic, Modf_Vector) {
|
||||
auto* res = Var("res", ty.vec3<f32>());
|
||||
auto* call = Call("modf", vec3<f32>(), AddressOf(res));
|
||||
WrapInFunction(res, call);
|
||||
|
||||
GeneratorImpl& gen = SanitizeAndBuild();
|
||||
|
||||
ASSERT_TRUE(gen.Generate()) << gen.error();
|
||||
EXPECT_THAT(gen.result(), HasSubstr("modf(float3(0.0f, 0.0f, 0.0f), res)"));
|
||||
}
|
||||
|
||||
TEST_F(HlslGeneratorImplTest_Intrinsic, Frexp_Scalar_i32) {
|
||||
auto* exp = Var("exp", ty.i32());
|
||||
auto* call = Call("frexp", 1.0f, AddressOf(exp));
|
||||
WrapInFunction(exp, call);
|
||||
|
||||
GeneratorImpl& gen = SanitizeAndBuild();
|
||||
|
||||
ASSERT_TRUE(gen.Generate()) << gen.error();
|
||||
EXPECT_EQ(gen.result(),
|
||||
R"(float tint_frexp(float param_0, inout int param_1) {
|
||||
float float_exp;
|
||||
float significand = frexp(param_0, float_exp);
|
||||
param_1 = int(float_exp);
|
||||
return significand;
|
||||
EXPECT_EQ(gen.result(), R"(struct modf_result {
|
||||
float fract;
|
||||
float whole;
|
||||
};
|
||||
modf_result tint_modf(float param_0) {
|
||||
float whole;
|
||||
float fract = modf(param_0, whole);
|
||||
modf_result result = {fract, whole};
|
||||
return result;
|
||||
}
|
||||
|
||||
[numthreads(1, 1, 1)]
|
||||
void test_function() {
|
||||
int exp = 0;
|
||||
tint_frexp(1.0f, exp);
|
||||
tint_modf(1.0f);
|
||||
return;
|
||||
}
|
||||
)");
|
||||
}
|
||||
|
||||
TEST_F(HlslGeneratorImplTest_Intrinsic, Modf_Vector) {
|
||||
auto* call = Call("modf", vec3<f32>());
|
||||
WrapInFunction(call);
|
||||
|
||||
GeneratorImpl& gen = SanitizeAndBuild();
|
||||
|
||||
ASSERT_TRUE(gen.Generate()) << gen.error();
|
||||
EXPECT_EQ(gen.result(), R"(struct modf_result_vec3 {
|
||||
float3 fract;
|
||||
float3 whole;
|
||||
};
|
||||
modf_result_vec3 tint_modf(float3 param_0) {
|
||||
float3 whole;
|
||||
float3 fract = modf(param_0, whole);
|
||||
modf_result_vec3 result = {fract, whole};
|
||||
return result;
|
||||
}
|
||||
|
||||
[numthreads(1, 1, 1)]
|
||||
void test_function() {
|
||||
tint_modf(float3(0.0f, 0.0f, 0.0f));
|
||||
return;
|
||||
}
|
||||
)");
|
||||
}
|
||||
|
||||
TEST_F(HlslGeneratorImplTest_Intrinsic, Frexp_Scalar_i32) {
|
||||
auto* call = Call("frexp", 1.0f);
|
||||
WrapInFunction(call);
|
||||
|
||||
GeneratorImpl& gen = SanitizeAndBuild();
|
||||
|
||||
ASSERT_TRUE(gen.Generate()) << gen.error();
|
||||
EXPECT_EQ(gen.result(), R"(struct frexp_result {
|
||||
float sig;
|
||||
int exp;
|
||||
};
|
||||
frexp_result tint_frexp(float param_0) {
|
||||
float exp;
|
||||
float sig = frexp(param_0, exp);
|
||||
frexp_result result = {sig, int(exp)};
|
||||
return result;
|
||||
}
|
||||
|
||||
[numthreads(1, 1, 1)]
|
||||
void test_function() {
|
||||
tint_frexp(1.0f);
|
||||
return;
|
||||
}
|
||||
)");
|
||||
}
|
||||
|
||||
TEST_F(HlslGeneratorImplTest_Intrinsic, Frexp_Vector_i32) {
|
||||
auto* res = Var("res", ty.vec3<i32>());
|
||||
auto* call = Call("frexp", vec3<f32>(), AddressOf(res));
|
||||
WrapInFunction(res, call);
|
||||
auto* call = Call("frexp", vec3<f32>());
|
||||
WrapInFunction(call);
|
||||
|
||||
GeneratorImpl& gen = SanitizeAndBuild();
|
||||
|
||||
ASSERT_TRUE(gen.Generate()) << gen.error();
|
||||
EXPECT_EQ(gen.result(),
|
||||
R"(float3 tint_frexp(float3 param_0, inout int3 param_1) {
|
||||
float3 float_exp;
|
||||
float3 significand = frexp(param_0, float_exp);
|
||||
param_1 = int3(float_exp);
|
||||
return significand;
|
||||
EXPECT_EQ(gen.result(), R"(struct frexp_result_vec3 {
|
||||
float3 sig;
|
||||
int3 exp;
|
||||
};
|
||||
frexp_result_vec3 tint_frexp(float3 param_0) {
|
||||
float3 exp;
|
||||
float3 sig = frexp(param_0, exp);
|
||||
frexp_result_vec3 result = {sig, int3(exp)};
|
||||
return result;
|
||||
}
|
||||
|
||||
[numthreads(1, 1, 1)]
|
||||
void test_function() {
|
||||
int3 res = int3(0, 0, 0);
|
||||
tint_frexp(float3(0.0f, 0.0f, 0.0f), res);
|
||||
tint_frexp(float3(0.0f, 0.0f, 0.0f));
|
||||
return;
|
||||
}
|
||||
)");
|
||||
|
||||
@@ -1034,48 +1034,27 @@ bool GeneratorImpl::EmitTextureCall(std::ostream& out,
|
||||
bool GeneratorImpl::EmitModfCall(std::ostream& out,
|
||||
ast::CallExpression* expr,
|
||||
const sem::Intrinsic* intrinsic) {
|
||||
if (expr->params().size() == 1) {
|
||||
return CallIntrinsicHelper(
|
||||
out, expr, intrinsic,
|
||||
[&](TextBuffer* b, const std::vector<std::string>& params) {
|
||||
auto* ty = intrinsic->Parameters()[0]->Type();
|
||||
auto in = params[0];
|
||||
|
||||
std::string width;
|
||||
if (auto* vec = ty->As<sem::Vector>()) {
|
||||
width = std::to_string(vec->Width());
|
||||
}
|
||||
|
||||
// Emit the builtin return type unique to this overload. This does not
|
||||
// exist in the AST, so it will not be generated in Generate().
|
||||
if (!EmitStructType(&helpers_,
|
||||
intrinsic->ReturnType()->As<sem::Struct>())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
line(b) << "float" << width << " whole;";
|
||||
line(b) << "float" << width << " fract = modf(" << in << ", whole);";
|
||||
line(b) << "return {fract, whole};";
|
||||
return true;
|
||||
});
|
||||
}
|
||||
// DEPRECATED
|
||||
return CallIntrinsicHelper(
|
||||
out, expr, intrinsic,
|
||||
[&](TextBuffer* b, const std::vector<std::string>& params) {
|
||||
auto* ty = intrinsic->Parameters()[0]->Type();
|
||||
auto in = params[0];
|
||||
auto out_whole = params[1];
|
||||
|
||||
std::string width;
|
||||
if (auto* vec = ty->As<sem::Vector>()) {
|
||||
width = std::to_string(vec->Width());
|
||||
}
|
||||
|
||||
// Emit the builtin return type unique to this overload. This does not
|
||||
// exist in the AST, so it will not be generated in Generate().
|
||||
if (!EmitStructType(&helpers_,
|
||||
intrinsic->ReturnType()->As<sem::Struct>())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
line(b) << "float" << width << " whole;";
|
||||
line(b) << "float" << width << " fract = modf(" << in << ", whole);";
|
||||
line(b) << "*" << out_whole << " = whole;";
|
||||
line(b) << "return fract;";
|
||||
line(b) << "return {fract, whole};";
|
||||
return true;
|
||||
});
|
||||
}
|
||||
@@ -1083,49 +1062,27 @@ bool GeneratorImpl::EmitModfCall(std::ostream& out,
|
||||
bool GeneratorImpl::EmitFrexpCall(std::ostream& out,
|
||||
ast::CallExpression* expr,
|
||||
const sem::Intrinsic* intrinsic) {
|
||||
if (expr->params().size() == 1) {
|
||||
return CallIntrinsicHelper(
|
||||
out, expr, intrinsic,
|
||||
[&](TextBuffer* b, const std::vector<std::string>& params) {
|
||||
auto* ty = intrinsic->Parameters()[0]->Type();
|
||||
auto in = params[0];
|
||||
|
||||
std::string width;
|
||||
if (auto* vec = ty->As<sem::Vector>()) {
|
||||
width = std::to_string(vec->Width());
|
||||
}
|
||||
|
||||
// Emit the builtin return type unique to this overload. This does not
|
||||
// exist in the AST, so it will not be generated in Generate().
|
||||
if (!EmitStructType(&helpers_,
|
||||
intrinsic->ReturnType()->As<sem::Struct>())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
line(b) << "int" << width << " exp;";
|
||||
line(b) << "float" << width << " sig = frexp(" << in << ", exp);";
|
||||
line(b) << "return {sig, exp};";
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
// DEPRECATED
|
||||
return CallIntrinsicHelper(
|
||||
out, expr, intrinsic,
|
||||
[&](TextBuffer* b, const std::vector<std::string>& params) {
|
||||
auto* ty = intrinsic->Parameters()[0]->Type();
|
||||
auto in = params[0];
|
||||
auto out_exp = params[1];
|
||||
|
||||
std::string width;
|
||||
if (auto* vec = ty->As<sem::Vector>()) {
|
||||
width = std::to_string(vec->Width());
|
||||
}
|
||||
|
||||
// Emit the builtin return type unique to this overload. This does not
|
||||
// exist in the AST, so it will not be generated in Generate().
|
||||
if (!EmitStructType(&helpers_,
|
||||
intrinsic->ReturnType()->As<sem::Struct>())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
line(b) << "int" << width << " exp;";
|
||||
line(b) << "float" << width << " sig = frexp(" << in << ", exp);";
|
||||
line(b) << "*" << out_exp << " = exp;";
|
||||
line(b) << "return sig;";
|
||||
line(b) << "return {sig, exp};";
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
@@ -165,8 +165,7 @@ uint32_t intrinsic_to_glsl_method(const sem::Intrinsic* intrinsic) {
|
||||
case IntrinsicType::kFract:
|
||||
return GLSLstd450Fract;
|
||||
case IntrinsicType::kFrexp:
|
||||
return (intrinsic->Parameters().size() == 1) ? GLSLstd450FrexpStruct
|
||||
: GLSLstd450Frexp;
|
||||
return GLSLstd450FrexpStruct;
|
||||
case IntrinsicType::kInverseSqrt:
|
||||
return GLSLstd450InverseSqrt;
|
||||
case IntrinsicType::kLdexp:
|
||||
@@ -196,8 +195,7 @@ uint32_t intrinsic_to_glsl_method(const sem::Intrinsic* intrinsic) {
|
||||
case IntrinsicType::kMix:
|
||||
return GLSLstd450FMix;
|
||||
case IntrinsicType::kModf:
|
||||
return (intrinsic->Parameters().size() == 1) ? GLSLstd450ModfStruct
|
||||
: GLSLstd450Modf;
|
||||
return GLSLstd450ModfStruct;
|
||||
case IntrinsicType::kNormalize:
|
||||
return GLSLstd450Normalize;
|
||||
case IntrinsicType::kPack4x8snorm:
|
||||
|
||||
@@ -1452,16 +1452,48 @@ INSTANTIATE_TEST_SUITE_P(IntrinsicBuilderTest,
|
||||
testing::Values(IntrinsicData{"clamp", "UClamp"}));
|
||||
|
||||
TEST_F(IntrinsicBuilderTest, Call_Modf) {
|
||||
auto* out = Var("out", ty.vec2<f32>());
|
||||
auto* expr = Call("modf", vec2<f32>(1.0f, 2.0f), AddressOf("out"));
|
||||
Func("a_func", ast::VariableList{}, ty.void_(),
|
||||
ast::StatementList{
|
||||
Decl(out),
|
||||
Ignore(expr),
|
||||
},
|
||||
ast::DecorationList{
|
||||
Stage(ast::PipelineStage::kFragment),
|
||||
});
|
||||
auto* expr = Call("modf", vec2<f32>(1.0f, 2.0f));
|
||||
Func("a_func", {}, ty.void_(), {Ignore(expr)},
|
||||
{Stage(ast::PipelineStage::kFragment)});
|
||||
|
||||
spirv::Builder& b = Build();
|
||||
|
||||
ASSERT_TRUE(b.Build()) << b.error();
|
||||
auto got = DumpBuilder(b);
|
||||
auto* expect = R"(OpCapability Shader
|
||||
%10 = OpExtInstImport "GLSL.std.450"
|
||||
OpMemoryModel Logical GLSL450
|
||||
OpEntryPoint Fragment %3 "a_func"
|
||||
OpExecutionMode %3 OriginUpperLeft
|
||||
OpName %3 "a_func"
|
||||
OpName %7 "_modf_result_vec2"
|
||||
OpMemberName %7 0 "fract"
|
||||
OpMemberName %7 1 "whole"
|
||||
OpMemberDecorate %7 0 Offset 0
|
||||
OpMemberDecorate %7 1 Offset 8
|
||||
%2 = OpTypeVoid
|
||||
%1 = OpTypeFunction %2
|
||||
%9 = OpTypeFloat 32
|
||||
%8 = OpTypeVector %9 2
|
||||
%7 = OpTypeStruct %8 %8
|
||||
%11 = OpConstant %9 1
|
||||
%12 = OpConstant %9 2
|
||||
%13 = OpConstantComposite %8 %11 %12
|
||||
%3 = OpFunction %2 None %1
|
||||
%4 = OpLabel
|
||||
%6 = OpExtInst %7 %10 ModfStruct %13
|
||||
OpReturn
|
||||
OpFunctionEnd
|
||||
)";
|
||||
EXPECT_EQ(expect, got);
|
||||
|
||||
Validate(b);
|
||||
}
|
||||
|
||||
TEST_F(IntrinsicBuilderTest, Call_Frexp) {
|
||||
auto* expr = Call("frexp", vec2<f32>(1.0f, 2.0f));
|
||||
Func("a_func", {}, ty.void_(), {Ignore(expr)},
|
||||
{Stage(ast::PipelineStage::kFragment)});
|
||||
|
||||
spirv::Builder& b = Build();
|
||||
|
||||
@@ -1473,66 +1505,24 @@ OpMemoryModel Logical GLSL450
|
||||
OpEntryPoint Fragment %3 "a_func"
|
||||
OpExecutionMode %3 OriginUpperLeft
|
||||
OpName %3 "a_func"
|
||||
OpName %5 "out"
|
||||
OpName %7 "_frexp_result_vec2"
|
||||
OpMemberName %7 0 "sig"
|
||||
OpMemberName %7 1 "exp"
|
||||
OpMemberDecorate %7 0 Offset 0
|
||||
OpMemberDecorate %7 1 Offset 8
|
||||
%2 = OpTypeVoid
|
||||
%1 = OpTypeFunction %2
|
||||
%8 = OpTypeFloat 32
|
||||
%7 = OpTypeVector %8 2
|
||||
%6 = OpTypePointer Function %7
|
||||
%9 = OpConstantNull %7
|
||||
%13 = OpConstant %8 1
|
||||
%14 = OpConstant %8 2
|
||||
%15 = OpConstantComposite %7 %13 %14
|
||||
%9 = OpTypeFloat 32
|
||||
%8 = OpTypeVector %9 2
|
||||
%11 = OpTypeInt 32 1
|
||||
%10 = OpTypeVector %11 2
|
||||
%7 = OpTypeStruct %8 %10
|
||||
%13 = OpConstant %9 1
|
||||
%14 = OpConstant %9 2
|
||||
%15 = OpConstantComposite %8 %13 %14
|
||||
%3 = OpFunction %2 None %1
|
||||
%4 = OpLabel
|
||||
%5 = OpVariable %6 Function %9
|
||||
%11 = OpExtInst %7 %12 Modf %15 %5
|
||||
OpReturn
|
||||
OpFunctionEnd
|
||||
)";
|
||||
EXPECT_EQ(expect, got);
|
||||
|
||||
Validate(b);
|
||||
}
|
||||
|
||||
TEST_F(IntrinsicBuilderTest, Call_Frexp) {
|
||||
auto* out = Var("out", ty.vec2<i32>());
|
||||
auto* expr = Call("frexp", vec2<f32>(1.0f, 2.0f), AddressOf("out"));
|
||||
Func("a_func", ast::VariableList{}, ty.void_(),
|
||||
ast::StatementList{
|
||||
Decl(out),
|
||||
Ignore(expr),
|
||||
},
|
||||
ast::DecorationList{
|
||||
Stage(ast::PipelineStage::kFragment),
|
||||
});
|
||||
|
||||
spirv::Builder& b = Build();
|
||||
|
||||
ASSERT_TRUE(b.Build()) << b.error();
|
||||
auto got = DumpBuilder(b);
|
||||
auto* expect = R"(OpCapability Shader
|
||||
%14 = OpExtInstImport "GLSL.std.450"
|
||||
OpMemoryModel Logical GLSL450
|
||||
OpEntryPoint Fragment %3 "a_func"
|
||||
OpExecutionMode %3 OriginUpperLeft
|
||||
OpName %3 "a_func"
|
||||
OpName %5 "out"
|
||||
%2 = OpTypeVoid
|
||||
%1 = OpTypeFunction %2
|
||||
%8 = OpTypeInt 32 1
|
||||
%7 = OpTypeVector %8 2
|
||||
%6 = OpTypePointer Function %7
|
||||
%9 = OpConstantNull %7
|
||||
%13 = OpTypeFloat 32
|
||||
%12 = OpTypeVector %13 2
|
||||
%15 = OpConstant %13 1
|
||||
%16 = OpConstant %13 2
|
||||
%17 = OpConstantComposite %12 %15 %16
|
||||
%3 = OpFunction %2 None %1
|
||||
%4 = OpLabel
|
||||
%5 = OpVariable %6 Function %9
|
||||
%11 = OpExtInst %12 %14 Frexp %17 %5
|
||||
%6 = OpExtInst %7 %12 FrexpStruct %15
|
||||
OpReturn
|
||||
OpFunctionEnd
|
||||
)";
|
||||
|
||||
Reference in New Issue
Block a user