Assemble uint32_t instead of uint8_t
Vulkan receives SPIR-V modules with a uint32_t alignment. Returning uint8_t forced users to invoke undefined behaviour (reinterpret_cast) or copy.
This commit is contained in:
parent
ab507033db
commit
8cf3d225db
7 changed files with 31 additions and 31 deletions
|
@ -37,7 +37,7 @@ public:
|
||||||
* externally.
|
* externally.
|
||||||
* @return A stream of bytes representing a SPIR-V module.
|
* @return A stream of bytes representing a SPIR-V module.
|
||||||
*/
|
*/
|
||||||
std::vector<std::uint8_t> Assemble() const;
|
std::vector<std::uint32_t> Assemble() const;
|
||||||
|
|
||||||
/// Adds a SPIR-V extension.
|
/// Adds a SPIR-V extension.
|
||||||
void AddExtension(std::string extension_name);
|
void AddExtension(std::string extension_name);
|
||||||
|
|
|
@ -17,12 +17,7 @@ LiteralString::LiteralString(std::string string) : string{std::move(string)} {
|
||||||
LiteralString::~LiteralString() = default;
|
LiteralString::~LiteralString() = default;
|
||||||
|
|
||||||
void LiteralString::Fetch(Stream& stream) const {
|
void LiteralString::Fetch(Stream& stream) const {
|
||||||
for (std::size_t i = 0; i < string.size(); i++) {
|
stream.Write(string);
|
||||||
stream.Write(static_cast<u8>(string[i]));
|
|
||||||
}
|
|
||||||
for (std::size_t i = 0; i < 4 - (string.size() % 4); i++) {
|
|
||||||
stream.Write(static_cast<u8>(0));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
u16 LiteralString::GetWordCount() const {
|
u16 LiteralString::GetWordCount() const {
|
||||||
|
|
|
@ -49,8 +49,7 @@ bool Op::operator==(const Operand& other) const {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Op::Write(Stream& stream) const {
|
void Op::Write(Stream& stream) const {
|
||||||
stream.Write(static_cast<u16>(opcode));
|
stream.Write(static_cast<u16>(opcode), WordCount());
|
||||||
stream.Write(WordCount());
|
|
||||||
|
|
||||||
if (result_type) {
|
if (result_type) {
|
||||||
result_type->Fetch(stream);
|
result_type->Fetch(stream);
|
||||||
|
|
|
@ -24,8 +24,8 @@ Module::Module(u32 version) : version(version) {}
|
||||||
|
|
||||||
Module::~Module() = default;
|
Module::~Module() = default;
|
||||||
|
|
||||||
std::vector<u8> Module::Assemble() const {
|
std::vector<u32> Module::Assemble() const {
|
||||||
std::vector<u8> bytes;
|
std::vector<u32> bytes;
|
||||||
Stream stream{bytes};
|
Stream stream{bytes};
|
||||||
|
|
||||||
stream.Write(spv::MagicNumber);
|
stream.Write(spv::MagicNumber);
|
||||||
|
|
|
@ -8,36 +8,42 @@
|
||||||
|
|
||||||
namespace Sirit {
|
namespace Sirit {
|
||||||
|
|
||||||
Stream::Stream(std::vector<u8>& bytes) : bytes(bytes) {}
|
Stream::Stream(std::vector<u32>& words) : words(words) {}
|
||||||
|
|
||||||
Stream::~Stream() = default;
|
Stream::~Stream() = default;
|
||||||
|
|
||||||
void Stream::Write(std::string_view string) {
|
void Stream::Write(std::string_view string) {
|
||||||
bytes.insert(bytes.end(), string.begin(), string.end());
|
constexpr std::size_t word_size = 4;
|
||||||
|
const auto size = string.size();
|
||||||
|
auto read = [string, size](std::size_t offset) { return offset < size ? string[offset] : 0; };
|
||||||
|
|
||||||
const auto size{string.size()};
|
words.reserve(words.size() + size / word_size + 1);
|
||||||
for (std::size_t i = 0; i < 4 - size % 4; i++) {
|
for (std::size_t i = 0; i < size; i += word_size) {
|
||||||
Write(static_cast<u8>(0));
|
Write(read(i), read(i + 1), read(i + 2), read(i + 3));
|
||||||
|
}
|
||||||
|
if (size % word_size == 0) {
|
||||||
|
Write(u32(0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Stream::Write(u64 value) {
|
void Stream::Write(u64 value) {
|
||||||
const auto* const mem = reinterpret_cast<const u8*>(&value);
|
const u32 dword[] = {static_cast<u32>(value), static_cast<u32>(value >> 32)};
|
||||||
bytes.insert(bytes.end(), mem, mem + sizeof(u64));
|
words.insert(std::begin(words), std::cbegin(dword), std::cend(dword));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Stream::Write(u32 value) {
|
void Stream::Write(u32 value) {
|
||||||
const auto* const mem = reinterpret_cast<const u8*>(&value);
|
words.push_back(value);
|
||||||
bytes.insert(bytes.end(), mem, mem + sizeof(u32));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Stream::Write(u16 value) {
|
void Stream::Write(u16 first, u16 second) {
|
||||||
const auto* const mem{reinterpret_cast<const u8*>(&value)};
|
const u32 word = static_cast<u32>(first) | static_cast<u32>(second) << 16;
|
||||||
bytes.insert(bytes.end(), mem, mem + sizeof(u16));
|
Write(word);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Stream::Write(u8 value) {
|
void Stream::Write(u8 first, u8 second, u8 third, u8 fourth) {
|
||||||
bytes.push_back(value);
|
const u32 word = static_cast<u32>(first) | static_cast<u32>(second) << 8 |
|
||||||
|
static_cast<u32>(third) << 16 | static_cast<u32>(fourth) << 24;
|
||||||
|
Write(word);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Sirit
|
} // namespace Sirit
|
||||||
|
|
|
@ -14,7 +14,7 @@ namespace Sirit {
|
||||||
|
|
||||||
class Stream {
|
class Stream {
|
||||||
public:
|
public:
|
||||||
explicit Stream(std::vector<u8>& bytes);
|
explicit Stream(std::vector<u32>& words);
|
||||||
~Stream();
|
~Stream();
|
||||||
|
|
||||||
void Write(std::string_view string);
|
void Write(std::string_view string);
|
||||||
|
@ -23,12 +23,12 @@ public:
|
||||||
|
|
||||||
void Write(u32 value);
|
void Write(u32 value);
|
||||||
|
|
||||||
void Write(u16 value);
|
void Write(u16 first, u16 second);
|
||||||
|
|
||||||
void Write(u8 value);
|
void Write(u8 first, u8 second, u8 third, u8 fourth);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<u8>& bytes;
|
std::vector<u32>& words;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Sirit
|
} // namespace Sirit
|
||||||
|
|
|
@ -79,10 +79,10 @@ int main(int argc, char** argv) {
|
||||||
MyModule module;
|
MyModule module;
|
||||||
module.Generate();
|
module.Generate();
|
||||||
|
|
||||||
std::vector<std::uint8_t> code{module.Assemble()};
|
std::vector<std::uint32_t> code{module.Assemble()};
|
||||||
|
|
||||||
FILE* file = fopen("sirit.spv", "wb");
|
FILE* file = fopen("sirit.spv", "wb");
|
||||||
fwrite(code.data(), 1, code.size(), file);
|
fwrite(code.data(), sizeof(std::uint32_t), code.size(), file);
|
||||||
fclose(file);
|
fclose(file);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
Loading…
Reference in a new issue