mirror of
https://github.com/encounter/dawn-cmake.git
synced 2025-06-05 22:23:29 +00:00
Use it for entry point IO sanitizing transforms to fix cases where structures were being inserted before type aliases that they reference. Also fixes up some ordering issues with the FirstIndexOffset transform. Change-Id: I50d472ccb844b388f69914dcecbc0fcda1a579ed Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/45000 Reviewed-by: Ben Clayton <bclayton@google.com> Commit-Queue: Ben Clayton <bclayton@google.com> Auto-Submit: James Price <jrprice@google.com>
435 lines
14 KiB
C++
435 lines
14 KiB
C++
// 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/transform/msl.h"
|
|
|
|
#include <string>
|
|
|
|
#include "src/transform/test_helper.h"
|
|
|
|
namespace tint {
|
|
namespace transform {
|
|
namespace {
|
|
|
|
using MslReservedKeywordTest = TransformTestWithParam<std::string>;
|
|
|
|
TEST_F(MslReservedKeywordTest, Basic) {
|
|
auto* src = R"(
|
|
struct class {
|
|
delete : i32;
|
|
};
|
|
|
|
[[stage(fragment)]]
|
|
fn main() -> void {
|
|
var foo : i32;
|
|
var half : f32;
|
|
var half1 : f32;
|
|
var half2 : f32;
|
|
var _tint_half2 : f32;
|
|
}
|
|
)";
|
|
|
|
auto* expect = R"(
|
|
struct _tint_class {
|
|
_tint_delete : i32;
|
|
};
|
|
|
|
[[stage(fragment)]]
|
|
fn _tint_main() -> void {
|
|
var foo : i32;
|
|
var _tint_half : f32;
|
|
var half1 : f32;
|
|
var _tint_half2_0 : f32;
|
|
var _tint_half2 : f32;
|
|
}
|
|
)";
|
|
|
|
auto got = Run<Msl>(src);
|
|
|
|
EXPECT_EQ(expect, str(got));
|
|
}
|
|
|
|
TEST_P(MslReservedKeywordTest, Keywords) {
|
|
auto keyword = GetParam();
|
|
|
|
auto src = R"(
|
|
[[stage(fragment)]]
|
|
fn main() -> void {
|
|
var )" + keyword +
|
|
R"( : i32;
|
|
}
|
|
)";
|
|
|
|
auto expect = R"(
|
|
[[stage(fragment)]]
|
|
fn _tint_main() -> void {
|
|
var _tint_)" + keyword +
|
|
R"( : i32;
|
|
}
|
|
)";
|
|
|
|
auto got = Run<Msl>(src);
|
|
|
|
EXPECT_EQ(expect, str(got));
|
|
}
|
|
INSTANTIATE_TEST_SUITE_P(MslReservedKeywordTest,
|
|
MslReservedKeywordTest,
|
|
testing::Values(
|
|
// c++14 spec
|
|
"alignas",
|
|
"alignof",
|
|
"and",
|
|
"and_eq",
|
|
// "asm", // Also reserved in WGSL
|
|
"auto",
|
|
"bitand",
|
|
"bitor",
|
|
// "bool", // Also used in WGSL
|
|
// "break", // Also used in WGSL
|
|
// "case", // Also used in WGSL
|
|
"catch",
|
|
"char",
|
|
"char16_t",
|
|
"char32_t",
|
|
"class",
|
|
"compl",
|
|
// "const", // Also used in WGSL
|
|
"const_cast",
|
|
"constexpr",
|
|
// "continue", // Also used in WGSL
|
|
"decltype",
|
|
// "default", // Also used in WGSL
|
|
"delete",
|
|
// "do", // Also used in WGSL
|
|
"double",
|
|
"dynamic_cast",
|
|
// "else", // Also used in WGSL
|
|
// "enum", // Also used in WGSL
|
|
"explicit",
|
|
"extern",
|
|
// "false", // Also used in WGSL
|
|
"final",
|
|
"float",
|
|
// "for", // Also used in WGSL
|
|
"friend",
|
|
"goto",
|
|
// "if", // Also used in WGSL
|
|
"inline",
|
|
"int",
|
|
"long",
|
|
"mutable",
|
|
"namespace",
|
|
"new",
|
|
"noexcept",
|
|
"not",
|
|
"not_eq",
|
|
"nullptr",
|
|
"operator",
|
|
"or",
|
|
"or_eq",
|
|
"override",
|
|
// "private", // Also used in WGSL
|
|
"protected",
|
|
"public",
|
|
"register",
|
|
"reinterpret_cast",
|
|
// "return", // Also used in WGSL
|
|
"short",
|
|
"signed",
|
|
"sizeof",
|
|
"static",
|
|
"static_assert",
|
|
"static_cast",
|
|
// "struct", // Also used in WGSL
|
|
// "switch", // Also used in WGSL
|
|
"template",
|
|
"this",
|
|
"thread_local",
|
|
"throw",
|
|
// "true", // Also used in WGSL
|
|
"try",
|
|
// "typedef", // Also used in WGSL
|
|
"typeid",
|
|
"typename",
|
|
"union",
|
|
"unsigned",
|
|
"using",
|
|
"virtual",
|
|
// "void", // Also used in WGSL
|
|
"volatile",
|
|
"wchar_t",
|
|
"while",
|
|
"xor",
|
|
"xor_eq",
|
|
|
|
// Metal Spec
|
|
"access",
|
|
// "array", // Also used in WGSL
|
|
"array_ref",
|
|
"as_type",
|
|
"atomic",
|
|
"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
|
|
"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", // Also used in WGSL
|
|
"reference",
|
|
"rg11b10f",
|
|
"rg16snorm",
|
|
"rg16unorm",
|
|
// "rg8snorm", // Also used in WGSL
|
|
// "rg8unorm", // Also used in WGSL
|
|
"rgb10a2",
|
|
"rgb9e5",
|
|
"rgba16snorm",
|
|
"rgba16unorm",
|
|
// "rgba8snorm", // Also used in WGSL
|
|
// "rgba8unorm", // Also used in WGSL
|
|
// "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",
|
|
"vertex"));
|
|
|
|
using MslEntryPointIOTest = TransformTest;
|
|
|
|
TEST_F(MslEntryPointIOTest, HandleEntryPointIOTypes_Parameters) {
|
|
auto* src = R"(
|
|
[[stage(fragment)]]
|
|
fn frag_main([[builtin(frag_coord)]] coord : vec4<f32>,
|
|
[[location(1)]] loc1 : f32,
|
|
[[location(2)]] loc2 : vec4<u32>) -> void {
|
|
var col : f32 = (coord.x * loc1);
|
|
}
|
|
)";
|
|
|
|
auto* expect = R"(
|
|
struct tint_symbol_3 {
|
|
[[location(1)]]
|
|
loc1 : f32;
|
|
[[location(2)]]
|
|
loc2 : vec4<u32>;
|
|
};
|
|
|
|
[[stage(fragment)]]
|
|
fn frag_main(tint_symbol_4 : tint_symbol_3, [[builtin(frag_coord)]] coord : vec4<f32>) -> void {
|
|
const loc1 : f32 = tint_symbol_4.loc1;
|
|
const loc2 : vec4<u32> = tint_symbol_4.loc2;
|
|
var col : f32 = (coord.x * loc1);
|
|
}
|
|
)";
|
|
|
|
auto got = Run<Msl>(src);
|
|
|
|
EXPECT_EQ(expect, str(got));
|
|
}
|
|
|
|
TEST_F(MslEntryPointIOTest, HandleEntryPointIOTypes_OnlyBuiltinParameters) {
|
|
// Expect no change.
|
|
auto* src = R"(
|
|
[[stage(fragment)]]
|
|
fn frag_main([[builtin(frag_coord)]] coord : vec4<f32>) -> void {
|
|
}
|
|
)";
|
|
|
|
auto got = Run<Msl>(src);
|
|
|
|
EXPECT_EQ(src, str(got));
|
|
}
|
|
|
|
TEST_F(MslEntryPointIOTest, HandleEntryPointIOTypes_Parameter_TypeAlias) {
|
|
auto* src = R"(
|
|
type myf32 = f32;
|
|
|
|
[[stage(fragment)]]
|
|
fn frag_main([[location(1)]] loc1 : myf32) -> void {
|
|
}
|
|
)";
|
|
|
|
auto* expect = R"(
|
|
type myf32 = f32;
|
|
|
|
struct tint_symbol_3 {
|
|
[[location(1)]]
|
|
loc1 : myf32;
|
|
};
|
|
|
|
[[stage(fragment)]]
|
|
fn frag_main(tint_symbol_4 : tint_symbol_3) -> void {
|
|
const loc1 : myf32 = tint_symbol_4.loc1;
|
|
}
|
|
)";
|
|
|
|
auto got = Run<Msl>(src);
|
|
|
|
EXPECT_EQ(expect, str(got));
|
|
}
|
|
|
|
TEST_F(MslEntryPointIOTest, HandleEntryPointIOTypes_Parameters_EmptyBody) {
|
|
auto* src = R"(
|
|
[[stage(fragment)]]
|
|
fn frag_main([[builtin(frag_coord)]] coord : vec4<f32>,
|
|
[[location(1)]] loc1 : f32,
|
|
[[location(2)]] loc2 : vec4<u32>) -> void {
|
|
}
|
|
)";
|
|
|
|
auto* expect = R"(
|
|
struct tint_symbol_3 {
|
|
[[location(1)]]
|
|
loc1 : f32;
|
|
[[location(2)]]
|
|
loc2 : vec4<u32>;
|
|
};
|
|
|
|
[[stage(fragment)]]
|
|
fn frag_main(tint_symbol_4 : tint_symbol_3, [[builtin(frag_coord)]] coord : vec4<f32>) -> void {
|
|
const loc1 : f32 = tint_symbol_4.loc1;
|
|
const loc2 : vec4<u32> = tint_symbol_4.loc2;
|
|
}
|
|
)";
|
|
|
|
auto got = Run<Msl>(src);
|
|
|
|
EXPECT_EQ(expect, str(got));
|
|
}
|
|
|
|
} // namespace
|
|
} // namespace transform
|
|
} // namespace tint
|