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;
|
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::OpCapability, {Operand::Int(SpvCapabilityShader)});
|
||||||
push_preamble(spv::Op::OpExtInstImport,
|
push_preamble(spv::Op::OpCapability,
|
||||||
{result_op(), Operand::String("GLSL.std.450")});
|
{Operand::Int(SpvCapabilityVulkanMemoryModel)});
|
||||||
|
|
||||||
|
for (const auto& imp : m.imports()) {
|
||||||
|
GenerateImport(imp.get());
|
||||||
|
}
|
||||||
|
|
||||||
push_preamble(spv::Op::OpMemoryModel,
|
push_preamble(spv::Op::OpMemoryModel,
|
||||||
{Operand::Int(SpvAddressingModelLogical),
|
{Operand::Int(SpvAddressingModelLogical),
|
||||||
Operand::Int(SpvMemoryModelVulkanKHR)});
|
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 spirv
|
||||||
} // namespace writer
|
} // namespace writer
|
||||||
} // namespace tint
|
} // namespace tint
|
||||||
|
|
|
@ -16,6 +16,8 @@
|
||||||
#define SRC_WRITER_SPIRV_BUILDER_H_
|
#define SRC_WRITER_SPIRV_BUILDER_H_
|
||||||
|
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
#include <string>
|
||||||
|
#include <unordered_map>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "src/ast/module.h"
|
#include "src/ast/module.h"
|
||||||
|
@ -43,6 +45,13 @@ class Builder {
|
||||||
/// @returns the id bound for this module
|
/// @returns the id bound for this module
|
||||||
uint32_t id_bound() const { return next_id_; }
|
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
|
/// Iterates over all the instructions in the correct order and calls the
|
||||||
/// given callback
|
/// given callback
|
||||||
/// @param cb the callback to execute
|
/// @param cb the callback to execute
|
||||||
|
@ -89,13 +98,12 @@ class Builder {
|
||||||
/// @returns the annotations
|
/// @returns the annotations
|
||||||
const std::vector<Instruction>& annot() const { return annotations_; }
|
const std::vector<Instruction>& annot() const { return annotations_; }
|
||||||
|
|
||||||
|
/// Generates an import instruction
|
||||||
|
/// @param imp the import
|
||||||
|
void GenerateImport(ast::Import* imp);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Operand result_op();
|
Operand result_op();
|
||||||
uint32_t next_id() {
|
|
||||||
auto id = next_id_;
|
|
||||||
next_id_ += 1;
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t next_id_ = 1;
|
uint32_t next_id_ = 1;
|
||||||
std::vector<Instruction> preamble_;
|
std::vector<Instruction> preamble_;
|
||||||
|
@ -103,6 +111,8 @@ class Builder {
|
||||||
std::vector<Instruction> types_;
|
std::vector<Instruction> types_;
|
||||||
std::vector<Instruction> instructions_;
|
std::vector<Instruction> instructions_;
|
||||||
std::vector<Instruction> annotations_;
|
std::vector<Instruction> annotations_;
|
||||||
|
|
||||||
|
std::unordered_map<std::string, uint32_t> import_name_to_id_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace spirv
|
} // namespace spirv
|
||||||
|
|
|
@ -14,8 +14,12 @@
|
||||||
|
|
||||||
#include "src/writer/spirv/builder.h"
|
#include "src/writer/spirv/builder.h"
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
#include "gtest/gtest.h"
|
#include "gtest/gtest.h"
|
||||||
|
#include "spirv/unified1/spirv.h"
|
||||||
#include "spirv/unified1/spirv.hpp11"
|
#include "spirv/unified1/spirv.hpp11"
|
||||||
|
#include "src/ast/import.h"
|
||||||
#include "src/ast/module.h"
|
#include "src/ast/module.h"
|
||||||
|
|
||||||
namespace tint {
|
namespace tint {
|
||||||
|
@ -24,17 +28,48 @@ namespace spirv {
|
||||||
|
|
||||||
using BuilderTest = testing::Test;
|
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;
|
ast::Module m;
|
||||||
Builder b;
|
Builder b;
|
||||||
ASSERT_TRUE(b.Build(m));
|
ASSERT_TRUE(b.Build(m));
|
||||||
ASSERT_EQ(b.preamble().size(), 3);
|
ASSERT_EQ(b.preamble().size(), 3);
|
||||||
|
|
||||||
auto pre = b.preamble();
|
auto pre = b.preamble();
|
||||||
EXPECT_EQ(pre[0].opcode(), spv::Op::OpCapability);
|
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);
|
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 spirv
|
||||||
} // namespace writer
|
} // namespace writer
|
||||||
} // namespace tint
|
} // namespace tint
|
||||||
|
|
Loading…
Reference in New Issue