spirv-reader: Polyfill GLSLStd450 Degrees and Radians

Fixed: tint:1044
Change-Id: I5b2f3820b35c47bdc589ef41fb7a8735a7c6dff1
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/59660
Auto-Submit: Corentin Wallez <cwallez@chromium.org>
Commit-Queue: Ben Clayton <bclayton@google.com>
Kokoro: Kokoro <noreply+kokoro@google.com>
Reviewed-by: Ben Clayton <bclayton@google.com>
This commit is contained in:
Corentin Wallez
2021-07-26 09:12:57 +00:00
committed by Tint LUCI CQ
parent 13081d4e46
commit b32c22cead
12 changed files with 385 additions and 0 deletions

View File

@@ -4065,6 +4065,41 @@ TypedExpression FunctionEmitter::EmitGlslStd450ExtInst(
}
}
// Some GLSLStd450 builtins don't have a WGSL equivalent. Polyfill them.
switch (ext_opcode) {
case GLSLstd450Radians: {
auto degrees = MakeOperand(inst, 2);
TINT_ASSERT(Reader, degrees.type->IsFloatScalarOrVector());
constexpr auto kPiOver180 = static_cast<float>(3.141592653589793 / 180.0);
auto* factor = builder_.Expr(kPiOver180);
if (degrees.type->Is<F32>()) {
return {degrees.type, builder_.Mul(degrees.expr, factor)};
} else {
uint32_t size = degrees.type->As<Vector>()->size;
return {degrees.type,
builder_.Mul(degrees.expr,
builder_.vec(builder_.ty.f32(), size, factor))};
}
}
case GLSLstd450Degrees: {
auto radians = MakeOperand(inst, 2);
TINT_ASSERT(Reader, radians.type->IsFloatScalarOrVector());
constexpr auto k180OverPi = static_cast<float>(180.0 / 3.141592653589793);
auto* factor = builder_.Expr(k180OverPi);
if (radians.type->Is<F32>()) {
return {radians.type, builder_.Mul(radians.expr, factor)};
} else {
uint32_t size = radians.type->As<Vector>()->size;
return {radians.type,
builder_.Mul(radians.expr,
builder_.vec(builder_.ty.f32(), size, factor))};
}
}
}
const auto name = GetGlslStd450FuncName(ext_opcode);
if (name.empty()) {
Fail() << "unhandled GLSL.std.450 instruction " << ext_opcode;

View File

@@ -2051,6 +2051,142 @@ VariableDeclStatement{
EXPECT_THAT(body, HasSubstr(expected)) << body;
}
TEST_F(SpvParserTest, GlslStd450_Degrees_Scalar) {
const auto assembly = Preamble() + R"(
%1 = OpExtInst %float %glsl Degrees %float_50
OpReturn
OpFunctionEnd
)";
auto p = parser(test::Assemble(assembly));
ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
auto fe = p->function_emitter(100);
EXPECT_TRUE(fe.EmitBody()) << p->error();
const auto body = ToString(p->builder(), fe.ast_body());
const auto* expected = R"(VariableDeclStatement{
VariableConst{
x_1
none
undefined
__f32
{
Binary[not set]{
ScalarConstructor[not set]{50.000000}
multiply
ScalarConstructor[not set]{57.295780}
}
}
}
})";
EXPECT_THAT(body, HasSubstr(expected)) << body;
}
TEST_F(SpvParserTest, GlslStd450_Degrees_Vector) {
const auto assembly = Preamble() + R"(
%1 = OpExtInst %v3float %glsl Degrees %v3float_60_70_50
OpReturn
OpFunctionEnd
)";
auto p = parser(test::Assemble(assembly));
ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
auto fe = p->function_emitter(100);
EXPECT_TRUE(fe.EmitBody()) << p->error();
const auto body = ToString(p->builder(), fe.ast_body());
const auto* expected = R"(VariableDeclStatement{
VariableConst{
x_1
none
undefined
__vec_3__f32
{
Binary[not set]{
TypeConstructor[not set]{
__vec_3__f32
ScalarConstructor[not set]{60.000000}
ScalarConstructor[not set]{70.000000}
ScalarConstructor[not set]{50.000000}
}
multiply
TypeConstructor[not set]{
__vec_3__f32
ScalarConstructor[not set]{57.295780}
}
}
}
}
})";
EXPECT_THAT(body, HasSubstr(expected)) << body;
}
TEST_F(SpvParserTest, GlslStd450_Radians_Scalar) {
const auto assembly = Preamble() + R"(
%1 = OpExtInst %float %glsl Radians %float_50
OpReturn
OpFunctionEnd
)";
auto p = parser(test::Assemble(assembly));
ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
auto fe = p->function_emitter(100);
EXPECT_TRUE(fe.EmitBody()) << p->error();
const auto body = ToString(p->builder(), fe.ast_body());
const auto* expected = R"(VariableDeclStatement{
VariableConst{
x_1
none
undefined
__f32
{
Binary[not set]{
ScalarConstructor[not set]{50.000000}
multiply
ScalarConstructor[not set]{0.017453}
}
}
}
})";
EXPECT_THAT(body, HasSubstr(expected)) << body;
}
TEST_F(SpvParserTest, GlslStd450_Radians_Vector) {
const auto assembly = Preamble() + R"(
%1 = OpExtInst %v3float %glsl Radians %v3float_60_70_50
OpReturn
OpFunctionEnd
)";
auto p = parser(test::Assemble(assembly));
ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
auto fe = p->function_emitter(100);
EXPECT_TRUE(fe.EmitBody()) << p->error();
const auto body = ToString(p->builder(), fe.ast_body());
const auto* expected = R"(VariableDeclStatement{
VariableConst{
x_1
none
undefined
__vec_3__f32
{
Binary[not set]{
TypeConstructor[not set]{
__vec_3__f32
ScalarConstructor[not set]{60.000000}
ScalarConstructor[not set]{70.000000}
ScalarConstructor[not set]{50.000000}
}
multiply
TypeConstructor[not set]{
__vec_3__f32
ScalarConstructor[not set]{0.017453}
}
}
}
}
})";
EXPECT_THAT(body, HasSubstr(expected)) << body;
}
} // namespace
} // namespace spirv
} // namespace reader