2017-10-11 23:29:05 +02:00
|
|
|
#include <array>
|
|
|
|
#include <cstring>
|
|
|
|
|
2017-10-18 09:50:30 +02:00
|
|
|
#include "spirv_code_buffer.h"
|
2017-10-11 23:29:05 +02:00
|
|
|
|
|
|
|
namespace dxvk {
|
|
|
|
|
2017-10-14 23:52:47 +02:00
|
|
|
DxvkSpirvCodeBuffer:: DxvkSpirvCodeBuffer() { }
|
|
|
|
DxvkSpirvCodeBuffer::~DxvkSpirvCodeBuffer() { }
|
2017-10-11 23:29:05 +02:00
|
|
|
|
|
|
|
|
2017-10-15 17:56:06 +02:00
|
|
|
DxvkSpirvCodeBuffer::DxvkSpirvCodeBuffer(std::istream&& stream) {
|
|
|
|
stream.ignore(std::numeric_limits<std::streamsize>::max());
|
|
|
|
std::streamsize length = stream.gcount();
|
|
|
|
stream.clear();
|
|
|
|
stream.seekg(0, std::ios_base::beg);
|
|
|
|
|
|
|
|
std::vector<char> buffer(length);
|
|
|
|
stream.read(buffer.data(), length);
|
|
|
|
buffer.resize(stream.gcount());
|
|
|
|
|
|
|
|
m_code.resize(buffer.size() / sizeof(uint32_t));
|
|
|
|
std::memcpy(reinterpret_cast<char*>(m_code.data()),
|
|
|
|
buffer.data(), m_code.size() * sizeof(uint32_t));
|
|
|
|
}
|
2017-10-11 23:29:05 +02:00
|
|
|
|
|
|
|
|
2017-10-14 23:52:47 +02:00
|
|
|
void DxvkSpirvCodeBuffer::append(const DxvkSpirvCodeBuffer& other) {
|
2017-10-16 19:52:54 +02:00
|
|
|
if (other.size() != 0) {
|
|
|
|
const size_t size = m_code.size();
|
|
|
|
m_code.resize(size + other.m_code.size());
|
|
|
|
|
|
|
|
uint32_t* dst = this->m_code.data();
|
|
|
|
const uint32_t* src = other.m_code.data();
|
|
|
|
|
2017-10-17 13:02:57 +02:00
|
|
|
std::memcpy(dst + size, src, other.size());
|
2017-10-16 19:52:54 +02:00
|
|
|
}
|
2017-10-11 23:29:05 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-10-14 23:52:47 +02:00
|
|
|
void DxvkSpirvCodeBuffer::putWord(uint32_t word) {
|
2017-10-11 23:29:05 +02:00
|
|
|
m_code.push_back(word);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-10-14 23:52:47 +02:00
|
|
|
void DxvkSpirvCodeBuffer::putIns(spv::Op opCode, uint16_t wordCount) {
|
2017-10-11 23:29:05 +02:00
|
|
|
this->putWord(
|
|
|
|
(static_cast<uint32_t>(opCode) << 0)
|
|
|
|
| (static_cast<uint32_t>(wordCount) << 16));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-10-14 23:52:47 +02:00
|
|
|
void DxvkSpirvCodeBuffer::putInt32(uint32_t word) {
|
2017-10-11 23:29:05 +02:00
|
|
|
this->putWord(word);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-10-14 23:52:47 +02:00
|
|
|
void DxvkSpirvCodeBuffer::putInt64(uint64_t value) {
|
2017-10-11 23:29:05 +02:00
|
|
|
this->putWord(value >> 0);
|
|
|
|
this->putWord(value >> 32);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-10-14 23:52:47 +02:00
|
|
|
void DxvkSpirvCodeBuffer::putFloat32(float value) {
|
2017-10-11 23:29:05 +02:00
|
|
|
uint32_t tmp;
|
|
|
|
static_assert(sizeof(tmp) == sizeof(value));
|
|
|
|
std::memcpy(&tmp, &value, sizeof(value));
|
|
|
|
this->putInt32(tmp);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-10-14 23:52:47 +02:00
|
|
|
void DxvkSpirvCodeBuffer::putFloat64(double value) {
|
2017-10-11 23:29:05 +02:00
|
|
|
uint64_t tmp;
|
|
|
|
static_assert(sizeof(tmp) == sizeof(value));
|
|
|
|
std::memcpy(&tmp, &value, sizeof(value));
|
|
|
|
this->putInt64(tmp);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-10-14 23:52:47 +02:00
|
|
|
void DxvkSpirvCodeBuffer::putStr(const char* str) {
|
2017-10-11 23:29:05 +02:00
|
|
|
uint32_t word = 0;
|
|
|
|
uint32_t nbit = 0;
|
|
|
|
|
|
|
|
for (uint32_t i = 0; str[i] != '\0'; str++) {
|
|
|
|
word |= (static_cast<uint32_t>(str[i]) & 0xFF) << nbit;
|
|
|
|
|
|
|
|
if ((nbit += 8) == 32) {
|
|
|
|
this->putWord(word);
|
|
|
|
word = 0;
|
|
|
|
nbit = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Commit current word
|
|
|
|
this->putWord(word);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-10-14 23:52:47 +02:00
|
|
|
void DxvkSpirvCodeBuffer::putHeader(uint32_t boundIds) {
|
2017-10-11 23:29:05 +02:00
|
|
|
this->putWord(spv::MagicNumber);
|
|
|
|
this->putWord(spv::Version);
|
|
|
|
this->putWord(0); // Generator
|
|
|
|
this->putWord(boundIds);
|
|
|
|
this->putWord(0); // Schema
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-10-14 23:52:47 +02:00
|
|
|
uint32_t DxvkSpirvCodeBuffer::strLen(const char* str) {
|
2017-10-11 23:29:05 +02:00
|
|
|
// Null-termination plus padding
|
|
|
|
return (std::strlen(str) + 4) / 4;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-10-15 17:56:06 +02:00
|
|
|
void DxvkSpirvCodeBuffer::store(std::ostream&& stream) const {
|
|
|
|
stream.write(
|
|
|
|
reinterpret_cast<const char*>(m_code.data()),
|
|
|
|
sizeof(uint32_t) * m_code.size());
|
2017-10-11 23:29:05 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|