spirv-reader: Substitute 1.0 for scalar normalize
WGSL only has vector normalize, not scalar. Scalar normalize is always 1.0, so return that directly. Bug: tint:765 Change-Id: I08332c20922f5834f65284b9aaeb22995423171d Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/50603 Kokoro: Kokoro <noreply+kokoro@google.com> Commit-Queue: David Neto <dneto@google.com> Reviewed-by: Antonio Maiorano <amaiorano@google.com>
This commit is contained in:
parent
32b5018c5d
commit
6344d4c2f5
|
@ -3444,6 +3444,17 @@ TypedExpression FunctionEmitter::MaybeEmitCombinatorialValue(
|
||||||
TypedExpression FunctionEmitter::EmitGlslStd450ExtInst(
|
TypedExpression FunctionEmitter::EmitGlslStd450ExtInst(
|
||||||
const spvtools::opt::Instruction& inst) {
|
const spvtools::opt::Instruction& inst) {
|
||||||
const auto ext_opcode = inst.GetSingleWordInOperand(1);
|
const auto ext_opcode = inst.GetSingleWordInOperand(1);
|
||||||
|
|
||||||
|
auto* result_type = parser_impl_.ConvertType(inst.type_id());
|
||||||
|
|
||||||
|
if ((ext_opcode == GLSLstd450Normalize) && result_type->IsScalar()) {
|
||||||
|
// WGSL does not have scalar form of the normalize builtin.
|
||||||
|
// The answer would be 1 anyway, so return that directly.
|
||||||
|
return {ty_.F32(),
|
||||||
|
create<ast::ScalarConstructorExpression>(
|
||||||
|
Source{}, create<ast::FloatLiteral>(Source{}, 1.0f))};
|
||||||
|
}
|
||||||
|
|
||||||
const auto name = GetGlslStd450FuncName(ext_opcode);
|
const auto name = GetGlslStd450FuncName(ext_opcode);
|
||||||
if (name.empty()) {
|
if (name.empty()) {
|
||||||
Fail() << "unhandled GLSL.std.450 instruction " << ext_opcode;
|
Fail() << "unhandled GLSL.std.450 instruction " << ext_opcode;
|
||||||
|
@ -3462,9 +3473,8 @@ TypedExpression FunctionEmitter::EmitGlslStd450ExtInst(
|
||||||
}
|
}
|
||||||
operands.emplace_back(operand.expr);
|
operands.emplace_back(operand.expr);
|
||||||
}
|
}
|
||||||
auto* ast_type = parser_impl_.ConvertType(inst.type_id());
|
|
||||||
auto* call = create<ast::CallExpression>(Source{}, func, std::move(operands));
|
auto* call = create<ast::CallExpression>(Source{}, func, std::move(operands));
|
||||||
TypedExpression call_expr{ast_type, call};
|
TypedExpression call_expr{result_type, call};
|
||||||
return parser_impl_.RectifyForcedResultType(call_expr, inst,
|
return parser_impl_.RectifyForcedResultType(call_expr, inst,
|
||||||
first_operand_type);
|
first_operand_type);
|
||||||
}
|
}
|
||||||
|
|
|
@ -681,7 +681,6 @@ INSTANTIATE_TEST_SUITE_P(Samples,
|
||||||
{"InverseSqrt", "inverseSqrt"},
|
{"InverseSqrt", "inverseSqrt"},
|
||||||
{"Log", "log"},
|
{"Log", "log"},
|
||||||
{"Log2", "log2"},
|
{"Log2", "log2"},
|
||||||
{"Normalize", "normalize"},
|
|
||||||
{"Round", "round"},
|
{"Round", "round"},
|
||||||
{"RoundEven", "round"},
|
{"RoundEven", "round"},
|
||||||
{"Sin", "sin"},
|
{"Sin", "sin"},
|
||||||
|
@ -1080,6 +1079,121 @@ INSTANTIATE_TEST_SUITE_P(Samples,
|
||||||
SpvParserTest_GlslStd450_Uinting_UintingUintingUinting,
|
SpvParserTest_GlslStd450_Uinting_UintingUintingUinting,
|
||||||
::testing::Values(GlslStd450Case{"UClamp", "clamp"}));
|
::testing::Values(GlslStd450Case{"UClamp", "clamp"}));
|
||||||
|
|
||||||
|
// Test Normalize. WGSL does not have a scalar form of the normalize builtin.
|
||||||
|
// So we have to test it separately, as it does not fit the patterns tested
|
||||||
|
// above.
|
||||||
|
|
||||||
|
TEST_F(SpvParserTest, Normalize_Scalar) {
|
||||||
|
// Scalar normalize always results in 1.0
|
||||||
|
const auto assembly = Preamble() + R"(
|
||||||
|
%1 = OpExtInst %float %glsl Normalize %f1
|
||||||
|
OpReturn
|
||||||
|
OpFunctionEnd
|
||||||
|
)";
|
||||||
|
auto p = parser(test::Assemble(assembly));
|
||||||
|
ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << assembly;
|
||||||
|
auto fe = p->function_emitter(100);
|
||||||
|
EXPECT_TRUE(fe.EmitBody()) << p->error();
|
||||||
|
const auto body = ToString(p->builder(), fe.ast_body());
|
||||||
|
EXPECT_THAT(body, HasSubstr(R"(
|
||||||
|
VariableConst{
|
||||||
|
x_1
|
||||||
|
none
|
||||||
|
__f32
|
||||||
|
{
|
||||||
|
ScalarConstructor[not set]{1.000000}
|
||||||
|
}
|
||||||
|
})"))
|
||||||
|
<< body;
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(SpvParserTest, Normalize_Vector2) {
|
||||||
|
// Scalar normalize always results in 1.0
|
||||||
|
const auto assembly = Preamble() + R"(
|
||||||
|
%1 = OpExtInst %v2float %glsl Normalize %v2f1
|
||||||
|
OpReturn
|
||||||
|
OpFunctionEnd
|
||||||
|
)";
|
||||||
|
auto p = parser(test::Assemble(assembly));
|
||||||
|
ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << assembly;
|
||||||
|
auto fe = p->function_emitter(100);
|
||||||
|
EXPECT_TRUE(fe.EmitBody()) << p->error();
|
||||||
|
const auto body = ToString(p->builder(), fe.ast_body());
|
||||||
|
EXPECT_THAT(body, HasSubstr(R"(
|
||||||
|
VariableConst{
|
||||||
|
x_1
|
||||||
|
none
|
||||||
|
__vec_2__f32
|
||||||
|
{
|
||||||
|
Call[not set]{
|
||||||
|
Identifier[not set]{normalize}
|
||||||
|
(
|
||||||
|
Identifier[not set]{v2f1}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})"))
|
||||||
|
<< body;
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(SpvParserTest, Normalize_Vector3) {
|
||||||
|
// Scalar normalize always results in 1.0
|
||||||
|
const auto assembly = Preamble() + R"(
|
||||||
|
%1 = OpExtInst %v3float %glsl Normalize %v3f1
|
||||||
|
OpReturn
|
||||||
|
OpFunctionEnd
|
||||||
|
)";
|
||||||
|
auto p = parser(test::Assemble(assembly));
|
||||||
|
ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << assembly;
|
||||||
|
auto fe = p->function_emitter(100);
|
||||||
|
EXPECT_TRUE(fe.EmitBody()) << p->error();
|
||||||
|
const auto body = ToString(p->builder(), fe.ast_body());
|
||||||
|
EXPECT_THAT(body, HasSubstr(R"(
|
||||||
|
VariableConst{
|
||||||
|
x_1
|
||||||
|
none
|
||||||
|
__vec_3__f32
|
||||||
|
{
|
||||||
|
Call[not set]{
|
||||||
|
Identifier[not set]{normalize}
|
||||||
|
(
|
||||||
|
Identifier[not set]{v3f1}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})"))
|
||||||
|
<< body;
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(SpvParserTest, Normalize_Vector4) {
|
||||||
|
// Scalar normalize always results in 1.0
|
||||||
|
const auto assembly = Preamble() + R"(
|
||||||
|
%1 = OpExtInst %v4float %glsl Normalize %v4f1
|
||||||
|
OpReturn
|
||||||
|
OpFunctionEnd
|
||||||
|
)";
|
||||||
|
auto p = parser(test::Assemble(assembly));
|
||||||
|
ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << assembly;
|
||||||
|
auto fe = p->function_emitter(100);
|
||||||
|
EXPECT_TRUE(fe.EmitBody()) << p->error();
|
||||||
|
const auto body = ToString(p->builder(), fe.ast_body());
|
||||||
|
EXPECT_THAT(body, HasSubstr(R"(
|
||||||
|
VariableConst{
|
||||||
|
x_1
|
||||||
|
none
|
||||||
|
__vec_4__f32
|
||||||
|
{
|
||||||
|
Call[not set]{
|
||||||
|
Identifier[not set]{normalize}
|
||||||
|
(
|
||||||
|
Identifier[not set]{v4f1}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})"))
|
||||||
|
<< body;
|
||||||
|
}
|
||||||
|
|
||||||
// Check that we convert signedness of operands and result type.
|
// Check that we convert signedness of operands and result type.
|
||||||
// This is needed for each of the integer-based extended instructions.
|
// This is needed for each of the integer-based extended instructions.
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue