Files
sirit/src/sirit.cpp

148 lines
4.0 KiB
C++
Raw Normal View History

2018-08-23 04:59:57 -03:00
/* This file is part of the sirit project.
* Copyright (c) 2018 ReinUsesLisp
* This software may be used and distributed according to the terms of the GNU
2018-11-16 04:10:10 -03:00
* Lesser General Public License version 3 or any later version.
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);
}
}
2018-11-02 13:38:33 -03:00
Module::Module(u32 version) : version(version) {}
2018-08-25 20:16:37 -03:00
Module::~Module() = default;
2018-08-31 03:41:30 -03:00
std::vector<u8> Module::Assemble() const {
2018-08-25 20:16:37 -03:00
std::vector<u8> bytes;
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);
2018-10-20 02:52:55 -03:00
WriteSet(stream, declarations);
WriteSet(stream, global_variables);
WriteSet(stream, code);
2018-08-25 20:16:37 -03:00
return bytes;
}
2019-03-08 21:09:11 -03:00
void Module::AddExtension(const std::string& extension_name) {
extensions.insert(extension_name);
}
2018-08-25 20:16:37 -03:00
void Module::AddCapability(spv::Capability capability) {
capabilities.insert(capability);
}
2019-03-11 03:26:21 -03:00
void Module::SetMemoryModel(spv::AddressingModel addressing_model, spv::MemoryModel memory_model) {
2018-08-25 20:16:37 -03:00
this->addressing_model = addressing_model;
this->memory_model = memory_model;
}
2018-10-31 22:20:49 -03:00
void Module::AddEntryPoint(spv::ExecutionModel execution_model, Id entry_point,
2019-03-11 03:26:21 -03:00
const std::string& name, const std::vector<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);
op->Add(name);
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,
2019-03-11 03:26:21 -03:00
const std::vector<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));
}
2018-10-31 22:20:49 -03:00
Id Module::Emit(Id op) {
2019-03-13 19:20:29 -03:00
assert(op != nullptr);
2018-08-25 20:34:06 -03:00
code.push_back(op);
return op;
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);
global_variables.push_back(variable);
return variable;
}
Id Module::AddCode(std::unique_ptr<Op> op) {
2018-11-01 05:13:30 -03:00
const auto id = op.get();
code_store.push_back(std::move(op));
2018-11-01 05:13:30 -03:00
return 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) {
return AddCode(std::make_unique<Op>(opcode, id));
2018-08-25 20:16:37 -03:00
}
Id Module::AddDeclaration(std::unique_ptr<Op> op) {
2019-03-11 03:26:21 -03:00
const auto& found{std::find_if(declarations.begin(), declarations.end(),
[&op](const auto& other) { return *other == *op; })};
2018-08-25 20:16:37 -03:00
if (found != declarations.end()) {
return found->get();
}
const auto id = op.get();
declarations.push_back(std::move(op));
bound++;
return id;
2018-08-25 20:16:37 -03:00
}
void Module::AddAnnotation(std::unique_ptr<Op> op) {
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