spirv-writer: avoid dup OpCapability instructions
Change-Id: Iaf53d2addadd8efbb912e4f97ff426fd4182c9f3
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/34002
Reviewed-by: Ben Clayton <bclayton@google.com>
Commit-Queue: Ben Clayton <bclayton@google.com>
Auto-Submit: David Neto <dneto@google.com>
diff --git a/src/writer/spirv/builder.cc b/src/writer/spirv/builder.cc
index b2c0a7e..2681e9a 100644
--- a/src/writer/spirv/builder.cc
+++ b/src/writer/spirv/builder.cc
@@ -357,8 +357,11 @@
}
void Builder::push_capability(uint32_t cap) {
- capabilities_.push_back(
- Instruction{spv::Op::OpCapability, {Operand::Int(cap)}});
+ if (capability_set_.count(cap) == 0) {
+ capability_set_.insert(cap);
+ capabilities_.push_back(
+ Instruction{spv::Op::OpCapability, {Operand::Int(cap)}});
+ }
}
void Builder::GenerateLabel(uint32_t id) {
diff --git a/src/writer/spirv/builder.h b/src/writer/spirv/builder.h
index 7e6acbb..e50131c 100644
--- a/src/writer/spirv/builder.h
+++ b/src/writer/spirv/builder.h
@@ -18,6 +18,7 @@
#include <functional>
#include <string>
#include <unordered_map>
+#include <unordered_set>
#include <vector>
#include "spirv/unified1/spirv.h"
@@ -93,7 +94,8 @@
/// @param cb the callback to execute
void iterate(std::function<void(const Instruction&)> cb) const;
- /// Adds an instruction to the list of capabilities
+ /// Adds an instruction to the list of capabilities, if the capability
+ /// hasn't already been added.
/// @param cap the capability to set
void push_capability(uint32_t cap);
/// @returns the capabilities
@@ -500,6 +502,7 @@
std::unordered_map<uint32_t, ast::Variable*> spirv_id_to_variable_;
std::vector<uint32_t> merge_stack_;
std::vector<uint32_t> continue_stack_;
+ std::unordered_set<uint32_t> capability_set_;
};
} // namespace spirv
diff --git a/src/writer/spirv/builder_test.cc b/src/writer/spirv/builder_test.cc
index 0d4a92e..fb2549f 100644
--- a/src/writer/spirv/builder_test.cc
+++ b/src/writer/spirv/builder_test.cc
@@ -45,6 +45,14 @@
EXPECT_EQ(6u, b.id_bound());
}
+TEST_F(BuilderTest, Capabilities_Dedup) {
+ b.push_capability(SpvCapabilityShader);
+ b.push_capability(SpvCapabilityShader);
+ b.push_capability(SpvCapabilityShader);
+
+ EXPECT_EQ(DumpInstructions(b.capabilities()), "OpCapability Shader\n");
+}
+
} // namespace
} // namespace spirv
} // namespace writer