| // Copyright 2021 The Tint Authors. |
| // |
| // Licensed under the Apache License, Version 2.0 (the "License"); |
| // you may not use this file except in compliance with the License. |
| // You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| |
| #include "src/tint/transform/renamer.h" |
| |
| #include <memory> |
| #include <unordered_set> |
| #include <vector> |
| |
| #include "gmock/gmock.h" |
| #include "src/tint/builtin/builtin.h" |
| #include "src/tint/builtin/texel_format.h" |
| #include "src/tint/transform/test_helper.h" |
| |
| namespace tint::transform { |
| namespace { |
| |
| constexpr const char kUnicodeIdentifier[] = // "𝖎𝖉𝖊𝖓𝖙𝖎𝖋𝖎𝖊𝖗123" |
| "\xf0\x9d\x96\x8e\xf0\x9d\x96\x89\xf0\x9d\x96\x8a\xf0\x9d\x96\x93" |
| "\xf0\x9d\x96\x99\xf0\x9d\x96\x8e\xf0\x9d\x96\x8b\xf0\x9d\x96\x8e" |
| "\xf0\x9d\x96\x8a\xf0\x9d\x96\x97\x31\x32\x33"; |
| |
| using ::testing::ContainerEq; |
| |
| using RenamerTest = TransformTest; |
| |
| TEST_F(RenamerTest, EmptyModule) { |
| auto* src = ""; |
| auto* expect = ""; |
| |
| auto got = Run<Renamer>(src); |
| |
| EXPECT_EQ(expect, str(got)); |
| |
| auto* data = got.data.Get<Renamer::Data>(); |
| |
| ASSERT_EQ(data->remappings.size(), 0u); |
| } |
| |
| TEST_F(RenamerTest, BasicModuleVertexIndex) { |
| auto* src = R"( |
| fn test(vert_idx : u32) -> u32 { |
| return vert_idx; |
| } |
| |
| @vertex |
| fn entry(@builtin(vertex_index) vert_idx : u32 |
| ) -> @builtin(position) vec4<f32> { |
| _ = test(vert_idx); |
| return vec4<f32>(); |
| } |
| )"; |
| |
| auto* expect = R"( |
| fn tint_symbol(tint_symbol_1 : u32) -> u32 { |
| return tint_symbol_1; |
| } |
| |
| @vertex |
| fn tint_symbol_2(@builtin(vertex_index) tint_symbol_1 : u32) -> @builtin(position) vec4<f32> { |
| _ = tint_symbol(tint_symbol_1); |
| return vec4<f32>(); |
| } |
| )"; |
| |
| auto got = Run<Renamer>(src); |
| |
| EXPECT_EQ(expect, str(got)); |
| |
| auto* data = got.data.Get<Renamer::Data>(); |
| |
| ASSERT_NE(data, nullptr); |
| Renamer::Data::Remappings expected_remappings = { |
| {"vert_idx", "tint_symbol_1"}, |
| {"test", "tint_symbol"}, |
| {"entry", "tint_symbol_2"}, |
| }; |
| EXPECT_THAT(data->remappings, ContainerEq(expected_remappings)); |
| } |
| |
| TEST_F(RenamerTest, PreserveSwizzles) { |
| auto* src = R"( |
| @vertex |
| fn entry() -> @builtin(position) vec4<f32> { |
| var v : vec4<f32>; |
| var rgba : f32; |
| var xyzw : f32; |
| var z : f32; |
| return v.zyxw + v.rgab * v.z; |
| } |
| )"; |
| |
| auto* expect = R"( |
| @vertex |
| fn tint_symbol() -> @builtin(position) vec4<f32> { |
| var tint_symbol_1 : vec4<f32>; |
| var tint_symbol_2 : f32; |
| var tint_symbol_3 : f32; |
| var tint_symbol_4 : f32; |
| return (tint_symbol_1.zyxw + (tint_symbol_1.rgab * tint_symbol_1.z)); |
| } |
| )"; |
| |
| auto got = Run<Renamer>(src); |
| |
| EXPECT_EQ(expect, str(got)); |
| |
| auto* data = got.data.Get<Renamer::Data>(); |
| |
| ASSERT_NE(data, nullptr); |
| Renamer::Data::Remappings expected_remappings = { |
| {"entry", "tint_symbol"}, {"v", "tint_symbol_1"}, {"rgba", "tint_symbol_2"}, |
| {"xyzw", "tint_symbol_3"}, {"z", "tint_symbol_4"}, |
| }; |
| EXPECT_THAT(data->remappings, ContainerEq(expected_remappings)); |
| } |
| |
| TEST_F(RenamerTest, PreserveBuiltins) { |
| auto* src = R"( |
| @vertex |
| fn entry() -> @builtin(position) vec4<f32> { |
| var blah : vec4<f32>; |
| return abs(blah); |
| } |
| )"; |
| |
| auto* expect = R"( |
| @vertex |
| fn tint_symbol() -> @builtin(position) vec4<f32> { |
| var tint_symbol_1 : vec4<f32>; |
| return abs(tint_symbol_1); |
| } |
| )"; |
| |
| auto got = Run<Renamer>(src); |
| |
| EXPECT_EQ(expect, str(got)); |
| |
| auto* data = got.data.Get<Renamer::Data>(); |
| |
| ASSERT_NE(data, nullptr); |
| Renamer::Data::Remappings expected_remappings = { |
| {"entry", "tint_symbol"}, |
| {"blah", "tint_symbol_1"}, |
| }; |
| EXPECT_THAT(data->remappings, ContainerEq(expected_remappings)); |
| } |
| |
| TEST_F(RenamerTest, PreserveBuiltinTypes) { |
| auto* src = R"( |
| @compute @workgroup_size(1) |
| fn entry() { |
| var a = modf(1.0).whole; |
| var b = modf(1.0).fract; |
| var c = frexp(1.0).fract; |
| var d = frexp(1.0).exp; |
| } |
| )"; |
| |
| auto* expect = R"( |
| @compute @workgroup_size(1) |
| fn tint_symbol() { |
| var tint_symbol_1 = modf(1.0).whole; |
| var tint_symbol_2 = modf(1.0).fract; |
| var tint_symbol_3 = frexp(1.0).fract; |
| var tint_symbol_4 = frexp(1.0).exp; |
| } |
| )"; |
| |
| auto got = Run<Renamer>(src); |
| |
| EXPECT_EQ(expect, str(got)); |
| |
| auto* data = got.data.Get<Renamer::Data>(); |
| |
| ASSERT_NE(data, nullptr); |
| Renamer::Data::Remappings expected_remappings = { |
| {"entry", "tint_symbol"}, {"a", "tint_symbol_1"}, {"b", "tint_symbol_2"}, |
| {"c", "tint_symbol_3"}, {"d", "tint_symbol_4"}, |
| }; |
| EXPECT_THAT(data->remappings, ContainerEq(expected_remappings)); |
| } |
| |
| TEST_F(RenamerTest, PreserveDiagnosticControls) { |
| auto* src = R"( |
| diagnostic(off, unreachable_code); |
| |
| @diagnostic(off, derivative_uniformity) |
| @fragment |
| fn entry(@location(0) value : f32) -> @location(0) f32 { |
| if (value > 0) { |
| return dpdx(value); |
| return 0.0; |
| } |
| return 1.0; |
| } |
| )"; |
| |
| auto* expect = R"( |
| diagnostic(off, unreachable_code); |
| |
| @diagnostic(off, derivative_uniformity) @fragment |
| fn tint_symbol(@location(0) tint_symbol_1 : f32) -> @location(0) f32 { |
| if ((tint_symbol_1 > 0)) { |
| return dpdx(tint_symbol_1); |
| return 0.0; |
| } |
| return 1.0; |
| } |
| )"; |
| |
| auto got = Run<Renamer>(src); |
| |
| EXPECT_EQ(expect, str(got)); |
| |
| auto* data = got.data.Get<Renamer::Data>(); |
| |
| ASSERT_NE(data, nullptr); |
| Renamer::Data::Remappings expected_remappings = { |
| {"entry", "tint_symbol"}, |
| {"value", "tint_symbol_1"}, |
| }; |
| EXPECT_THAT(data->remappings, ContainerEq(expected_remappings)); |
| } |
| |
| TEST_F(RenamerTest, PreserveUnicode) { |
| auto src = R"( |
| @fragment |
| fn frag_main() { |
| var )" + std::string(kUnicodeIdentifier) + |
| R"( : i32; |
| } |
| )"; |
| |
| auto expect = src; |
| |
| DataMap inputs; |
| inputs.Add<Renamer::Config>(Renamer::Target::kMslKeywords, |
| /* preserve_unicode */ true); |
| auto got = Run<Renamer>(src, inputs); |
| |
| EXPECT_EQ(expect, str(got)); |
| } |
| |
| TEST_F(RenamerTest, PreserveUnicodeRenameAll) { |
| auto src = R"( |
| @fragment |
| fn frag_main() { |
| var )" + std::string(kUnicodeIdentifier) + |
| R"( : i32; |
| } |
| )"; |
| |
| auto expect = R"( |
| @fragment |
| fn tint_symbol() { |
| var tint_symbol_1 : i32; |
| } |
| )"; |
| |
| DataMap inputs; |
| inputs.Add<Renamer::Config>(Renamer::Target::kAll, |
| /* preserve_unicode */ true); |
| auto got = Run<Renamer>(src, inputs); |
| |
| EXPECT_EQ(expect, str(got)); |
| } |
| |
| TEST_F(RenamerTest, AttemptSymbolCollision) { |
| auto* src = R"( |
| @vertex |
| fn entry() -> @builtin(position) vec4<f32> { |
| var tint_symbol : vec4<f32>; |
| var tint_symbol_2 : vec4<f32>; |
| var tint_symbol_4 : vec4<f32>; |
| return tint_symbol + tint_symbol_2 + tint_symbol_4; |
| } |
| )"; |
| |
| auto* expect = R"( |
| @vertex |
| fn tint_symbol() -> @builtin(position) vec4<f32> { |
| var tint_symbol_1 : vec4<f32>; |
| var tint_symbol_2 : vec4<f32>; |
| var tint_symbol_3 : vec4<f32>; |
| return ((tint_symbol_1 + tint_symbol_2) + tint_symbol_3); |
| } |
| )"; |
| |
| auto got = Run<Renamer>(src); |
| |
| EXPECT_EQ(expect, str(got)); |
| |
| auto* data = got.data.Get<Renamer::Data>(); |
| |
| ASSERT_NE(data, nullptr); |
| Renamer::Data::Remappings expected_remappings = { |
| {"entry", "tint_symbol"}, |
| {"tint_symbol", "tint_symbol_1"}, |
| {"tint_symbol_2", "tint_symbol_2"}, |
| {"tint_symbol_4", "tint_symbol_3"}, |
| }; |
| EXPECT_THAT(data->remappings, ContainerEq(expected_remappings)); |
| } |
| |
| TEST_F(RenamerTest, PreserveTexelFormatAndAccess) { |
| auto src = R"( |
| @group(0) @binding(0) var texture : texture_storage_2d<rgba8unorm, write>; |
| |
| fn f() { |
| var dims = textureDimensions(texture); |
| } |
| )"; |
| |
| auto expect = R"( |
| @group(0) @binding(0) var tint_symbol : texture_storage_2d<rgba8unorm, write>; |
| |
| fn tint_symbol_1() { |
| var tint_symbol_2 = textureDimensions(tint_symbol); |
| } |
| )"; |
| |
| auto got = Run<Renamer>(src); |
| |
| EXPECT_EQ(expect, str(got)); |
| } |
| |
| TEST_F(RenamerTest, PreserveAddressSpace) { |
| auto src = R"( |
| var<private> p : i32; |
| |
| fn f() { |
| var v = p; |
| } |
| )"; |
| |
| auto expect = R"( |
| var<private> tint_symbol : i32; |
| |
| fn tint_symbol_1() { |
| var tint_symbol_2 = tint_symbol; |
| } |
| )"; |
| |
| auto got = Run<Renamer>(src); |
| |
| EXPECT_EQ(expect, str(got)); |
| } |
| using RenamerTestGlsl = TransformTestWithParam<std::string>; |
| using RenamerTestHlsl = TransformTestWithParam<std::string>; |
| using RenamerTestMsl = TransformTestWithParam<std::string>; |
| |
| TEST_P(RenamerTestGlsl, Keywords) { |
| auto keyword = GetParam(); |
| |
| auto src = R"( |
| @fragment |
| fn frag_main() { |
| var )" + keyword + |
| R"( : i32; |
| } |
| )"; |
| |
| auto* expect = R"( |
| @fragment |
| fn frag_main() { |
| var tint_symbol : i32; |
| } |
| )"; |
| |
| DataMap inputs; |
| inputs.Add<Renamer::Config>(Renamer::Target::kGlslKeywords, |
| /* preserve_unicode */ false); |
| auto got = Run<Renamer>(src, inputs); |
| |
| EXPECT_EQ(expect, str(got)); |
| } |
| |
| TEST_P(RenamerTestHlsl, Keywords) { |
| auto keyword = GetParam(); |
| |
| auto src = R"( |
| @fragment |
| fn frag_main() { |
| var )" + keyword + |
| R"( : i32; |
| } |
| )"; |
| |
| auto* expect = R"( |
| @fragment |
| fn frag_main() { |
| var tint_symbol : i32; |
| } |
| )"; |
| |
| DataMap inputs; |
| inputs.Add<Renamer::Config>(Renamer::Target::kHlslKeywords, |
| /* preserve_unicode */ false); |
| auto got = Run<Renamer>(src, inputs); |
| |
| EXPECT_EQ(expect, str(got)); |
| } |
| |
| TEST_P(RenamerTestMsl, Keywords) { |
| auto keyword = GetParam(); |
| |
| auto src = R"( |
| @fragment |
| fn frag_main() { |
| var )" + keyword + |
| R"( : i32; |
| } |
| )"; |
| |
| auto* expect = R"( |
| @fragment |
| fn frag_main() { |
| var tint_symbol : i32; |
| } |
| )"; |
| |
| DataMap inputs; |
| inputs.Add<Renamer::Config>(Renamer::Target::kMslKeywords, |
| /* preserve_unicode */ false); |
| auto got = Run<Renamer>(src, inputs); |
| |
| EXPECT_EQ(expect, str(got)); |
| } |
| |
| INSTANTIATE_TEST_SUITE_P(RenamerTestGlsl, |
| RenamerTestGlsl, |
| testing::Values( // "active", // Also reserved in WGSL |
| // "asm", // WGSL keyword |
| "atomic_uint", |
| // "attribute", // Also reserved in WGSL |
| // "bool", // WGSL keyword |
| // "break", // WGSL keyword |
| "buffer", |
| "bvec2", |
| "bvec3", |
| "bvec4", |
| // "case", // WGSL keyword |
| // "cast", // Also reserved in WGSL |
| "centroid", |
| // "class", // Also reserved in WGSL |
| // "coherent", // Also reserved in WGSL |
| // "common", // Also reserved in WGSL |
| // "const", // WGSL keyword |
| // "continue", // WGSL keyword |
| // "default", // WGSL keyword |
| // "discard", // WGSL keyword |
| "dmat2", |
| "dmat2x2", |
| "dmat2x3", |
| "dmat2x4", |
| "dmat3", |
| "dmat3x2", |
| "dmat3x3", |
| "dmat3x4", |
| "dmat4", |
| "dmat4x2", |
| "dmat4x3", |
| "dmat4x4", |
| // "do", // WGSL keyword |
| "double", |
| "dvec2", |
| "dvec3", |
| "dvec4", |
| // "else" // WGSL keyword |
| // "enum", // WGSL keyword |
| // "extern", // Also reserved in WGSL |
| // "external", // Also reserved in WGSL |
| // "false", // WGSL keyword |
| // "filter", // Also reserved in WGSL |
| "fixed", |
| "flat", |
| "float", |
| // "for", // WGSL keyword |
| "fvec2", |
| "fvec3", |
| "fvec4", |
| "gl_BaseInstance", |
| "gl_BaseVertex", |
| "gl_ClipDistance", |
| "gl_DepthRangeParameters", |
| "gl_DrawID", |
| "gl_FragCoord", |
| "gl_FragDepth", |
| "gl_FrontFacing", |
| "gl_GlobalInvocationID", |
| "gl_InstanceID", |
| "gl_LocalInvocationID", |
| "gl_LocalInvocationIndex", |
| "gl_NumSamples", |
| "gl_NumWorkGroups", |
| "gl_PerVertex", |
| "gl_PointCoord", |
| "gl_PointSize", |
| "gl_Position", |
| "gl_PrimitiveID", |
| "gl_SampleID", |
| "gl_SampleMask", |
| "gl_SampleMaskIn", |
| "gl_SamplePosition", |
| "gl_VertexID", |
| "gl_WorkGroupID", |
| "gl_WorkGroupSize", |
| // "goto", // Also reserved in WGSL |
| "half", |
| // "highp", // Also reserved in WGSL |
| "hvec2", |
| "hvec3", |
| "hvec4", |
| // "if", // WGSL keyword |
| "iimage1D", |
| "iimage1DArray", |
| "iimage2D", |
| "iimage2DArray", |
| "iimage2DMS", |
| "iimage2DMSArray", |
| "iimage2DRect", |
| "iimage3D", |
| "iimageBuffer", |
| "iimageCube", |
| "iimageCubeArray", |
| "image1D", |
| "image1DArray", |
| "image2D", |
| "image2DArray", |
| "image2DMS", |
| "image2DMSArray", |
| "image2DRect", |
| "image3D", |
| "imageBuffer", |
| "imageCube", |
| "imageCubeArray", |
| "in", |
| // "inline", // Also reserved in WGSL |
| // "inout", // Also reserved in WGSL |
| "input", |
| "int", |
| // "interface", // Also reserved in WGSL |
| // "invariant", // Also reserved in WGSL |
| "isampler1D", |
| "isampler1DArray", |
| "isampler2D", |
| "isampler2DArray", |
| "isampler2DMS", |
| "isampler2DMSArray", |
| "isampler2DRect", |
| "isampler3D", |
| "isamplerBuffer", |
| "isamplerCube", |
| "isamplerCubeArray", |
| "ivec2", |
| "ivec3", |
| "ivec4", |
| // "layout", // Also reserved in WGSL |
| "long", |
| // "lowp", // Also reserved in WGSL |
| // "mat2x2", // WGSL keyword |
| // "mat2x3", // WGSL keyword |
| // "mat2x4", // WGSL keyword |
| // "mat2", |
| "mat3", |
| // "mat3x2", // WGSL keyword |
| // "mat3x3", // WGSL keyword |
| // "mat3x4", // WGSL keyword |
| "mat4", |
| // "mat4x2", // WGSL keyword |
| // "mat4x3", // WGSL keyword |
| // "mat4x4", // WGSL keyword |
| // "mediump", // Also reserved in WGSL |
| // "namespace", // Also reserved in WGSL |
| // "noinline", // Also reserved in WGSL |
| // "noperspective", // Also reserved in WGSL |
| "out", |
| "output", |
| // "partition", // Also reserved in WGSL |
| // "patch", // Also reserved in WGSL |
| // "precise", // Also reserved in WGSL |
| // "precision", // Also reserved in WGSL |
| // "public", // Also reserved in WGSL |
| // "readonly", // Also reserved in WGSL |
| // "resource", // Also reserved in WGSL |
| // "restrict", // Also reserved in WGSL |
| // "return", // WGSL keyword |
| "sample", |
| "sampler1D", |
| "sampler1DArray", |
| "sampler1DArrayShadow", |
| "sampler1DShadow", |
| "sampler2D", |
| "sampler2DArray", |
| "sampler2DArrayShadow", |
| "sampler2DMS", |
| "sampler2DMSArray", |
| "sampler2DRect", |
| "sampler2DRectShadow", |
| "sampler2DShadow", |
| "sampler3D", |
| "sampler3DRect", |
| "samplerBuffer", |
| "samplerCube", |
| "samplerCubeArray", |
| "samplerCubeArrayShadow", |
| "samplerCubeShadow", |
| // "shared" // Also reserved in WGSL, |
| "short", |
| // "sizeof", // Also reserved in WGSL |
| // "smooth", // Also reserved in WGSL |
| // "static", // Also reserved in WGSL |
| // "struct", // WGSL keyword |
| // "subroutine", // Also reserved in WGSL |
| "superp", |
| // "switch", // WGSL keyword |
| // "template", // Also reserved in WGSL |
| // "this", // Also reserved in WGSL |
| // "true", // WGSL keyword |
| // "typedef", // WGSL keyword |
| "uimage1D", |
| "uimage1DArray", |
| "uimage2D", |
| "uimage2DArray", |
| "uimage2DMS", |
| "uimage2DMSArray", |
| "uimage2DRect", |
| "uimage3D", |
| "uimageBuffer", |
| "uimageCube", |
| "uimageCubeArray", |
| "uint", |
| // "uniform", // WGSL keyword |
| // "union", // Also reserved in WGSL |
| "unsigned", |
| "usampler1D", |
| "usampler1DArray", |
| "usampler2D", |
| "usampler2DArray", |
| "usampler2DMS", |
| "usampler2DMSArray", |
| "usampler2DRect", |
| "usampler3D", |
| "usamplerBuffer", |
| "usamplerCube", |
| "usamplerCubeArray", |
| // "using", // WGSL keyword |
| "uvec2", |
| "uvec3", |
| "uvec4", |
| // "varying", // Also reserved in WGSL |
| // "vec2", // WGSL keyword |
| // "vec3", // WGSL keyword |
| // "vec4", // WGSL keyword |
| // "void", // WGSL keyword |
| // "volatile", // Also reserved in WGSL |
| // "while", // WGSL keyword |
| // "writeonly", // Also reserved in WGSL |
| kUnicodeIdentifier)); |
| |
| INSTANTIATE_TEST_SUITE_P(RenamerTestHlsl, |
| RenamerTestHlsl, |
| testing::Values("AddressU", |
| "AddressV", |
| "AddressW", |
| "AllMemoryBarrier", |
| "AllMemoryBarrierWithGroupSync", |
| "AppendStructuredBuffer", |
| "BINORMAL", |
| "BLENDINDICES", |
| "BLENDWEIGHT", |
| "BlendState", |
| "BorderColor", |
| "Buffer", |
| "ByteAddressBuffer", |
| "COLOR", |
| "CheckAccessFullyMapped", |
| "ComparisonFunc", |
| // "CompileShader", // Also reserved in WGSL |
| // "ComputeShader", // Also reserved in WGSL |
| "ConsumeStructuredBuffer", |
| "D3DCOLORtoUBYTE4", |
| "DEPTH", |
| "DepthStencilState", |
| "DepthStencilView", |
| "DeviceMemoryBarrier", |
| "DeviceMemroyBarrierWithGroupSync", |
| // "DomainShader", // Also reserved in WGSL |
| "EvaluateAttributeAtCentroid", |
| "EvaluateAttributeAtSample", |
| "EvaluateAttributeSnapped", |
| "FOG", |
| "Filter", |
| // "GeometryShader", // Also reserved in WGSL |
| "GetRenderTargetSampleCount", |
| "GetRenderTargetSamplePosition", |
| "GroupMemoryBarrier", |
| "GroupMemroyBarrierWithGroupSync", |
| // "Hullshader", // Also reserved in WGSL |
| "InputPatch", |
| "InterlockedAdd", |
| "InterlockedAnd", |
| "InterlockedCompareExchange", |
| "InterlockedCompareStore", |
| "InterlockedExchange", |
| "InterlockedMax", |
| "InterlockedMin", |
| "InterlockedOr", |
| "InterlockedXor", |
| "LineStream", |
| "MaxAnisotropy", |
| "MaxLOD", |
| "MinLOD", |
| "MipLODBias", |
| "NORMAL", |
| // "NULL", // Also reserved in WGSL |
| "Normal", |
| "OutputPatch", |
| "POSITION", |
| "POSITIONT", |
| "PSIZE", |
| "PixelShader", |
| "PointStream", |
| "Process2DQuadTessFactorsAvg", |
| "Process2DQuadTessFactorsMax", |
| "Process2DQuadTessFactorsMin", |
| "ProcessIsolineTessFactors", |
| "ProcessQuadTessFactorsAvg", |
| "ProcessQuadTessFactorsMax", |
| "ProcessQuadTessFactorsMin", |
| "ProcessTriTessFactorsAvg", |
| "ProcessTriTessFactorsMax", |
| "ProcessTriTessFactorsMin", |
| "RWBuffer", |
| "RWByteAddressBuffer", |
| "RWStructuredBuffer", |
| "RWTexture1D", |
| "RWTexture1DArray", |
| "RWTexture2D", |
| "RWTexture2DArray", |
| "RWTexture3D", |
| "RasterizerState", |
| "RenderTargetView", |
| "SV_ClipDistance", |
| "SV_Coverage", |
| "SV_CullDistance", |
| "SV_Depth", |
| "SV_DepthGreaterEqual", |
| "SV_DepthLessEqual", |
| "SV_DispatchThreadID", |
| "SV_DomainLocation", |
| "SV_GSInstanceID", |
| "SV_GroupID", |
| "SV_GroupIndex", |
| "SV_GroupThreadID", |
| "SV_InnerCoverage", |
| "SV_InsideTessFactor", |
| "SV_InstanceID", |
| "SV_IsFrontFace", |
| "SV_OutputControlPointID", |
| "SV_Position", |
| "SV_PrimitiveID", |
| "SV_RenderTargetArrayIndex", |
| "SV_SampleIndex", |
| "SV_StencilRef", |
| "SV_Target", |
| "SV_TessFactor", |
| "SV_VertexArrayIndex", |
| "SV_VertexID", |
| "Sampler", |
| "Sampler1D", |
| "Sampler2D", |
| "Sampler3D", |
| "SamplerCUBE", |
| "SamplerComparisonState", |
| "SamplerState", |
| "StructuredBuffer", |
| "TANGENT", |
| "TESSFACTOR", |
| "TEXCOORD", |
| "Texcoord", |
| "Texture", |
| "Texture1D", |
| "Texture1DArray", |
| "Texture2D", |
| "Texture2DArray", |
| "Texture2DMS", |
| "Texture2DMSArray", |
| "Texture3D", |
| "TextureCube", |
| "TextureCubeArray", |
| "TriangleStream", |
| "VFACE", |
| "VPOS", |
| "VertexShader", |
| "abort", |
| // "abs", // WGSL builtin |
| // "acos", // WGSL builtin |
| // "all", // WGSL builtin |
| "allow_uav_condition", |
| // "any", // WGSL builtin |
| "asdouble", |
| "asfloat", |
| // "asin", // WGSL builtin |
| "asint", |
| // "asm", // WGSL keyword |
| // "asm_fragment", // Also reserved in WGSL |
| "asuint", |
| // "atan", // WGSL builtin |
| // "atan2", // WGSL builtin |
| // "auto", // Also reserved in WGSL |
| // "bool", // WGSL keyword |
| "bool1", |
| "bool1x1", |
| "bool1x2", |
| "bool1x3", |
| "bool1x4", |
| "bool2", |
| "bool2x1", |
| "bool2x2", |
| "bool2x3", |
| "bool2x4", |
| "bool3", |
| "bool3x1", |
| "bool3x2", |
| "bool3x3", |
| "bool3x4", |
| "bool4", |
| "bool4x1", |
| "bool4x2", |
| "bool4x3", |
| "bool4x4", |
| "branch", |
| // "break", // WGSL keyword |
| // "call", // WGSL builtin |
| // "case", // WGSL keyword |
| // "catch", // Also reserved in WGSL |
| "cbuffer", |
| // "ceil", // WGSL builtin |
| "centroid", |
| "char", |
| // "clamp", // WGSL builtin |
| // "class", // Also reserved in WGSL |
| "clip", |
| // "column_major", // Also reserved in WGSL |
| // "compile", // Also reserved in WGSL |
| // "compile_fragment", // Also reserved in WGSL |
| // "const", // WGSL keyword |
| // "const_cast", // Also reserved in WGSL |
| // "continue", // WGSL keyword |
| // "cos", // WGSL builtin |
| // "cosh", // WGSL builtin |
| "countbits", |
| // "cross", // WGSL builtin |
| "ddx", |
| "ddx_coarse", |
| "ddx_fine", |
| "ddy", |
| "ddy_coarse", |
| "ddy_fine", |
| // "default", // WGSL keyword |
| "degrees", |
| // "delete", // Also reserved in WGSL |
| // "determinant", // WGSL builtin |
| // "discard", // WGSL keyword |
| // "distance", // WGSL builtin |
| // "do", // WGSL keyword |
| // "dot", // WGSL builtin |
| "double", |
| "double1", |
| "double1x1", |
| "double1x2", |
| "double1x3", |
| "double1x4", |
| "double2", |
| "double2x1", |
| "double2x2", |
| "double2x3", |
| "double2x4", |
| "double3", |
| "double3x1", |
| "double3x2", |
| "double3x3", |
| "double3x4", |
| "double4", |
| "double4x1", |
| "double4x2", |
| "double4x3", |
| "double4x4", |
| "dst", |
| "dword", |
| "dword1", |
| "dword1x1", |
| "dword1x2", |
| "dword1x3", |
| "dword1x4", |
| "dword2", |
| "dword2x1", |
| "dword2x2", |
| "dword2x3", |
| "dword2x4", |
| "dword3", |
| "dword3x1", |
| "dword3x2", |
| "dword3x3", |
| "dword3x4", |
| "dword4", |
| "dword4x1", |
| "dword4x2", |
| "dword4x3", |
| "dword4x4", |
| // "dynamic_cast", // Also reserved in WGSL |
| // "else", // WGSL keyword |
| // "enum", // WGSL keyword |
| "errorf", |
| // "exp", // WGSL builtin |
| // "exp2", // WGSL builtin |
| // "explicit", // Also reserved in WGSL |
| // "export", // Also reserved in WGSL |
| // "extern", // Also reserved in WGSL |
| "f16to32", |
| "f32tof16", |
| // "faceforward", // WGSL builtin |
| // "false", // WGSL keyword |
| "fastopt", |
| "firstbithigh", |
| "firstbitlow", |
| "flatten", |
| "float", |
| "float1", |
| "float1x1", |
| "float1x2", |
| "float1x3", |
| "float1x4", |
| "float2", |
| "float2x1", |
| "float2x2", |
| "float2x3", |
| "float2x4", |
| "float3", |
| "float3x1", |
| "float3x2", |
| "float3x3", |
| "float3x4", |
| "float4", |
| "float4x1", |
| "float4x2", |
| "float4x3", |
| "float4x4", |
| // "floor", // WGSL builtin |
| // "fma", // WGSL builtin |
| "fmod", |
| // "for", // WGSL keyword |
| "forcecase", |
| "frac", |
| // "frexp", // WGSL builtin |
| // "friend", // Also reserved in WGSL |
| // "fwidth", // WGSL builtin |
| // "fxgroup", // Also reserved in WGSL |
| // "goto", // Also reserved in WGSL |
| // "groupshared", // Also reserved in WGSL |
| "half", |
| "half1", |
| "half1x1", |
| "half1x2", |
| "half1x3", |
| "half1x4", |
| "half2", |
| "half2x1", |
| "half2x2", |
| "half2x3", |
| "half2x4", |
| "half3", |
| "half3x1", |
| "half3x2", |
| "half3x3", |
| "half3x4", |
| "half4", |
| "half4x1", |
| "half4x2", |
| "half4x3", |
| "half4x4", |
| // "if", // WGSL keyword |
| // "in", // WGSL keyword |
| // "inline", // Also reserved in WGSL |
| // "inout", // Also reserved in WGSL |
| "int", |
| "int1", |
| "int1x1", |
| "int1x2", |
| "int1x3", |
| "int1x4", |
| "int2", |
| "int2x1", |
| "int2x2", |
| "int2x3", |
| "int2x4", |
| "int3", |
| "int3x1", |
| "int3x2", |
| "int3x3", |
| "int3x4", |
| "int4", |
| "int4x1", |
| "int4x2", |
| "int4x3", |
| "int4x4", |
| // "interface", // Also reserved in WGSL |
| "isfinite", |
| "isinf", |
| "isnan", |
| // "ldexp", // WGSL builtin |
| // "length", // WGSL builtin |
| "lerp", |
| // "line", // Also reserved in WGSL |
| // "lineadj", // Also reserved in WGSL |
| "linear", |
| "lit", |
| // "log", // WGSL builtin |
| "log10", |
| // "log2", // WGSL builtin |
| "long", |
| // "loop", // WGSL keyword |
| "mad", |
| "matrix", |
| // "max", // WGSL builtin |
| // "min", // WGSL builtin |
| "min10float", |
| "min10float1", |
| "min10float1x1", |
| "min10float1x2", |
| "min10float1x3", |
| "min10float1x4", |
| "min10float2", |
| "min10float2x1", |
| "min10float2x2", |
| "min10float2x3", |
| "min10float2x4", |
| "min10float3", |
| "min10float3x1", |
| "min10float3x2", |
| "min10float3x3", |
| "min10float3x4", |
| "min10float4", |
| "min10float4x1", |
| "min10float4x2", |
| "min10float4x3", |
| "min10float4x4", |
| "min12int", |
| "min12int1", |
| "min12int1x1", |
| "min12int1x2", |
| "min12int1x3", |
| "min12int1x4", |
| "min12int2", |
| "min12int2x1", |
| "min12int2x2", |
| "min12int2x3", |
| "min12int2x4", |
| "min12int3", |
| "min12int3x1", |
| "min12int3x2", |
| "min12int3x3", |
| "min12int3x4", |
| "min12int4", |
| "min12int4x1", |
| "min12int4x2", |
| "min12int4x3", |
| "min12int4x4", |
| "min16float", |
| "min16float1", |
| "min16float1x1", |
| "min16float1x2", |
| "min16float1x3", |
| "min16float1x4", |
| "min16float2", |
| "min16float2x1", |
| "min16float2x2", |
| "min16float2x3", |
| "min16float2x4", |
| "min16float3", |
| "min16float3x1", |
| "min16float3x2", |
| "min16float3x3", |
| "min16float3x4", |
| "min16float4", |
| "min16float4x1", |
| "min16float4x2", |
| "min16float4x3", |
| "min16float4x4", |
| "min16int", |
| "min16int1", |
| "min16int1x1", |
| "min16int1x2", |
| "min16int1x3", |
| "min16int1x4", |
| "min16int2", |
| "min16int2x1", |
| "min16int2x2", |
| "min16int2x3", |
| "min16int2x4", |
| "min16int3", |
| "min16int3x1", |
| "min16int3x2", |
| "min16int3x3", |
| "min16int3x4", |
| "min16int4", |
| "min16int4x1", |
| "min16int4x2", |
| "min16int4x3", |
| "min16int4x4", |
| "min16uint", |
| "min16uint1", |
| "min16uint1x1", |
| "min16uint1x2", |
| "min16uint1x3", |
| "min16uint1x4", |
| "min16uint2", |
| "min16uint2x1", |
| "min16uint2x2", |
| "min16uint2x3", |
| "min16uint2x4", |
| "min16uint3", |
| "min16uint3x1", |
| "min16uint3x2", |
| "min16uint3x3", |
| "min16uint3x4", |
| "min16uint4", |
| "min16uint4x1", |
| "min16uint4x2", |
| "min16uint4x3", |
| "min16uint4x4", |
| // "modf", // WGSL builtin |
| "msad4", |
| "mul", |
| // "mutable", // Also reserved in WGSL |
| // "namespace", // Also reserved in WGSL |
| // "new", // Also reserved in WGSL |
| // "nointerpolation", // Also reserved in WGSL |
| "noise", |
| // "noperspective", // Also reserved in WGSL |
| // "normalize", // WGSL builtin |
| "numthreads", |
| // "operator", // Also reserved in WGSL |
| // "out", // WGSL keyword |
| // "packoffset", // Also reserved in WGSL |
| // "pass", // Also reserved in WGSL |
| // "pixelfragment", // Also reserved in WGSL |
| "pixelshader", |
| // "point", // Also reserved in WGSL |
| // "pow", // WGSL builtin |
| // "precise", // Also reserved in WGSL |
| "printf", |
| // "private", // WGSL keyword |
| // "protected", // Also reserved in WGSL |
| // "public", // Also reserved in WGSL |
| "radians", |
| "rcp", |
| // "reflect", // WGSL builtin |
| "refract", |
| // "register", // Also reserved in WGSL |
| // "reinterpret_cast", // Also reserved in WGSL |
| // "return", // WGSL keyword |
| // "reversebits", // WGSL builtin |
| // "round", // WGSL builtin |
| "row_major", |
| "rsqrt", |
| "sample", |
| "sampler1D", |
| "sampler2D", |
| "sampler3D", |
| "samplerCUBE", |
| "sampler_state", |
| "saturate", |
| // "shared", // Also reserved in WGSL |
| "short", |
| // "sign", // WGSL builtin |
| // "signed", // Also reserved in WGSL |
| // "sin", // WGSL builtin |
| "sincos", |
| // "sinh", // WGSL builtin |
| // "sizeof", // Also reserved in WGSL |
| // "smoothstep", // WGSL builtin |
| // "snorm", // Also reserved in WGSL |
| // "sqrt", // WGSL builtin |
| "stateblock", |
| "stateblock_state", |
| // "static", // Also reserved in WGSL |
| // "static_cast", // Also reserved in WGSL |
| // "step", // WGSL builtin |
| "string", |
| // "struct", // WGSL keyword |
| // "switch", // WGSL keyword |
| // "tan", // WGSL builtin |
| // "tanh", // WGSL builtin |
| "tbuffer", |
| "technique", |
| "technique10", |
| "technique11", |
| // "template", // Also reserved in WGSL |
| "tex1D", |
| "tex1Dbias", |
| "tex1Dgrad", |
| "tex1Dlod", |
| "tex1Dproj", |
| "tex2D", |
| "tex2Dbias", |
| "tex2Dgrad", |
| "tex2Dlod", |
| "tex2Dproj", |
| "tex3D", |
| "tex3Dbias", |
| "tex3Dgrad", |
| "tex3Dlod", |
| "tex3Dproj", |
| "texCUBE", |
| "texCUBEbias", |
| "texCUBEgrad", |
| "texCUBElod", |
| "texCUBEproj", |
| "texture", |
| "texture1D", |
| "texture1DArray", |
| "texture2D", |
| "texture2DArray", |
| "texture2DMS", |
| "texture2DMSArray", |
| "texture3D", |
| "textureCube", |
| "textureCubeArray", |
| // "this", // Also reserved in WGSL |
| // "throw", // Also reserved in WGSL |
| "transpose", |
| "triangle", |
| "triangleadj", |
| // "true", // WGSL keyword |
| // "trunc", // WGSL builtin |
| // "try", // Also reserved in WGSL |
| // "typedef", // WGSL keyword |
| // "typename", // Also reserved in WGSL |
| "uint", |
| "uint1", |
| "uint1x1", |
| "uint1x2", |
| "uint1x3", |
| "uint1x4", |
| "uint2", |
| "uint2x1", |
| "uint2x2", |
| "uint2x3", |
| "uint2x4", |
| "uint3", |
| "uint3x1", |
| "uint3x2", |
| "uint3x3", |
| "uint3x4", |
| "uint4", |
| "uint4x1", |
| "uint4x2", |
| "uint4x3", |
| "uint4x4", |
| // "uniform", // WGSL keyword |
| // "union", // Also reserved in WGSL |
| // "unorm", // Also reserved in WGSL |
| "unroll", |
| "unsigned", |
| // "using", // WGSL reserved keyword |
| "vector", |
| "vertexfragment", |
| "vertexshader", |
| // "virtual", // Also reserved in WGSL |
| // "void", // WGSL keyword |
| // "volatile", // Also reserved in WGSL |
| // "while" // WGSL reserved keyword |
| kUnicodeIdentifier)); |
| |
| INSTANTIATE_TEST_SUITE_P( |
| RenamerTestMsl, |
| RenamerTestMsl, |
| testing::Values( |
| // c++14 spec |
| // "alignas", // Also reserved in WGSL |
| // "alignof", // Also reserved in WGSL |
| "and", |
| "and_eq", |
| // "asm", // Also reserved in WGSL |
| // "auto", // Also reserved in WGSL |
| "bitand", |
| "bitor", |
| // "bool", // Also used in WGSL |
| // "break", // Also used in WGSL |
| // "case", // Also used in WGSL |
| // "catch", // Also reserved in WGSL |
| "char", |
| "char16_t", |
| "char32_t", |
| // "class", // Also reserved in WGSL |
| "compl", |
| // "const", // Also used in WGSL |
| // "const_cast", // Also reserved in WGSL |
| // "constexpr", // Also reserved in WGSL |
| // "continue", // Also used in WGSL |
| // "decltype", // Also reserved in WGSL |
| // "default", // Also used in WGSL |
| // "delete", // Also reserved in WGSL |
| // "do", // Also used in WGSL |
| "double", |
| // "dynamic_cast", // Also reserved in WGSL |
| // "else", // Also used in WGSL |
| // "enum", // Also used in WGSL |
| // "explicit", // Also reserved in WGSL |
| // "extern", // Also reserved in WGSL |
| // "false", // Also used in WGSL |
| // "final", // Also reserved in WGSL |
| "float", |
| // "for", // Also used in WGSL |
| // "friend", // Also reserved in WGSL |
| // "goto", // Also reserved in WGSL |
| // "if", // Also used in WGSL |
| // "inline", // Also reserved in WGSL |
| "int", |
| "long", |
| // "mutable", // Also reserved in WGSL |
| // "namespace", // Also reserved in WGSL |
| // "new", // Also reserved in WGSL |
| // "noexcept", // Also reserved in WGSL |
| "not", |
| "not_eq", |
| // "nullptr", // Also reserved in WGSL |
| // "operator", // Also reserved in WGSL |
| "or", |
| "or_eq", |
| // "override", // Also used in WGSL |
| // "private", // Also used in WGSL |
| // "protected", // Also reserved in WGSL |
| // "public", // Also reserved in WGSL |
| // "register", // Also reserved in WGSL |
| // "reinterpret_cast", // Also reserved in WGSL |
| // "return", // Also used in WGSL |
| "short", |
| // "signed", // Also reserved in WGSL |
| // "sizeof", // Also reserved in WGSL |
| // "static", // Also reserved in WGSL |
| // "static_assert", // Also reserved in WGSL |
| // "static_cast", // Also reserved in WGSL |
| // "struct", // Also used in WGSL |
| // "switch", // Also used in WGSL |
| // "template", // Also reserved in WGSL |
| // "this", // Also reserved in WGSL |
| // "thread_local", // Also reserved in WGSL |
| // "throw", // Also reserved in WGSL |
| // "true", // Also used in WGSL |
| // "try", // Also reserved in WGSL |
| // "typedef", // Also used in WGSL |
| // "typeid", // Also reserved in WGSL |
| // "typename", // Also reserved in WGSL |
| // "union", // Also reserved in WGSL |
| "unsigned", |
| // "using", // WGSL reserved keyword |
| // "virtual", // Also reserved in WGSL |
| // "void", // Also used in WGSL |
| // "volatile", // Also reserved in WGSL |
| "wchar_t", |
| // "while", // WGSL reserved keyword |
| "xor", |
| "xor_eq", |
| |
| // Metal Spec |
| "access", |
| // "array", // Also used in WGSL |
| "array_ref", |
| "as_type", |
| // "atomic", // Also used in WGSL |
| "atomic_bool", |
| "atomic_int", |
| "atomic_uint", |
| "bool2", |
| "bool3", |
| "bool4", |
| "buffer", |
| "char2", |
| "char3", |
| "char4", |
| "const_reference", |
| "constant", |
| "depth2d", |
| "depth2d_array", |
| "depth2d_ms", |
| "depth2d_ms_array", |
| "depthcube", |
| "depthcube_array", |
| "device", |
| "discard_fragment", |
| "float2", |
| "float2x2", |
| "float2x3", |
| "float2x4", |
| "float3", |
| "float3x2", |
| "float3x3", |
| "float3x4", |
| "float4", |
| "float4x2", |
| "float4x3", |
| "float4x4", |
| "fragment", |
| "half", |
| "half2", |
| "half2x2", |
| "half2x3", |
| "half2x4", |
| "half3", |
| "half3x2", |
| "half3x3", |
| "half3x4", |
| "half4", |
| "half4x2", |
| "half4x3", |
| "half4x4", |
| "imageblock", |
| "int16_t", |
| "int2", |
| "int3", |
| "int32_t", |
| "int4", |
| "int64_t", |
| "int8_t", |
| "kernel", |
| "long2", |
| "long3", |
| "long4", |
| "main", // No functions called main |
| "matrix", |
| "metal", // The namespace |
| "packed_bool2", |
| "packed_bool3", |
| "packed_bool4", |
| "packed_char2", |
| "packed_char3", |
| "packed_char4", |
| "packed_float2", |
| "packed_float3", |
| "packed_float4", |
| "packed_half2", |
| "packed_half3", |
| "packed_half4", |
| "packed_int2", |
| "packed_int3", |
| "packed_int4", |
| "packed_short2", |
| "packed_short3", |
| "packed_short4", |
| "packed_uchar2", |
| "packed_uchar3", |
| "packed_uchar4", |
| "packed_uint2", |
| "packed_uint3", |
| "packed_uint4", |
| "packed_ushort2", |
| "packed_ushort3", |
| "packed_ushort4", |
| "patch_control_point", |
| "ptrdiff_t", |
| "r16snorm", |
| "r16unorm", |
| "r8unorm", |
| "reference", |
| "rg11b10f", |
| "rg16snorm", |
| "rg16unorm", |
| "rg8snorm", |
| "rg8unorm", |
| "rgb10a2", |
| "rgb9e5", |
| "rgba16snorm", |
| "rgba16unorm", |
| "rgba8snorm", |
| "rgba8unorm", |
| // "sampler", // Also used in WGSL |
| "short2", |
| "short3", |
| "short4", |
| "size_t", |
| "srgba8unorm", |
| "texture", |
| "texture1d", |
| "texture1d_array", |
| "texture2d", |
| "texture2d_array", |
| "texture2d_ms", |
| "texture2d_ms_array", |
| "texture3d", |
| "texture_buffer", |
| "texturecube", |
| "texturecube_array", |
| "thread", |
| "threadgroup", |
| "threadgroup_imageblock", |
| "uchar", |
| "uchar2", |
| "uchar3", |
| "uchar4", |
| "uint", |
| "uint16_t", |
| "uint2", |
| "uint3", |
| "uint32_t", |
| "uint4", |
| "uint64_t", |
| "uint8_t", |
| "ulong2", |
| "ulong3", |
| "ulong4", |
| // "uniform", // Also used in WGSL |
| "ushort", |
| "ushort2", |
| "ushort3", |
| "ushort4", |
| // "vec", // WGSL reserved keyword |
| "vertex", |
| |
| // https://developer.apple.com/metal/Metal-Shading-Language-Specification.pdf |
| // Table 6.5. Constants for single-precision floating-point math |
| // functions |
| "MAXFLOAT", |
| "HUGE_VALF", |
| "INFINITY", |
| "infinity", |
| "NAN", |
| "M_E_F", |
| "M_LOG2E_F", |
| "M_LOG10E_F", |
| "M_LN2_F", |
| "M_LN10_F", |
| "M_PI_F", |
| "M_PI_2_F", |
| "M_PI_4_F", |
| "M_1_PI_F", |
| "M_2_PI_F", |
| "M_2_SQRTPI_F", |
| "M_SQRT2_F", |
| "M_SQRT1_2_F", |
| "MAXHALF", |
| "HUGE_VALH", |
| "M_E_H", |
| "M_LOG2E_H", |
| "M_LOG10E_H", |
| "M_LN2_H", |
| "M_LN10_H", |
| "M_PI_H", |
| "M_PI_2_H", |
| "M_PI_4_H", |
| "M_1_PI_H", |
| "M_2_PI_H", |
| "M_2_SQRTPI_H", |
| "M_SQRT2_H", |
| "M_SQRT1_2_H", |
| // "while" // WGSL reserved keyword |
| kUnicodeIdentifier)); |
| |
| std::string ExpandBuiltinType(std::string_view name) { |
| if (name == "array") { |
| return "array<i32, 4>"; |
| } |
| if (name == "atomic") { |
| return "atomic<i32>"; |
| } |
| if (name == "mat2x2") { |
| return "mat2x2<f32>"; |
| } |
| if (name == "mat2x2f") { |
| return "mat2x2<f32>"; |
| } |
| if (name == "mat2x2h") { |
| return "mat2x2<f16>"; |
| } |
| if (name == "mat2x3") { |
| return "mat2x3<f32>"; |
| } |
| if (name == "mat2x3f") { |
| return "mat2x3<f32>"; |
| } |
| if (name == "mat2x3h") { |
| return "mat2x3<f16>"; |
| } |
| if (name == "mat2x4") { |
| return "mat2x4<f32>"; |
| } |
| if (name == "mat2x4f") { |
| return "mat2x4<f32>"; |
| } |
| if (name == "mat2x4h") { |
| return "mat2x4<f16>"; |
| } |
| if (name == "mat3x2") { |
| return "mat3x2<f32>"; |
| } |
| if (name == "mat3x2f") { |
| return "mat3x2<f32>"; |
| } |
| if (name == "mat3x2h") { |
| return "mat3x2<f16>"; |
| } |
| if (name == "mat3x3") { |
| return "mat3x3<f32>"; |
| } |
| if (name == "mat3x3f") { |
| return "mat3x3<f32>"; |
| } |
| if (name == "mat3x3h") { |
| return "mat3x3<f16>"; |
| } |
| if (name == "mat3x4") { |
| return "mat3x4<f32>"; |
| } |
| if (name == "mat3x4f") { |
| return "mat3x4<f32>"; |
| } |
| if (name == "mat3x4h") { |
| return "mat3x4<f16>"; |
| } |
| if (name == "mat4x2") { |
| return "mat4x2<f32>"; |
| } |
| if (name == "mat4x2f") { |
| return "mat4x2<f32>"; |
| } |
| if (name == "mat4x2h") { |
| return "mat4x2<f16>"; |
| } |
| if (name == "mat4x3") { |
| return "mat4x3<f32>"; |
| } |
| if (name == "mat4x3f") { |
| return "mat4x3<f32>"; |
| } |
| if (name == "mat4x3h") { |
| return "mat4x3<f16>"; |
| } |
| if (name == "mat4x4") { |
| return "mat4x4<f32>"; |
| } |
| if (name == "mat4x4f") { |
| return "mat4x4<f32>"; |
| } |
| if (name == "mat4x4h") { |
| return "mat4x4<f16>"; |
| } |
| if (name == "ptr") { |
| return "ptr<function, i32>"; |
| } |
| if (name == "vec2") { |
| return "vec2<f32>"; |
| } |
| if (name == "vec2f") { |
| return "vec2<f32>"; |
| } |
| if (name == "vec2h") { |
| return "vec2<f16>"; |
| } |
| if (name == "vec2i") { |
| return "vec2<i32>"; |
| } |
| if (name == "vec2u") { |
| return "vec2<u32>"; |
| } |
| if (name == "vec3") { |
| return "vec3<f32>"; |
| } |
| if (name == "vec3f") { |
| return "vec3<f32>"; |
| } |
| if (name == "vec3h") { |
| return "vec3<f16>"; |
| } |
| if (name == "vec3i") { |
| return "vec3<i32>"; |
| } |
| if (name == "vec3u") { |
| return "vec3<u32>"; |
| } |
| if (name == "vec4") { |
| return "vec4<f32>"; |
| } |
| if (name == "vec4f") { |
| return "vec4<f32>"; |
| } |
| if (name == "vec4h") { |
| return "vec4<f16>"; |
| } |
| if (name == "vec4i") { |
| return "vec4<i32>"; |
| } |
| if (name == "vec4u") { |
| return "vec4<u32>"; |
| } |
| return std::string(name); |
| } |
| |
| std::vector<const char*> ConstructableTypes() { |
| std::vector<const char*> out; |
| for (auto* ty : builtin::kBuiltinStrings) { |
| std::string_view type(ty); |
| if (type != "ptr" && type != "atomic" && !utils::HasPrefix(type, "sampler") && |
| !utils::HasPrefix(type, "texture") && !utils::HasPrefix(type, "__")) { |
| out.push_back(ty); |
| } |
| } |
| return out; |
| } |
| |
| using RenamerBuiltinTypeTest = TransformTestWithParam<const char*>; |
| |
| TEST_P(RenamerBuiltinTypeTest, PreserveTypeUsage) { |
| auto expand = [&](const char* source) { |
| return utils::ReplaceAll(source, "$type", ExpandBuiltinType(GetParam())); |
| }; |
| |
| auto src = expand(R"( |
| enable f16; |
| |
| fn x(v : $type) -> $type { |
| const a : $type = $type(); |
| let b : $type = a; |
| var c : $type = b; |
| return c; |
| } |
| |
| struct y { |
| a : $type, |
| } |
| )"); |
| |
| auto expect = expand(R"( |
| enable f16; |
| |
| fn tint_symbol(tint_symbol_1 : $type) -> $type { |
| const tint_symbol_2 : $type = $type(); |
| let tint_symbol_3 : $type = tint_symbol_2; |
| var tint_symbol_4 : $type = tint_symbol_3; |
| return tint_symbol_4; |
| } |
| |
| struct tint_symbol_5 { |
| tint_symbol_2 : $type, |
| } |
| )"); |
| |
| auto got = Run<Renamer>(src); |
| |
| EXPECT_EQ(expect, str(got)); |
| } |
| TEST_P(RenamerBuiltinTypeTest, PreserveTypeInitializer) { |
| auto expand = [&](const char* source) { |
| return utils::ReplaceAll(source, "$type", ExpandBuiltinType(GetParam())); |
| }; |
| |
| auto src = expand(R"( |
| enable f16; |
| |
| @fragment |
| fn f() { |
| var v : $type = $type(); |
| } |
| )"); |
| |
| auto expect = expand(R"( |
| enable f16; |
| |
| @fragment |
| fn tint_symbol() { |
| var tint_symbol_1 : $type = $type(); |
| } |
| )"); |
| |
| auto got = Run<Renamer>(src); |
| |
| EXPECT_EQ(expect, str(got)); |
| } |
| |
| TEST_P(RenamerBuiltinTypeTest, PreserveTypeConversion) { |
| if (std::string_view(GetParam()) == "array") { |
| return; // Cannot value convert arrays. |
| } |
| |
| auto expand = [&](const char* source) { |
| return utils::ReplaceAll(source, "$type", ExpandBuiltinType(GetParam())); |
| }; |
| |
| auto src = expand(R"( |
| enable f16; |
| |
| @fragment |
| fn f() { |
| var v : $type = $type($type()); |
| } |
| )"); |
| |
| auto expect = expand(R"( |
| enable f16; |
| |
| @fragment |
| fn tint_symbol() { |
| var tint_symbol_1 : $type = $type($type()); |
| } |
| )"); |
| |
| auto got = Run<Renamer>(src); |
| |
| EXPECT_EQ(expect, str(got)); |
| } |
| |
| TEST_F(RenamerBuiltinTypeTest, PreserveTypeExpression) { |
| auto src = R"( |
| enable f16; |
| |
| @fragment |
| fn f() { |
| var v : array<f32, 2> = array<f32, 2>(); |
| } |
| )"; |
| |
| auto expect = R"( |
| enable f16; |
| |
| @fragment |
| fn tint_symbol() { |
| var tint_symbol_1 : array<f32, 2> = array<f32, 2>(); |
| } |
| )"; |
| |
| auto got = Run<Renamer>(src); |
| |
| EXPECT_EQ(expect, str(got)); |
| } |
| |
| TEST_P(RenamerBuiltinTypeTest, RenameShadowedByAlias) { |
| auto expand = [&](const char* source) { |
| std::string_view ty = GetParam(); |
| auto out = utils::ReplaceAll(source, "$name", ty); |
| out = utils::ReplaceAll(out, "$type", ExpandBuiltinType(ty)); |
| out = utils::ReplaceAll(out, "$other_type", ty == "i32" ? "u32" : "i32"); |
| return out; |
| }; |
| |
| auto src = expand(R"( |
| alias $name = $other_type; |
| |
| @fragment |
| fn f() { |
| var v : $other_type = $name(); |
| } |
| )"); |
| |
| auto expect = expand(R"( |
| alias tint_symbol = $other_type; |
| |
| @fragment |
| fn tint_symbol_1() { |
| var tint_symbol_2 : $other_type = tint_symbol(); |
| } |
| )"); |
| |
| auto got = Run<Renamer>(src); |
| |
| EXPECT_EQ(expect, str(got)); |
| } |
| |
| TEST_P(RenamerBuiltinTypeTest, RenameShadowedByStruct) { |
| auto expand = [&](const char* source) { |
| std::string_view ty = GetParam(); |
| auto out = utils::ReplaceAll(source, "$name", ty); |
| out = utils::ReplaceAll(out, "$type", ExpandBuiltinType(ty)); |
| out = utils::ReplaceAll(out, "$other_type", ty == "i32" ? "u32" : "i32"); |
| return out; |
| }; |
| |
| auto src = expand(R"( |
| struct $name { |
| i : $other_type, |
| } |
| |
| @fragment |
| fn f() { |
| var a = $name(); |
| var b = a.i; |
| } |
| )"); |
| |
| auto expect = expand(R"( |
| struct tint_symbol { |
| tint_symbol_1 : $other_type, |
| } |
| |
| @fragment |
| fn tint_symbol_2() { |
| var tint_symbol_3 = tint_symbol(); |
| var tint_symbol_4 = tint_symbol_3.tint_symbol_1; |
| } |
| )"); |
| |
| auto got = Run<Renamer>(src); |
| |
| EXPECT_EQ(expect, str(got)); |
| } |
| |
| INSTANTIATE_TEST_SUITE_P(RenamerBuiltinTypeTest, |
| RenamerBuiltinTypeTest, |
| testing::ValuesIn(ConstructableTypes())); |
| |
| /// @return WGSL builtin identifier keywords |
| std::vector<const char*> Identifiers() { |
| std::vector<const char*> out; |
| for (auto* ident : builtin::kBuiltinStrings) { |
| if (!utils::HasPrefix(ident, "__")) { |
| out.push_back(ident); |
| } |
| } |
| for (auto* ident : builtin::kAddressSpaceStrings) { |
| if (!utils::HasPrefix(ident, "_")) { |
| out.push_back(ident); |
| } |
| } |
| for (auto* ident : builtin::kTexelFormatStrings) { |
| out.push_back(ident); |
| } |
| for (auto* ident : builtin::kAccessStrings) { |
| out.push_back(ident); |
| } |
| return out; |
| } |
| |
| using RenamerBuiltinIdentifierTest = TransformTestWithParam<const char*>; |
| |
| TEST_P(RenamerBuiltinIdentifierTest, GlobalConstName) { |
| auto expand = [&](const char* source) { |
| return utils::ReplaceAll(source, "$name", GetParam()); |
| }; |
| |
| auto src = expand(R"( |
| const $name = 42; |
| |
| fn f() { |
| const v = $name; |
| } |
| )"); |
| |
| auto expect = expand(R"( |
| const tint_symbol = 42; |
| |
| fn tint_symbol_1() { |
| const tint_symbol_2 = tint_symbol; |
| } |
| )"); |
| |
| auto got = Run<Renamer>(src); |
| |
| EXPECT_EQ(expect, str(got)); |
| } |
| |
| TEST_P(RenamerBuiltinIdentifierTest, LocalVarName) { |
| auto expand = [&](const char* source) { |
| return utils::ReplaceAll(source, "$name", GetParam()); |
| }; |
| |
| auto src = expand(R"( |
| fn f() { |
| var $name = 42; |
| } |
| )"); |
| |
| auto expect = expand(R"( |
| fn tint_symbol() { |
| var tint_symbol_1 = 42; |
| } |
| )"); |
| |
| auto got = Run<Renamer>(src); |
| |
| EXPECT_EQ(expect, str(got)); |
| } |
| |
| TEST_P(RenamerBuiltinIdentifierTest, FunctionName) { |
| auto expand = [&](const char* source) { |
| return utils::ReplaceAll(source, "$name", GetParam()); |
| }; |
| |
| auto src = expand(R"( |
| fn $name() { |
| } |
| |
| fn f() { |
| $name(); |
| } |
| )"); |
| |
| auto expect = expand(R"( |
| fn tint_symbol() { |
| } |
| |
| fn tint_symbol_1() { |
| tint_symbol(); |
| } |
| )"); |
| |
| auto got = Run<Renamer>(src); |
| |
| EXPECT_EQ(expect, str(got)); |
| } |
| |
| TEST_P(RenamerBuiltinIdentifierTest, StructName) { |
| auto expand = [&](const char* source) { |
| std::string_view name = GetParam(); |
| auto out = utils::ReplaceAll(source, "$name", name); |
| return utils::ReplaceAll(out, "$other_type", name == "i32" ? "u32" : "i32"); |
| }; |
| |
| auto src = expand(R"( |
| struct $name { |
| i : $other_type, |
| } |
| |
| fn f() { |
| var x = $name(); |
| } |
| )"); |
| |
| auto expect = expand(R"( |
| struct tint_symbol { |
| tint_symbol_1 : $other_type, |
| } |
| |
| fn tint_symbol_2() { |
| var tint_symbol_3 = tint_symbol(); |
| } |
| )"); |
| |
| auto got = Run<Renamer>(src); |
| |
| EXPECT_EQ(expect, str(got)); |
| } |
| |
| INSTANTIATE_TEST_SUITE_P(RenamerBuiltinIdentifierTest, |
| RenamerBuiltinIdentifierTest, |
| testing::ValuesIn(Identifiers())); |
| |
| } // namespace |
| } // namespace tint::transform |