[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/break_statement.h"
|
||||||
#include "src/ast/call_expression.h"
|
#include "src/ast/call_expression.h"
|
||||||
#include "src/ast/case_statement.h"
|
#include "src/ast/case_statement.h"
|
||||||
|
#include "src/ast/cast_expression.h"
|
||||||
#include "src/ast/continue_statement.h"
|
#include "src/ast/continue_statement.h"
|
||||||
#include "src/ast/else_statement.h"
|
#include "src/ast/else_statement.h"
|
||||||
#include "src/ast/fallthrough_statement.h"
|
#include "src/ast/fallthrough_statement.h"
|
||||||
|
@ -2533,6 +2534,9 @@ TypedExpression FunctionEmitter::MaybeEmitCombinatorialValue(
|
||||||
if (opcode == SpvOpVectorShuffle) {
|
if (opcode == SpvOpVectorShuffle) {
|
||||||
return MakeVectorShuffle(inst);
|
return MakeVectorShuffle(inst);
|
||||||
}
|
}
|
||||||
|
if (opcode == SpvOpConvertSToF || opcode == SpvOpConvertUToF) {
|
||||||
|
return MakeNumericConversion(inst);
|
||||||
|
}
|
||||||
|
|
||||||
// builtin readonly function
|
// builtin readonly function
|
||||||
// glsl.std.450 readonly function
|
// glsl.std.450 readonly function
|
||||||
|
@ -2545,8 +2549,6 @@ TypedExpression FunctionEmitter::MaybeEmitCombinatorialValue(
|
||||||
// OpSatConvertUToS
|
// OpSatConvertUToS
|
||||||
// OpConvertFToS
|
// OpConvertFToS
|
||||||
// OpConvertFToU
|
// OpConvertFToU
|
||||||
// OpConvertSToF
|
|
||||||
// OpConvertUToF
|
|
||||||
// OpUConvert // Only needed when multiple widths supported
|
// OpUConvert // Only needed when multiple widths supported
|
||||||
// OpSConvert // Only needed when multiple widths supported
|
// OpSConvert // Only needed when multiple widths supported
|
||||||
// OpFConvert // 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 spirv
|
||||||
} // namespace reader
|
} // namespace reader
|
||||||
} // namespace tint
|
} // namespace tint
|
||||||
|
|
|
@ -463,6 +463,11 @@ class FunctionEmitter {
|
||||||
/// @returns an AST expression for the instruction, or nullptr.
|
/// @returns an AST expression for the instruction, or nullptr.
|
||||||
TypedExpression MakeVectorShuffle(const spvtools::opt::Instruction& inst);
|
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
|
/// Gets the block info for a block ID, if any exists
|
||||||
/// @param id the SPIR-V ID of the OpLabel instruction starting the block
|
/// @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
|
/// @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());
|
<< 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): OpConvertFToU
|
||||||
// TODO(dneto): OpConvertFToS
|
// TODO(dneto): OpConvertFToS
|
||||||
// TODO(dneto): OpConvertUToF
|
|
||||||
// TODO(dneto): OpConvertSToF
|
|
||||||
// TODO(dneto): OpSConvert // only if multiple widths
|
// TODO(dneto): OpSConvert // only if multiple widths
|
||||||
// TODO(dneto): OpUConvert // only if multiple widths
|
// TODO(dneto): OpUConvert // only if multiple widths
|
||||||
// TODO(dneto): OpFConvert // only if multiple widths
|
// TODO(dneto): OpFConvert // only if multiple widths
|
||||||
|
|
|
@ -133,6 +133,7 @@ bool AssumesSignedOperands(SpvOp opcode) {
|
||||||
case SpvOpSLessThanEqual:
|
case SpvOpSLessThanEqual:
|
||||||
case SpvOpSGreaterThan:
|
case SpvOpSGreaterThan:
|
||||||
case SpvOpSGreaterThanEqual:
|
case SpvOpSGreaterThanEqual:
|
||||||
|
case SpvOpConvertSToF:
|
||||||
return true;
|
return true;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
@ -149,6 +150,7 @@ bool AssumesUnsignedOperands(SpvOp opcode) {
|
||||||
case SpvOpULessThanEqual:
|
case SpvOpULessThanEqual:
|
||||||
case SpvOpUGreaterThan:
|
case SpvOpUGreaterThan:
|
||||||
case SpvOpUGreaterThanEqual:
|
case SpvOpUGreaterThanEqual:
|
||||||
|
case SpvOpConvertUToF:
|
||||||
return true;
|
return true;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Reference in New Issue