mirror of
https://github.com/encounter/dawn-cmake.git
synced 2025-12-11 06:27:54 +00:00
transform: Avoid symbol collision in Canonicalize IO
Correctly rename fields when combining two or more input structures together into a single input structure. Bug: chromium:1251009 Change-Id: I0c7ab5ed3116b97035e100d1ef96e772e819f640 Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/64545 Kokoro: Kokoro <noreply+kokoro@google.com> Reviewed-by: James Price <jrprice@google.com> Commit-Queue: Ben Clayton <bclayton@google.com>
This commit is contained in:
committed by
Tint LUCI CQ
parent
231b50baab
commit
9c7cd9e9c3
@@ -112,6 +112,8 @@ struct CanonicalizeEntryPointIO::State {
|
||||
std::vector<OutputValue> wrapper_output_values;
|
||||
/// The body of the wrapper function.
|
||||
ast::StatementList wrapper_body;
|
||||
/// Input names used by the entrypoint
|
||||
std::unordered_set<std::string> input_names;
|
||||
|
||||
/// Constructor
|
||||
/// @param context the clone context
|
||||
@@ -171,29 +173,35 @@ struct CanonicalizeEntryPointIO::State {
|
||||
ctx.dst->ID(), ast::DisabledValidation::kIgnoreStorageClass));
|
||||
|
||||
// Create the global variable and use its value for the shader input.
|
||||
auto var = ctx.dst->Symbols().New(name);
|
||||
ast::Expression* value = ctx.dst->Expr(var);
|
||||
auto symbol = ctx.dst->Symbols().New(name);
|
||||
ast::Expression* value = ctx.dst->Expr(symbol);
|
||||
if (HasSampleMask(attributes)) {
|
||||
// Vulkan requires the type of a SampleMask builtin to be an array.
|
||||
// Declare it as array<u32, 1> and then load the first element.
|
||||
type = ctx.dst->ty.array(type, 1);
|
||||
value = ctx.dst->IndexAccessor(value, 0);
|
||||
}
|
||||
ctx.dst->Global(var, type, ast::StorageClass::kInput,
|
||||
ctx.dst->Global(symbol, type, ast::StorageClass::kInput,
|
||||
std::move(attributes));
|
||||
return value;
|
||||
} else if (cfg.shader_style == ShaderStyle::kMsl &&
|
||||
ast::HasDecoration<ast::BuiltinDecoration>(attributes)) {
|
||||
// If this input is a builtin and we are targeting MSL, then add it to the
|
||||
// parameter list and pass it directly to the inner function.
|
||||
Symbol symbol = input_names.emplace(name).second
|
||||
? ctx.dst->Symbols().Register(name)
|
||||
: ctx.dst->Symbols().New(name);
|
||||
wrapper_ep_parameters.push_back(
|
||||
ctx.dst->Param(name, type, std::move(attributes)));
|
||||
return ctx.dst->Expr(name);
|
||||
ctx.dst->Param(symbol, type, std::move(attributes)));
|
||||
return ctx.dst->Expr(symbol);
|
||||
} else {
|
||||
// Otherwise, move it to the new structure member list.
|
||||
Symbol symbol = input_names.emplace(name).second
|
||||
? ctx.dst->Symbols().Register(name)
|
||||
: ctx.dst->Symbols().New(name);
|
||||
wrapper_struct_param_members.push_back(
|
||||
ctx.dst->Member(name, type, std::move(attributes)));
|
||||
return ctx.dst->MemberAccessor(InputStructSymbol(), name);
|
||||
ctx.dst->Member(symbol, type, std::move(attributes)));
|
||||
return ctx.dst->MemberAccessor(InputStructSymbol(), symbol);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2062,18 +2062,31 @@ var<private> vertex_point_size : f32;
|
||||
var<private> vertex_point_size_1 : f32;
|
||||
var<private> vertex_point_size_2 : f32;
|
||||
|
||||
struct VertIn1 {
|
||||
[[location(0)]] collide : f32;
|
||||
};
|
||||
|
||||
struct VertIn2 {
|
||||
[[location(1)]] collide : f32;
|
||||
};
|
||||
|
||||
struct VertOut {
|
||||
[[location(0)]] vertex_point_size : f32;
|
||||
[[builtin(position)]] vertex_point_size_1 : vec4<f32>;
|
||||
};
|
||||
|
||||
[[stage(vertex)]]
|
||||
fn vert_main() -> VertOut {
|
||||
fn vert_main(collide : VertIn1, collide_1 : VertIn2) -> VertOut {
|
||||
let x = collide.collide + collide_1.collide;
|
||||
return VertOut();
|
||||
}
|
||||
)";
|
||||
|
||||
auto* expect = R"(
|
||||
[[location(0), internal(disable_validation__ignore_storage_class)]] var<in> collide_2 : f32;
|
||||
|
||||
[[location(1), internal(disable_validation__ignore_storage_class)]] var<in> collide_3 : f32;
|
||||
|
||||
[[location(0), internal(disable_validation__ignore_storage_class)]] var<out> vertex_point_size_3 : f32;
|
||||
|
||||
[[builtin(position), internal(disable_validation__ignore_storage_class)]] var<out> vertex_point_size_1_1 : vec4<f32>;
|
||||
@@ -2086,18 +2099,27 @@ var<private> vertex_point_size_1 : f32;
|
||||
|
||||
var<private> vertex_point_size_2 : f32;
|
||||
|
||||
struct VertIn1 {
|
||||
collide : f32;
|
||||
};
|
||||
|
||||
struct VertIn2 {
|
||||
collide : f32;
|
||||
};
|
||||
|
||||
struct VertOut {
|
||||
vertex_point_size : f32;
|
||||
vertex_point_size_1 : vec4<f32>;
|
||||
};
|
||||
|
||||
fn vert_main_inner() -> VertOut {
|
||||
fn vert_main_inner(collide : VertIn1, collide_1 : VertIn2) -> VertOut {
|
||||
let x = (collide.collide + collide_1.collide);
|
||||
return VertOut();
|
||||
}
|
||||
|
||||
[[stage(vertex)]]
|
||||
fn vert_main() {
|
||||
let inner_result = vert_main_inner();
|
||||
let inner_result = vert_main_inner(VertIn1(collide_2), VertIn2(collide_3));
|
||||
vertex_point_size_3 = inner_result.vertex_point_size;
|
||||
vertex_point_size_1_1 = inner_result.vertex_point_size_1;
|
||||
vertex_point_size_4 = 1.0;
|
||||
@@ -2114,24 +2136,48 @@ fn vert_main() {
|
||||
|
||||
TEST_F(CanonicalizeEntryPointIOTest, EmitVertexPointSize_AvoidNameClash_Msl) {
|
||||
auto* src = R"(
|
||||
struct VertIn1 {
|
||||
[[location(0)]] collide : f32;
|
||||
};
|
||||
|
||||
struct VertIn2 {
|
||||
[[location(1)]] collide : f32;
|
||||
};
|
||||
|
||||
struct VertOut {
|
||||
[[location(0)]] vertex_point_size : vec4<f32>;
|
||||
[[builtin(position)]] vertex_point_size_1 : vec4<f32>;
|
||||
};
|
||||
|
||||
[[stage(vertex)]]
|
||||
fn vert_main() -> VertOut {
|
||||
fn vert_main(collide : VertIn1, collide_1 : VertIn2) -> VertOut {
|
||||
let x = collide.collide + collide_1.collide;
|
||||
return VertOut();
|
||||
}
|
||||
)";
|
||||
|
||||
auto* expect = R"(
|
||||
struct VertIn1 {
|
||||
collide : f32;
|
||||
};
|
||||
|
||||
struct VertIn2 {
|
||||
collide : f32;
|
||||
};
|
||||
|
||||
struct VertOut {
|
||||
vertex_point_size : vec4<f32>;
|
||||
vertex_point_size_1 : vec4<f32>;
|
||||
};
|
||||
|
||||
struct tint_symbol {
|
||||
struct tint_symbol_1 {
|
||||
[[location(0)]]
|
||||
collide : f32;
|
||||
[[location(1)]]
|
||||
collide_2 : f32;
|
||||
};
|
||||
|
||||
struct tint_symbol_2 {
|
||||
[[location(0)]]
|
||||
vertex_point_size : vec4<f32>;
|
||||
[[builtin(position)]]
|
||||
@@ -2140,14 +2186,15 @@ struct tint_symbol {
|
||||
vertex_point_size_2 : f32;
|
||||
};
|
||||
|
||||
fn vert_main_inner() -> VertOut {
|
||||
fn vert_main_inner(collide : VertIn1, collide_1 : VertIn2) -> VertOut {
|
||||
let x = (collide.collide + collide_1.collide);
|
||||
return VertOut();
|
||||
}
|
||||
|
||||
[[stage(vertex)]]
|
||||
fn vert_main() -> tint_symbol {
|
||||
let inner_result = vert_main_inner();
|
||||
var wrapper_result : tint_symbol;
|
||||
fn vert_main(tint_symbol : tint_symbol_1) -> tint_symbol_2 {
|
||||
let inner_result = vert_main_inner(VertIn1(tint_symbol.collide), VertIn2(tint_symbol.collide_2));
|
||||
var wrapper_result : tint_symbol_2;
|
||||
wrapper_result.vertex_point_size = inner_result.vertex_point_size;
|
||||
wrapper_result.vertex_point_size_1 = inner_result.vertex_point_size_1;
|
||||
wrapper_result.vertex_point_size_2 = 1.0;
|
||||
@@ -2163,6 +2210,82 @@ fn vert_main() -> tint_symbol {
|
||||
EXPECT_EQ(expect, str(got));
|
||||
}
|
||||
|
||||
TEST_F(CanonicalizeEntryPointIOTest, EmitVertexPointSize_AvoidNameClash_Hlsl) {
|
||||
auto* src = R"(
|
||||
struct VertIn1 {
|
||||
[[location(0)]] collide : f32;
|
||||
};
|
||||
|
||||
struct VertIn2 {
|
||||
[[location(1)]] collide : f32;
|
||||
};
|
||||
|
||||
struct VertOut {
|
||||
[[location(0)]] vertex_point_size : vec4<f32>;
|
||||
[[builtin(position)]] vertex_point_size_1 : vec4<f32>;
|
||||
};
|
||||
|
||||
[[stage(vertex)]]
|
||||
fn vert_main(collide : VertIn1, collide_1 : VertIn2) -> VertOut {
|
||||
let x = collide.collide + collide_1.collide;
|
||||
return VertOut();
|
||||
}
|
||||
)";
|
||||
|
||||
auto* expect = R"(
|
||||
struct VertIn1 {
|
||||
collide : f32;
|
||||
};
|
||||
|
||||
struct VertIn2 {
|
||||
collide : f32;
|
||||
};
|
||||
|
||||
struct VertOut {
|
||||
vertex_point_size : vec4<f32>;
|
||||
vertex_point_size_1 : vec4<f32>;
|
||||
};
|
||||
|
||||
struct tint_symbol_1 {
|
||||
[[location(0)]]
|
||||
collide : f32;
|
||||
[[location(1)]]
|
||||
collide_2 : f32;
|
||||
};
|
||||
|
||||
struct tint_symbol_2 {
|
||||
[[location(0)]]
|
||||
vertex_point_size : vec4<f32>;
|
||||
[[builtin(position)]]
|
||||
vertex_point_size_1 : vec4<f32>;
|
||||
[[builtin(pointsize)]]
|
||||
vertex_point_size_2 : f32;
|
||||
};
|
||||
|
||||
fn vert_main_inner(collide : VertIn1, collide_1 : VertIn2) -> VertOut {
|
||||
let x = (collide.collide + collide_1.collide);
|
||||
return VertOut();
|
||||
}
|
||||
|
||||
[[stage(vertex)]]
|
||||
fn vert_main(tint_symbol : tint_symbol_1) -> tint_symbol_2 {
|
||||
let inner_result = vert_main_inner(VertIn1(tint_symbol.collide), VertIn2(tint_symbol.collide_2));
|
||||
var wrapper_result : tint_symbol_2;
|
||||
wrapper_result.vertex_point_size = inner_result.vertex_point_size;
|
||||
wrapper_result.vertex_point_size_1 = inner_result.vertex_point_size_1;
|
||||
wrapper_result.vertex_point_size_2 = 1.0;
|
||||
return wrapper_result;
|
||||
}
|
||||
)";
|
||||
|
||||
DataMap data;
|
||||
data.Add<CanonicalizeEntryPointIO::Config>(
|
||||
CanonicalizeEntryPointIO::ShaderStyle::kHlsl, 0xFFFFFFFF, true);
|
||||
auto got = Run<CanonicalizeEntryPointIO>(src, data);
|
||||
|
||||
EXPECT_EQ(expect, str(got));
|
||||
}
|
||||
|
||||
TEST_F(CanonicalizeEntryPointIOTest, SpirvSampleMaskBuiltins) {
|
||||
auto* src = R"(
|
||||
[[stage(fragment)]]
|
||||
|
||||
Reference in New Issue
Block a user