Generate OpExtInstImport
This CL updates the SPIR-V generator to only create the GLSL import if it's requested. Bug: tint:5 Change-Id: I96a9100adf0a0c59dcdd82c12ac27c566ea2663f Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/17341 Reviewed-by: David Neto <dneto@google.com>
This commit is contained in:
parent
d854fc1543
commit
7b7ff741c5
|
@ -35,10 +35,15 @@ Builder::Builder() = default;
|
|||
|
||||
Builder::~Builder() = default;
|
||||
|
||||
bool Builder::Build(const ast::Module&) {
|
||||
bool Builder::Build(const ast::Module& m) {
|
||||
push_preamble(spv::Op::OpCapability, {Operand::Int(SpvCapabilityShader)});
|
||||
push_preamble(spv::Op::OpExtInstImport,
|
||||
{result_op(), Operand::String("GLSL.std.450")});
|
||||
push_preamble(spv::Op::OpCapability,
|
||||
{Operand::Int(SpvCapabilityVulkanMemoryModel)});
|
||||
|
||||
for (const auto& imp : m.imports()) {
|
||||
GenerateImport(imp.get());
|
||||
}
|
||||
|
||||
push_preamble(spv::Op::OpMemoryModel,
|
||||
{Operand::Int(SpvAddressingModelLogical),
|
||||
Operand::Int(SpvMemoryModelVulkanKHR)});
|
||||
|
@ -80,6 +85,15 @@ void Builder::iterate(std::function<void(const Instruction&)> cb) const {
|
|||
}
|
||||
}
|
||||
|
||||
void Builder::GenerateImport(ast::Import* imp) {
|
||||
auto op = result_op();
|
||||
auto id = op.to_i();
|
||||
|
||||
push_preamble(spv::Op::OpExtInstImport, {op, Operand::String(imp->path())});
|
||||
|
||||
import_name_to_id_[imp->name()] = id;
|
||||
}
|
||||
|
||||
} // namespace spirv
|
||||
} // namespace writer
|
||||
} // namespace tint
|
||||
|
|
|
@ -16,6 +16,8 @@
|
|||
#define SRC_WRITER_SPIRV_BUILDER_H_
|
||||
|
||||
#include <functional>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
#include "src/ast/module.h"
|
||||
|
@ -43,6 +45,13 @@ class Builder {
|
|||
/// @returns the id bound for this module
|
||||
uint32_t id_bound() const { return next_id_; }
|
||||
|
||||
/// @returns the next id to be used
|
||||
uint32_t next_id() {
|
||||
auto id = next_id_;
|
||||
next_id_ += 1;
|
||||
return id;
|
||||
}
|
||||
|
||||
/// Iterates over all the instructions in the correct order and calls the
|
||||
/// given callback
|
||||
/// @param cb the callback to execute
|
||||
|
@ -89,13 +98,12 @@ class Builder {
|
|||
/// @returns the annotations
|
||||
const std::vector<Instruction>& annot() const { return annotations_; }
|
||||
|
||||
/// Generates an import instruction
|
||||
/// @param imp the import
|
||||
void GenerateImport(ast::Import* imp);
|
||||
|
||||
private:
|
||||
Operand result_op();
|
||||
uint32_t next_id() {
|
||||
auto id = next_id_;
|
||||
next_id_ += 1;
|
||||
return id;
|
||||
}
|
||||
|
||||
uint32_t next_id_ = 1;
|
||||
std::vector<Instruction> preamble_;
|
||||
|
@ -103,6 +111,8 @@ class Builder {
|
|||
std::vector<Instruction> types_;
|
||||
std::vector<Instruction> instructions_;
|
||||
std::vector<Instruction> annotations_;
|
||||
|
||||
std::unordered_map<std::string, uint32_t> import_name_to_id_;
|
||||
};
|
||||
|
||||
} // namespace spirv
|
||||
|
|
|
@ -14,8 +14,12 @@
|
|||
|
||||
#include "src/writer/spirv/builder.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
#include "spirv/unified1/spirv.h"
|
||||
#include "spirv/unified1/spirv.hpp11"
|
||||
#include "src/ast/import.h"
|
||||
#include "src/ast/module.h"
|
||||
|
||||
namespace tint {
|
||||
|
@ -24,17 +28,48 @@ namespace spirv {
|
|||
|
||||
using BuilderTest = testing::Test;
|
||||
|
||||
TEST_F(BuilderTest, InsertsPreamble) {
|
||||
TEST_F(BuilderTest, InsertsPreambleWithImport) {
|
||||
ast::Module m;
|
||||
m.AddImport(std::make_unique<ast::Import>("GLSL.std.450", "glsl"));
|
||||
|
||||
Builder b;
|
||||
ASSERT_TRUE(b.Build(m));
|
||||
ASSERT_EQ(b.preamble().size(), 4);
|
||||
|
||||
auto pre = b.preamble();
|
||||
EXPECT_EQ(pre[0].opcode(), spv::Op::OpCapability);
|
||||
EXPECT_EQ(pre[0].operands()[0].to_i(), SpvCapabilityShader);
|
||||
EXPECT_EQ(pre[1].opcode(), spv::Op::OpCapability);
|
||||
EXPECT_EQ(pre[1].operands()[0].to_i(), SpvCapabilityVulkanMemoryModel);
|
||||
EXPECT_EQ(pre[2].opcode(), spv::Op::OpExtInstImport);
|
||||
EXPECT_EQ(pre[2].operands()[1].to_s(), "GLSL.std.450");
|
||||
EXPECT_EQ(pre[3].opcode(), spv::Op::OpMemoryModel);
|
||||
}
|
||||
|
||||
TEST_F(BuilderTest, InsertsPreambleWithoutImport) {
|
||||
ast::Module m;
|
||||
Builder b;
|
||||
ASSERT_TRUE(b.Build(m));
|
||||
ASSERT_EQ(b.preamble().size(), 3);
|
||||
|
||||
auto pre = b.preamble();
|
||||
EXPECT_EQ(pre[0].opcode(), spv::Op::OpCapability);
|
||||
EXPECT_EQ(pre[1].opcode(), spv::Op::OpExtInstImport);
|
||||
EXPECT_EQ(pre[0].operands()[0].to_i(), SpvCapabilityShader);
|
||||
EXPECT_EQ(pre[1].opcode(), spv::Op::OpCapability);
|
||||
EXPECT_EQ(pre[1].operands()[0].to_i(), SpvCapabilityVulkanMemoryModel);
|
||||
EXPECT_EQ(pre[2].opcode(), spv::Op::OpMemoryModel);
|
||||
}
|
||||
|
||||
TEST_F(BuilderTest, TracksIdBounds) {
|
||||
Builder b;
|
||||
|
||||
for (size_t i = 0; i < 5; i++) {
|
||||
EXPECT_EQ(b.next_id(), i + 1);
|
||||
}
|
||||
|
||||
EXPECT_EQ(6, b.id_bound());
|
||||
}
|
||||
|
||||
} // namespace spirv
|
||||
} // namespace writer
|
||||
} // namespace tint
|
||||
|
|
Loading…
Reference in New Issue