[hlsl] Emit `sign` in IR Writer
This CL adds support for `sign` to the HLSL IR Writer.
Bug: 42251045
Change-Id: I7dbb0934b06bd4386b6d5c8fe9d34a3ee382cd87
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/197497
Commit-Queue: dan sinclair <dsinclair@chromium.org>
Reviewed-by: James Price <jrprice@google.com>
diff --git a/src/tint/lang/hlsl/builtin_fn.cc b/src/tint/lang/hlsl/builtin_fn.cc
index 9fb3784..0bba3e4 100644
--- a/src/tint/lang/hlsl/builtin_fn.cc
+++ b/src/tint/lang/hlsl/builtin_fn.cc
@@ -54,6 +54,8 @@
return "f16tof32";
case BuiltinFn::kMul:
return "mul";
+ case BuiltinFn::kSign:
+ return "sign";
case BuiltinFn::kLoad:
return "Load";
case BuiltinFn::kLoad2:
diff --git a/src/tint/lang/hlsl/builtin_fn.h b/src/tint/lang/hlsl/builtin_fn.h
index fb6c0b1..c9a4b46 100644
--- a/src/tint/lang/hlsl/builtin_fn.h
+++ b/src/tint/lang/hlsl/builtin_fn.h
@@ -53,6 +53,7 @@
kF32Tof16,
kF16Tof32,
kMul,
+ kSign,
kLoad,
kLoad2,
kLoad3,
diff --git a/src/tint/lang/hlsl/hlsl.def b/src/tint/lang/hlsl/hlsl.def
index 4378ba6..0ccc52f 100644
--- a/src/tint/lang/hlsl/hlsl.def
+++ b/src/tint/lang/hlsl/hlsl.def
@@ -72,6 +72,7 @@
match f32_u32: f32 | u32
match f32_i32: f32 | i32
match f32_f16: f32 | f16
+match fi32_f16: f32 | i32 | f16
match storage: address_space.storage
match function: address_space.function
@@ -105,6 +106,9 @@
fn mul [T: f32_f16, C: num, R: num](vec<R, T>, mat<C, R, T>) -> vec<C, T>
fn mul [T: f32_f16, K: num, C: num, R: num](mat<K, R, T>, mat<C, K, T>) -> mat<C, R, T>
+fn sign[T: fi32_f16](T) -> i32
+fn sign[N: num, T: fi32_f16](vec<N, T>) -> vec<N, i32>
+
@member_function fn Load(byte_address_buffer<readable>, offset: u32) -> u32
@member_function fn Load2(byte_address_buffer<readable>, offset: u32) -> vec2<u32>
@member_function fn Load3(byte_address_buffer<readable>, offset: u32) -> vec3<u32>
diff --git a/src/tint/lang/hlsl/intrinsic/data.cc b/src/tint/lang/hlsl/intrinsic/data.cc
index 4232917..fa5c6e6 100644
--- a/src/tint/lang/hlsl/intrinsic/data.cc
+++ b/src/tint/lang/hlsl/intrinsic/data.cc
@@ -549,6 +549,26 @@
kF32Matcher.print(nullptr, out); out << style::Plain(" or "); kF16Matcher.print(nullptr, out);}
};
+/// TypeMatcher for 'match fi32_f16'
+constexpr TypeMatcher kFi32F16Matcher {
+/* match */ [](MatchState& state, const Type* ty) -> const Type* {
+ if (MatchF32(state, ty)) {
+ return BuildF32(state, ty);
+ }
+ if (MatchI32(state, ty)) {
+ return BuildI32(state, ty);
+ }
+ if (MatchF16(state, ty)) {
+ return BuildF16(state, ty);
+ }
+ return nullptr;
+ },
+/* print */ [](MatchState*, StyledText& out) {
+ // Note: We pass nullptr to the Matcher.print() functions, as matchers do not support
+ // template arguments, nor can they match sub-types. As such, they have no use for the MatchState.
+ kF32Matcher.print(nullptr, out); out << style::Plain(", "); kI32Matcher.print(nullptr, out); out << style::Plain(" or "); kF16Matcher.print(nullptr, out);}
+};
+
/// EnumMatcher for 'match storage'
constexpr NumberMatcher kStorageMatcher {
/* match */ [](MatchState&, Number number) -> Number {
@@ -639,6 +659,7 @@
/* [25] */ kF32U32Matcher,
/* [26] */ kF32I32Matcher,
/* [27] */ kF32F16Matcher,
+ /* [28] */ kFi32F16Matcher,
};
/// The template numbers, and number matchers
@@ -695,28 +716,35 @@
/* [38] */ MatcherIndex(12),
/* [39] */ MatcherIndex(2),
/* [40] */ MatcherIndex(0),
- /* [41] */ MatcherIndex(23),
- /* [42] */ MatcherIndex(6),
- /* [43] */ MatcherIndex(9),
- /* [44] */ MatcherIndex(5),
- /* [45] */ MatcherIndex(10),
- /* [46] */ MatcherIndex(5),
- /* [47] */ MatcherIndex(11),
- /* [48] */ MatcherIndex(5),
+ /* [41] */ MatcherIndex(12),
+ /* [42] */ MatcherIndex(0),
+ /* [43] */ MatcherIndex(4),
+ /* [44] */ MatcherIndex(12),
+ /* [45] */ MatcherIndex(0),
+ /* [46] */ MatcherIndex(1),
+ /* [47] */ MatcherIndex(23),
+ /* [48] */ MatcherIndex(6),
/* [49] */ MatcherIndex(9),
- /* [50] */ MatcherIndex(7),
+ /* [50] */ MatcherIndex(5),
/* [51] */ MatcherIndex(10),
- /* [52] */ MatcherIndex(7),
+ /* [52] */ MatcherIndex(5),
/* [53] */ MatcherIndex(11),
- /* [54] */ MatcherIndex(7),
- /* [55] */ MatcherIndex(23),
+ /* [54] */ MatcherIndex(5),
+ /* [55] */ MatcherIndex(9),
/* [56] */ MatcherIndex(7),
- /* [57] */ MatcherIndex(23),
- /* [58] */ MatcherIndex(0),
- /* [59] */ MatcherIndex(25),
- /* [60] */ MatcherIndex(26),
- /* [61] */ MatcherIndex(24),
- /* [62] */ MatcherIndex(27),
+ /* [57] */ MatcherIndex(10),
+ /* [58] */ MatcherIndex(7),
+ /* [59] */ MatcherIndex(11),
+ /* [60] */ MatcherIndex(7),
+ /* [61] */ MatcherIndex(23),
+ /* [62] */ MatcherIndex(7),
+ /* [63] */ MatcherIndex(23),
+ /* [64] */ MatcherIndex(0),
+ /* [65] */ MatcherIndex(25),
+ /* [66] */ MatcherIndex(26),
+ /* [67] */ MatcherIndex(24),
+ /* [68] */ MatcherIndex(27),
+ /* [69] */ MatcherIndex(28),
};
static_assert(MatcherIndicesIndex::CanIndex(kMatcherIndices),
@@ -726,7 +754,7 @@
{
/* [0] */
/* usage */ core::ParameterUsage::kNone,
- /* matcher_indices */ MatcherIndicesIndex(55),
+ /* matcher_indices */ MatcherIndicesIndex(61),
},
{
/* [1] */
@@ -741,7 +769,7 @@
{
/* [3] */
/* usage */ core::ParameterUsage::kNone,
- /* matcher_indices */ MatcherIndicesIndex(55),
+ /* matcher_indices */ MatcherIndicesIndex(61),
},
{
/* [4] */
@@ -751,12 +779,12 @@
{
/* [5] */
/* usage */ core::ParameterUsage::kValue,
- /* matcher_indices */ MatcherIndicesIndex(43),
+ /* matcher_indices */ MatcherIndicesIndex(49),
},
{
/* [6] */
/* usage */ core::ParameterUsage::kNone,
- /* matcher_indices */ MatcherIndicesIndex(55),
+ /* matcher_indices */ MatcherIndicesIndex(61),
},
{
/* [7] */
@@ -766,12 +794,12 @@
{
/* [8] */
/* usage */ core::ParameterUsage::kValue,
- /* matcher_indices */ MatcherIndicesIndex(45),
+ /* matcher_indices */ MatcherIndicesIndex(51),
},
{
/* [9] */
/* usage */ core::ParameterUsage::kNone,
- /* matcher_indices */ MatcherIndicesIndex(55),
+ /* matcher_indices */ MatcherIndicesIndex(61),
},
{
/* [10] */
@@ -781,7 +809,7 @@
{
/* [11] */
/* usage */ core::ParameterUsage::kValue,
- /* matcher_indices */ MatcherIndicesIndex(47),
+ /* matcher_indices */ MatcherIndicesIndex(53),
},
{
/* [12] */
@@ -816,7 +844,7 @@
{
/* [18] */
/* usage */ core::ParameterUsage::kNone,
- /* matcher_indices */ MatcherIndicesIndex(41),
+ /* matcher_indices */ MatcherIndicesIndex(47),
},
{
/* [19] */
@@ -826,7 +854,7 @@
{
/* [20] */
/* usage */ core::ParameterUsage::kNone,
- /* matcher_indices */ MatcherIndicesIndex(57),
+ /* matcher_indices */ MatcherIndicesIndex(63),
},
{
/* [21] */
@@ -858,6 +886,11 @@
/* usage */ core::ParameterUsage::kNone,
/* matcher_indices */ MatcherIndicesIndex(32),
},
+ {
+ /* [27] */
+ /* usage */ core::ParameterUsage::kNone,
+ /* matcher_indices */ MatcherIndicesIndex(44),
+ },
};
static_assert(ParameterIndex::CanIndex(kParameters),
@@ -867,7 +900,7 @@
{
/* [0] */
/* name */ "T",
- /* matcher_indices */ MatcherIndicesIndex(62),
+ /* matcher_indices */ MatcherIndicesIndex(68),
/* kind */ TemplateInfo::Kind::kType,
},
{
@@ -891,7 +924,7 @@
{
/* [4] */
/* name */ "T",
- /* matcher_indices */ MatcherIndicesIndex(62),
+ /* matcher_indices */ MatcherIndicesIndex(68),
/* kind */ TemplateInfo::Kind::kType,
},
{
@@ -909,7 +942,7 @@
{
/* [7] */
/* name */ "T",
- /* matcher_indices */ MatcherIndicesIndex(59),
+ /* matcher_indices */ MatcherIndicesIndex(65),
/* kind */ TemplateInfo::Kind::kType,
},
{
@@ -921,29 +954,35 @@
{
/* [9] */
/* name */ "T",
- /* matcher_indices */ MatcherIndicesIndex(60),
+ /* matcher_indices */ MatcherIndicesIndex(69),
/* kind */ TemplateInfo::Kind::kType,
},
{
/* [10] */
- /* name */ "N",
- /* matcher_indices */ MatcherIndicesIndex(/* invalid */),
- /* kind */ TemplateInfo::Kind::kNumber,
- },
- {
- /* [11] */
/* name */ "T",
- /* matcher_indices */ MatcherIndicesIndex(61),
+ /* matcher_indices */ MatcherIndicesIndex(66),
/* kind */ TemplateInfo::Kind::kType,
},
{
- /* [12] */
+ /* [11] */
/* name */ "N",
/* matcher_indices */ MatcherIndicesIndex(/* invalid */),
/* kind */ TemplateInfo::Kind::kNumber,
},
{
+ /* [12] */
+ /* name */ "T",
+ /* matcher_indices */ MatcherIndicesIndex(67),
+ /* kind */ TemplateInfo::Kind::kType,
+ },
+ {
/* [13] */
+ /* name */ "N",
+ /* matcher_indices */ MatcherIndicesIndex(/* invalid */),
+ /* kind */ TemplateInfo::Kind::kNumber,
+ },
+ {
+ /* [14] */
/* name */ "A",
/* matcher_indices */ MatcherIndicesIndex(/* invalid */),
/* kind */ TemplateInfo::Kind::kNumber,
@@ -1015,7 +1054,7 @@
/* num_parameters */ 1,
/* num_explicit_templates */ 0,
/* num_templates */ 1,
- /* templates */ TemplateIndex(9),
+ /* templates */ TemplateIndex(10),
/* parameters */ ParameterIndex(22),
/* return_matcher_indices */ MatcherIndicesIndex(17),
/* const_eval_fn */ ConstEvalFunctionIndex(/* invalid */),
@@ -1026,7 +1065,7 @@
/* num_parameters */ 1,
/* num_explicit_templates */ 0,
/* num_templates */ 2,
- /* templates */ TemplateIndex(9),
+ /* templates */ TemplateIndex(10),
/* parameters */ ParameterIndex(13),
/* return_matcher_indices */ MatcherIndicesIndex(26),
/* const_eval_fn */ ConstEvalFunctionIndex(/* invalid */),
@@ -1037,7 +1076,7 @@
/* num_parameters */ 1,
/* num_explicit_templates */ 0,
/* num_templates */ 1,
- /* templates */ TemplateIndex(11),
+ /* templates */ TemplateIndex(12),
/* parameters */ ParameterIndex(22),
/* return_matcher_indices */ MatcherIndicesIndex(31),
/* const_eval_fn */ ConstEvalFunctionIndex(/* invalid */),
@@ -1048,7 +1087,7 @@
/* num_parameters */ 1,
/* num_explicit_templates */ 0,
/* num_templates */ 2,
- /* templates */ TemplateIndex(11),
+ /* templates */ TemplateIndex(12),
/* parameters */ ParameterIndex(13),
/* return_matcher_indices */ MatcherIndicesIndex(29),
/* const_eval_fn */ ConstEvalFunctionIndex(/* invalid */),
@@ -1099,24 +1138,24 @@
},
{
/* [13] */
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline, OverloadFlag::kMemberFunction),
- /* num_parameters */ 2,
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* num_parameters */ 1,
/* num_explicit_templates */ 0,
- /* num_templates */ 0,
- /* templates */ TemplateIndex(/* invalid */),
- /* parameters */ ParameterIndex(18),
- /* return_matcher_indices */ MatcherIndicesIndex(17),
+ /* num_templates */ 1,
+ /* templates */ TemplateIndex(9),
+ /* parameters */ ParameterIndex(22),
+ /* return_matcher_indices */ MatcherIndicesIndex(22),
/* const_eval_fn */ ConstEvalFunctionIndex(/* invalid */),
},
{
/* [14] */
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline, OverloadFlag::kMemberFunction),
- /* num_parameters */ 2,
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* num_parameters */ 1,
/* num_explicit_templates */ 0,
- /* num_templates */ 0,
- /* templates */ TemplateIndex(/* invalid */),
- /* parameters */ ParameterIndex(18),
- /* return_matcher_indices */ MatcherIndicesIndex(43),
+ /* num_templates */ 2,
+ /* templates */ TemplateIndex(8),
+ /* parameters */ ParameterIndex(27),
+ /* return_matcher_indices */ MatcherIndicesIndex(41),
/* const_eval_fn */ ConstEvalFunctionIndex(/* invalid */),
},
{
@@ -1127,7 +1166,7 @@
/* num_templates */ 0,
/* templates */ TemplateIndex(/* invalid */),
/* parameters */ ParameterIndex(18),
- /* return_matcher_indices */ MatcherIndicesIndex(45),
+ /* return_matcher_indices */ MatcherIndicesIndex(17),
/* const_eval_fn */ ConstEvalFunctionIndex(/* invalid */),
},
{
@@ -1138,7 +1177,7 @@
/* num_templates */ 0,
/* templates */ TemplateIndex(/* invalid */),
/* parameters */ ParameterIndex(18),
- /* return_matcher_indices */ MatcherIndicesIndex(47),
+ /* return_matcher_indices */ MatcherIndicesIndex(49),
/* const_eval_fn */ ConstEvalFunctionIndex(/* invalid */),
},
{
@@ -1149,7 +1188,7 @@
/* num_templates */ 0,
/* templates */ TemplateIndex(/* invalid */),
/* parameters */ ParameterIndex(18),
- /* return_matcher_indices */ MatcherIndicesIndex(19),
+ /* return_matcher_indices */ MatcherIndicesIndex(51),
/* const_eval_fn */ ConstEvalFunctionIndex(/* invalid */),
},
{
@@ -1160,7 +1199,7 @@
/* num_templates */ 0,
/* templates */ TemplateIndex(/* invalid */),
/* parameters */ ParameterIndex(18),
- /* return_matcher_indices */ MatcherIndicesIndex(49),
+ /* return_matcher_indices */ MatcherIndicesIndex(53),
/* const_eval_fn */ ConstEvalFunctionIndex(/* invalid */),
},
{
@@ -1171,7 +1210,7 @@
/* num_templates */ 0,
/* templates */ TemplateIndex(/* invalid */),
/* parameters */ ParameterIndex(18),
- /* return_matcher_indices */ MatcherIndicesIndex(51),
+ /* return_matcher_indices */ MatcherIndicesIndex(19),
/* const_eval_fn */ ConstEvalFunctionIndex(/* invalid */),
},
{
@@ -1182,12 +1221,34 @@
/* num_templates */ 0,
/* templates */ TemplateIndex(/* invalid */),
/* parameters */ ParameterIndex(18),
- /* return_matcher_indices */ MatcherIndicesIndex(53),
+ /* return_matcher_indices */ MatcherIndicesIndex(55),
/* const_eval_fn */ ConstEvalFunctionIndex(/* invalid */),
},
{
/* [21] */
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline, OverloadFlag::kMemberFunction),
+ /* num_parameters */ 2,
+ /* num_explicit_templates */ 0,
+ /* num_templates */ 0,
+ /* templates */ TemplateIndex(/* invalid */),
+ /* parameters */ ParameterIndex(18),
+ /* return_matcher_indices */ MatcherIndicesIndex(57),
+ /* const_eval_fn */ ConstEvalFunctionIndex(/* invalid */),
+ },
+ {
+ /* [22] */
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline, OverloadFlag::kMemberFunction),
+ /* num_parameters */ 2,
+ /* num_explicit_templates */ 0,
+ /* num_templates */ 0,
+ /* templates */ TemplateIndex(/* invalid */),
+ /* parameters */ ParameterIndex(18),
+ /* return_matcher_indices */ MatcherIndicesIndex(59),
+ /* const_eval_fn */ ConstEvalFunctionIndex(/* invalid */),
+ },
+ {
+ /* [23] */
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline, OverloadFlag::kMemberFunction),
/* num_parameters */ 3,
/* num_explicit_templates */ 0,
/* num_templates */ 0,
@@ -1197,7 +1258,7 @@
/* const_eval_fn */ ConstEvalFunctionIndex(/* invalid */),
},
{
- /* [22] */
+ /* [24] */
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline, OverloadFlag::kMemberFunction),
/* num_parameters */ 3,
/* num_explicit_templates */ 0,
@@ -1208,7 +1269,7 @@
/* const_eval_fn */ ConstEvalFunctionIndex(/* invalid */),
},
{
- /* [23] */
+ /* [25] */
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline, OverloadFlag::kMemberFunction),
/* num_parameters */ 3,
/* num_explicit_templates */ 0,
@@ -1219,7 +1280,7 @@
/* const_eval_fn */ ConstEvalFunctionIndex(/* invalid */),
},
{
- /* [24] */
+ /* [26] */
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline, OverloadFlag::kMemberFunction),
/* num_parameters */ 3,
/* num_explicit_templates */ 0,
@@ -1230,12 +1291,12 @@
/* const_eval_fn */ ConstEvalFunctionIndex(/* invalid */),
},
{
- /* [25] */
+ /* [27] */
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline, OverloadFlag::kMemberFunction),
/* num_parameters */ 2,
/* num_explicit_templates */ 0,
/* num_templates */ 1,
- /* templates */ TemplateIndex(13),
+ /* templates */ TemplateIndex(14),
/* parameters */ ParameterIndex(20),
/* return_matcher_indices */ MatcherIndicesIndex(/* invalid */),
/* const_eval_fn */ ConstEvalFunctionIndex(/* invalid */),
@@ -1291,82 +1352,89 @@
},
{
/* [6] */
- /* fn Load(byte_address_buffer<readable>, offset: u32) -> u32 */
- /* num overloads */ 1,
+ /* fn sign[T : fi32_f16](T) -> i32 */
+ /* fn sign[N : num, T : fi32_f16](vec<N, T>) -> vec<N, i32> */
+ /* num overloads */ 2,
/* overloads */ OverloadIndex(13),
},
{
/* [7] */
- /* fn Load2(byte_address_buffer<readable>, offset: u32) -> vec2<u32> */
- /* num overloads */ 1,
- /* overloads */ OverloadIndex(14),
- },
- {
- /* [8] */
- /* fn Load3(byte_address_buffer<readable>, offset: u32) -> vec3<u32> */
+ /* fn Load(byte_address_buffer<readable>, offset: u32) -> u32 */
/* num overloads */ 1,
/* overloads */ OverloadIndex(15),
},
{
- /* [9] */
- /* fn Load4(byte_address_buffer<readable>, offset: u32) -> vec4<u32> */
+ /* [8] */
+ /* fn Load2(byte_address_buffer<readable>, offset: u32) -> vec2<u32> */
/* num overloads */ 1,
/* overloads */ OverloadIndex(16),
},
{
- /* [10] */
- /* fn LoadF16(byte_address_buffer<readable>, offset: u32) -> f16 */
+ /* [9] */
+ /* fn Load3(byte_address_buffer<readable>, offset: u32) -> vec3<u32> */
/* num overloads */ 1,
/* overloads */ OverloadIndex(17),
},
{
- /* [11] */
- /* fn Load2F16(byte_address_buffer<readable>, offset: u32) -> vec2<f16> */
+ /* [10] */
+ /* fn Load4(byte_address_buffer<readable>, offset: u32) -> vec4<u32> */
/* num overloads */ 1,
/* overloads */ OverloadIndex(18),
},
{
- /* [12] */
- /* fn Load3F16(byte_address_buffer<readable>, offset: u32) -> vec3<f16> */
+ /* [11] */
+ /* fn LoadF16(byte_address_buffer<readable>, offset: u32) -> f16 */
/* num overloads */ 1,
/* overloads */ OverloadIndex(19),
},
{
- /* [13] */
- /* fn Load4F16(byte_address_buffer<readable>, offset: u32) -> vec4<f16> */
+ /* [12] */
+ /* fn Load2F16(byte_address_buffer<readable>, offset: u32) -> vec2<f16> */
/* num overloads */ 1,
/* overloads */ OverloadIndex(20),
},
{
- /* [14] */
- /* fn Store(byte_address_buffer<writable>, offset: u32, value: u32) */
+ /* [13] */
+ /* fn Load3F16(byte_address_buffer<readable>, offset: u32) -> vec3<f16> */
/* num overloads */ 1,
/* overloads */ OverloadIndex(21),
},
{
- /* [15] */
- /* fn Store2(byte_address_buffer<writable>, offset: u32, value: vec2<u32>) */
+ /* [14] */
+ /* fn Load4F16(byte_address_buffer<readable>, offset: u32) -> vec4<f16> */
/* num overloads */ 1,
/* overloads */ OverloadIndex(22),
},
{
- /* [16] */
- /* fn Store3(byte_address_buffer<writable>, offset: u32, value: vec3<u32>) */
+ /* [15] */
+ /* fn Store(byte_address_buffer<writable>, offset: u32, value: u32) */
/* num overloads */ 1,
/* overloads */ OverloadIndex(23),
},
{
- /* [17] */
- /* fn Store4(byte_address_buffer<writable>, offset: u32, value: vec4<u32>) */
+ /* [16] */
+ /* fn Store2(byte_address_buffer<writable>, offset: u32, value: vec2<u32>) */
/* num overloads */ 1,
/* overloads */ OverloadIndex(24),
},
{
- /* [18] */
- /* fn GetDimensions[A : access](byte_address_buffer<A>, ptr<function, u32, writable>) */
+ /* [17] */
+ /* fn Store3(byte_address_buffer<writable>, offset: u32, value: vec3<u32>) */
/* num overloads */ 1,
/* overloads */ OverloadIndex(25),
},
+ {
+ /* [18] */
+ /* fn Store4(byte_address_buffer<writable>, offset: u32, value: vec4<u32>) */
+ /* num overloads */ 1,
+ /* overloads */ OverloadIndex(26),
+ },
+ {
+ /* [19] */
+ /* fn GetDimensions[A : access](byte_address_buffer<A>, ptr<function, u32, writable>) */
+ /* num overloads */ 1,
+ /* overloads */ OverloadIndex(27),
+ },
};
// clang-format on
diff --git a/src/tint/lang/hlsl/writer/builtin_test.cc b/src/tint/lang/hlsl/writer/builtin_test.cc
index 0b0df56..40fedfa 100644
--- a/src/tint/lang/hlsl/writer/builtin_test.cc
+++ b/src/tint/lang/hlsl/writer/builtin_test.cc
@@ -671,6 +671,39 @@
)");
}
+TEST_F(HlslWriterTest, BuiltinSignScalar) {
+ auto* func = b.Function("foo", ty.void_(), core::ir::Function::PipelineStage::kFragment);
+ b.Append(func->Block(), [&] {
+ b.Let("x", b.Call(ty.f16(), core::BuiltinFn::kSign, 1_h));
+ b.Return(func);
+ });
+
+ ASSERT_TRUE(Generate()) << err_ << output_.hlsl;
+ EXPECT_EQ(output_.hlsl, R"(
+void foo() {
+ float16_t x = float16_t(sign(float16_t(1.0h)));
+}
+
+)");
+}
+
+TEST_F(HlslWriterTest, BuiltinSignVector) {
+ auto* func = b.Function("foo", ty.void_(), core::ir::Function::PipelineStage::kFragment);
+ b.Append(func->Block(), [&] {
+ b.Let("x", b.Call(ty.vec3<f32>(), core::BuiltinFn::kSign,
+ b.Composite(ty.vec3<f32>(), 1_f, 2_f, 3_f)));
+ b.Return(func);
+ });
+
+ ASSERT_TRUE(Generate()) << err_ << output_.hlsl;
+ EXPECT_EQ(output_.hlsl, R"(
+void foo() {
+ float3 x = float3(sign(float3(1.0f, 2.0f, 3.0f)));
+}
+
+)");
+}
+
TEST_F(HlslWriterTest, BuiltinStorageBarrier) {
auto* func = b.Function("foo", ty.void_(), core::ir::Function::PipelineStage::kCompute);
func->SetWorkgroupSize(1, 1, 1);
diff --git a/src/tint/lang/hlsl/writer/raise/builtin_polyfill.cc b/src/tint/lang/hlsl/writer/raise/builtin_polyfill.cc
index efcca68..ea129b5 100644
--- a/src/tint/lang/hlsl/writer/raise/builtin_polyfill.cc
+++ b/src/tint/lang/hlsl/writer/raise/builtin_polyfill.cc
@@ -77,8 +77,7 @@
if (auto* call = inst->As<core::ir::CoreBuiltinCall>()) {
switch (call->Func()) {
case core::BuiltinFn::kSelect:
- call_worklist.Push(call);
- break;
+ case core::BuiltinFn::kSign:
case core::BuiltinFn::kTrunc:
call_worklist.Push(call);
break;
@@ -112,6 +111,9 @@
case core::BuiltinFn::kSelect:
Select(call);
break;
+ case core::BuiltinFn::kSign:
+ Sign(call);
+ break;
case core::BuiltinFn::kTrunc:
Trunc(call);
break;
@@ -348,6 +350,24 @@
});
}
+ // The HLSL `sign` method always returns an `int` result (scalar or vector). In WGSL the result
+ // is expected to be the same type as the argument. This injects a cast to the expected WGSL
+ // result type after the call to `hlsl.sign`.
+ void Sign(core::ir::BuiltinCall* call) {
+ b.InsertBefore(call, [&] {
+ const core::type::Type* result_ty = ty.i32();
+ if (auto* vec = call->Result(0)->Type()->As<core::type::Vector>()) {
+ result_ty = ty.vec(result_ty, vec->Width());
+ }
+
+ auto* sign =
+ b.Call<hlsl::ir::BuiltinCall>(result_ty, hlsl::BuiltinFn::kSign, call->Args()[0]);
+
+ b.ConvertWithResult(call->DetachResult(), sign);
+ });
+ call->Destroy();
+ }
+
/// Replaces a bitcast with a call to the ToF16 polyfill for the given types
void ReplaceBitcastWithToF16Polyfill(core::ir::Bitcast* bitcast) {
auto* src_type = bitcast->Val()->Type();
diff --git a/src/tint/lang/hlsl/writer/raise/builtin_polyfill_test.cc b/src/tint/lang/hlsl/writer/raise/builtin_polyfill_test.cc
index f9545d6..4ae83d2 100644
--- a/src/tint/lang/hlsl/writer/raise/builtin_polyfill_test.cc
+++ b/src/tint/lang/hlsl/writer/raise/builtin_polyfill_test.cc
@@ -391,5 +391,72 @@
EXPECT_EQ(expect, str());
}
+TEST_F(HlslWriter_BuiltinPolyfillTest, Sign) {
+ auto* func = b.Function("foo", ty.void_(), core::ir::Function::PipelineStage::kFragment);
+ b.Append(func->Block(), [&] {
+ b.Let("a", b.Call(ty.f32(), core::BuiltinFn::kSign, -1_f));
+ b.Return(func);
+ });
+
+ auto* src = R"(
+%foo = @fragment func():void {
+ $B1: {
+ %2:f32 = sign -1.0f
+ %a:f32 = let %2
+ ret
+ }
+}
+)";
+ EXPECT_EQ(src, str());
+
+ auto* expect = R"(
+%foo = @fragment func():void {
+ $B1: {
+ %2:i32 = hlsl.sign -1.0f
+ %3:f32 = convert %2
+ %a:f32 = let %3
+ ret
+ }
+}
+)";
+
+ Run(BuiltinPolyfill);
+ EXPECT_EQ(expect, str());
+}
+
+TEST_F(HlslWriter_BuiltinPolyfillTest, SignVec) {
+ auto* func = b.Function("foo", ty.void_(), core::ir::Function::PipelineStage::kFragment);
+ b.Append(func->Block(), [&] {
+ b.Let("a", b.Call(ty.vec3<i32>(), core::BuiltinFn::kSign,
+ b.Composite(ty.vec3<i32>(), 1_i, 2_i, 3_i)));
+ b.Return(func);
+ });
+
+ auto* src = R"(
+%foo = @fragment func():void {
+ $B1: {
+ %2:vec3<i32> = sign vec3<i32>(1i, 2i, 3i)
+ %a:vec3<i32> = let %2
+ ret
+ }
+}
+)";
+ EXPECT_EQ(src, str());
+
+ auto* expect = R"(
+%foo = @fragment func():void {
+ $B1: {
+ %2:vec3<i32> = hlsl.sign vec3<i32>(1i, 2i, 3i)
+ %3:vec3<i32> = convert %2
+ %a:vec3<i32> = let %3
+ ret
+ }
+}
+)";
+
+ Run(BuiltinPolyfill);
+ EXPECT_EQ(expect, str());
+}
+
} // namespace
} // namespace tint::hlsl::writer::raise