spirv/reader: Implement derivative intrinsics
Fixed: tint:719 Change-Id: Iaa5e44a574b2843f4f6f9264b8baa8d199acd70f Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/47770 Commit-Queue: Ben Clayton <bclayton@chromium.org> Commit-Queue: Ben Clayton <bclayton@google.com> Reviewed-by: Alan Baker <alanbaker@google.com>
This commit is contained in:
parent
434cd396fe
commit
98b084e4a4
|
@ -442,6 +442,24 @@ semantic::IntrinsicType GetIntrinsic(SpvOp opcode) {
|
||||||
return semantic::IntrinsicType::kReverseBits;
|
return semantic::IntrinsicType::kReverseBits;
|
||||||
case SpvOpDot:
|
case SpvOpDot:
|
||||||
return semantic::IntrinsicType::kDot;
|
return semantic::IntrinsicType::kDot;
|
||||||
|
case SpvOpDPdx:
|
||||||
|
return semantic::IntrinsicType::kDpdx;
|
||||||
|
case SpvOpDPdy:
|
||||||
|
return semantic::IntrinsicType::kDpdy;
|
||||||
|
case SpvOpFwidth:
|
||||||
|
return semantic::IntrinsicType::kFwidth;
|
||||||
|
case SpvOpDPdxFine:
|
||||||
|
return semantic::IntrinsicType::kDpdxFine;
|
||||||
|
case SpvOpDPdyFine:
|
||||||
|
return semantic::IntrinsicType::kDpdyFine;
|
||||||
|
case SpvOpFwidthFine:
|
||||||
|
return semantic::IntrinsicType::kFwidthFine;
|
||||||
|
case SpvOpDPdxCoarse:
|
||||||
|
return semantic::IntrinsicType::kDpdxCoarse;
|
||||||
|
case SpvOpDPdyCoarse:
|
||||||
|
return semantic::IntrinsicType::kDpdyCoarse;
|
||||||
|
case SpvOpFwidthCoarse:
|
||||||
|
return semantic::IntrinsicType::kFwidthCoarse;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1478,6 +1478,79 @@ TEST_F(SpvBinaryArithTestBasic, OuterProduct) {
|
||||||
<< got;
|
<< got;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct IntrinsicData {
|
||||||
|
const std::string spirv;
|
||||||
|
const std::string wgsl;
|
||||||
|
};
|
||||||
|
inline std::ostream& operator<<(std::ostream& out, IntrinsicData data) {
|
||||||
|
out << "OpData{" << data.spirv << "," << data.wgsl << "}";
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
struct ArgAndTypeData {
|
||||||
|
const std::string spirv_type;
|
||||||
|
const std::string spirv_arg;
|
||||||
|
const std::string ast_type;
|
||||||
|
};
|
||||||
|
inline std::ostream& operator<<(std::ostream& out, ArgAndTypeData data) {
|
||||||
|
out << "ArgAndTypeData{" << data.spirv_type << "," << data.spirv_arg << ","
|
||||||
|
<< data.ast_type << "}";
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
using SpvBinaryDerivativeTest = SpvParserTestBase<
|
||||||
|
::testing::TestWithParam<std::tuple<IntrinsicData, ArgAndTypeData>>>;
|
||||||
|
|
||||||
|
TEST_P(SpvBinaryDerivativeTest, Derivatives) {
|
||||||
|
auto& intrinsic = std::get<0>(GetParam());
|
||||||
|
auto& arg = std::get<1>(GetParam());
|
||||||
|
|
||||||
|
const auto assembly = CommonTypes() + R"(
|
||||||
|
%100 = OpFunction %void None %voidfn
|
||||||
|
%entry = OpLabel
|
||||||
|
%1 = OpCopyObject %)" +
|
||||||
|
arg.spirv_type + " %" + arg.spirv_arg + R"(
|
||||||
|
%2 = )" + intrinsic.spirv +
|
||||||
|
" %" + arg.spirv_type + R"( %1
|
||||||
|
OpReturn
|
||||||
|
OpFunctionEnd
|
||||||
|
)";
|
||||||
|
auto p = parser(test::Assemble(assembly));
|
||||||
|
ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << assembly;
|
||||||
|
FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
|
||||||
|
EXPECT_TRUE(fe.EmitBody()) << p->error();
|
||||||
|
EXPECT_THAT(ToString(p->builder(), fe.ast_body()), HasSubstr(R"(VariableConst{
|
||||||
|
x_2
|
||||||
|
none
|
||||||
|
)" + arg.ast_type + R"(
|
||||||
|
{
|
||||||
|
Call[not set]{
|
||||||
|
Identifier[not set]{)" + intrinsic.wgsl + R"(}
|
||||||
|
(
|
||||||
|
Identifier[not set]{x_1}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})"));
|
||||||
|
}
|
||||||
|
|
||||||
|
INSTANTIATE_TEST_SUITE_P(
|
||||||
|
SpvBinaryDerivativeTest,
|
||||||
|
SpvBinaryDerivativeTest,
|
||||||
|
testing::Combine(
|
||||||
|
::testing::Values(IntrinsicData{"OpDPdx", "dpdx"},
|
||||||
|
IntrinsicData{"OpDPdy", "dpdy"},
|
||||||
|
IntrinsicData{"OpFwidth", "fwidth"},
|
||||||
|
IntrinsicData{"OpDPdxFine", "dpdxFine"},
|
||||||
|
IntrinsicData{"OpDPdyFine", "dpdyFine"},
|
||||||
|
IntrinsicData{"OpFwidthFine", "fwidthFine"},
|
||||||
|
IntrinsicData{"OpDPdxCoarse", "dpdxCoarse"},
|
||||||
|
IntrinsicData{"OpDPdyCoarse", "dpdyCoarse"},
|
||||||
|
IntrinsicData{"OpFwidthCoarse", "fwidthCoarse"}),
|
||||||
|
::testing::Values(
|
||||||
|
ArgAndTypeData{"float", "float_50", "__f32"},
|
||||||
|
ArgAndTypeData{"v2float", "v2float_50_60", "__vec_2__f32"},
|
||||||
|
ArgAndTypeData{"v3float", "v3float_50_60_70", "__vec_3__f32"})));
|
||||||
|
|
||||||
// TODO(dneto): OpSRem. Missing from WGSL
|
// TODO(dneto): OpSRem. Missing from WGSL
|
||||||
// https://github.com/gpuweb/gpuweb/issues/702
|
// https://github.com/gpuweb/gpuweb/issues/702
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue