diff options
| author | jsmall-nvidia <jsmall@nvidia.com> | 2018-10-09 11:51:41 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2018-10-09 11:51:41 -0400 |
| commit | 7ea9ff03f4fc766f21d5896aea220d17f236dd70 (patch) | |
| tree | 6b705d44424e250a68f435837f545a74c1437883 /source/slang/ir-serialize.h | |
| parent | 4cb2a19ef192424c0a4eb205a773624563222383 (diff) | |
Feature/var byte encoding (#665)
* * Remove the need for IRHighLevelDecoration in Emit
* Use the IRLayoutDecoration for GeometryShaderPrimitiveTypeModifier
* Initial look at at variable byte encoding, and simple unit test.
* Fixing problems with comparison due to naming differences with slang/fxc.
* * More tests and perf improvements for byte encoding.
* Mechanism to detect processor and processor features in main slang header.
* Split out cpu based defines into slang-cpu-defines.h so do not polute slang.h
* Support for variable byte encoding on serialization.
* Removed unused flag.
* Fix warning.
* Fix calcMsByte32 for 0 values without using intrinsic.
* Fix a mistake in calculating maximum instruction size.
Diffstat (limited to 'source/slang/ir-serialize.h')
| -rw-r--r-- | source/slang/ir-serialize.h | 85 |
1 files changed, 83 insertions, 2 deletions
diff --git a/source/slang/ir-serialize.h b/source/slang/ir-serialize.h index 356e14055..28f90303e 100644 --- a/source/slang/ir-serialize.h +++ b/source/slang/ir-serialize.h @@ -17,6 +17,8 @@ class Name; struct IRSerialData { + typedef IRSerialData ThisType; + enum class InstIndex : uint32_t; enum class StringIndex : uint32_t; enum class ArrayIndex : uint32_t; @@ -32,6 +34,15 @@ struct IRSerialData /// A run of instructions struct InstRun { + typedef InstRun ThisType; + SLANG_FORCE_INLINE bool operator==(const ThisType& rhs) const + { + return m_parentIndex == rhs.m_parentIndex && + m_startInstIndex == rhs.m_startInstIndex && + m_numChildren == rhs.m_numChildren; + } + SLANG_FORCE_INLINE bool operator!=(const ThisType& rhs) const { return !(*this == rhs); } + InstIndex m_parentIndex; ///< The parent instruction InstIndex m_startInstIndex; ///< The index to the first instruction SizeType m_numChildren; ///< The number of children @@ -49,6 +60,7 @@ struct IRSerialData // Decoration information is stored in m_decorationRuns struct Inst { + typedef Inst ThisType; enum { kMaxOperands = 2, ///< Maximum number of operands that can be held in an instruction (otherwise held 'externally') @@ -76,6 +88,10 @@ struct IRSerialData /// Get the number of operands SLANG_FORCE_INLINE int getNumOperands() const; + bool operator==(const ThisType& rhs) const; + + SLANG_FORCE_INLINE bool operator!=(const ThisType& rhs) const { return !(*this == rhs); } + uint8_t m_op; ///< For now one of IROp PayloadType m_payloadType; ///< The type of payload uint16_t m_pad0; ///< Not currently used @@ -115,6 +131,10 @@ struct IRSerialData /// Get the operands of an instruction SLANG_FORCE_INLINE int getOperands(const Inst& inst, const InstIndex** operandsOut) const; + /// == + bool operator==(const ThisType& rhs) const; + SLANG_FORCE_INLINE bool operator!=(const ThisType& rhs) const { return !(*this == rhs); } + /// Calculate the amount of memory used by this IRSerialData size_t calcSizeInBytes() const; @@ -146,6 +166,43 @@ SLANG_FORCE_INLINE int IRSerialData::Inst::getNumOperands() const } // -------------------------------------------------------------------------- +SLANG_FORCE_INLINE bool IRSerialData::Inst::operator==(const ThisType& rhs) const +{ + if (m_op == rhs.m_op && + m_payloadType == rhs.m_payloadType && + m_resultTypeIndex == rhs.m_resultTypeIndex) + { + switch (m_payloadType) + { + case PayloadType::Empty: + { + return true; + } + case PayloadType::Operand_1: + case PayloadType::String_1: + case PayloadType::UInt32: + { + return m_payload.m_operands[0] == rhs.m_payload.m_operands[0]; + } + case PayloadType::OperandAndUInt32: + case PayloadType::OperandExternal: + case PayloadType::Operand_2: + case PayloadType::String_2: + { + return m_payload.m_operands[0] == rhs.m_payload.m_operands[0] && + m_payload.m_operands[1] == rhs.m_payload.m_operands[1]; + } + case PayloadType::Float64: + case PayloadType::Int64: + { + return m_payload.m_int64 == rhs.m_payload.m_int64; + } + default: break; + } + } + return false; +} +// -------------------------------------------------------------------------- SLANG_FORCE_INLINE int IRSerialData::getOperands(const Inst& inst, const InstIndex** operandsOut) const { if (inst.m_payloadType == Inst::PayloadType::OperandExternal) @@ -163,6 +220,8 @@ SLANG_FORCE_INLINE int IRSerialData::getOperands(const Inst& inst, const InstInd #define SLANG_FOUR_CC(c0, c1, c2, c3) ((uint32_t(c0) << 0) | (uint32_t(c1) << 8) | (uint32_t(c2) << 16) | (uint32_t(c3) << 24)) +#define SLANG_MAKE_COMPRESSED_FOUR_CC(fourCc) (((fourCc) & 0xffff00ff) | (uint32_t('c') << 8)) + struct IRSerialBinary { // http://fileformats.archiveteam.org/wiki/RIFF @@ -173,6 +232,14 @@ struct IRSerialBinary uint32_t m_type; uint32_t m_size; }; + + enum class CompressionType + { + None, + VariableByteLite, + }; + + static const uint32_t kRiffFourCc = SLANG_FOUR_CC('R', 'I', 'F', 'F'); static const uint32_t kSlangFourCc = SLANG_FOUR_CC('S', 'L', 'N', 'G'); ///< Holds all the slang specific chunks @@ -180,6 +247,12 @@ struct IRSerialBinary static const uint32_t kDecoratorRunFourCc = SLANG_FOUR_CC('S', 'L', 'd', 'r'); static const uint32_t kChildRunFourCc = SLANG_FOUR_CC('S', 'L', 'c', 'r'); static const uint32_t kExternalOperandsFourCc = SLANG_FOUR_CC('S', 'L', 'e', 'o'); + + static const uint32_t kCompressedInstFourCc = SLANG_MAKE_COMPRESSED_FOUR_CC(kInstFourCc); + static const uint32_t kCompressedDecoratorRunFourCc = SLANG_MAKE_COMPRESSED_FOUR_CC(kDecoratorRunFourCc); + static const uint32_t kCompressedChildRunFourCc = SLANG_MAKE_COMPRESSED_FOUR_CC(kChildRunFourCc); + static const uint32_t kCompressedExternalOperandsFourCc = SLANG_MAKE_COMPRESSED_FOUR_CC(kExternalOperandsFourCc); + static const uint32_t kStringFourCc = SLANG_FOUR_CC('S', 'L', 's', 't'); /// 4 bytes per entry static const uint32_t kUInt32SourceLocFourCc = SLANG_FOUR_CC('S', 'r', 's', '4'); @@ -190,32 +263,40 @@ struct IRSerialBinary { Chunk m_chunk; uint32_t m_decorationBase; + uint32_t m_compressionType; ///< Holds the compression type used (if used at all) }; struct ArrayHeader { Chunk m_chunk; uint32_t m_numEntries; }; + struct CompressedArrayHeader + { + Chunk m_chunk; + uint32_t m_numEntries; ///< The number of entries + uint32_t m_numCompressedEntries; ///< The amount of compressed entries + }; }; struct IRSerialWriter { typedef IRSerialData Ser; + typedef IRSerialBinary Bin; struct OptionFlag { typedef uint32_t Type; enum Enum: Type { - RawSourceLocation = 1, + RawSourceLocation = 0x01, }; }; typedef OptionFlag::Type OptionFlags; Result write(IRModule* module, SourceManager* sourceManager, OptionFlags options, IRSerialData* serialData); - static Result writeStream(const IRSerialData& data, Stream* stream); + static Result writeStream(const IRSerialData& data, Bin::CompressionType compressionType, Stream* stream); /// Get a slice from an index UnownedStringSlice getStringSlice(Ser::StringIndex index) const; |
