[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