tint: Add chromium_internal_relaxed_uniform_layout
This will be used by the PackedVec3 transform to avoid triggering stricter layout validation rules for the uniform address space when mutating types. Bug: tint:1571 Change-Id: Ib15737fbe3cab4a8fbe453bcaf96ef2acc595921 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/121601 Commit-Queue: James Price <jrprice@google.com> Reviewed-by: Ben Clayton <bclayton@google.com> Kokoro: Kokoro <noreply+kokoro@google.com>
This commit is contained in:
parent
806135658d
commit
0b3400c56e
|
@ -40,6 +40,9 @@ Extension ParseExtension(std::string_view str) {
|
|||
if (str == "chromium_experimental_push_constant") {
|
||||
return Extension::kChromiumExperimentalPushConstant;
|
||||
}
|
||||
if (str == "chromium_internal_relaxed_uniform_layout") {
|
||||
return Extension::kChromiumInternalRelaxedUniformLayout;
|
||||
}
|
||||
if (str == "f16") {
|
||||
return Extension::kF16;
|
||||
}
|
||||
|
@ -58,6 +61,8 @@ std::ostream& operator<<(std::ostream& out, Extension value) {
|
|||
return out << "chromium_experimental_full_ptr_parameters";
|
||||
case Extension::kChromiumExperimentalPushConstant:
|
||||
return out << "chromium_experimental_push_constant";
|
||||
case Extension::kChromiumInternalRelaxedUniformLayout:
|
||||
return out << "chromium_internal_relaxed_uniform_layout";
|
||||
case Extension::kF16:
|
||||
return out << "f16";
|
||||
}
|
||||
|
|
|
@ -37,6 +37,7 @@ enum class Extension {
|
|||
kChromiumExperimentalDp4A,
|
||||
kChromiumExperimentalFullPtrParameters,
|
||||
kChromiumExperimentalPushConstant,
|
||||
kChromiumInternalRelaxedUniformLayout,
|
||||
kF16,
|
||||
};
|
||||
|
||||
|
@ -51,11 +52,9 @@ std::ostream& operator<<(std::ostream& out, Extension value);
|
|||
Extension ParseExtension(std::string_view str);
|
||||
|
||||
constexpr const char* kExtensionStrings[] = {
|
||||
"chromium_disable_uniformity_analysis",
|
||||
"chromium_experimental_dp4a",
|
||||
"chromium_experimental_full_ptr_parameters",
|
||||
"chromium_experimental_push_constant",
|
||||
"f16",
|
||||
"chromium_disable_uniformity_analysis", "chromium_experimental_dp4a",
|
||||
"chromium_experimental_full_ptr_parameters", "chromium_experimental_push_constant",
|
||||
"chromium_internal_relaxed_uniform_layout", "f16",
|
||||
};
|
||||
|
||||
// A unique vector of extensions
|
||||
|
|
|
@ -59,13 +59,20 @@ void ExtensionParser(::benchmark::State& state) {
|
|||
"chromium_exp9rimFntal_ush_constant",
|
||||
"chrmium_experimental_push_constant",
|
||||
"cOOromium_experiVeHtal_puh_conRRtant",
|
||||
"y1",
|
||||
"l77rrn6",
|
||||
"4016",
|
||||
"chromium_internl_relaxyd_uniform_layout",
|
||||
"chromnnum_internrr77_Gelaxell_uniform_layout",
|
||||
"chromium_intern4l_relaxe00_uniform_layout",
|
||||
"chromium_internal_relaxed_uniform_layout",
|
||||
"chrmoom_internal_relaxed_uniform_lyout",
|
||||
"chroium_internal_rlaxed_uniform_layzzut",
|
||||
"chromium_internaii_r11axed_uppifor_layout",
|
||||
"f1XX",
|
||||
"55199II",
|
||||
"frSSHHa",
|
||||
"f16",
|
||||
"5",
|
||||
"u16",
|
||||
"f",
|
||||
"U",
|
||||
"jV3",
|
||||
"",
|
||||
};
|
||||
for (auto _ : state) {
|
||||
for (auto* str : kStrings) {
|
||||
|
|
|
@ -48,6 +48,7 @@ static constexpr Case kValidCases[] = {
|
|||
{"chromium_experimental_full_ptr_parameters",
|
||||
Extension::kChromiumExperimentalFullPtrParameters},
|
||||
{"chromium_experimental_push_constant", Extension::kChromiumExperimentalPushConstant},
|
||||
{"chromium_internal_relaxed_uniform_layout", Extension::kChromiumInternalRelaxedUniformLayout},
|
||||
{"f16", Extension::kF16},
|
||||
};
|
||||
|
||||
|
@ -64,9 +65,12 @@ static constexpr Case kInvalidCases[] = {
|
|||
{"chvomium_experimental_push_constiint", Extension::kUndefined},
|
||||
{"chromiu8WWexperimental_push_constant", Extension::kUndefined},
|
||||
{"chromium_experiMental_push_costanxx", Extension::kUndefined},
|
||||
{"fgg", Extension::kUndefined},
|
||||
{"X", Extension::kUndefined},
|
||||
{"316", Extension::kUndefined},
|
||||
{"chromium_internal_relaxed_unXform_layugg", Extension::kUndefined},
|
||||
{"chromiuu_iVterna_relxed_unifXrm_layout", Extension::kUndefined},
|
||||
{"chromium_internal_relaxed_uni3orm_layout", Extension::kUndefined},
|
||||
{"fE6", Extension::kUndefined},
|
||||
{"fPTT", Extension::kUndefined},
|
||||
{"dxx6", Extension::kUndefined},
|
||||
};
|
||||
|
||||
using ExtensionParseTest = testing::TestWithParam<Case>;
|
||||
|
|
|
@ -70,6 +70,8 @@ enum extension {
|
|||
// A Chromium-specific extension that enables passing of uniform, storage and workgroup
|
||||
// address-spaced pointers as parameters, as well as pointers into sub-objects.
|
||||
chromium_experimental_full_ptr_parameters
|
||||
// A Chromium-specific extension that relaxes memory layout requirements for uniform storage.
|
||||
chromium_internal_relaxed_uniform_layout
|
||||
}
|
||||
|
||||
// https://gpuweb.github.io/gpuweb/wgsl/#storage-class
|
||||
|
|
|
@ -62,7 +62,7 @@ TEST_F(EnableDirectiveTest, InvalidIdentifier) {
|
|||
// Error when unknown extension found
|
||||
EXPECT_TRUE(p->has_error());
|
||||
EXPECT_EQ(p->error(), R"(1:8: expected extension
|
||||
Possible values: 'chromium_disable_uniformity_analysis', 'chromium_experimental_dp4a', 'chromium_experimental_full_ptr_parameters', 'chromium_experimental_push_constant', 'f16')");
|
||||
Possible values: 'chromium_disable_uniformity_analysis', 'chromium_experimental_dp4a', 'chromium_experimental_full_ptr_parameters', 'chromium_experimental_push_constant', 'chromium_internal_relaxed_uniform_layout', 'f16')");
|
||||
auto program = p->program();
|
||||
auto& ast = program.AST();
|
||||
EXPECT_EQ(ast.Enables().Length(), 0u);
|
||||
|
@ -76,7 +76,7 @@ TEST_F(EnableDirectiveTest, InvalidIdentifierSuggest) {
|
|||
EXPECT_TRUE(p->has_error());
|
||||
EXPECT_EQ(p->error(), R"(1:8: expected extension
|
||||
Did you mean 'f16'?
|
||||
Possible values: 'chromium_disable_uniformity_analysis', 'chromium_experimental_dp4a', 'chromium_experimental_full_ptr_parameters', 'chromium_experimental_push_constant', 'f16')");
|
||||
Possible values: 'chromium_disable_uniformity_analysis', 'chromium_experimental_dp4a', 'chromium_experimental_full_ptr_parameters', 'chromium_experimental_push_constant', 'chromium_internal_relaxed_uniform_layout', 'f16')");
|
||||
auto program = p->program();
|
||||
auto& ast = program.AST();
|
||||
EXPECT_EQ(ast.Enables().Length(), 0u);
|
||||
|
@ -124,7 +124,7 @@ TEST_F(EnableDirectiveTest, InvalidTokens) {
|
|||
p->translation_unit();
|
||||
EXPECT_TRUE(p->has_error());
|
||||
EXPECT_EQ(p->error(), R"(1:8: expected extension
|
||||
Possible values: 'chromium_disable_uniformity_analysis', 'chromium_experimental_dp4a', 'chromium_experimental_full_ptr_parameters', 'chromium_experimental_push_constant', 'f16')");
|
||||
Possible values: 'chromium_disable_uniformity_analysis', 'chromium_experimental_dp4a', 'chromium_experimental_full_ptr_parameters', 'chromium_experimental_push_constant', 'chromium_internal_relaxed_uniform_layout', 'f16')");
|
||||
auto program = p->program();
|
||||
auto& ast = program.AST();
|
||||
EXPECT_EQ(ast.Enables().Length(), 0u);
|
||||
|
@ -135,7 +135,7 @@ Possible values: 'chromium_disable_uniformity_analysis', 'chromium_experimental_
|
|||
p->translation_unit();
|
||||
EXPECT_TRUE(p->has_error());
|
||||
EXPECT_EQ(p->error(), R"(1:8: expected extension
|
||||
Possible values: 'chromium_disable_uniformity_analysis', 'chromium_experimental_dp4a', 'chromium_experimental_full_ptr_parameters', 'chromium_experimental_push_constant', 'f16')");
|
||||
Possible values: 'chromium_disable_uniformity_analysis', 'chromium_experimental_dp4a', 'chromium_experimental_full_ptr_parameters', 'chromium_experimental_push_constant', 'chromium_internal_relaxed_uniform_layout', 'f16')");
|
||||
auto program = p->program();
|
||||
auto& ast = program.AST();
|
||||
EXPECT_EQ(ast.Enables().Length(), 0u);
|
||||
|
@ -147,7 +147,7 @@ Possible values: 'chromium_disable_uniformity_analysis', 'chromium_experimental_
|
|||
EXPECT_TRUE(p->has_error());
|
||||
EXPECT_EQ(p->error(), R"(1:8: expected extension
|
||||
Did you mean 'f16'?
|
||||
Possible values: 'chromium_disable_uniformity_analysis', 'chromium_experimental_dp4a', 'chromium_experimental_full_ptr_parameters', 'chromium_experimental_push_constant', 'f16')");
|
||||
Possible values: 'chromium_disable_uniformity_analysis', 'chromium_experimental_dp4a', 'chromium_experimental_full_ptr_parameters', 'chromium_experimental_push_constant', 'chromium_internal_relaxed_uniform_layout', 'f16')");
|
||||
auto program = p->program();
|
||||
auto& ast = program.AST();
|
||||
EXPECT_EQ(ast.Enables().Length(), 0u);
|
||||
|
|
|
@ -603,5 +603,150 @@ TEST_F(ResolverAddressSpaceLayoutValidationTest, PushConstant_Aligned) {
|
|||
ASSERT_TRUE(r()->Resolve()) << r()->error();
|
||||
}
|
||||
|
||||
TEST_F(ResolverAddressSpaceLayoutValidationTest, RelaxedUniformLayout_StructMemberOffset_Struct) {
|
||||
// enable chromium_internal_relaxed_uniform_layout;
|
||||
//
|
||||
// struct Inner {
|
||||
// scalar : i32;
|
||||
// };
|
||||
//
|
||||
// struct Outer {
|
||||
// scalar : f32;
|
||||
// inner : Inner;
|
||||
// };
|
||||
//
|
||||
// @group(0) @binding(0)
|
||||
// var<uniform> a : Outer;
|
||||
|
||||
Enable(builtin::Extension::kChromiumInternalRelaxedUniformLayout);
|
||||
|
||||
Structure(Source{{12, 34}}, "Inner",
|
||||
utils::Vector{
|
||||
Member("scalar", ty.i32()),
|
||||
});
|
||||
|
||||
Structure(Source{{34, 56}}, "Outer",
|
||||
utils::Vector{
|
||||
Member("scalar", ty.f32()),
|
||||
Member(Source{{56, 78}}, "inner", ty("Inner")),
|
||||
});
|
||||
|
||||
GlobalVar(Source{{78, 90}}, "a", ty("Outer"), builtin::AddressSpace::kUniform, Group(0_a),
|
||||
Binding(0_a));
|
||||
|
||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||
}
|
||||
|
||||
TEST_F(ResolverAddressSpaceLayoutValidationTest, RelaxedUniformLayout_StructMemberOffset_Array) {
|
||||
// enable chromium_internal_relaxed_uniform_layout;
|
||||
//
|
||||
// type Inner = @stride(16) array<f32, 10u>;
|
||||
//
|
||||
// struct Outer {
|
||||
// scalar : f32;
|
||||
// inner : Inner;
|
||||
// };
|
||||
//
|
||||
// @group(0) @binding(0)
|
||||
// var<uniform> a : Outer;
|
||||
|
||||
Enable(builtin::Extension::kChromiumInternalRelaxedUniformLayout);
|
||||
|
||||
Alias("Inner", ty.array<f32, 10>(utils::Vector{Stride(16)}));
|
||||
|
||||
Structure(Source{{12, 34}}, "Outer",
|
||||
utils::Vector{
|
||||
Member("scalar", ty.f32()),
|
||||
Member(Source{{56, 78}}, "inner", ty("Inner")),
|
||||
});
|
||||
|
||||
GlobalVar(Source{{78, 90}}, "a", ty("Outer"), builtin::AddressSpace::kUniform, Group(0_a),
|
||||
Binding(0_a));
|
||||
|
||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||
}
|
||||
|
||||
TEST_F(ResolverAddressSpaceLayoutValidationTest, RelaxedUniformLayout_MemberOffsetNotMutipleOf16) {
|
||||
// enable chromium_internal_relaxed_uniform_layout;
|
||||
//
|
||||
// struct Inner {
|
||||
// @align(1) @size(5) scalar : i32;
|
||||
// };
|
||||
//
|
||||
// struct Outer {
|
||||
// inner : Inner;
|
||||
// scalar : i32;
|
||||
// };
|
||||
//
|
||||
// @group(0) @binding(0)
|
||||
// var<uniform> a : Outer;
|
||||
|
||||
Enable(builtin::Extension::kChromiumInternalRelaxedUniformLayout);
|
||||
|
||||
Structure(Source{{12, 34}}, "Inner",
|
||||
utils::Vector{
|
||||
Member("scalar", ty.i32(), utils::Vector{MemberAlign(1_i), MemberSize(5_a)}),
|
||||
});
|
||||
|
||||
Structure(Source{{34, 56}}, "Outer",
|
||||
utils::Vector{
|
||||
Member(Source{{56, 78}}, "inner", ty("Inner")),
|
||||
Member(Source{{78, 90}}, "scalar", ty.i32()),
|
||||
});
|
||||
|
||||
GlobalVar(Source{{22, 24}}, "a", ty("Outer"), builtin::AddressSpace::kUniform, Group(0_a),
|
||||
Binding(0_a));
|
||||
|
||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||
}
|
||||
|
||||
TEST_F(ResolverAddressSpaceLayoutValidationTest, RelaxedUniformLayout_ArrayStride_Scalar) {
|
||||
// enable chromium_internal_relaxed_uniform_layout;
|
||||
//
|
||||
// struct Outer {
|
||||
// arr : array<f32, 10u>;
|
||||
// };
|
||||
//
|
||||
// @group(0) @binding(0)
|
||||
// var<uniform> a : Outer;
|
||||
|
||||
Enable(builtin::Extension::kChromiumInternalRelaxedUniformLayout);
|
||||
|
||||
Structure(Source{{12, 34}}, "Outer",
|
||||
utils::Vector{
|
||||
Member("arr", ty.array<f32, 10>()),
|
||||
});
|
||||
|
||||
GlobalVar(Source{{78, 90}}, "a", ty("Outer"), builtin::AddressSpace::kUniform, Group(0_a),
|
||||
Binding(0_a));
|
||||
|
||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||
}
|
||||
|
||||
TEST_F(ResolverAddressSpaceLayoutValidationTest, RelaxedUniformLayout_ArrayStride_Vech) {
|
||||
// enable f16;
|
||||
// enable chromium_internal_relaxed_uniform_layout;
|
||||
//
|
||||
// struct Outer {
|
||||
// arr : array<vec3<f16>, 10u>;
|
||||
// };
|
||||
//
|
||||
// @group(0) @binding(0)
|
||||
// var<uniform> a : Outer;
|
||||
|
||||
Enable(builtin::Extension::kF16);
|
||||
Enable(builtin::Extension::kChromiumInternalRelaxedUniformLayout);
|
||||
|
||||
Structure(Source{{12, 34}}, "Outer",
|
||||
utils::Vector{
|
||||
Member("arr", ty.array(ty.vec3<f16>(), 10_u)),
|
||||
});
|
||||
|
||||
GlobalVar(Source{{78, 90}}, "a", ty("Outer"), builtin::AddressSpace::kUniform, Group(0_a),
|
||||
Binding(0_a));
|
||||
|
||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace tint::resolver
|
||||
|
|
|
@ -467,7 +467,9 @@ bool Validator::AddressSpaceLayout(const type::Type* store_ty,
|
|||
}
|
||||
|
||||
// Validate that member is at a valid byte offset
|
||||
if (m->Offset() % required_align != 0) {
|
||||
if (m->Offset() % required_align != 0 &&
|
||||
!enabled_extensions_.Contains(
|
||||
builtin::Extension::kChromiumInternalRelaxedUniformLayout)) {
|
||||
AddError("the offset of a struct member of type '" +
|
||||
m->Type()->UnwrapRef()->FriendlyName(symbols_) +
|
||||
"' in address space '" + utils::ToString(address_space) +
|
||||
|
@ -493,7 +495,9 @@ bool Validator::AddressSpaceLayout(const type::Type* store_ty,
|
|||
auto* const prev_member = (i == 0) ? nullptr : str->Members()[i - 1];
|
||||
if (prev_member && is_uniform_struct(prev_member->Type())) {
|
||||
const uint32_t prev_to_curr_offset = m->Offset() - prev_member->Offset();
|
||||
if (prev_to_curr_offset % 16 != 0) {
|
||||
if (prev_to_curr_offset % 16 != 0 &&
|
||||
!enabled_extensions_.Contains(
|
||||
builtin::Extension::kChromiumInternalRelaxedUniformLayout)) {
|
||||
AddError(
|
||||
"uniform storage requires that the number of bytes between the "
|
||||
"start of the previous member of type struct and the current "
|
||||
|
@ -526,7 +530,9 @@ bool Validator::AddressSpaceLayout(const type::Type* store_ty,
|
|||
return false;
|
||||
}
|
||||
|
||||
if (address_space == builtin::AddressSpace::kUniform) {
|
||||
if (address_space == builtin::AddressSpace::kUniform &&
|
||||
!enabled_extensions_.Contains(
|
||||
builtin::Extension::kChromiumInternalRelaxedUniformLayout)) {
|
||||
// We already validated that this array member is itself aligned to 16 bytes above, so
|
||||
// we only need to validate that stride is a multiple of 16 bytes.
|
||||
if (arr->Stride() % 16 != 0) {
|
||||
|
|
Loading…
Reference in New Issue