2018-08-23 04:59:57 -03:00
|
|
|
/* This file is part of the sirit project.
|
2019-07-14 18:48:59 -03:00
|
|
|
* Copyright (c) 2019 sirit
|
|
|
|
|
* This software may be used and distributed according to the terms of the
|
|
|
|
|
* 3-Clause BSD License
|
2018-08-23 04:59:57 -03:00
|
|
|
*/
|
|
|
|
|
|
2019-03-11 03:26:21 -03:00
|
|
|
#include <algorithm>
|
|
|
|
|
#include <cassert>
|
2018-08-25 20:16:37 -03:00
|
|
|
#include "common_types.h"
|
2018-08-25 20:34:06 -03:00
|
|
|
#include "op.h"
|
2019-03-11 03:26:21 -03:00
|
|
|
#include "sirit/sirit.h"
|
2018-08-25 20:16:37 -03:00
|
|
|
#include "stream.h"
|
|
|
|
|
|
|
|
|
|
namespace Sirit {
|
|
|
|
|
|
2019-03-11 03:26:21 -03:00
|
|
|
template <typename T>
|
|
|
|
|
static void WriteSet(Stream& stream, const T& set) {
|
2018-10-20 02:52:55 -03:00
|
|
|
for (const auto& item : set) {
|
|
|
|
|
item->Write(stream);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-11-27 05:46:03 -03:00
|
|
|
Module::Module(u32 version_) : version{version_} {}
|
2018-08-25 20:16:37 -03:00
|
|
|
|
|
|
|
|
Module::~Module() = default;
|
|
|
|
|
|
2019-10-18 03:44:49 -03:00
|
|
|
std::vector<u32> Module::Assemble() const {
|
|
|
|
|
std::vector<u32> bytes;
|
2018-08-25 20:16:37 -03:00
|
|
|
Stream stream{bytes};
|
|
|
|
|
|
|
|
|
|
stream.Write(spv::MagicNumber);
|
2018-11-02 13:38:33 -03:00
|
|
|
stream.Write(version);
|
2018-10-03 00:32:45 -03:00
|
|
|
stream.Write(GENERATOR_MAGIC_NUMBER);
|
2018-08-25 20:16:37 -03:00
|
|
|
stream.Write(bound);
|
|
|
|
|
stream.Write(static_cast<u32>(0));
|
|
|
|
|
|
2018-10-23 05:09:17 -03:00
|
|
|
for (const auto capability : capabilities) {
|
2018-11-16 04:21:37 -03:00
|
|
|
Op op(spv::Op::OpCapability);
|
|
|
|
|
op.Add(static_cast<u32>(capability));
|
|
|
|
|
op.Write(stream);
|
2018-08-25 20:16:37 -03:00
|
|
|
}
|
2019-03-08 21:09:11 -03:00
|
|
|
|
|
|
|
|
for (const auto& extension_name : extensions) {
|
|
|
|
|
Op op(spv::Op::OpExtension);
|
|
|
|
|
op.Add(extension_name);
|
|
|
|
|
op.Write(stream);
|
|
|
|
|
}
|
|
|
|
|
|
2018-11-04 03:03:06 -03:00
|
|
|
if (glsl_std_450) {
|
|
|
|
|
glsl_std_450->Write(stream);
|
|
|
|
|
}
|
2018-08-25 20:16:37 -03:00
|
|
|
|
2018-08-25 20:34:06 -03:00
|
|
|
Op memory_model_ref{spv::Op::OpMemoryModel};
|
2018-08-25 20:16:37 -03:00
|
|
|
memory_model_ref.Add(static_cast<u32>(addressing_model));
|
|
|
|
|
memory_model_ref.Add(static_cast<u32>(memory_model));
|
|
|
|
|
memory_model_ref.Write(stream);
|
|
|
|
|
|
2018-10-20 02:52:55 -03:00
|
|
|
WriteSet(stream, entry_points);
|
2018-12-04 21:30:32 -03:00
|
|
|
WriteSet(stream, execution_modes);
|
2018-10-20 02:52:55 -03:00
|
|
|
WriteSet(stream, debug);
|
2018-10-23 04:45:56 -03:00
|
|
|
WriteSet(stream, annotations);
|
2019-09-09 16:48:05 -03:00
|
|
|
WriteSet(stream, declarations);
|
2018-10-20 02:52:55 -03:00
|
|
|
WriteSet(stream, global_variables);
|
|
|
|
|
WriteSet(stream, code);
|
2018-08-25 20:16:37 -03:00
|
|
|
|
|
|
|
|
return bytes;
|
|
|
|
|
}
|
|
|
|
|
|
2019-03-14 02:52:54 -04:00
|
|
|
void Module::AddExtension(std::string extension_name) {
|
|
|
|
|
extensions.insert(std::move(extension_name));
|
2019-03-08 21:09:11 -03:00
|
|
|
}
|
|
|
|
|
|
2018-08-25 20:16:37 -03:00
|
|
|
void Module::AddCapability(spv::Capability capability) {
|
|
|
|
|
capabilities.insert(capability);
|
|
|
|
|
}
|
|
|
|
|
|
2020-07-29 05:46:50 -03:00
|
|
|
void Module::SetMemoryModel(spv::AddressingModel addressing_model_,
|
|
|
|
|
spv::MemoryModel memory_model_) {
|
2019-03-14 17:34:28 -04:00
|
|
|
this->addressing_model = addressing_model_;
|
|
|
|
|
this->memory_model = memory_model_;
|
2018-08-25 20:16:37 -03:00
|
|
|
}
|
|
|
|
|
|
2020-07-29 05:46:50 -03:00
|
|
|
void Module::AddEntryPoint(spv::ExecutionModel execution_model, Id entry_point, std::string name,
|
|
|
|
|
std::span<const Id> interfaces) {
|
2018-11-01 05:13:30 -03:00
|
|
|
auto op{std::make_unique<Op>(spv::Op::OpEntryPoint)};
|
2018-08-25 20:16:37 -03:00
|
|
|
op->Add(static_cast<u32>(execution_model));
|
|
|
|
|
op->Add(entry_point);
|
2019-03-14 02:52:54 -04:00
|
|
|
op->Add(std::move(name));
|
2018-08-25 20:16:37 -03:00
|
|
|
op->Add(interfaces);
|
2018-11-01 05:13:30 -03:00
|
|
|
entry_points.push_back(std::move(op));
|
2018-08-25 20:16:37 -03:00
|
|
|
}
|
|
|
|
|
|
2018-12-04 21:30:32 -03:00
|
|
|
void Module::AddExecutionMode(Id entry_point, spv::ExecutionMode mode,
|
2020-07-29 05:46:50 -03:00
|
|
|
std::span<const Literal> literals) {
|
2018-12-04 21:30:32 -03:00
|
|
|
auto op{std::make_unique<Op>(spv::Op::OpExecutionMode)};
|
|
|
|
|
op->Add(entry_point);
|
|
|
|
|
op->Add(static_cast<u32>(mode));
|
|
|
|
|
op->Add(literals);
|
|
|
|
|
execution_modes.push_back(std::move(op));
|
|
|
|
|
}
|
|
|
|
|
|
2019-10-18 04:25:57 -03:00
|
|
|
Id Module::AddLabel(Id label) {
|
|
|
|
|
assert(label != nullptr);
|
|
|
|
|
return code.emplace_back(label);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Id Module::AddLocalVariable(Id variable) {
|
|
|
|
|
assert(variable != nullptr);
|
|
|
|
|
return code.emplace_back(variable);
|
2018-08-25 20:16:37 -03:00
|
|
|
}
|
|
|
|
|
|
2018-10-31 22:20:49 -03:00
|
|
|
Id Module::AddGlobalVariable(Id variable) {
|
2018-10-20 02:52:55 -03:00
|
|
|
assert(variable);
|
2019-10-18 04:25:57 -03:00
|
|
|
return global_variables.emplace_back(variable);
|
2018-10-20 02:52:55 -03:00
|
|
|
}
|
|
|
|
|
|
2018-11-01 00:02:45 -03:00
|
|
|
Id Module::AddCode(std::unique_ptr<Op> op) {
|
2019-10-18 04:25:57 -03:00
|
|
|
const Id id = code_store.emplace_back(std::move(op)).get();
|
|
|
|
|
return code.emplace_back(id);
|
2018-08-25 20:16:37 -03:00
|
|
|
}
|
|
|
|
|
|
2018-10-31 22:20:49 -03:00
|
|
|
Id Module::AddCode(spv::Op opcode, std::optional<u32> id) {
|
2018-11-01 00:02:45 -03:00
|
|
|
return AddCode(std::make_unique<Op>(opcode, id));
|
2018-08-25 20:16:37 -03:00
|
|
|
}
|
|
|
|
|
|
2018-11-01 00:02:45 -03:00
|
|
|
Id Module::AddDeclaration(std::unique_ptr<Op> op) {
|
2020-07-29 05:46:50 -03:00
|
|
|
const auto found = std::find_if(declarations.begin(), declarations.end(),
|
|
|
|
|
[&op](const auto& other) { return op->Equal(*other); });
|
2019-09-09 16:48:05 -03:00
|
|
|
if (found != declarations.end()) {
|
|
|
|
|
return found->get();
|
2018-08-25 20:16:37 -03:00
|
|
|
}
|
2019-09-09 16:48:05 -03:00
|
|
|
const auto id = op.get();
|
|
|
|
|
declarations.push_back(std::move(op));
|
2020-07-29 05:46:50 -03:00
|
|
|
++bound;
|
2018-11-01 00:02:45 -03:00
|
|
|
return id;
|
2018-08-25 20:16:37 -03:00
|
|
|
}
|
|
|
|
|
|
2018-11-06 04:47:40 -03:00
|
|
|
void Module::AddAnnotation(std::unique_ptr<Op> op) {
|
2018-11-01 00:02:45 -03:00
|
|
|
annotations.push_back(std::move(op));
|
2018-10-23 04:45:56 -03:00
|
|
|
}
|
|
|
|
|
|
2018-11-04 03:03:06 -03:00
|
|
|
Id Module::GetGLSLstd450() {
|
|
|
|
|
if (!glsl_std_450) {
|
|
|
|
|
glsl_std_450 = std::make_unique<Op>(spv::Op::OpExtInstImport, bound++);
|
2018-11-13 19:30:29 -03:00
|
|
|
glsl_std_450->Add("GLSL.std.450");
|
2018-11-04 03:03:06 -03:00
|
|
|
}
|
|
|
|
|
return glsl_std_450.get();
|
|
|
|
|
}
|
|
|
|
|
|
2018-08-25 20:16:37 -03:00
|
|
|
} // namespace Sirit
|