1
0
mirror of https://github.com/doitsujin/dxvk.git synced 2024-12-13 16:08:50 +01:00
dxvk/src/spirv/spirv_code_buffer.h
Mike Lothian de0f81fcdc [spirv] Add utility include
This fixes a compile issue with GCC 12.1

FAILED: src/spirv/libspirv.a.p/spirv_compression.cpp.obj
i686-w64-mingw32-g++ -Isrc/spirv/libspirv.a.p -Isrc/spirv -I../dxvk-9999/src/spirv -I../dxvk-9999/include -fdiagnostics-color=always -D_FILE_OFFSET_BITS=64 -Wall -Winvalid-pch -Wnon-virtual-dtor -std=c++17 -O0 -DNOMINMAX -D_WIN32_WINNT=0xa00 -msse -msse2 -msse3 -mfpmath=sse -Wimplicit-fallthrough -O3 -march=native -pipe -flto=16 -mno-avx -MD -MQ src/spirv/libspirv.a.p/spirv_compression.cpp.obj -MF src/spirv/libspirv.a.p/spirv_compression.cpp.obj.d -o src/spirv/libspirv.a.p/spirv_compression.cpp.obj -c ../dxvk-9999/src/spirv/spirv_compression.cpp
In file included from ../dxvk-9999/src/spirv/../util/util_flags.h:5,
                 from ../dxvk-9999/src/spirv/spirv_include.h:7,
                 from ../dxvk-9999/src/spirv/spirv_instruction.h:6,
                 from ../dxvk-9999/src/spirv/spirv_code_buffer.h:8,
                 from ../dxvk-9999/src/spirv/spirv_compression.h:5,
                 from ../dxvk-9999/src/spirv/spirv_compression.cpp:1:
../dxvk-9999/src/spirv/../util/util_bit.h:300:33: warning: ‘template<class _Category, class _Tp, class _Distance, class _Pointer, class _Reference> struct std::iterator’ is deprecated [-Wdeprecated-declarations]
  300 |     class iterator: public std::iterator<std::input_iterator_tag,
      |                                 ^~~~~~~~
In file included from /usr/lib/gcc/i686-w64-mingw32/12.1.0/include/g++-v12/bits/stl_algobase.h:65,
                 from /usr/lib/gcc/i686-w64-mingw32/12.1.0/include/g++-v12/vector:60,
                 from ../dxvk-9999/src/spirv/spirv_compression.h:3:
/usr/lib/gcc/i686-w64-mingw32/12.1.0/include/g++-v12/bits/stl_iterator_base_types.h:127:34: note: declared here
  127 |     struct _GLIBCXX17_DEPRECATED iterator
      |                                  ^~~~~~~~
../dxvk-9999/src/spirv/spirv_code_buffer.h: In member function ‘size_t dxvk::SpirvCodeBuffer::endInsertion()’:
../dxvk-9999/src/spirv/spirv_code_buffer.h:214:19: error: ‘exchange’ is not a member of ‘std’
  214 |       return std::exchange(m_ptr, m_code.size());
      |                   ^~~~~~~~

Signed-off-by: Mike Lothian <mike@fireburn.co.uk>
2022-06-02 15:10:53 +02:00

226 lines
5.6 KiB
C++

