1
0
mirror of https://github.com/doitsujin/dxvk.git synced 2025-02-28 07:54:14 +01:00

[spirv] Track instruction offset in instruction iterator

This commit is contained in:
Philip Rebohle 2018-04-10 12:48:24 +02:00
parent 1fb22a6022
commit 5d1642af1f
No known key found for this signature in database
GPG Key ID: C8CC613427A31C99
2 changed files with 44 additions and 29 deletions

View File

@ -34,9 +34,8 @@ namespace dxvk {
* \brief Code data * \brief Code data
* \returns Code data * \returns Code data
*/ */
const uint32_t* data() const { const uint32_t* data() const { return m_code.data(); }
return m_code.data(); uint32_t* data() { return m_code.data(); }
}
/** /**
* \brief Code size, in bytes * \brief Code size, in bytes
@ -54,7 +53,8 @@ namespace dxvk {
* \returns Instruction iterator * \returns Instruction iterator
*/ */
SpirvInstructionIterator begin() { SpirvInstructionIterator begin() {
return SpirvInstructionIterator(m_code.data(), m_code.size()); return SpirvInstructionIterator(
m_code.data(), 0, m_code.size());
} }
/** /**
@ -64,7 +64,7 @@ namespace dxvk {
* \returns Instruction iterator * \returns Instruction iterator
*/ */
SpirvInstructionIterator end() { SpirvInstructionIterator end() {
return SpirvInstructionIterator(nullptr, 0); return SpirvInstructionIterator(nullptr, 0, 0);
} }
/** /**

View File

@ -19,8 +19,8 @@ namespace dxvk {
public: public:
SpirvInstruction() { } SpirvInstruction() { }
SpirvInstruction(uint32_t* code, uint32_t size) SpirvInstruction(uint32_t* code, uint32_t offset, uint32_t length)
: m_code(code), m_size(size) { } : m_code(code), m_offset(offset), m_length(length) { }
/** /**
* \brief SPIR-V Op code * \brief SPIR-V Op code
@ -39,6 +39,14 @@ namespace dxvk {
return this->arg(0) >> spv::WordCountShift; return this->arg(0) >> spv::WordCountShift;
} }
/**
* \brief Instruction offset
* \returns Offset in DWORDs
*/
uint32_t offset() const {
return m_offset;
}
/** /**
* \brief Argument value * \brief Argument value
* *
@ -50,7 +58,8 @@ namespace dxvk {
* \returns The argument value * \returns The argument value
*/ */
uint32_t arg(uint32_t id) const { uint32_t arg(uint32_t id) const {
return id < m_size ? m_code[id] : 0; const uint32_t index = m_offset + id;
return index < m_length ? m_code[index] : 0;
} }
/** /**
@ -60,20 +69,21 @@ namespace dxvk {
* \param [in] word New argument word * \param [in] word New argument word
*/ */
void setArg(uint32_t id, uint32_t word) const { void setArg(uint32_t id, uint32_t word) const {
if (id < m_size) if (m_offset + id < m_length)
m_code[id] = word; m_code[m_offset + id] = word;
} }
private: private:
uint32_t* m_code = nullptr; uint32_t* m_code = nullptr;
uint32_t m_size = 0; uint32_t m_offset = 0;
uint32_t m_length = 0;
}; };
/** /**
* \brief SPIR-V instruction * \brief SPIR-V instruction iterator
* *
* Convenient iterator that can be used * Convenient iterator that can be used
* to process raw SPIR-V shader code. * to process raw SPIR-V shader code.
@ -83,43 +93,48 @@ namespace dxvk {
public: public:
SpirvInstructionIterator() { } SpirvInstructionIterator() { }
SpirvInstructionIterator(uint32_t* code, uint32_t size) SpirvInstructionIterator(uint32_t* code, uint32_t offset, uint32_t length)
: m_code(size != 0 ? code : nullptr), m_size(size) { : m_code (length != 0 ? code : nullptr),
if ((size >= 5) && (m_code[0] == spv::MagicNumber)) m_offset(length != 0 ? offset : 0),
m_length(length) {
if ((length >= 5) && (m_code[0] == spv::MagicNumber))
this->advance(5); this->advance(5);
} }
SpirvInstructionIterator& operator ++ () { SpirvInstructionIterator& operator ++ () {
this->advance(SpirvInstruction(m_code, m_size).length()); this->advance(SpirvInstruction(m_code, m_offset, m_length).length());
return *this; return *this;
} }
SpirvInstruction operator * () const { SpirvInstruction operator * () const {
return SpirvInstruction(m_code, m_size); return SpirvInstruction(m_code, m_offset, m_length);
} }
bool operator == (const SpirvInstructionIterator& other) const { bool operator == (const SpirvInstructionIterator& other) const {
return this->m_code == other.m_code return this->m_code == other.m_code
&& this->m_size == other.m_size; && this->m_offset == other.m_offset
&& this->m_length == other.m_length;
} }
bool operator != (const SpirvInstructionIterator& other) const { bool operator != (const SpirvInstructionIterator& other) const {
return this->m_code != other.m_code return this->m_code != other.m_code
&& this->m_size != other.m_size; || this->m_offset != other.m_offset
|| this->m_length != other.m_length;
} }
private: private:
uint32_t* m_code = nullptr; uint32_t* m_code = nullptr;
uint32_t m_size = 0; uint32_t m_offset = 0;
uint32_t m_length = 0;
void advance(uint32_t n) { void advance(uint32_t n) {
if (n < m_size) { if (m_offset + n < m_length) {
m_code += n; m_offset += n;
m_size -= n;
} else { } else {
m_code = nullptr; m_code = nullptr;
m_size = 0; m_offset = 0;
m_length = 0;
} }
} }