[hlsl] Add `unpack*` support.
This Cl adds support to the HLSL IR backend for the various `unpack`
methods.
Bug: 42251045
Change-Id: Ic06ad065d5fc8c1e42a164f08a38ecdb43ad86fc
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/198757
Reviewed-by: James Price <jrprice@google.com>
Commit-Queue: dan sinclair <dsinclair@chromium.org>
diff --git a/src/tint/lang/hlsl/builtin_fn.cc b/src/tint/lang/hlsl/builtin_fn.cc
index 7db232d..de112ff 100644
--- a/src/tint/lang/hlsl/builtin_fn.cc
+++ b/src/tint/lang/hlsl/builtin_fn.cc
@@ -56,6 +56,10 @@
return "mul";
case BuiltinFn::kSign:
return "sign";
+ case BuiltinFn::kUnpackS8S32:
+ return "unpack_s8s32";
+ case BuiltinFn::kUnpackU8U32:
+ return "unpack_u8u32";
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 b443159..274fb89 100644
--- a/src/tint/lang/hlsl/builtin_fn.h
+++ b/src/tint/lang/hlsl/builtin_fn.h
@@ -54,6 +54,8 @@
kF16Tof32,
kMul,
kSign,
+ kUnpackS8S32,
+ kUnpackU8U32,
kLoad,
kLoad2,
kLoad3,
diff --git a/src/tint/lang/hlsl/hlsl.def b/src/tint/lang/hlsl/hlsl.def
index daa4806..3f71d36 100644
--- a/src/tint/lang/hlsl/hlsl.def
+++ b/src/tint/lang/hlsl/hlsl.def
@@ -64,6 +64,8 @@
@display("mat{N}x{M}<{T}>") type mat<N: num, M: num, T>
type byte_address_buffer<A: access>
+type int8_t4_packed
+type uint8_t4_packed
type sampler
type sampler_comparison
@@ -155,6 +157,9 @@
fn sign[T: fi32_f16](T) -> i32
fn sign[N: num, T: fi32_f16](vec<N, T>) -> vec<N, i32>
+fn unpack_s8s32(int8_t4_packed) -> vec4<i32>
+fn unpack_u8u32(uint8_t4_packed) -> vec4<u32>
+
@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 67206ae..61a763c 100644
--- a/src/tint/lang/hlsl/intrinsic/data.cc
+++ b/src/tint/lang/hlsl/intrinsic/data.cc
@@ -481,6 +481,34 @@
};
+/// TypeMatcher for 'type int8_t4_packed'
+constexpr TypeMatcher kInt8T4PackedMatcher {
+/* match */ [](MatchState& state, const Type* ty) -> const Type* {
+ if (!MatchInt8T4Packed(state, ty)) {
+ return nullptr;
+ }
+ return BuildInt8T4Packed(state, ty);
+ },
+/* print */ []([[maybe_unused]] MatchState* state, StyledText& out) {
+ out << style::Type("int8_t4_packed");
+ }
+};
+
+
+/// TypeMatcher for 'type uint8_t4_packed'
+constexpr TypeMatcher kUint8T4PackedMatcher {
+/* match */ [](MatchState& state, const Type* ty) -> const Type* {
+ if (!MatchUint8T4Packed(state, ty)) {
+ return nullptr;
+ }
+ return BuildUint8T4Packed(state, ty);
+ },
+/* print */ []([[maybe_unused]] MatchState* state, StyledText& out) {
+ out << style::Type("uint8_t4_packed");
+ }
+};
+
+
/// TypeMatcher for 'type sampler'
constexpr TypeMatcher kSamplerMatcher {
/* match */ [](MatchState& state, const Type* ty) -> const Type* {
@@ -1077,30 +1105,32 @@
/* [21] */ kMat4X4Matcher,
/* [22] */ kMatMatcher,
/* [23] */ kByteAddressBufferMatcher,
- /* [24] */ kSamplerMatcher,
- /* [25] */ kSamplerComparisonMatcher,
- /* [26] */ kTexture1DMatcher,
- /* [27] */ kTexture2DMatcher,
- /* [28] */ kTexture2DArrayMatcher,
- /* [29] */ kTexture3DMatcher,
- /* [30] */ kTextureCubeMatcher,
- /* [31] */ kTextureCubeArrayMatcher,
- /* [32] */ kTextureDepth2DMatcher,
- /* [33] */ kTextureDepth2DArrayMatcher,
- /* [34] */ kTextureDepthCubeMatcher,
- /* [35] */ kTextureDepthCubeArrayMatcher,
- /* [36] */ kTextureDepthMultisampled2DMatcher,
- /* [37] */ kTextureMultisampled2DMatcher,
- /* [38] */ kTextureStorage1DMatcher,
- /* [39] */ kTextureStorage2DMatcher,
- /* [40] */ kTextureStorage2DArrayMatcher,
- /* [41] */ kTextureStorage3DMatcher,
- /* [42] */ kIu32Matcher,
- /* [43] */ kFiu32Matcher,
- /* [44] */ kF32U32Matcher,
- /* [45] */ kF32I32Matcher,
- /* [46] */ kF32F16Matcher,
- /* [47] */ kFi32F16Matcher,
+ /* [24] */ kInt8T4PackedMatcher,
+ /* [25] */ kUint8T4PackedMatcher,
+ /* [26] */ kSamplerMatcher,
+ /* [27] */ kSamplerComparisonMatcher,
+ /* [28] */ kTexture1DMatcher,
+ /* [29] */ kTexture2DMatcher,
+ /* [30] */ kTexture2DArrayMatcher,
+ /* [31] */ kTexture3DMatcher,
+ /* [32] */ kTextureCubeMatcher,
+ /* [33] */ kTextureCubeArrayMatcher,
+ /* [34] */ kTextureDepth2DMatcher,
+ /* [35] */ kTextureDepth2DArrayMatcher,
+ /* [36] */ kTextureDepthCubeMatcher,
+ /* [37] */ kTextureDepthCubeArrayMatcher,
+ /* [38] */ kTextureDepthMultisampled2DMatcher,
+ /* [39] */ kTextureMultisampled2DMatcher,
+ /* [40] */ kTextureStorage1DMatcher,
+ /* [41] */ kTextureStorage2DMatcher,
+ /* [42] */ kTextureStorage2DArrayMatcher,
+ /* [43] */ kTextureStorage3DMatcher,
+ /* [44] */ kIu32Matcher,
+ /* [45] */ kFiu32Matcher,
+ /* [46] */ kF32U32Matcher,
+ /* [47] */ kF32I32Matcher,
+ /* [48] */ kF32F16Matcher,
+ /* [49] */ kFi32F16Matcher,
};
/// The template numbers, and number matchers
@@ -1166,78 +1196,78 @@
/* [44] */ MatcherIndex(12),
/* [45] */ MatcherIndex(0),
/* [46] */ MatcherIndex(1),
- /* [47] */ MatcherIndex(38),
+ /* [47] */ MatcherIndex(40),
/* [48] */ MatcherIndex(0),
/* [49] */ MatcherIndex(1),
- /* [50] */ MatcherIndex(39),
+ /* [50] */ MatcherIndex(41),
/* [51] */ MatcherIndex(0),
/* [52] */ MatcherIndex(1),
- /* [53] */ MatcherIndex(40),
+ /* [53] */ MatcherIndex(42),
/* [54] */ MatcherIndex(0),
/* [55] */ MatcherIndex(1),
- /* [56] */ MatcherIndex(41),
+ /* [56] */ MatcherIndex(43),
/* [57] */ MatcherIndex(0),
/* [58] */ MatcherIndex(1),
- /* [59] */ MatcherIndex(38),
+ /* [59] */ MatcherIndex(40),
/* [60] */ MatcherIndex(8),
/* [61] */ MatcherIndex(7),
- /* [62] */ MatcherIndex(39),
+ /* [62] */ MatcherIndex(41),
/* [63] */ MatcherIndex(8),
/* [64] */ MatcherIndex(7),
- /* [65] */ MatcherIndex(40),
+ /* [65] */ MatcherIndex(42),
/* [66] */ MatcherIndex(8),
/* [67] */ MatcherIndex(7),
- /* [68] */ MatcherIndex(41),
+ /* [68] */ MatcherIndex(43),
/* [69] */ MatcherIndex(8),
/* [70] */ MatcherIndex(7),
- /* [71] */ MatcherIndex(38),
+ /* [71] */ MatcherIndex(40),
/* [72] */ MatcherIndex(10),
/* [73] */ MatcherIndex(7),
- /* [74] */ MatcherIndex(39),
+ /* [74] */ MatcherIndex(41),
/* [75] */ MatcherIndex(10),
/* [76] */ MatcherIndex(7),
- /* [77] */ MatcherIndex(40),
+ /* [77] */ MatcherIndex(42),
/* [78] */ MatcherIndex(10),
/* [79] */ MatcherIndex(7),
- /* [80] */ MatcherIndex(41),
+ /* [80] */ MatcherIndex(43),
/* [81] */ MatcherIndex(10),
/* [82] */ MatcherIndex(7),
- /* [83] */ MatcherIndex(38),
+ /* [83] */ MatcherIndex(40),
/* [84] */ MatcherIndex(9),
/* [85] */ MatcherIndex(7),
- /* [86] */ MatcherIndex(39),
+ /* [86] */ MatcherIndex(41),
/* [87] */ MatcherIndex(9),
/* [88] */ MatcherIndex(7),
- /* [89] */ MatcherIndex(40),
+ /* [89] */ MatcherIndex(42),
/* [90] */ MatcherIndex(9),
/* [91] */ MatcherIndex(7),
- /* [92] */ MatcherIndex(41),
+ /* [92] */ MatcherIndex(43),
/* [93] */ MatcherIndex(9),
/* [94] */ MatcherIndex(7),
- /* [95] */ MatcherIndex(23),
- /* [96] */ MatcherIndex(6),
+ /* [95] */ MatcherIndex(11),
+ /* [96] */ MatcherIndex(4),
/* [97] */ MatcherIndex(11),
- /* [98] */ MatcherIndex(0),
- /* [99] */ MatcherIndex(26),
- /* [100] */ MatcherIndex(0),
- /* [101] */ MatcherIndex(9),
- /* [102] */ MatcherIndex(4),
- /* [103] */ MatcherIndex(27),
+ /* [98] */ MatcherIndex(5),
+ /* [99] */ MatcherIndex(23),
+ /* [100] */ MatcherIndex(6),
+ /* [101] */ MatcherIndex(11),
+ /* [102] */ MatcherIndex(0),
+ /* [103] */ MatcherIndex(28),
/* [104] */ MatcherIndex(0),
- /* [105] */ MatcherIndex(10),
+ /* [105] */ MatcherIndex(9),
/* [106] */ MatcherIndex(4),
- /* [107] */ MatcherIndex(28),
+ /* [107] */ MatcherIndex(29),
/* [108] */ MatcherIndex(0),
- /* [109] */ MatcherIndex(11),
+ /* [109] */ MatcherIndex(10),
/* [110] */ MatcherIndex(4),
- /* [111] */ MatcherIndex(37),
+ /* [111] */ MatcherIndex(30),
/* [112] */ MatcherIndex(0),
- /* [113] */ MatcherIndex(29),
+ /* [113] */ MatcherIndex(39),
/* [114] */ MatcherIndex(0),
- /* [115] */ MatcherIndex(11),
- /* [116] */ MatcherIndex(6),
+ /* [115] */ MatcherIndex(31),
+ /* [116] */ MatcherIndex(0),
/* [117] */ MatcherIndex(11),
- /* [118] */ MatcherIndex(5),
+ /* [118] */ MatcherIndex(6),
/* [119] */ MatcherIndex(9),
/* [120] */ MatcherIndex(5),
/* [121] */ MatcherIndex(10),
@@ -1248,25 +1278,27 @@
/* [126] */ MatcherIndex(7),
/* [127] */ MatcherIndex(23),
/* [128] */ MatcherIndex(0),
- /* [129] */ MatcherIndex(30),
+ /* [129] */ MatcherIndex(32),
/* [130] */ MatcherIndex(0),
- /* [131] */ MatcherIndex(31),
+ /* [131] */ MatcherIndex(33),
/* [132] */ MatcherIndex(0),
/* [133] */ MatcherIndex(9),
/* [134] */ MatcherIndex(0),
/* [135] */ MatcherIndex(10),
/* [136] */ MatcherIndex(0),
- /* [137] */ MatcherIndex(44),
- /* [138] */ MatcherIndex(45),
- /* [139] */ MatcherIndex(42),
- /* [140] */ MatcherIndex(46),
- /* [141] */ MatcherIndex(47),
- /* [142] */ MatcherIndex(43),
- /* [143] */ MatcherIndex(32),
- /* [144] */ MatcherIndex(33),
- /* [145] */ MatcherIndex(36),
- /* [146] */ MatcherIndex(34),
- /* [147] */ MatcherIndex(35),
+ /* [137] */ MatcherIndex(46),
+ /* [138] */ MatcherIndex(47),
+ /* [139] */ MatcherIndex(44),
+ /* [140] */ MatcherIndex(48),
+ /* [141] */ MatcherIndex(49),
+ /* [142] */ MatcherIndex(24),
+ /* [143] */ MatcherIndex(25),
+ /* [144] */ MatcherIndex(45),
+ /* [145] */ MatcherIndex(34),
+ /* [146] */ MatcherIndex(35),
+ /* [147] */ MatcherIndex(38),
+ /* [148] */ MatcherIndex(36),
+ /* [149] */ MatcherIndex(37),
};
static_assert(MatcherIndicesIndex::CanIndex(kMatcherIndices),
@@ -1276,7 +1308,7 @@
{
/* [0] */
/* usage */ core::ParameterUsage::kTexture,
- /* matcher_indices */ MatcherIndicesIndex(107),
+ /* matcher_indices */ MatcherIndicesIndex(111),
},
{
/* [1] */
@@ -1306,7 +1338,7 @@
{
/* [6] */
/* usage */ core::ParameterUsage::kTexture,
- /* matcher_indices */ MatcherIndicesIndex(113),
+ /* matcher_indices */ MatcherIndicesIndex(115),
},
{
/* [7] */
@@ -1366,7 +1398,7 @@
{
/* [18] */
/* usage */ core::ParameterUsage::kTexture,
- /* matcher_indices */ MatcherIndicesIndex(144),
+ /* matcher_indices */ MatcherIndicesIndex(146),
},
{
/* [19] */
@@ -1396,7 +1428,7 @@
{
/* [24] */
/* usage */ core::ParameterUsage::kTexture,
- /* matcher_indices */ MatcherIndicesIndex(147),
+ /* matcher_indices */ MatcherIndicesIndex(149),
},
{
/* [25] */
@@ -1426,7 +1458,7 @@
{
/* [30] */
/* usage */ core::ParameterUsage::kTexture,
- /* matcher_indices */ MatcherIndicesIndex(103),
+ /* matcher_indices */ MatcherIndicesIndex(107),
},
{
/* [31] */
@@ -1476,7 +1508,7 @@
{
/* [40] */
/* usage */ core::ParameterUsage::kTexture,
- /* matcher_indices */ MatcherIndicesIndex(143),
+ /* matcher_indices */ MatcherIndicesIndex(145),
},
{
/* [41] */
@@ -1501,7 +1533,7 @@
{
/* [45] */
/* usage */ core::ParameterUsage::kTexture,
- /* matcher_indices */ MatcherIndicesIndex(146),
+ /* matcher_indices */ MatcherIndicesIndex(148),
},
{
/* [46] */
@@ -1526,7 +1558,7 @@
{
/* [50] */
/* usage */ core::ParameterUsage::kTexture,
- /* matcher_indices */ MatcherIndicesIndex(99),
+ /* matcher_indices */ MatcherIndicesIndex(103),
},
{
/* [51] */
@@ -1546,7 +1578,7 @@
{
/* [54] */
/* usage */ core::ParameterUsage::kTexture,
- /* matcher_indices */ MatcherIndicesIndex(107),
+ /* matcher_indices */ MatcherIndicesIndex(111),
},
{
/* [55] */
@@ -1586,7 +1618,7 @@
{
/* [62] */
/* usage */ core::ParameterUsage::kTexture,
- /* matcher_indices */ MatcherIndicesIndex(113),
+ /* matcher_indices */ MatcherIndicesIndex(115),
},
{
/* [63] */
@@ -1646,7 +1678,7 @@
{
/* [74] */
/* usage */ core::ParameterUsage::kTexture,
- /* matcher_indices */ MatcherIndicesIndex(111),
+ /* matcher_indices */ MatcherIndicesIndex(113),
},
{
/* [75] */
@@ -1666,7 +1698,7 @@
{
/* [78] */
/* usage */ core::ParameterUsage::kTexture,
- /* matcher_indices */ MatcherIndicesIndex(144),
+ /* matcher_indices */ MatcherIndicesIndex(146),
},
{
/* [79] */
@@ -1686,7 +1718,7 @@
{
/* [82] */
/* usage */ core::ParameterUsage::kTexture,
- /* matcher_indices */ MatcherIndicesIndex(147),
+ /* matcher_indices */ MatcherIndicesIndex(149),
},
{
/* [83] */
@@ -1706,7 +1738,7 @@
{
/* [86] */
/* usage */ core::ParameterUsage::kTexture,
- /* matcher_indices */ MatcherIndicesIndex(145),
+ /* matcher_indices */ MatcherIndicesIndex(147),
},
{
/* [87] */
@@ -1726,12 +1758,12 @@
{
/* [90] */
/* usage */ core::ParameterUsage::kTexture,
- /* matcher_indices */ MatcherIndicesIndex(111),
+ /* matcher_indices */ MatcherIndicesIndex(113),
},
{
/* [91] */
/* usage */ core::ParameterUsage::kLocation,
- /* matcher_indices */ MatcherIndicesIndex(101),
+ /* matcher_indices */ MatcherIndicesIndex(105),
},
{
/* [92] */
@@ -1741,12 +1773,12 @@
{
/* [93] */
/* usage */ core::ParameterUsage::kTexture,
- /* matcher_indices */ MatcherIndicesIndex(145),
+ /* matcher_indices */ MatcherIndicesIndex(147),
},
{
/* [94] */
/* usage */ core::ParameterUsage::kLocation,
- /* matcher_indices */ MatcherIndicesIndex(101),
+ /* matcher_indices */ MatcherIndicesIndex(105),
},
{
/* [95] */
@@ -1811,12 +1843,12 @@
{
/* [107] */
/* usage */ core::ParameterUsage::kValue,
- /* matcher_indices */ MatcherIndicesIndex(117),
+ /* matcher_indices */ MatcherIndicesIndex(97),
},
{
/* [108] */
/* usage */ core::ParameterUsage::kTexture,
- /* matcher_indices */ MatcherIndicesIndex(103),
+ /* matcher_indices */ MatcherIndicesIndex(107),
},
{
/* [109] */
@@ -1861,7 +1893,7 @@
{
/* [117] */
/* usage */ core::ParameterUsage::kTexture,
- /* matcher_indices */ MatcherIndicesIndex(143),
+ /* matcher_indices */ MatcherIndicesIndex(145),
},
{
/* [118] */
@@ -1876,7 +1908,7 @@
{
/* [120] */
/* usage */ core::ParameterUsage::kTexture,
- /* matcher_indices */ MatcherIndicesIndex(146),
+ /* matcher_indices */ MatcherIndicesIndex(148),
},
{
/* [121] */
@@ -1901,7 +1933,7 @@
{
/* [125] */
/* usage */ core::ParameterUsage::kValue,
- /* matcher_indices */ MatcherIndicesIndex(115),
+ /* matcher_indices */ MatcherIndicesIndex(117),
},
{
/* [126] */
@@ -1916,7 +1948,7 @@
{
/* [128] */
/* usage */ core::ParameterUsage::kValue,
- /* matcher_indices */ MatcherIndicesIndex(115),
+ /* matcher_indices */ MatcherIndicesIndex(117),
},
{
/* [129] */
@@ -1931,7 +1963,7 @@
{
/* [131] */
/* usage */ core::ParameterUsage::kValue,
- /* matcher_indices */ MatcherIndicesIndex(115),
+ /* matcher_indices */ MatcherIndicesIndex(117),
},
{
/* [132] */
@@ -1946,7 +1978,7 @@
{
/* [134] */
/* usage */ core::ParameterUsage::kValue,
- /* matcher_indices */ MatcherIndicesIndex(115),
+ /* matcher_indices */ MatcherIndicesIndex(117),
},
{
/* [135] */
@@ -1961,7 +1993,7 @@
{
/* [137] */
/* usage */ core::ParameterUsage::kValue,
- /* matcher_indices */ MatcherIndicesIndex(109),
+ /* matcher_indices */ MatcherIndicesIndex(95),
},
{
/* [138] */
@@ -1976,7 +2008,7 @@
{
/* [140] */
/* usage */ core::ParameterUsage::kValue,
- /* matcher_indices */ MatcherIndicesIndex(109),
+ /* matcher_indices */ MatcherIndicesIndex(95),
},
{
/* [141] */
@@ -1991,7 +2023,7 @@
{
/* [143] */
/* usage */ core::ParameterUsage::kValue,
- /* matcher_indices */ MatcherIndicesIndex(109),
+ /* matcher_indices */ MatcherIndicesIndex(95),
},
{
/* [144] */
@@ -2006,7 +2038,7 @@
{
/* [146] */
/* usage */ core::ParameterUsage::kValue,
- /* matcher_indices */ MatcherIndicesIndex(109),
+ /* matcher_indices */ MatcherIndicesIndex(95),
},
{
/* [147] */
@@ -2021,7 +2053,7 @@
{
/* [149] */
/* usage */ core::ParameterUsage::kValue,
- /* matcher_indices */ MatcherIndicesIndex(117),
+ /* matcher_indices */ MatcherIndicesIndex(97),
},
{
/* [150] */
@@ -2036,7 +2068,7 @@
{
/* [152] */
/* usage */ core::ParameterUsage::kValue,
- /* matcher_indices */ MatcherIndicesIndex(117),
+ /* matcher_indices */ MatcherIndicesIndex(97),
},
{
/* [153] */
@@ -2051,7 +2083,7 @@
{
/* [155] */
/* usage */ core::ParameterUsage::kValue,
- /* matcher_indices */ MatcherIndicesIndex(117),
+ /* matcher_indices */ MatcherIndicesIndex(97),
},
{
/* [156] */
@@ -2066,7 +2098,7 @@
{
/* [158] */
/* usage */ core::ParameterUsage::kValue,
- /* matcher_indices */ MatcherIndicesIndex(117),
+ /* matcher_indices */ MatcherIndicesIndex(97),
},
{
/* [159] */
@@ -2101,7 +2133,7 @@
{
/* [165] */
/* usage */ core::ParameterUsage::kNone,
- /* matcher_indices */ MatcherIndicesIndex(95),
+ /* matcher_indices */ MatcherIndicesIndex(99),
},
{
/* [166] */
@@ -2111,62 +2143,62 @@
{
/* [167] */
/* usage */ core::ParameterUsage::kTexture,
- /* matcher_indices */ MatcherIndicesIndex(99),
+ /* matcher_indices */ MatcherIndicesIndex(103),
},
{
/* [168] */
/* usage */ core::ParameterUsage::kLocation,
- /* matcher_indices */ MatcherIndicesIndex(101),
+ /* matcher_indices */ MatcherIndicesIndex(105),
},
{
/* [169] */
/* usage */ core::ParameterUsage::kTexture,
- /* matcher_indices */ MatcherIndicesIndex(103),
+ /* matcher_indices */ MatcherIndicesIndex(107),
},
{
/* [170] */
/* usage */ core::ParameterUsage::kLocation,
- /* matcher_indices */ MatcherIndicesIndex(105),
+ /* matcher_indices */ MatcherIndicesIndex(109),
},
{
/* [171] */
/* usage */ core::ParameterUsage::kTexture,
- /* matcher_indices */ MatcherIndicesIndex(107),
+ /* matcher_indices */ MatcherIndicesIndex(111),
},
{
/* [172] */
/* usage */ core::ParameterUsage::kLocation,
- /* matcher_indices */ MatcherIndicesIndex(109),
+ /* matcher_indices */ MatcherIndicesIndex(95),
},
{
/* [173] */
/* usage */ core::ParameterUsage::kTexture,
- /* matcher_indices */ MatcherIndicesIndex(113),
+ /* matcher_indices */ MatcherIndicesIndex(115),
},
{
/* [174] */
/* usage */ core::ParameterUsage::kLocation,
- /* matcher_indices */ MatcherIndicesIndex(109),
+ /* matcher_indices */ MatcherIndicesIndex(95),
},
{
/* [175] */
/* usage */ core::ParameterUsage::kTexture,
- /* matcher_indices */ MatcherIndicesIndex(143),
+ /* matcher_indices */ MatcherIndicesIndex(145),
},
{
/* [176] */
/* usage */ core::ParameterUsage::kLocation,
- /* matcher_indices */ MatcherIndicesIndex(105),
+ /* matcher_indices */ MatcherIndicesIndex(109),
},
{
/* [177] */
/* usage */ core::ParameterUsage::kTexture,
- /* matcher_indices */ MatcherIndicesIndex(144),
+ /* matcher_indices */ MatcherIndicesIndex(146),
},
{
/* [178] */
/* usage */ core::ParameterUsage::kLocation,
- /* matcher_indices */ MatcherIndicesIndex(109),
+ /* matcher_indices */ MatcherIndicesIndex(95),
},
{
/* [179] */
@@ -2176,7 +2208,7 @@
{
/* [180] */
/* usage */ core::ParameterUsage::kLocation,
- /* matcher_indices */ MatcherIndicesIndex(101),
+ /* matcher_indices */ MatcherIndicesIndex(105),
},
{
/* [181] */
@@ -2186,7 +2218,7 @@
{
/* [182] */
/* usage */ core::ParameterUsage::kLocation,
- /* matcher_indices */ MatcherIndicesIndex(105),
+ /* matcher_indices */ MatcherIndicesIndex(109),
},
{
/* [183] */
@@ -2196,7 +2228,7 @@
{
/* [184] */
/* usage */ core::ParameterUsage::kLocation,
- /* matcher_indices */ MatcherIndicesIndex(109),
+ /* matcher_indices */ MatcherIndicesIndex(95),
},
{
/* [185] */
@@ -2206,7 +2238,7 @@
{
/* [186] */
/* usage */ core::ParameterUsage::kLocation,
- /* matcher_indices */ MatcherIndicesIndex(109),
+ /* matcher_indices */ MatcherIndicesIndex(95),
},
{
/* [187] */
@@ -2221,7 +2253,7 @@
{
/* [189] */
/* usage */ core::ParameterUsage::kTexture,
- /* matcher_indices */ MatcherIndicesIndex(99),
+ /* matcher_indices */ MatcherIndicesIndex(103),
},
{
/* [190] */
@@ -2268,6 +2300,16 @@
/* usage */ core::ParameterUsage::kNone,
/* matcher_indices */ MatcherIndicesIndex(44),
},
+ {
+ /* [199] */
+ /* usage */ core::ParameterUsage::kNone,
+ /* matcher_indices */ MatcherIndicesIndex(142),
+ },
+ {
+ /* [200] */
+ /* usage */ core::ParameterUsage::kNone,
+ /* matcher_indices */ MatcherIndicesIndex(143),
+ },
};
static_assert(ParameterIndex::CanIndex(kParameters),
@@ -2409,7 +2451,7 @@
{
/* [22] */
/* name */ "T",
- /* matcher_indices */ MatcherIndicesIndex(142),
+ /* matcher_indices */ MatcherIndicesIndex(144),
/* kind */ TemplateInfo::Kind::kType,
},
{
@@ -2740,7 +2782,7 @@
/* num_templates */ 1,
/* templates */ TemplateIndex(22),
/* parameters */ ParameterIndex(167),
- /* return_matcher_indices */ MatcherIndicesIndex(97),
+ /* return_matcher_indices */ MatcherIndicesIndex(101),
/* const_eval_fn */ ConstEvalFunctionIndex(/* invalid */),
},
{
@@ -2751,7 +2793,7 @@
/* num_templates */ 1,
/* templates */ TemplateIndex(22),
/* parameters */ ParameterIndex(169),
- /* return_matcher_indices */ MatcherIndicesIndex(97),
+ /* return_matcher_indices */ MatcherIndicesIndex(101),
/* const_eval_fn */ ConstEvalFunctionIndex(/* invalid */),
},
{
@@ -2762,7 +2804,7 @@
/* num_templates */ 1,
/* templates */ TemplateIndex(22),
/* parameters */ ParameterIndex(171),
- /* return_matcher_indices */ MatcherIndicesIndex(97),
+ /* return_matcher_indices */ MatcherIndicesIndex(101),
/* const_eval_fn */ ConstEvalFunctionIndex(/* invalid */),
},
{
@@ -2773,7 +2815,7 @@
/* num_templates */ 1,
/* templates */ TemplateIndex(22),
/* parameters */ ParameterIndex(90),
- /* return_matcher_indices */ MatcherIndicesIndex(97),
+ /* return_matcher_indices */ MatcherIndicesIndex(101),
/* const_eval_fn */ ConstEvalFunctionIndex(/* invalid */),
},
{
@@ -2784,7 +2826,7 @@
/* num_templates */ 1,
/* templates */ TemplateIndex(22),
/* parameters */ ParameterIndex(173),
- /* return_matcher_indices */ MatcherIndicesIndex(97),
+ /* return_matcher_indices */ MatcherIndicesIndex(101),
/* const_eval_fn */ ConstEvalFunctionIndex(/* invalid */),
},
{
@@ -2795,7 +2837,7 @@
/* num_templates */ 0,
/* templates */ TemplateIndex(/* invalid */),
/* parameters */ ParameterIndex(175),
- /* return_matcher_indices */ MatcherIndicesIndex(115),
+ /* return_matcher_indices */ MatcherIndicesIndex(117),
/* const_eval_fn */ ConstEvalFunctionIndex(/* invalid */),
},
{
@@ -2806,7 +2848,7 @@
/* num_templates */ 0,
/* templates */ TemplateIndex(/* invalid */),
/* parameters */ ParameterIndex(177),
- /* return_matcher_indices */ MatcherIndicesIndex(115),
+ /* return_matcher_indices */ MatcherIndicesIndex(117),
/* const_eval_fn */ ConstEvalFunctionIndex(/* invalid */),
},
{
@@ -2817,7 +2859,7 @@
/* num_templates */ 0,
/* templates */ TemplateIndex(/* invalid */),
/* parameters */ ParameterIndex(93),
- /* return_matcher_indices */ MatcherIndicesIndex(115),
+ /* return_matcher_indices */ MatcherIndicesIndex(117),
/* const_eval_fn */ ConstEvalFunctionIndex(/* invalid */),
},
{
@@ -2828,7 +2870,7 @@
/* num_templates */ 2,
/* templates */ TemplateIndex(14),
/* parameters */ ParameterIndex(179),
- /* return_matcher_indices */ MatcherIndicesIndex(115),
+ /* return_matcher_indices */ MatcherIndicesIndex(117),
/* const_eval_fn */ ConstEvalFunctionIndex(/* invalid */),
},
{
@@ -2839,7 +2881,7 @@
/* num_templates */ 2,
/* templates */ TemplateIndex(14),
/* parameters */ ParameterIndex(181),
- /* return_matcher_indices */ MatcherIndicesIndex(115),
+ /* return_matcher_indices */ MatcherIndicesIndex(117),
/* const_eval_fn */ ConstEvalFunctionIndex(/* invalid */),
},
{
@@ -2850,7 +2892,7 @@
/* num_templates */ 2,
/* templates */ TemplateIndex(14),
/* parameters */ ParameterIndex(183),
- /* return_matcher_indices */ MatcherIndicesIndex(115),
+ /* return_matcher_indices */ MatcherIndicesIndex(117),
/* const_eval_fn */ ConstEvalFunctionIndex(/* invalid */),
},
{
@@ -2861,7 +2903,7 @@
/* num_templates */ 2,
/* templates */ TemplateIndex(14),
/* parameters */ ParameterIndex(185),
- /* return_matcher_indices */ MatcherIndicesIndex(115),
+ /* return_matcher_indices */ MatcherIndicesIndex(117),
/* const_eval_fn */ ConstEvalFunctionIndex(/* invalid */),
},
{
@@ -2872,7 +2914,7 @@
/* num_templates */ 2,
/* templates */ TemplateIndex(16),
/* parameters */ ParameterIndex(179),
- /* return_matcher_indices */ MatcherIndicesIndex(117),
+ /* return_matcher_indices */ MatcherIndicesIndex(97),
/* const_eval_fn */ ConstEvalFunctionIndex(/* invalid */),
},
{
@@ -2883,7 +2925,7 @@
/* num_templates */ 2,
/* templates */ TemplateIndex(16),
/* parameters */ ParameterIndex(181),
- /* return_matcher_indices */ MatcherIndicesIndex(117),
+ /* return_matcher_indices */ MatcherIndicesIndex(97),
/* const_eval_fn */ ConstEvalFunctionIndex(/* invalid */),
},
{
@@ -2894,7 +2936,7 @@
/* num_templates */ 2,
/* templates */ TemplateIndex(16),
/* parameters */ ParameterIndex(183),
- /* return_matcher_indices */ MatcherIndicesIndex(117),
+ /* return_matcher_indices */ MatcherIndicesIndex(97),
/* const_eval_fn */ ConstEvalFunctionIndex(/* invalid */),
},
{
@@ -2905,7 +2947,7 @@
/* num_templates */ 2,
/* templates */ TemplateIndex(16),
/* parameters */ ParameterIndex(185),
- /* return_matcher_indices */ MatcherIndicesIndex(117),
+ /* return_matcher_indices */ MatcherIndicesIndex(97),
/* const_eval_fn */ ConstEvalFunctionIndex(/* invalid */),
},
{
@@ -2916,7 +2958,7 @@
/* num_templates */ 2,
/* templates */ TemplateIndex(18),
/* parameters */ ParameterIndex(179),
- /* return_matcher_indices */ MatcherIndicesIndex(109),
+ /* return_matcher_indices */ MatcherIndicesIndex(95),
/* const_eval_fn */ ConstEvalFunctionIndex(/* invalid */),
},
{
@@ -2927,7 +2969,7 @@
/* num_templates */ 2,
/* templates */ TemplateIndex(18),
/* parameters */ ParameterIndex(181),
- /* return_matcher_indices */ MatcherIndicesIndex(109),
+ /* return_matcher_indices */ MatcherIndicesIndex(95),
/* const_eval_fn */ ConstEvalFunctionIndex(/* invalid */),
},
{
@@ -2938,7 +2980,7 @@
/* num_templates */ 2,
/* templates */ TemplateIndex(18),
/* parameters */ ParameterIndex(183),
- /* return_matcher_indices */ MatcherIndicesIndex(109),
+ /* return_matcher_indices */ MatcherIndicesIndex(95),
/* const_eval_fn */ ConstEvalFunctionIndex(/* invalid */),
},
{
@@ -2949,7 +2991,7 @@
/* num_templates */ 2,
/* templates */ TemplateIndex(18),
/* parameters */ ParameterIndex(185),
- /* return_matcher_indices */ MatcherIndicesIndex(109),
+ /* return_matcher_indices */ MatcherIndicesIndex(95),
/* const_eval_fn */ ConstEvalFunctionIndex(/* invalid */),
},
{
@@ -3251,24 +3293,24 @@
},
{
/* [75] */
- /* 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(165),
- /* return_matcher_indices */ MatcherIndicesIndex(119),
+ /* parameters */ ParameterIndex(199),
+ /* return_matcher_indices */ MatcherIndicesIndex(95),
/* const_eval_fn */ ConstEvalFunctionIndex(/* invalid */),
},
{
/* [76] */
- /* 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(165),
- /* return_matcher_indices */ MatcherIndicesIndex(121),
+ /* parameters */ ParameterIndex(200),
+ /* return_matcher_indices */ MatcherIndicesIndex(97),
/* const_eval_fn */ ConstEvalFunctionIndex(/* invalid */),
},
{
@@ -3279,7 +3321,7 @@
/* num_templates */ 0,
/* templates */ TemplateIndex(/* invalid */),
/* parameters */ ParameterIndex(165),
- /* return_matcher_indices */ MatcherIndicesIndex(117),
+ /* return_matcher_indices */ MatcherIndicesIndex(119),
/* const_eval_fn */ ConstEvalFunctionIndex(/* invalid */),
},
{
@@ -3290,7 +3332,7 @@
/* num_templates */ 0,
/* templates */ TemplateIndex(/* invalid */),
/* parameters */ ParameterIndex(165),
- /* return_matcher_indices */ MatcherIndicesIndex(19),
+ /* return_matcher_indices */ MatcherIndicesIndex(121),
/* const_eval_fn */ ConstEvalFunctionIndex(/* invalid */),
},
{
@@ -3301,7 +3343,7 @@
/* num_templates */ 0,
/* templates */ TemplateIndex(/* invalid */),
/* parameters */ ParameterIndex(165),
- /* return_matcher_indices */ MatcherIndicesIndex(84),
+ /* return_matcher_indices */ MatcherIndicesIndex(97),
/* const_eval_fn */ ConstEvalFunctionIndex(/* invalid */),
},
{
@@ -3312,7 +3354,7 @@
/* num_templates */ 0,
/* templates */ TemplateIndex(/* invalid */),
/* parameters */ ParameterIndex(165),
- /* return_matcher_indices */ MatcherIndicesIndex(72),
+ /* return_matcher_indices */ MatcherIndicesIndex(19),
/* const_eval_fn */ ConstEvalFunctionIndex(/* invalid */),
},
{
@@ -3323,12 +3365,34 @@
/* num_templates */ 0,
/* templates */ TemplateIndex(/* invalid */),
/* parameters */ ParameterIndex(165),
- /* return_matcher_indices */ MatcherIndicesIndex(123),
+ /* return_matcher_indices */ MatcherIndicesIndex(84),
/* const_eval_fn */ ConstEvalFunctionIndex(/* invalid */),
},
{
/* [82] */
/* 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(165),
+ /* return_matcher_indices */ MatcherIndicesIndex(72),
+ /* const_eval_fn */ ConstEvalFunctionIndex(/* invalid */),
+ },
+ {
+ /* [83] */
+ /* 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(165),
+ /* return_matcher_indices */ MatcherIndicesIndex(123),
+ /* const_eval_fn */ ConstEvalFunctionIndex(/* invalid */),
+ },
+ {
+ /* [84] */
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline, OverloadFlag::kMemberFunction),
/* num_parameters */ 3,
/* num_explicit_templates */ 0,
/* num_templates */ 0,
@@ -3338,7 +3402,7 @@
/* const_eval_fn */ ConstEvalFunctionIndex(/* invalid */),
},
{
- /* [83] */
+ /* [85] */
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline, OverloadFlag::kMemberFunction),
/* num_parameters */ 3,
/* num_explicit_templates */ 0,
@@ -3349,7 +3413,7 @@
/* const_eval_fn */ ConstEvalFunctionIndex(/* invalid */),
},
{
- /* [84] */
+ /* [86] */
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline, OverloadFlag::kMemberFunction),
/* num_parameters */ 3,
/* num_explicit_templates */ 0,
@@ -3360,7 +3424,7 @@
/* const_eval_fn */ ConstEvalFunctionIndex(/* invalid */),
},
{
- /* [85] */
+ /* [87] */
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline, OverloadFlag::kMemberFunction),
/* num_parameters */ 3,
/* num_explicit_templates */ 0,
@@ -3428,6 +3492,18 @@
},
{
/* [7] */
+ /* fn unpack_s8s32(int8_t4_packed) -> vec4<i32> */
+ /* num overloads */ 1,
+ /* overloads */ OverloadIndex(75),
+ },
+ {
+ /* [8] */
+ /* fn unpack_u8u32(uint8_t4_packed) -> vec4<u32> */
+ /* num overloads */ 1,
+ /* overloads */ OverloadIndex(76),
+ },
+ {
+ /* [9] */
/* fn Load(byte_address_buffer<readable>, offset: u32) -> u32 */
/* fn Load[T : fiu32](texture: texture_1d<T>, location: vec2<i32>) -> vec4<T> */
/* fn Load[T : fiu32](texture: texture_2d<T>, location: vec3<i32>) -> vec4<T> */
@@ -3453,73 +3529,73 @@
/* overloads */ OverloadIndex(27),
},
{
- /* [8] */
- /* fn Load2(byte_address_buffer<readable>, offset: u32) -> vec2<u32> */
- /* num overloads */ 1,
- /* overloads */ OverloadIndex(75),
- },
- {
- /* [9] */
- /* fn Load3(byte_address_buffer<readable>, offset: u32) -> vec3<u32> */
- /* num overloads */ 1,
- /* overloads */ OverloadIndex(76),
- },
- {
/* [10] */
- /* fn Load4(byte_address_buffer<readable>, offset: u32) -> vec4<u32> */
+ /* fn Load2(byte_address_buffer<readable>, offset: u32) -> vec2<u32> */
/* num overloads */ 1,
/* overloads */ OverloadIndex(77),
},
{
/* [11] */
- /* fn LoadF16(byte_address_buffer<readable>, offset: u32) -> f16 */
+ /* fn Load3(byte_address_buffer<readable>, offset: u32) -> vec3<u32> */
/* num overloads */ 1,
/* overloads */ OverloadIndex(78),
},
{
/* [12] */
- /* fn Load2F16(byte_address_buffer<readable>, offset: u32) -> vec2<f16> */
+ /* fn Load4(byte_address_buffer<readable>, offset: u32) -> vec4<u32> */
/* num overloads */ 1,
/* overloads */ OverloadIndex(79),
},
{
/* [13] */
- /* fn Load3F16(byte_address_buffer<readable>, offset: u32) -> vec3<f16> */
+ /* fn LoadF16(byte_address_buffer<readable>, offset: u32) -> f16 */
/* num overloads */ 1,
/* overloads */ OverloadIndex(80),
},
{
/* [14] */
- /* fn Load4F16(byte_address_buffer<readable>, offset: u32) -> vec4<f16> */
+ /* fn Load2F16(byte_address_buffer<readable>, offset: u32) -> vec2<f16> */
/* num overloads */ 1,
/* overloads */ OverloadIndex(81),
},
{
/* [15] */
- /* fn Store(byte_address_buffer<writable>, offset: u32, value: u32) */
+ /* fn Load3F16(byte_address_buffer<readable>, offset: u32) -> vec3<f16> */
/* num overloads */ 1,
/* overloads */ OverloadIndex(82),
},
{
/* [16] */
- /* fn Store2(byte_address_buffer<writable>, offset: u32, value: vec2<u32>) */
+ /* fn Load4F16(byte_address_buffer<readable>, offset: u32) -> vec4<f16> */
/* num overloads */ 1,
/* overloads */ OverloadIndex(83),
},
{
/* [17] */
- /* fn Store3(byte_address_buffer<writable>, offset: u32, value: vec3<u32>) */
+ /* fn Store(byte_address_buffer<writable>, offset: u32, value: u32) */
/* num overloads */ 1,
/* overloads */ OverloadIndex(84),
},
{
/* [18] */
- /* fn Store4(byte_address_buffer<writable>, offset: u32, value: vec4<u32>) */
+ /* fn Store2(byte_address_buffer<writable>, offset: u32, value: vec2<u32>) */
/* num overloads */ 1,
/* overloads */ OverloadIndex(85),
},
{
/* [19] */
+ /* fn Store3(byte_address_buffer<writable>, offset: u32, value: vec3<u32>) */
+ /* num overloads */ 1,
+ /* overloads */ OverloadIndex(86),
+ },
+ {
+ /* [20] */
+ /* fn Store4(byte_address_buffer<writable>, offset: u32, value: vec4<u32>) */
+ /* num overloads */ 1,
+ /* overloads */ OverloadIndex(87),
+ },
+ {
+ /* [21] */
/* fn GetDimensions[A : access](byte_address_buffer<A>, width: ptr<function, u32, writable>) */
/* fn GetDimensions[T : fiu32](texture: texture_1d<T>, width: ptr<function, u32, writable>) */
/* fn GetDimensions[T : fiu32](texture: texture_1d<T>, level: u32, width: ptr<function, u32, writable>, num_levels: ptr<function, u32, writable>) */
@@ -3551,7 +3627,7 @@
/* overloads */ OverloadIndex(0),
},
{
- /* [20] */
+ /* [22] */
/* fn textureStore[C : iu32](texture: texture_storage_1d<f32_texel_format, writable>, coords: C, value: vec4<f32>) */
/* fn textureStore[C : iu32](texture: texture_storage_2d<f32_texel_format, writable>, coords: vec2<C>, value: vec4<f32>) */
/* fn textureStore[C : iu32](texture: texture_storage_2d_array<f32_texel_format, writable>, coords: vec3<C>, value: vec4<f32>) */
diff --git a/src/tint/lang/hlsl/intrinsic/type_matchers.h b/src/tint/lang/hlsl/intrinsic/type_matchers.h
index e99c48b..1d76522 100644
--- a/src/tint/lang/hlsl/intrinsic/type_matchers.h
+++ b/src/tint/lang/hlsl/intrinsic/type_matchers.h
@@ -31,6 +31,8 @@
#include "src/tint/lang/core/intrinsic/table.h"
#include "src/tint/lang/core/type/manager.h"
#include "src/tint/lang/hlsl/type/byte_address_buffer.h"
+#include "src/tint/lang/hlsl/type/int8_t4_packed.h"
+#include "src/tint/lang/hlsl/type/uint8_t4_packed.h"
namespace tint::hlsl::intrinsic {
@@ -50,6 +52,24 @@
return state.types.Get<type::ByteAddressBuffer>(static_cast<core::Access>(A.Value()));
}
+inline bool MatchInt8T4Packed(core::intrinsic::MatchState&, const core::type::Type* ty) {
+ return ty->Is<type::Int8T4Packed>();
+}
+
+inline const type::Int8T4Packed* BuildInt8T4Packed(core::intrinsic::MatchState& state,
+ const core::type::Type*) {
+ return state.types.Get<type::Int8T4Packed>();
+}
+
+inline bool MatchUint8T4Packed(core::intrinsic::MatchState&, const core::type::Type* ty) {
+ return ty->Is<type::Uint8T4Packed>();
+}
+
+inline const type::Uint8T4Packed* BuildUint8T4Packed(core::intrinsic::MatchState& state,
+ const core::type::Type*) {
+ return state.types.Get<type::Uint8T4Packed>();
+}
+
} // namespace tint::hlsl::intrinsic
#endif // SRC_TINT_LANG_HLSL_INTRINSIC_TYPE_MATCHERS_H_
diff --git a/src/tint/lang/hlsl/type/BUILD.bazel b/src/tint/lang/hlsl/type/BUILD.bazel
index 96620ca..fbf73a0 100644
--- a/src/tint/lang/hlsl/type/BUILD.bazel
+++ b/src/tint/lang/hlsl/type/BUILD.bazel
@@ -40,9 +40,13 @@
name = "type",
srcs = [
"byte_address_buffer.cc",
+ "int8_t4_packed.cc",
+ "uint8_t4_packed.cc",
],
hdrs = [
"byte_address_buffer.h",
+ "int8_t4_packed.h",
+ "uint8_t4_packed.h",
],
deps = [
"//src/tint/lang/core",
@@ -69,6 +73,8 @@
alwayslink = True,
srcs = [
"byte_address_buffer_test.cc",
+ "int8_t4_packed_test.cc",
+ "uint8_t4_packed_test.cc",
],
deps = [
"//src/tint/lang/core",
diff --git a/src/tint/lang/hlsl/type/BUILD.cmake b/src/tint/lang/hlsl/type/BUILD.cmake
index ac50dd3..49b481b 100644
--- a/src/tint/lang/hlsl/type/BUILD.cmake
+++ b/src/tint/lang/hlsl/type/BUILD.cmake
@@ -41,6 +41,10 @@
tint_add_target(tint_lang_hlsl_type lib
lang/hlsl/type/byte_address_buffer.cc
lang/hlsl/type/byte_address_buffer.h
+ lang/hlsl/type/int8_t4_packed.cc
+ lang/hlsl/type/int8_t4_packed.h
+ lang/hlsl/type/uint8_t4_packed.cc
+ lang/hlsl/type/uint8_t4_packed.h
)
tint_target_add_dependencies(tint_lang_hlsl_type lib
@@ -67,6 +71,8 @@
################################################################################
tint_add_target(tint_lang_hlsl_type_test test
lang/hlsl/type/byte_address_buffer_test.cc
+ lang/hlsl/type/int8_t4_packed_test.cc
+ lang/hlsl/type/uint8_t4_packed_test.cc
)
tint_target_add_dependencies(tint_lang_hlsl_type_test test
diff --git a/src/tint/lang/hlsl/type/BUILD.gn b/src/tint/lang/hlsl/type/BUILD.gn
index cf5bf71..b4c1a07 100644
--- a/src/tint/lang/hlsl/type/BUILD.gn
+++ b/src/tint/lang/hlsl/type/BUILD.gn
@@ -46,6 +46,10 @@
sources = [
"byte_address_buffer.cc",
"byte_address_buffer.h",
+ "int8_t4_packed.cc",
+ "int8_t4_packed.h",
+ "uint8_t4_packed.cc",
+ "uint8_t4_packed.h",
]
deps = [
"${tint_src_dir}/lang/core",
@@ -67,7 +71,11 @@
}
if (tint_build_unittests) {
tint_unittests_source_set("unittests") {
- sources = [ "byte_address_buffer_test.cc" ]
+ sources = [
+ "byte_address_buffer_test.cc",
+ "int8_t4_packed_test.cc",
+ "uint8_t4_packed_test.cc",
+ ]
deps = [
"${tint_src_dir}:gmock_and_gtest",
"${tint_src_dir}/lang/core",
diff --git a/src/tint/lang/hlsl/type/int8_t4_packed.cc b/src/tint/lang/hlsl/type/int8_t4_packed.cc
new file mode 100644
index 0000000..20a1f1e
--- /dev/null
+++ b/src/tint/lang/hlsl/type/int8_t4_packed.cc
@@ -0,0 +1,61 @@
+// Copyright 2024 The Dawn & Tint Authors
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// 1. Redistributions of source code must retain the above copyright notice, this
+// list of conditions and the following disclaimer.
+//
+// 2. Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// 3. Neither the name of the copyright holder nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include "src/tint/lang/hlsl/type/int8_t4_packed.h"
+
+#include <cstddef>
+#include <string>
+
+#include "src/tint/lang/core/type/clone_context.h"
+#include "src/tint/lang/core/type/manager.h"
+#include "src/tint/lang/core/type/unique_node.h"
+#include "src/tint/utils/math/hash.h"
+#include "src/tint/utils/rtti/castable.h"
+
+TINT_INSTANTIATE_TYPEINFO(tint::hlsl::type::Int8T4Packed);
+
+namespace tint::hlsl::type {
+
+Int8T4Packed::Int8T4Packed()
+ : Base(static_cast<size_t>(Hash(tint::TypeCode::Of<Int8T4Packed>().bits)),
+ core::type::Flags{}) {}
+
+bool Int8T4Packed::Equals([[maybe_unused]] const UniqueNode& other) const {
+ return true;
+}
+
+std::string Int8T4Packed::FriendlyName() const {
+ StringStream out;
+ out << "hlsl.int8_t4_packed";
+ return out.str();
+}
+
+Int8T4Packed* Int8T4Packed::Clone(core::type::CloneContext& ctx) const {
+ return ctx.dst.mgr->Get<Int8T4Packed>();
+}
+
+} // namespace tint::hlsl::type
diff --git a/src/tint/lang/hlsl/type/int8_t4_packed.h b/src/tint/lang/hlsl/type/int8_t4_packed.h
new file mode 100644
index 0000000..2eceb2a
--- /dev/null
+++ b/src/tint/lang/hlsl/type/int8_t4_packed.h
@@ -0,0 +1,57 @@
+// Copyright 2024 The Dawn & Tint Authors
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// 1. Redistributions of source code must retain the above copyright notice, this
+// list of conditions and the following disclaimer.
+//
+// 2. Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// 3. Neither the name of the copyright holder nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef SRC_TINT_LANG_HLSL_TYPE_INT8_T4_PACKED_H_
+#define SRC_TINT_LANG_HLSL_TYPE_INT8_T4_PACKED_H_
+
+#include <string>
+
+#include "src/tint/lang/core/type/type.h"
+
+namespace tint::hlsl::type {
+
+/// Int8T4Packed represents a packed int8 vector
+class Int8T4Packed final : public Castable<Int8T4Packed, core::type::Type> {
+ public:
+ /// Constructor
+ Int8T4Packed();
+
+ /// @param other the other node to compare against
+ /// @returns true if the this type is equal to @p other
+ bool Equals(const UniqueNode& other) const override;
+
+ /// @returns the friendly name for this type
+ std::string FriendlyName() const override;
+
+ /// @param ctx the clone context
+ /// @returns a clone of this type
+ Int8T4Packed* Clone(core::type::CloneContext& ctx) const override;
+};
+
+} // namespace tint::hlsl::type
+
+#endif // SRC_TINT_LANG_HLSL_TYPE_INT8_T4_PACKED_H_
diff --git a/src/tint/lang/hlsl/type/int8_t4_packed_test.cc b/src/tint/lang/hlsl/type/int8_t4_packed_test.cc
new file mode 100644
index 0000000..955d7ed
--- /dev/null
+++ b/src/tint/lang/hlsl/type/int8_t4_packed_test.cc
@@ -0,0 +1,52 @@
+// Copyright 2024 The Dawn & Tint Authors
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// 1. Redistributions of source code must retain the above copyright notice, this
+// list of conditions and the following disclaimer.
+//
+// 2. Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// 3. Neither the name of the copyright holder nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include "src/tint/lang/hlsl/type/int8_t4_packed.h"
+
+#include <gtest/gtest.h>
+
+#include "src/tint/lang/core/type/f32.h"
+#include "src/tint/lang/core/type/i32.h"
+
+namespace tint::hlsl::type {
+namespace {
+
+TEST(HlslTypeInt8T4Packed, Equals) {
+ const Int8T4Packed a;
+ const Int8T4Packed b;
+
+ EXPECT_TRUE(a.Equals(b));
+}
+
+TEST(HlslTypeInt8T4Packed, FriendlyName) {
+ const Int8T4Packed l;
+
+ EXPECT_EQ(l.FriendlyName(), "hlsl.int8_t4_packed");
+}
+
+} // namespace
+} // namespace tint::hlsl::type
diff --git a/src/tint/lang/hlsl/type/uint8_t4_packed.cc b/src/tint/lang/hlsl/type/uint8_t4_packed.cc
new file mode 100644
index 0000000..962a6cb
--- /dev/null
+++ b/src/tint/lang/hlsl/type/uint8_t4_packed.cc
@@ -0,0 +1,61 @@
+// Copyright 2024 The Dawn & Tint Authors
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// 1. Redistributions of source code must retain the above copyright notice, this
+// list of conditions and the following disclaimer.
+//
+// 2. Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// 3. Neither the name of the copyright holder nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include "src/tint/lang/hlsl/type/uint8_t4_packed.h"
+
+#include <cstddef>
+#include <string>
+
+#include "src/tint/lang/core/type/clone_context.h"
+#include "src/tint/lang/core/type/manager.h"
+#include "src/tint/lang/core/type/unique_node.h"
+#include "src/tint/utils/math/hash.h"
+#include "src/tint/utils/rtti/castable.h"
+
+TINT_INSTANTIATE_TYPEINFO(tint::hlsl::type::Uint8T4Packed);
+
+namespace tint::hlsl::type {
+
+Uint8T4Packed::Uint8T4Packed()
+ : Base(static_cast<size_t>(Hash(tint::TypeCode::Of<Uint8T4Packed>().bits)),
+ core::type::Flags{}) {}
+
+bool Uint8T4Packed::Equals([[maybe_unused]] const UniqueNode& other) const {
+ return true;
+}
+
+std::string Uint8T4Packed::FriendlyName() const {
+ StringStream out;
+ out << "hlsl.uint8_t4_packed";
+ return out.str();
+}
+
+Uint8T4Packed* Uint8T4Packed::Clone(core::type::CloneContext& ctx) const {
+ return ctx.dst.mgr->Get<Uint8T4Packed>();
+}
+
+} // namespace tint::hlsl::type
diff --git a/src/tint/lang/hlsl/type/uint8_t4_packed.h b/src/tint/lang/hlsl/type/uint8_t4_packed.h
new file mode 100644
index 0000000..d2ecff6
--- /dev/null
+++ b/src/tint/lang/hlsl/type/uint8_t4_packed.h
@@ -0,0 +1,57 @@
+// Copyright 2024 The Dawn & Tint Authors
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// 1. Redistributions of source code must retain the above copyright notice, this
+// list of conditions and the following disclaimer.
+//
+// 2. Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// 3. Neither the name of the copyright holder nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef SRC_TINT_LANG_HLSL_TYPE_UINT8_T4_PACKED_H_
+#define SRC_TINT_LANG_HLSL_TYPE_UINT8_T4_PACKED_H_
+
+#include <string>
+
+#include "src/tint/lang/core/type/type.h"
+
+namespace tint::hlsl::type {
+
+/// Uint8T4Packed represents a packed unsigned int vector
+class Uint8T4Packed final : public Castable<Uint8T4Packed, core::type::Type> {
+ public:
+ /// Constructor
+ Uint8T4Packed();
+
+ /// @param other the other node to compare against
+ /// @returns true if the this type is equal to @p other
+ bool Equals(const UniqueNode& other) const override;
+
+ /// @returns the friendly name for this type
+ std::string FriendlyName() const override;
+
+ /// @param ctx the clone context
+ /// @returns a clone of this type
+ Uint8T4Packed* Clone(core::type::CloneContext& ctx) const override;
+};
+
+} // namespace tint::hlsl::type
+
+#endif // SRC_TINT_LANG_HLSL_TYPE_UINT8_T4_PACKED_H_
diff --git a/src/tint/lang/hlsl/type/uint8_t4_packed_test.cc b/src/tint/lang/hlsl/type/uint8_t4_packed_test.cc
new file mode 100644
index 0000000..af44acd
--- /dev/null
+++ b/src/tint/lang/hlsl/type/uint8_t4_packed_test.cc
@@ -0,0 +1,52 @@
+// Copyright 2024 The Dawn & Tint Authors
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// 1. Redistributions of source code must retain the above copyright notice, this
+// list of conditions and the following disclaimer.
+//
+// 2. Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// 3. Neither the name of the copyright holder nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include "src/tint/lang/hlsl/type/uint8_t4_packed.h"
+
+#include <gtest/gtest.h>
+
+#include "src/tint/lang/core/type/f32.h"
+#include "src/tint/lang/core/type/i32.h"
+
+namespace tint::hlsl::type {
+namespace {
+
+TEST(HlslTypeUint8T4Packed, Equals) {
+ const Uint8T4Packed a;
+ const Uint8T4Packed b;
+
+ EXPECT_TRUE(a.Equals(b));
+}
+
+TEST(HlslTypeUint8T4Packed, FriendlyName) {
+ const Uint8T4Packed l;
+
+ EXPECT_EQ(l.FriendlyName(), "hlsl.uint8_t4_packed");
+}
+
+} // namespace
+} // namespace tint::hlsl::type
diff --git a/src/tint/lang/hlsl/writer/builtin_test.cc b/src/tint/lang/hlsl/writer/builtin_test.cc
index 795b93f..64ea3a5 100644
--- a/src/tint/lang/hlsl/writer/builtin_test.cc
+++ b/src/tint/lang/hlsl/writer/builtin_test.cc
@@ -1318,5 +1318,182 @@
)");
}
+TEST_F(HlslWriterTest, BuiltinUnpack2x16Float) {
+ auto* func = b.Function("foo", ty.void_(), core::ir::Function::PipelineStage::kFragment);
+ b.Append(func->Block(), [&] {
+ auto* u = b.Var("u", 2_u);
+ b.Let("a", b.Call(ty.vec2<f32>(), core::BuiltinFn::kUnpack2X16Float, b.Load(u)));
+ b.Return(func);
+ });
+
+ ASSERT_TRUE(Generate()) << err_ << output_.hlsl;
+ EXPECT_EQ(output_.hlsl, R"(
+void foo() {
+ uint u = 2u;
+ uint v = u;
+ float2 a = f16tof32(uint2((v & 65535u), (v >> 16u)));
+}
+
+)");
+}
+
+TEST_F(HlslWriterTest, BuiltinUnpack2x16Snorm) {
+ auto* func = b.Function("foo", ty.void_(), core::ir::Function::PipelineStage::kFragment);
+ b.Append(func->Block(), [&] {
+ auto* u = b.Var("u", 2_u);
+ b.Let("a", b.Call(ty.vec2<f32>(), core::BuiltinFn::kUnpack2X16Snorm, b.Load(u)));
+ b.Return(func);
+ });
+
+ ASSERT_TRUE(Generate()) << err_ << output_.hlsl;
+ EXPECT_EQ(output_.hlsl, R"(
+void foo() {
+ uint u = 2u;
+ int v = int(u);
+ float2 a = clamp((float2((int2((v << 16u), v) >> (16u).xx)) / 32767.0f), (-1.0f).xx, (1.0f).xx);
+}
+
+)");
+}
+
+TEST_F(HlslWriterTest, BuiltinUnpack2x16Unorm) {
+ auto* func = b.Function("foo", ty.void_(), core::ir::Function::PipelineStage::kFragment);
+ b.Append(func->Block(), [&] {
+ auto* u = b.Var("u", 2_u);
+ b.Let("a", b.Call(ty.vec2<f32>(), core::BuiltinFn::kUnpack2X16Unorm, b.Load(u)));
+ b.Return(func);
+ });
+
+ ASSERT_TRUE(Generate()) << err_ << output_.hlsl;
+ EXPECT_EQ(output_.hlsl, R"(
+void foo() {
+ uint u = 2u;
+ uint v = u;
+ float2 a = (float2(uint2((v & 65535u), (v >> 16u))) / 65535.0f);
+}
+
+)");
+}
+
+TEST_F(HlslWriterTest, BuiltinUnpack4x8Snorm) {
+ auto* func = b.Function("foo", ty.void_(), core::ir::Function::PipelineStage::kFragment);
+ b.Append(func->Block(), [&] {
+ auto* u = b.Var("u", 2_u);
+ b.Let("a", b.Call(ty.vec4<f32>(), core::BuiltinFn::kUnpack4X8Snorm, b.Load(u)));
+ b.Return(func);
+ });
+
+ ASSERT_TRUE(Generate()) << err_ << output_.hlsl;
+ EXPECT_EQ(output_.hlsl, R"(
+void foo() {
+ uint u = 2u;
+ int v = int(u);
+ float4 a = clamp((float4((int4((v << 24u), (v << 16u), (v << 8u), v) >> (24u).xxxx)) / 127.0f), (-1.0f).xxxx, (1.0f).xxxx);
+}
+
+)");
+}
+
+TEST_F(HlslWriterTest, BuiltinUnpack4x8Unorm) {
+ auto* func = b.Function("foo", ty.void_(), core::ir::Function::PipelineStage::kFragment);
+ b.Append(func->Block(), [&] {
+ auto* u = b.Var("u", 2_u);
+ b.Let("a", b.Call(ty.vec4<f32>(), core::BuiltinFn::kUnpack4X8Unorm, b.Load(u)));
+ b.Return(func);
+ });
+
+ ASSERT_TRUE(Generate()) << err_ << output_.hlsl;
+ EXPECT_EQ(output_.hlsl, R"(
+void foo() {
+ uint u = 2u;
+ uint v = u;
+ float4 a = (float4(uint4((v & 255u), ((v >> 8u) & 255u), ((v >> 16u) & 255u), (v >> 24u))) / 255.0f);
+}
+
+)");
+}
+
+TEST_F(HlslWriterTest, BuiltinUnpack4xI8CorePolyfill) {
+ auto* func = b.Function("foo", ty.void_(), core::ir::Function::PipelineStage::kFragment);
+ b.Append(func->Block(), [&] {
+ auto* u = b.Var("u", 2_u);
+ b.Let("a", b.Call(ty.vec4<i32>(), core::BuiltinFn::kUnpack4XI8, b.Load(u)));
+ b.Return(func);
+ });
+
+ Options opts{};
+ opts.polyfill_pack_unpack_4x8 = true;
+ ASSERT_TRUE(Generate(opts)) << err_ << output_.hlsl;
+ EXPECT_EQ(output_.hlsl, R"(
+void foo() {
+ uint u = 2u;
+ uint v = u;
+ uint4 v_1 = uint4(24u, 16u, 8u, 0u);
+ int4 v_2 = asint((uint4((v).xxxx) << v_1));
+ int4 a = (v_2 >> uint4((24u).xxxx));
+}
+
+)");
+}
+
+TEST_F(HlslWriterTest, BuiltinUnpack4xI8) {
+ auto* func = b.Function("foo", ty.void_(), core::ir::Function::PipelineStage::kFragment);
+ b.Append(func->Block(), [&] {
+ auto* u = b.Var("u", 2_u);
+ b.Let("a", b.Call(ty.vec4<i32>(), core::BuiltinFn::kUnpack4XI8, b.Load(u)));
+ b.Return(func);
+ });
+
+ ASSERT_TRUE(Generate()) << err_ << output_.hlsl;
+ EXPECT_EQ(output_.hlsl, R"(
+void foo() {
+ uint u = 2u;
+ int4 a = unpack_s8s32(int8_t4_packed(u));
+}
+
+)");
+}
+
+TEST_F(HlslWriterTest, BuiltinUnpack4xU8CorePolyfill) {
+ auto* func = b.Function("foo", ty.void_(), core::ir::Function::PipelineStage::kFragment);
+ b.Append(func->Block(), [&] {
+ auto* u = b.Var("u", 2_u);
+ b.Let("a", b.Call(ty.vec4<u32>(), core::BuiltinFn::kUnpack4XU8, b.Load(u)));
+ b.Return(func);
+ });
+
+ Options opts{};
+ opts.polyfill_pack_unpack_4x8 = true;
+ ASSERT_TRUE(Generate(opts)) << err_ << output_.hlsl;
+ EXPECT_EQ(output_.hlsl, R"(
+void foo() {
+ uint u = 2u;
+ uint v = u;
+ uint4 v_1 = uint4(0u, 8u, 16u, 24u);
+ uint4 v_2 = (uint4((v).xxxx) >> v_1);
+ uint4 a = (v_2 & uint4((255u).xxxx));
+}
+
+)");
+}
+
+TEST_F(HlslWriterTest, BuiltinUnpack4xU8) {
+ auto* func = b.Function("foo", ty.void_(), core::ir::Function::PipelineStage::kFragment);
+ b.Append(func->Block(), [&] {
+ auto* u = b.Var("u", 2_u);
+ b.Let("a", b.Call(ty.vec4<u32>(), core::BuiltinFn::kUnpack4XU8, b.Load(u)));
+ b.Return(func);
+ });
+
+ ASSERT_TRUE(Generate()) << err_ << output_.hlsl;
+ EXPECT_EQ(output_.hlsl, R"(
+void foo() {
+ uint u = 2u;
+ uint4 a = unpack_u8u32(uint8_t4_packed(u));
+}
+
+)");
+}
+
} // namespace
} // namespace tint::hlsl::writer
diff --git a/src/tint/lang/hlsl/writer/printer/printer.cc b/src/tint/lang/hlsl/writer/printer/printer.cc
index c330bde..1f247a7 100644
--- a/src/tint/lang/hlsl/writer/printer/printer.cc
+++ b/src/tint/lang/hlsl/writer/printer/printer.cc
@@ -107,6 +107,8 @@
#include "src/tint/lang/hlsl/ir/member_builtin_call.h"
#include "src/tint/lang/hlsl/ir/ternary.h"
#include "src/tint/lang/hlsl/type/byte_address_buffer.h"
+#include "src/tint/lang/hlsl/type/int8_t4_packed.h"
+#include "src/tint/lang/hlsl/type/uint8_t4_packed.h"
#include "src/tint/utils/containers/hashmap.h"
#include "src/tint/utils/containers/map.h"
#include "src/tint/utils/generator/text_generator.h"
@@ -1221,6 +1223,9 @@
}
out << "ByteAddressBuffer";
},
+ [&](const hlsl::type::Int8T4Packed*) { out << "int8_t4_packed"; },
+ [&](const hlsl::type::Uint8T4Packed*) { out << "uint8_t4_packed"; },
+
[&](const core::type::Bool*) { out << "bool"; }, //
[&](const core::type::F16*) { out << "float16_t"; }, //
[&](const core::type::F32*) { out << "float"; }, //
diff --git a/src/tint/lang/hlsl/writer/raise/builtin_polyfill.cc b/src/tint/lang/hlsl/writer/raise/builtin_polyfill.cc
index 7552384..80274c7 100644
--- a/src/tint/lang/hlsl/writer/raise/builtin_polyfill.cc
+++ b/src/tint/lang/hlsl/writer/raise/builtin_polyfill.cc
@@ -47,6 +47,8 @@
#include "src/tint/lang/hlsl/ir/builtin_call.h"
#include "src/tint/lang/hlsl/ir/member_builtin_call.h"
#include "src/tint/lang/hlsl/ir/ternary.h"
+#include "src/tint/lang/hlsl/type/int8_t4_packed.h"
+#include "src/tint/lang/hlsl/type/uint8_t4_packed.h"
#include "src/tint/utils/containers/hashmap.h"
#include "src/tint/utils/math/hash.h"
@@ -94,6 +96,13 @@
case core::BuiltinFn::kTextureNumSamples:
case core::BuiltinFn::kTextureStore:
case core::BuiltinFn::kTrunc:
+ case core::BuiltinFn::kUnpack2X16Float:
+ case core::BuiltinFn::kUnpack2X16Snorm:
+ case core::BuiltinFn::kUnpack2X16Unorm:
+ case core::BuiltinFn::kUnpack4X8Snorm:
+ case core::BuiltinFn::kUnpack4X8Unorm:
+ case core::BuiltinFn::kUnpack4XI8:
+ case core::BuiltinFn::kUnpack4XU8:
call_worklist.Push(call);
break;
default:
@@ -150,6 +159,27 @@
case core::BuiltinFn::kTrunc:
Trunc(call);
break;
+ case core::BuiltinFn::kUnpack2X16Float:
+ Unpack2x16Float(call);
+ break;
+ case core::BuiltinFn::kUnpack2X16Snorm:
+ Unpack2x16Snorm(call);
+ break;
+ case core::BuiltinFn::kUnpack2X16Unorm:
+ Unpack2x16Unorm(call);
+ break;
+ case core::BuiltinFn::kUnpack4X8Snorm:
+ Unpack4x8Snorm(call);
+ break;
+ case core::BuiltinFn::kUnpack4X8Unorm:
+ Unpack4x8Unorm(call);
+ break;
+ case core::BuiltinFn::kUnpack4XI8:
+ Unpack4xI8(call);
+ break;
+ case core::BuiltinFn::kUnpack4XU8:
+ Unpack4xU8(call);
+ break;
default:
TINT_UNREACHABLE();
}
@@ -702,6 +732,112 @@
});
call->Destroy();
}
+
+ void Unpack2x16Float(core::ir::CoreBuiltinCall* call) {
+ auto args = call->Args();
+ b.InsertBefore(call, [&] {
+ auto* x = b.And(ty.u32(), args[0], 0xffff_u);
+ auto* y = b.ShiftRight(ty.u32(), args[0], 16_u);
+ auto* conv = b.Construct(ty.vec2<u32>(), x, y);
+
+ b.CallWithResult<hlsl::ir::BuiltinCall>(call->DetachResult(),
+ hlsl::BuiltinFn::kF16Tof32, conv);
+ });
+ call->Destroy();
+ }
+
+ void Unpack2x16Snorm(core::ir::CoreBuiltinCall* call) {
+ auto args = call->Args();
+ b.InsertBefore(call, [&] {
+ auto* conv = b.Convert(ty.i32(), args[0]);
+ auto* x = b.ShiftLeft(ty.i32(), conv, 16_u);
+
+ auto* vec = b.Construct(ty.vec2<i32>(), x, conv);
+ auto* v = b.ShiftRight(ty.vec2<i32>(), vec, b.Composite(ty.vec2<u32>(), 16_u));
+
+ auto* flt = b.Convert(ty.vec2<f32>(), v);
+ auto* scale = b.Divide(ty.vec2<f32>(), flt, 32767_f);
+
+ auto* lower = b.Splat(ty.vec2<f32>(), -1_f);
+ auto* upper = b.Splat(ty.vec2<f32>(), 1_f);
+ b.CallWithResult(call->DetachResult(), core::BuiltinFn::kClamp, scale, lower, upper);
+ });
+ call->Destroy();
+ }
+
+ void Unpack2x16Unorm(core::ir::CoreBuiltinCall* call) {
+ auto args = call->Args();
+ b.InsertBefore(call, [&] {
+ auto* x = b.And(ty.u32(), args[0], 0xffff_u);
+ auto* y = b.ShiftRight(ty.u32(), args[0], 16_u);
+ auto* conv = b.Construct(ty.vec2<u32>(), x, y);
+ auto* flt_conv = b.Convert(ty.vec2<f32>(), conv);
+ auto* scale = b.Divide(ty.vec2<f32>(), flt_conv, 0xffff_f);
+
+ call->Result(0)->ReplaceAllUsesWith(scale->Result(0));
+ });
+ call->Destroy();
+ }
+
+ void Unpack4x8Snorm(core::ir::CoreBuiltinCall* call) {
+ auto args = call->Args();
+ b.InsertBefore(call, [&] {
+ auto* conv = b.Convert(ty.i32(), args[0]);
+ auto* x = b.ShiftLeft(ty.i32(), conv, 24_u);
+ auto* y = b.ShiftLeft(ty.i32(), conv, 16_u);
+ auto* z = b.ShiftLeft(ty.i32(), conv, 8_u);
+ auto* cons = b.Construct(ty.vec4<i32>(), x, y, z, conv);
+ auto* shr = b.ShiftRight(ty.vec4<i32>(), cons, b.Composite(ty.vec4<u32>(), 24_u));
+ auto* flt = b.Convert(ty.vec4<f32>(), shr);
+ auto* scale = b.Divide(ty.vec4<f32>(), flt, 127_f);
+
+ auto* lower = b.Splat(ty.vec4<f32>(), -1_f);
+ auto* upper = b.Splat(ty.vec4<f32>(), 1_f);
+ b.CallWithResult(call->DetachResult(), core::BuiltinFn::kClamp, scale, lower, upper);
+ });
+ call->Destroy();
+ }
+
+ void Unpack4x8Unorm(core::ir::CoreBuiltinCall* call) {
+ auto args = call->Args();
+ b.InsertBefore(call, [&] {
+ auto* val = args[0];
+ auto* x = b.And(ty.u32(), val, 0xff_u);
+ auto* y = b.And(ty.u32(), b.ShiftRight(ty.u32(), val, 8_u), 0xff_u);
+ auto* z = b.And(ty.u32(), b.ShiftRight(ty.u32(), val, 16_u), 0xff_u);
+ auto* w = b.ShiftRight(ty.u32(), val, 24_u);
+ auto* cons = b.Construct(ty.vec4<u32>(), x, y, z, w);
+ auto* conv = b.Convert(ty.vec4<f32>(), cons);
+ auto* scale = b.Divide(ty.vec4<f32>(), conv, 255_f);
+
+ call->Result(0)->ReplaceAllUsesWith(scale->Result(0));
+ });
+ call->Destroy();
+ }
+
+ void Unpack4xI8(core::ir::CoreBuiltinCall* call) {
+ auto args = call->Args();
+ b.InsertBefore(call, [&] {
+ auto* type = ty.Get<hlsl::type::Int8T4Packed>();
+ auto* conv = b.Convert(type, args[0]);
+
+ b.CallWithResult<hlsl::ir::BuiltinCall>(call->DetachResult(),
+ hlsl::BuiltinFn::kUnpackS8S32, conv);
+ });
+ call->Destroy();
+ }
+
+ void Unpack4xU8(core::ir::CoreBuiltinCall* call) {
+ auto args = call->Args();
+ b.InsertBefore(call, [&] {
+ auto* type = ty.Get<hlsl::type::Uint8T4Packed>();
+ auto* conv = b.Convert(type, args[0]);
+
+ b.CallWithResult<hlsl::ir::BuiltinCall>(call->DetachResult(),
+ hlsl::BuiltinFn::kUnpackU8U32, conv);
+ });
+ call->Destroy();
+ }
};
} // namespace
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 1cc357d..ed52790 100644
--- a/src/tint/lang/hlsl/writer/raise/builtin_polyfill_test.cc
+++ b/src/tint/lang/hlsl/writer/raise/builtin_polyfill_test.cc
@@ -1173,5 +1173,295 @@
EXPECT_EQ(expect, str());
}
+TEST_F(HlslWriter_BuiltinPolyfillTest, Unpack2x16Float) {
+ auto* func = b.Function("foo", ty.void_(), core::ir::Function::PipelineStage::kFragment);
+ b.Append(func->Block(), [&] {
+ auto* u = b.Var("u", 2_u);
+ b.Let("a", b.Call(ty.vec2<f32>(), core::BuiltinFn::kUnpack2X16Float, b.Load(u)));
+ b.Return(func);
+ });
+
+ auto* src = R"(
+%foo = @fragment func():void {
+ $B1: {
+ %u:ptr<function, u32, read_write> = var, 2u
+ %3:u32 = load %u
+ %4:vec2<f32> = unpack2x16float %3
+ %a:vec2<f32> = let %4
+ ret
+ }
+}
+)";
+ ASSERT_EQ(src, str());
+
+ auto* expect = R"(
+%foo = @fragment func():void {
+ $B1: {
+ %u:ptr<function, u32, read_write> = var, 2u
+ %3:u32 = load %u
+ %4:u32 = and %3, 65535u
+ %5:u32 = shr %3, 16u
+ %6:vec2<u32> = construct %4, %5
+ %7:vec2<f32> = hlsl.f16tof32 %6
+ %a:vec2<f32> = let %7
+ ret
+ }
+}
+)";
+ Run(BuiltinPolyfill);
+
+ EXPECT_EQ(expect, str());
+}
+
+TEST_F(HlslWriter_BuiltinPolyfillTest, Unpack2x16snorm) {
+ auto* func = b.Function("foo", ty.void_(), core::ir::Function::PipelineStage::kFragment);
+ b.Append(func->Block(), [&] {
+ auto* u = b.Var("u", 2_u);
+ b.Let("a", b.Call(ty.vec2<f32>(), core::BuiltinFn::kUnpack2X16Snorm, b.Load(u)));
+ b.Return(func);
+ });
+
+ auto* src = R"(
+%foo = @fragment func():void {
+ $B1: {
+ %u:ptr<function, u32, read_write> = var, 2u
+ %3:u32 = load %u
+ %4:vec2<f32> = unpack2x16snorm %3
+ %a:vec2<f32> = let %4
+ ret
+ }
+}
+)";
+ ASSERT_EQ(src, str());
+
+ auto* expect = R"(
+%foo = @fragment func():void {
+ $B1: {
+ %u:ptr<function, u32, read_write> = var, 2u
+ %3:u32 = load %u
+ %4:i32 = convert %3
+ %5:i32 = shl %4, 16u
+ %6:vec2<i32> = construct %5, %4
+ %7:vec2<i32> = shr %6, vec2<u32>(16u)
+ %8:vec2<f32> = convert %7
+ %9:vec2<f32> = div %8, 32767.0f
+ %10:vec2<f32> = clamp %9, vec2<f32>(-1.0f), vec2<f32>(1.0f)
+ %a:vec2<f32> = let %10
+ ret
+ }
+}
+)";
+ Run(BuiltinPolyfill);
+
+ EXPECT_EQ(expect, str());
+}
+
+TEST_F(HlslWriter_BuiltinPolyfillTest, Unpack2x16unorm) {
+ auto* func = b.Function("foo", ty.void_(), core::ir::Function::PipelineStage::kFragment);
+ b.Append(func->Block(), [&] {
+ auto* u = b.Var("u", 2_u);
+ b.Let("a", b.Call(ty.vec2<f32>(), core::BuiltinFn::kUnpack2X16Unorm, b.Load(u)));
+ b.Return(func);
+ });
+
+ auto* src = R"(
+%foo = @fragment func():void {
+ $B1: {
+ %u:ptr<function, u32, read_write> = var, 2u
+ %3:u32 = load %u
+ %4:vec2<f32> = unpack2x16unorm %3
+ %a:vec2<f32> = let %4
+ ret
+ }
+}
+)";
+ ASSERT_EQ(src, str());
+
+ auto* expect = R"(
+%foo = @fragment func():void {
+ $B1: {
+ %u:ptr<function, u32, read_write> = var, 2u
+ %3:u32 = load %u
+ %4:u32 = and %3, 65535u
+ %5:u32 = shr %3, 16u
+ %6:vec2<u32> = construct %4, %5
+ %7:vec2<f32> = convert %6
+ %8:vec2<f32> = div %7, 65535.0f
+ %a:vec2<f32> = let %8
+ ret
+ }
+}
+)";
+ Run(BuiltinPolyfill);
+
+ EXPECT_EQ(expect, str());
+}
+
+TEST_F(HlslWriter_BuiltinPolyfillTest, Unpack4x8Snorm) {
+ auto* func = b.Function("foo", ty.void_(), core::ir::Function::PipelineStage::kFragment);
+ b.Append(func->Block(), [&] {
+ auto* u = b.Var("u", 2_u);
+ b.Let("a", b.Call(ty.vec4<f32>(), core::BuiltinFn::kUnpack4X8Snorm, b.Load(u)));
+ b.Return(func);
+ });
+
+ auto* src = R"(
+%foo = @fragment func():void {
+ $B1: {
+ %u:ptr<function, u32, read_write> = var, 2u
+ %3:u32 = load %u
+ %4:vec4<f32> = unpack4x8snorm %3
+ %a:vec4<f32> = let %4
+ ret
+ }
+}
+)";
+ ASSERT_EQ(src, str());
+
+ auto* expect = R"(
+%foo = @fragment func():void {
+ $B1: {
+ %u:ptr<function, u32, read_write> = var, 2u
+ %3:u32 = load %u
+ %4:i32 = convert %3
+ %5:i32 = shl %4, 24u
+ %6:i32 = shl %4, 16u
+ %7:i32 = shl %4, 8u
+ %8:vec4<i32> = construct %5, %6, %7, %4
+ %9:vec4<i32> = shr %8, vec4<u32>(24u)
+ %10:vec4<f32> = convert %9
+ %11:vec4<f32> = div %10, 127.0f
+ %12:vec4<f32> = clamp %11, vec4<f32>(-1.0f), vec4<f32>(1.0f)
+ %a:vec4<f32> = let %12
+ ret
+ }
+}
+)";
+ Run(BuiltinPolyfill);
+
+ EXPECT_EQ(expect, str());
+}
+
+TEST_F(HlslWriter_BuiltinPolyfillTest, Unpack4x8Unorm) {
+ auto* func = b.Function("foo", ty.void_(), core::ir::Function::PipelineStage::kFragment);
+ b.Append(func->Block(), [&] {
+ auto* u = b.Var("u", 2_u);
+ b.Let("a", b.Call(ty.vec4<f32>(), core::BuiltinFn::kUnpack4X8Unorm, b.Load(u)));
+ b.Return(func);
+ });
+
+ auto* src = R"(
+%foo = @fragment func():void {
+ $B1: {
+ %u:ptr<function, u32, read_write> = var, 2u
+ %3:u32 = load %u
+ %4:vec4<f32> = unpack4x8unorm %3
+ %a:vec4<f32> = let %4
+ ret
+ }
+}
+)";
+ ASSERT_EQ(src, str());
+
+ auto* expect = R"(
+%foo = @fragment func():void {
+ $B1: {
+ %u:ptr<function, u32, read_write> = var, 2u
+ %3:u32 = load %u
+ %4:u32 = and %3, 255u
+ %5:u32 = shr %3, 8u
+ %6:u32 = and %5, 255u
+ %7:u32 = shr %3, 16u
+ %8:u32 = and %7, 255u
+ %9:u32 = shr %3, 24u
+ %10:vec4<u32> = construct %4, %6, %8, %9
+ %11:vec4<f32> = convert %10
+ %12:vec4<f32> = div %11, 255.0f
+ %a:vec4<f32> = let %12
+ ret
+ }
+}
+)";
+ Run(BuiltinPolyfill);
+
+ EXPECT_EQ(expect, str());
+}
+
+TEST_F(HlslWriter_BuiltinPolyfillTest, Unpack4xI8) {
+ auto* func = b.Function("foo", ty.void_(), core::ir::Function::PipelineStage::kFragment);
+ b.Append(func->Block(), [&] {
+ auto* u = b.Var("u", 2_u);
+ b.Let("a", b.Call(ty.vec4<i32>(), core::BuiltinFn::kUnpack4XI8, b.Load(u)));
+ b.Return(func);
+ });
+
+ auto* src = R"(
+%foo = @fragment func():void {
+ $B1: {
+ %u:ptr<function, u32, read_write> = var, 2u
+ %3:u32 = load %u
+ %4:vec4<i32> = unpack4xI8 %3
+ %a:vec4<i32> = let %4
+ ret
+ }
+}
+)";
+ ASSERT_EQ(src, str());
+
+ auto* expect = R"(
+%foo = @fragment func():void {
+ $B1: {
+ %u:ptr<function, u32, read_write> = var, 2u
+ %3:u32 = load %u
+ %4:hlsl.int8_t4_packed = convert %3
+ %5:vec4<i32> = hlsl.unpack_s8s32 %4
+ %a:vec4<i32> = let %5
+ ret
+ }
+}
+)";
+ Run(BuiltinPolyfill);
+
+ EXPECT_EQ(expect, str());
+}
+
+TEST_F(HlslWriter_BuiltinPolyfillTest, Unpack4xU8) {
+ auto* func = b.Function("foo", ty.void_(), core::ir::Function::PipelineStage::kFragment);
+ b.Append(func->Block(), [&] {
+ auto* u = b.Var("u", 2_u);
+ b.Let("a", b.Call(ty.vec4<u32>(), core::BuiltinFn::kUnpack4XU8, b.Load(u)));
+ b.Return(func);
+ });
+
+ auto* src = R"(
+%foo = @fragment func():void {
+ $B1: {
+ %u:ptr<function, u32, read_write> = var, 2u
+ %3:u32 = load %u
+ %4:vec4<u32> = unpack4xU8 %3
+ %a:vec4<u32> = let %4
+ ret
+ }
+}
+)";
+ ASSERT_EQ(src, str());
+
+ auto* expect = R"(
+%foo = @fragment func():void {
+ $B1: {
+ %u:ptr<function, u32, read_write> = var, 2u
+ %3:u32 = load %u
+ %4:hlsl.uint8_t4_packed = convert %3
+ %5:vec4<u32> = hlsl.unpack_u8u32 %4
+ %a:vec4<u32> = let %5
+ ret
+ }
+}
+)";
+ Run(BuiltinPolyfill);
+
+ EXPECT_EQ(expect, str());
+}
+
} // namespace
} // namespace tint::hlsl::writer::raise