spirv-reader: Ignore Restrict, RestrictPointer decorations

They have no effect in graphics APIs.

Fixes: tint:1440
Change-Id: I80a4b2f5875fbabbd53fd1ebd085ba146401ca71
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/80980
Auto-Submit: David Neto <dneto@google.com>
Kokoro: David Neto <dneto@google.com>
Kokoro: Kokoro <noreply+kokoro@google.com>
Reviewed-by: Ben Clayton <bclayton@google.com>
Commit-Queue: Ben Clayton <bclayton@google.com>
This commit is contained in:
David Neto 2022-02-18 10:32:19 +00:00 committed by Tint LUCI CQ
parent 6f5316ba46
commit 27605e505b
3 changed files with 91 additions and 10 deletions

View File

@ -396,11 +396,19 @@ DecorationList ParserImpl::GetDecorationsFor(uint32_t id) const {
// Example: OpDecorate %struct_id Block
// Example: OpDecorate %array_ty ArrayStride 16
auto decoration_kind = inst->GetSingleWordInOperand(1);
if (visited.emplace(decoration_kind).second) {
std::vector<uint32_t> inst_as_words;
inst->ToBinaryWithoutAttachedDebugInsts(&inst_as_words);
Decoration d(inst_as_words.begin() + 2, inst_as_words.end());
result.push_back(d);
switch (decoration_kind) {
// Restrict and RestrictPointer have no effect in graphics APIs.
case SpvDecorationRestrict:
case SpvDecorationRestrictPointer:
break;
default:
if (visited.emplace(decoration_kind).second) {
std::vector<uint32_t> inst_as_words;
inst->ToBinaryWithoutAttachedDebugInsts(&inst_as_words);
Decoration d(inst_as_words.begin() + 2, inst_as_words.end());
result.push_back(d);
}
break;
}
}
return result;
@ -419,11 +427,18 @@ DecorationList ParserImpl::GetDecorationsForMember(
continue;
}
auto decoration_kind = inst->GetSingleWordInOperand(2);
if (visited.emplace(decoration_kind).second) {
std::vector<uint32_t> inst_as_words;
inst->ToBinaryWithoutAttachedDebugInsts(&inst_as_words);
Decoration d(inst_as_words.begin() + 3, inst_as_words.end());
result.push_back(d);
switch (decoration_kind) {
// Restrict and RestrictPointer have no effect in graphics APIs.
case SpvDecorationRestrict:
case SpvDecorationRestrictPointer:
break;
default:
if (visited.emplace(decoration_kind).second) {
std::vector<uint32_t> inst_as_words;
inst->ToBinaryWithoutAttachedDebugInsts(&inst_as_words);
Decoration d(inst_as_words.begin() + 3, inst_as_words.end());
result.push_back(d);
}
}
}
return result;

View File

@ -221,6 +221,8 @@ class ParserImpl : Reader {
/// Gets the list of unique decorations for a SPIR-V result ID. Returns an
/// empty vector if the ID is not a result ID, or if no decorations target
/// that ID. The internal representation must have already been built.
/// Ignores decorations that have no effect in graphics APIs, e.g. Restrict
/// and RestrictPointer.
/// @param id SPIR-V ID
/// @returns the list of decorations on the given ID
DecorationList GetDecorationsFor(uint32_t id) const;
@ -228,6 +230,8 @@ class ParserImpl : Reader {
/// an empty list if the `id` is not the ID of a struct, or if the member
/// index is out of range, or if the target member has no decorations. The
/// internal representation must have already been built.
/// Ignores decorations that have no effect in graphics APIs, e.g. Restrict
/// and RestrictPointer.
/// @param id SPIR-V ID of a struct
/// @param member_index the member within the struct
/// @returns the list of decorations on the member

View File

@ -198,6 +198,68 @@ TEST_F(SpvParserGetDecorationsTest,
EXPECT_TRUE(p->error().empty());
}
TEST_F(SpvParserGetDecorationsTest, GetDecorationsFor_Restrict) {
// RestrictPointer applies to a memory object declaration. Use a variable.
auto p = parser(test::Assemble(R"(
OpDecorate %10 Restrict
%float = OpTypeFloat 32
%ptr = OpTypePointer Workgroup %float
%10 = OpVariable %ptr Workgroup
)"));
EXPECT_TRUE(p->BuildAndParseInternalModule());
auto decorations = p->GetDecorationsFor(10);
EXPECT_TRUE(decorations.empty());
EXPECT_TRUE(p->error().empty());
p->SkipDumpingPending(kSkipReason);
}
TEST_F(SpvParserGetDecorationsTest, GetDecorationsForMember_Restrict) {
// Restrict applies to a memory object declaration.
// But OpMemberDecorate can only be applied to a structure type.
// Test the reader's ability to be resilient to more than what SPIR-V allows.
auto p = parser(test::Assemble(R"(
OpMemberDecorate %10 0 Restrict
%float = OpTypeFloat 32
%10 = OpTypeStruct %float
)"));
EXPECT_TRUE(p->BuildAndParseInternalModule());
auto decorations = p->GetDecorationsForMember(10, 0);
EXPECT_TRUE(decorations.empty());
EXPECT_TRUE(p->error().empty());
p->SkipDumpingPending(kSkipReason);
}
TEST_F(SpvParserGetDecorationsTest, GetDecorationsFor_RestrictPointer) {
// RestrictPointer applies to a memory object declaration. Use a variable.
auto p = parser(test::Assemble(R"(
OpDecorate %10 RestrictPointer
%float = OpTypeFloat 32
%ptr = OpTypePointer Workgroup %float
%10 = OpVariable %ptr Workgroup
)"));
EXPECT_TRUE(p->BuildAndParseInternalModule()) << p->error();
auto decorations = p->GetDecorationsFor(10);
EXPECT_TRUE(decorations.empty());
EXPECT_TRUE(p->error().empty());
p->SkipDumpingPending(kSkipReason);
}
TEST_F(SpvParserGetDecorationsTest, GetDecorationsForMember_RestrictPointer) {
// RestrictPointer applies to a memory object declaration.
// But OpMemberDecorate can only be applied to a structure type.
// Test the reader's ability to be resilient to more than what SPIR-V allows.
auto p = parser(test::Assemble(R"(
OpMemberDecorate %10 0 RestrictPointer
%float = OpTypeFloat 32
%10 = OpTypeStruct %float
)"));
EXPECT_TRUE(p->BuildAndParseInternalModule()) << p->error();
auto decorations = p->GetDecorationsFor(10);
EXPECT_TRUE(decorations.empty());
EXPECT_TRUE(p->error().empty());
p->SkipDumpingPending(kSkipReason);
}
} // namespace
} // namespace spirv
} // namespace reader