#pragma once
#include <spirv/spirv.hpp>
#include <iostream>
#include <utility>
#include <vector>
#include "spirv_instruction.h"
namespace dxvk {
/**
* \brief SPIR-V code buffer
*
* Helper class for generating SPIR-V shaders.
* Stores arbitrary SPIR-V instructions in a
* format that can be read by Vulkan drivers.
*/
class SpirvCodeBuffer {
public:
SpirvCodeBuffer();
explicit SpirvCodeBuffer(uint32_t size);
SpirvCodeBuffer(uint32_t size, const uint32_t* data);
SpirvCodeBuffer(std::istream& stream);
template<size_t N>
SpirvCodeBuffer(const uint32_t (&data)[N])
: SpirvCodeBuffer(N, data) { }
~SpirvCodeBuffer();
/**
* \brief Code data
* \returns Code data
*/
const uint32_t* data() const { return m_code.data(); }
uint32_t* data() { return m_code.data(); }
/**
* \brief Code size, in dwords
* \returns Code size, in dwords
*/
uint32_t dwords() const {
return m_code.size();
}
/**
* \brief Code size, in bytes
* \returns Code size, in bytes
*/
size_t size() const {
return m_code.size() * sizeof(uint32_t);
}
/**
* \brief Begin instruction iterator
*
* Points to the first instruction in the instruction
* block. The header, if any, will be skipped over.
* \returns Instruction iterator
*/
SpirvInstructionIterator begin() {
return SpirvInstructionIterator(
m_code.data(), 0, m_code.size());
}
/**
* \brief End instruction iterator
*
* Points to the end of the instruction block.
* \returns Instruction iterator
*/
SpirvInstructionIterator end() {
return SpirvInstructionIterator(nullptr, 0, 0);
}
/**
* \brief Allocates a new ID
*
* Returns a new valid ID and increments the
* maximum ID count stored in the header.
* \returns The new SPIR-V ID
*/
uint32_t allocId();
/**
* \brief Merges two code buffers
*
* This is useful to generate declarations or
* the SPIR-V header at the same time as the
* code when doing so in advance is impossible.
* \param [in] other Code buffer to append
*/
void append(const SpirvCodeBuffer& other);
/**
* \brief Appends an 32-bit word to the buffer
* \param [in] word The word to append
*/
void putWord(uint32_t word);
/**
* \brief Appends an instruction word to the buffer
*
* Adds a single word containing both the word count
* and the op code number for a single instruction.
* \param [in] opCode Operand code
* \param [in] wordCount Number of words
*/
void putIns(spv::Op opCode, uint16_t wordCount);
/**
* \brief Appends a 32-bit integer to the buffer
* \param [in] value The number to add
*/
void putInt32(uint32_t word);
/**
* \brief Appends a 64-bit integer to the buffer
*
* A 64-bit integer will take up two 32-bit words.
* \param [in] value 64-bit value to add
*/
void putInt64(uint64_t value);
/**
* \brief Appends a 32-bit float to the buffer
* \param [in] value The number to add
*/
void putFloat32(float value);
/**
* \brief Appends a 64-bit float to the buffer
* \param [in] value The number to add
*/
void putFloat64(double value);
/**
* \brief Appends a literal string to the buffer
* \param [in] str String to append to the buffer
*/
void putStr(const char* str);
/**
* \brief Adds the header to the buffer
*
* \param [in] version SPIR-V version
* \param [in] boundIds Number of bound IDs
*/
void putHeader(uint32_t version, uint32_t boundIds);
/**
* \brief Erases given number of dwords
*
* Removes data from the code buffer, starting
* at the current insertion offset.
* \param [in] size Number of words to remove
*/
void erase(size_t size);
/**
* \brief Computes length of a literal string
*
* \param [in] str The string to check
* \returns Number of words consumed by a string
*/
uint32_t strLen(const char* str);
/**
* \brief Stores the SPIR-V module to a stream
*
* The ability to save modules to a file
* exists mostly for debugging purposes.
* \param [in] stream Output stream
*/
void store(std::ostream& stream) const;
/**
* \brief Retrieves current insertion pointer
*
* Sometimes it may be necessay to insert code into the
* middle of the stream rather than appending it. This
* retrieves the current function pointer. Note that the
* pointer will become invalid if any code is inserted
* before the current pointer location.
* \returns Current instruction pointr
*/
size_t getInsertionPtr() const {
return m_ptr;
}
/**
* \brief Sets insertion pointer to a specific value
*
* Sets the insertion pointer to a value that was
* previously retrieved by \ref getInsertionPtr.
* \returns Current instruction pointr
*/
void beginInsertion(size_t ptr) {
m_ptr = ptr;
}
/**
* \brief Sets insertion pointer to the end
*
* After this call, new instructions will be
* appended to the stream. In other words,
* this will restore default behaviour.
* \returns Previous instruction pointer
*/
size_t endInsertion() {
return std::exchange(m_ptr, m_code.size());
}
private:
std::vector<uint32_t> m_code;
size_t m_ptr = 0;
};
}