[spirv-reader] Add ConvertSToF, ConvertUToF
Bug: tint:3 Change-Id: I28bcc109a207ef6f5225b9ea707bff11b1b6fd50 Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/23420 Reviewed-by: dan sinclair <dsinclair@google.com>
This commit is contained in:
parent
3238eaa3b1
commit
b961e0069b
|
@ -35,6 +35,7 @@
|
|||
#include "src/ast/break_statement.h"
|
||||
#include "src/ast/call_expression.h"
|
||||
#include "src/ast/case_statement.h"
|
||||
#include "src/ast/cast_expression.h"
|
||||
#include "src/ast/continue_statement.h"
|
||||
#include "src/ast/else_statement.h"
|
||||
#include "src/ast/fallthrough_statement.h"
|
||||
|
@ -2533,6 +2534,9 @@ TypedExpression FunctionEmitter::MaybeEmitCombinatorialValue(
|
|||
if (opcode == SpvOpVectorShuffle) {
|
||||
return MakeVectorShuffle(inst);
|
||||
}
|
||||
if (opcode == SpvOpConvertSToF || opcode == SpvOpConvertUToF) {
|
||||
return MakeNumericConversion(inst);
|
||||
}
|
||||
|
||||
// builtin readonly function
|
||||
// glsl.std.450 readonly function
|
||||
|
@ -2545,8 +2549,6 @@ TypedExpression FunctionEmitter::MaybeEmitCombinatorialValue(
|
|||
// OpSatConvertUToS
|
||||
// OpConvertFToS
|
||||
// OpConvertFToU
|
||||
// OpConvertSToF
|
||||
// OpConvertUToF
|
||||
// OpUConvert // Only needed when multiple widths supported
|
||||
// OpSConvert // Only needed when multiple widths supported
|
||||
// OpFConvert // Only needed when multiple widths supported
|
||||
|
@ -2893,6 +2895,15 @@ void FunctionEmitter::RegisterValuesNeedingNamedDefinition() {
|
|||
}
|
||||
}
|
||||
|
||||
TypedExpression FunctionEmitter::MakeNumericConversion(
|
||||
const spvtools::opt::Instruction& inst) {
|
||||
auto* result_type = parser_impl_.ConvertType(inst.type_id());
|
||||
auto arg_expr = MakeOperand(inst, 0);
|
||||
|
||||
return {result_type, std::make_unique<ast::CastExpression>(
|
||||
result_type, std::move(arg_expr.expr))};
|
||||
}
|
||||
|
||||
} // namespace spirv
|
||||
} // namespace reader
|
||||
} // namespace tint
|
||||
|
|
|
@ -463,6 +463,11 @@ class FunctionEmitter {
|
|||
/// @returns an AST expression for the instruction, or nullptr.
|
||||
TypedExpression MakeVectorShuffle(const spvtools::opt::Instruction& inst);
|
||||
|
||||
/// Creates an expression for a numeric conversion.
|
||||
/// @param inst a numeric conversion instruction
|
||||
/// @returns an AST expression for the instruction, or nullptr.
|
||||
TypedExpression MakeNumericConversion(const spvtools::opt::Instruction& inst);
|
||||
|
||||
/// Gets the block info for a block ID, if any exists
|
||||
/// @param id the SPIR-V ID of the OpLabel instruction starting the block
|
||||
/// @returns the block info for the given ID, if it exists, or nullptr
|
||||
|
|
|
@ -119,10 +119,224 @@ TEST_F(SpvUnaryConversionTest, Bitcast_Vector) {
|
|||
<< ToString(fe.ast_body());
|
||||
}
|
||||
|
||||
TEST_F(SpvUnaryConversionTest, ConvertSToF_Scalar_FromSigned) {
|
||||
const auto assembly = CommonTypes() + R"(
|
||||
%100 = OpFunction %void None %voidfn
|
||||
%entry = OpLabel
|
||||
%30 = OpCopyObject %int %int_30
|
||||
%1 = OpConvertSToF %float %30
|
||||
OpReturn
|
||||
OpFunctionEnd
|
||||
)";
|
||||
auto* p = parser(test::Assemble(assembly));
|
||||
ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
|
||||
FunctionEmitter fe(p, *spirv_function(100));
|
||||
EXPECT_TRUE(fe.EmitBody()) << p->error();
|
||||
EXPECT_THAT(ToString(fe.ast_body()), HasSubstr(R"(Variable{
|
||||
x_1
|
||||
none
|
||||
__f32
|
||||
{
|
||||
Cast<__f32>(
|
||||
Identifier{x_30}
|
||||
)
|
||||
}
|
||||
})"))
|
||||
<< ToString(fe.ast_body());
|
||||
}
|
||||
|
||||
TEST_F(SpvUnaryConversionTest, ConvertSToF_Scalar_FromUnsigned) {
|
||||
const auto assembly = CommonTypes() + R"(
|
||||
%100 = OpFunction %void None %voidfn
|
||||
%entry = OpLabel
|
||||
%30 = OpCopyObject %uint %uint_10
|
||||
%1 = OpConvertSToF %float %30
|
||||
OpReturn
|
||||
OpFunctionEnd
|
||||
)";
|
||||
auto* p = parser(test::Assemble(assembly));
|
||||
ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
|
||||
FunctionEmitter fe(p, *spirv_function(100));
|
||||
EXPECT_TRUE(fe.EmitBody()) << p->error();
|
||||
EXPECT_THAT(ToString(fe.ast_body()), HasSubstr(R"(Variable{
|
||||
x_1
|
||||
none
|
||||
__f32
|
||||
{
|
||||
Cast<__f32>(
|
||||
As<__i32>{
|
||||
Identifier{x_30}
|
||||
}
|
||||
)
|
||||
}
|
||||
})"))
|
||||
<< ToString(fe.ast_body());
|
||||
}
|
||||
|
||||
TEST_F(SpvUnaryConversionTest, ConvertSToF_Vector_FromSigned) {
|
||||
const auto assembly = CommonTypes() + R"(
|
||||
%100 = OpFunction %void None %voidfn
|
||||
%entry = OpLabel
|
||||
%30 = OpCopyObject %v2int %v2int_30_40
|
||||
%1 = OpConvertSToF %v2float %30
|
||||
OpReturn
|
||||
OpFunctionEnd
|
||||
)";
|
||||
auto* p = parser(test::Assemble(assembly));
|
||||
ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
|
||||
FunctionEmitter fe(p, *spirv_function(100));
|
||||
EXPECT_TRUE(fe.EmitBody()) << p->error();
|
||||
EXPECT_THAT(ToString(fe.ast_body()), HasSubstr(R"(Variable{
|
||||
x_1
|
||||
none
|
||||
__vec_2__f32
|
||||
{
|
||||
Cast<__vec_2__f32>(
|
||||
Identifier{x_30}
|
||||
)
|
||||
}
|
||||
})"))
|
||||
<< ToString(fe.ast_body());
|
||||
}
|
||||
|
||||
TEST_F(SpvUnaryConversionTest, ConvertSToF_Vector_FromUnsigned) {
|
||||
const auto assembly = CommonTypes() + R"(
|
||||
%100 = OpFunction %void None %voidfn
|
||||
%entry = OpLabel
|
||||
%30 = OpCopyObject %v2uint %v2uint_10_20
|
||||
%1 = OpConvertSToF %v2float %30
|
||||
OpReturn
|
||||
OpFunctionEnd
|
||||
)";
|
||||
auto* p = parser(test::Assemble(assembly));
|
||||
ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
|
||||
FunctionEmitter fe(p, *spirv_function(100));
|
||||
EXPECT_TRUE(fe.EmitBody()) << p->error();
|
||||
EXPECT_THAT(ToString(fe.ast_body()), HasSubstr(R"(Variable{
|
||||
x_1
|
||||
none
|
||||
__vec_2__f32
|
||||
{
|
||||
Cast<__vec_2__f32>(
|
||||
As<__vec_2__i32>{
|
||||
Identifier{x_30}
|
||||
}
|
||||
)
|
||||
}
|
||||
})"))
|
||||
<< ToString(fe.ast_body());
|
||||
}
|
||||
|
||||
TEST_F(SpvUnaryConversionTest, ConvertUToF_Scalar_FromSigned) {
|
||||
const auto assembly = CommonTypes() + R"(
|
||||
%100 = OpFunction %void None %voidfn
|
||||
%entry = OpLabel
|
||||
%30 = OpCopyObject %int %int_30
|
||||
%1 = OpConvertUToF %float %30
|
||||
OpReturn
|
||||
OpFunctionEnd
|
||||
)";
|
||||
auto* p = parser(test::Assemble(assembly));
|
||||
ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
|
||||
FunctionEmitter fe(p, *spirv_function(100));
|
||||
EXPECT_TRUE(fe.EmitBody()) << p->error();
|
||||
EXPECT_THAT(ToString(fe.ast_body()), HasSubstr(R"(Variable{
|
||||
x_1
|
||||
none
|
||||
__f32
|
||||
{
|
||||
Cast<__f32>(
|
||||
As<__u32>{
|
||||
Identifier{x_30}
|
||||
}
|
||||
)
|
||||
}
|
||||
})"))
|
||||
<< ToString(fe.ast_body());
|
||||
}
|
||||
|
||||
TEST_F(SpvUnaryConversionTest, ConvertUToF_Scalar_FromUnsigned) {
|
||||
const auto assembly = CommonTypes() + R"(
|
||||
%100 = OpFunction %void None %voidfn
|
||||
%entry = OpLabel
|
||||
%30 = OpCopyObject %uint %uint_10
|
||||
%1 = OpConvertUToF %float %30
|
||||
OpReturn
|
||||
OpFunctionEnd
|
||||
)";
|
||||
auto* p = parser(test::Assemble(assembly));
|
||||
ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
|
||||
FunctionEmitter fe(p, *spirv_function(100));
|
||||
EXPECT_TRUE(fe.EmitBody()) << p->error();
|
||||
EXPECT_THAT(ToString(fe.ast_body()), HasSubstr(R"(Variable{
|
||||
x_1
|
||||
none
|
||||
__f32
|
||||
{
|
||||
Cast<__f32>(
|
||||
Identifier{x_30}
|
||||
)
|
||||
}
|
||||
})"))
|
||||
<< ToString(fe.ast_body());
|
||||
}
|
||||
|
||||
TEST_F(SpvUnaryConversionTest, ConvertUToF_Vector_FromSigned) {
|
||||
const auto assembly = CommonTypes() + R"(
|
||||
%100 = OpFunction %void None %voidfn
|
||||
%entry = OpLabel
|
||||
%30 = OpCopyObject %v2int %v2int_30_40
|
||||
%1 = OpConvertUToF %v2float %30
|
||||
OpReturn
|
||||
OpFunctionEnd
|
||||
)";
|
||||
auto* p = parser(test::Assemble(assembly));
|
||||
ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
|
||||
FunctionEmitter fe(p, *spirv_function(100));
|
||||
EXPECT_TRUE(fe.EmitBody()) << p->error();
|
||||
EXPECT_THAT(ToString(fe.ast_body()), HasSubstr(R"(Variable{
|
||||
x_1
|
||||
none
|
||||
__vec_2__f32
|
||||
{
|
||||
Cast<__vec_2__f32>(
|
||||
As<__vec_2__u32>{
|
||||
Identifier{x_30}
|
||||
}
|
||||
)
|
||||
}
|
||||
})"))
|
||||
<< ToString(fe.ast_body());
|
||||
}
|
||||
|
||||
TEST_F(SpvUnaryConversionTest, ConvertUToF_Vector_FromUnsigned) {
|
||||
const auto assembly = CommonTypes() + R"(
|
||||
%100 = OpFunction %void None %voidfn
|
||||
%entry = OpLabel
|
||||
%30 = OpCopyObject %v2uint %v2uint_10_20
|
||||
%1 = OpConvertUToF %v2float %30
|
||||
OpReturn
|
||||
OpFunctionEnd
|
||||
)";
|
||||
auto* p = parser(test::Assemble(assembly));
|
||||
ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
|
||||
FunctionEmitter fe(p, *spirv_function(100));
|
||||
EXPECT_TRUE(fe.EmitBody()) << p->error();
|
||||
EXPECT_THAT(ToString(fe.ast_body()), HasSubstr(R"(Variable{
|
||||
x_1
|
||||
none
|
||||
__vec_2__f32
|
||||
{
|
||||
Cast<__vec_2__f32>(
|
||||
Identifier{x_30}
|
||||
)
|
||||
}
|
||||
})"))
|
||||
<< ToString(fe.ast_body());
|
||||
}
|
||||
|
||||
// TODO(dneto): OpConvertFToU
|
||||
// TODO(dneto): OpConvertFToS
|
||||
// TODO(dneto): OpConvertUToF
|
||||
// TODO(dneto): OpConvertSToF
|
||||
// TODO(dneto): OpSConvert // only if multiple widths
|
||||
// TODO(dneto): OpUConvert // only if multiple widths
|
||||
// TODO(dneto): OpFConvert // only if multiple widths
|
||||
|
|
|
@ -133,6 +133,7 @@ bool AssumesSignedOperands(SpvOp opcode) {
|
|||
case SpvOpSLessThanEqual:
|
||||
case SpvOpSGreaterThan:
|
||||
case SpvOpSGreaterThanEqual:
|
||||
case SpvOpConvertSToF:
|
||||
return true;
|
||||
default:
|
||||
break;
|
||||
|
@ -149,6 +150,7 @@ bool AssumesUnsignedOperands(SpvOp opcode) {
|
|||
case SpvOpULessThanEqual:
|
||||
case SpvOpUGreaterThan:
|
||||
case SpvOpUGreaterThanEqual:
|
||||
case SpvOpConvertUToF:
|
||||
return true;
|
||||
default:
|
||||
break;
|
||||
|
|
Loading…
Reference in New Issue