summaryrefslogtreecommitdiffstats
path: root/src/libs/dxvk-native-1.9.2a/src/dxso/dxso_decoder.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/libs/dxvk-native-1.9.2a/src/dxso/dxso_decoder.h')
-rw-r--r--src/libs/dxvk-native-1.9.2a/src/dxso/dxso_decoder.h276
1 files changed, 276 insertions, 0 deletions
diff --git a/src/libs/dxvk-native-1.9.2a/src/dxso/dxso_decoder.h b/src/libs/dxvk-native-1.9.2a/src/dxso/dxso_decoder.h
new file mode 100644
index 00000000..178f8075
--- /dev/null
+++ b/src/libs/dxvk-native-1.9.2a/src/dxso/dxso_decoder.h
@@ -0,0 +1,276 @@
+#pragma once
+
+#include "dxso_common.h"
+#include "dxso_enums.h"
+#include "dxso_code.h"
+
+namespace dxvk {
+
+ constexpr size_t DxsoMaxTempRegs = 32;
+ constexpr size_t DxsoMaxTextureRegs = 10;
+ constexpr size_t DxsoMaxInterfaceRegs = 16;
+ constexpr size_t DxsoMaxOperandCount = 8;
+
+ constexpr uint32_t DxsoRegModifierShift = 24;
+
+ class DxsoDecodeContext;
+
+ /**
+ * \brief Source operand modifiers
+ *
+ * These are applied after loading
+ * an operand register.
+ */
+ enum class DxsoRegModifier : uint32_t {
+ None = 0, // r
+ Neg = 1, // -r
+ Bias = 2, // r - 0.5
+ BiasNeg = 3, // -(r - 0.5)
+ Sign = 4, // fma(r, 2.0f, -1.0f)
+ SignNeg = 5, // -fma(r, 2.0f, -1.0f)
+ Comp = 6, // 1 - r
+ X2 = 7, // r * 2
+ X2Neg = 8, // -r * 2
+ Dz = 9, // r / r.z
+ Dw = 10, // r / r.w
+ Abs = 11, // abs(r)
+ AbsNeg = 12, // -abs(r)
+ Not = 13, // !r
+ };
+
+ enum class DxsoInstructionArgumentType : uint16_t {
+ Source,
+ Destination
+ };
+
+ enum class DxsoComparison : uint32_t {
+ // < = >
+ Never = 0, // 0 0 0
+ GreaterThan = 1, // 0 0 1
+ Equal = 2, // 0 1 0
+ GreaterEqual = 3, // 0 1 1
+ LessThan = 4, // 1 0 0
+ NotEqual = 5, // 1 0 1
+ LessEqual = 6, // 1 1 0
+ Always = 7 // 1 1 1
+ };
+
+ enum class DxsoTexLdMode : uint32_t {
+ Regular = 0,
+ Project = 1,
+ Bias = 2
+ };
+
+ union DxsoOpcodeSpecificData {
+ DxsoComparison comparison;
+ DxsoTexLdMode texld;
+
+ uint32_t uint32;
+ };
+
+ struct DxsoShaderInstruction {
+ DxsoOpcode opcode;
+ bool predicated;
+ bool coissue;
+ DxsoOpcodeSpecificData specificData;
+
+ uint32_t tokenLength;
+ };
+
+ struct DxsoRegisterId {
+ DxsoRegisterType type;
+ uint32_t num;
+
+ bool operator == (const DxsoRegisterId& other) const { return type == other.type && num == other.num; }
+ bool operator != (const DxsoRegisterId& other) const { return type != other.type || num != other.num; }
+ };
+
+ class DxsoRegMask {
+
+ public:
+
+ DxsoRegMask(uint8_t mask)
+ : m_mask(mask) { }
+
+ DxsoRegMask(bool x, bool y, bool z, bool w)
+ : m_mask((x ? 0x1 : 0) | (y ? 0x2 : 0)
+ | (z ? 0x4 : 0) | (w ? 0x8 : 0)) { }
+
+ bool operator [] (uint32_t id) const {
+ return ((m_mask & (1u << id)) != 0);
+ }
+
+ uint32_t popCount() const {
+ const uint8_t n[16] = { 0, 1, 1, 2, 1, 2, 2, 3,
+ 1, 2, 2, 3, 2, 3, 3, 4 };
+ return n[m_mask & 0xF];
+ }
+
+ uint32_t firstSet() const {
+ const uint8_t n[16] = { 4, 0, 1, 0, 2, 0, 1, 0,
+ 3, 0, 1, 0, 2, 0, 1, 0 };
+ return n[m_mask & 0xF];
+ }
+
+ uint32_t minComponents() const {
+ const uint8_t n[16] = { 0, 1, 2, 2, 3, 3, 3, 3,
+ 4, 4, 4, 4, 4, 4, 4, 4 };
+ return n[m_mask & 0xF];
+ }
+
+ bool operator == (const DxsoRegMask& other) const { return m_mask == other.m_mask; }
+ bool operator != (const DxsoRegMask& other) const { return m_mask != other.m_mask; }
+
+ private:
+
+ uint8_t m_mask;
+
+ };
+
+ const DxsoRegMask IdentityWriteMask = DxsoRegMask(true, true, true, true);
+
+ class DxsoRegSwizzle {
+
+ public:
+
+ DxsoRegSwizzle(uint8_t mask)
+ : m_mask(mask) { }
+
+ DxsoRegSwizzle(uint32_t x, uint32_t y, uint32_t z, uint32_t w)
+ : m_mask((x << 0) | (y << 2) | (z << 4) | (w << 6)) {}
+
+ uint32_t operator [] (uint32_t id) const {
+ return (m_mask >> (id + id)) & 0x3;
+ }
+
+ bool operator == (const DxsoRegSwizzle& other) const { return m_mask == other.m_mask; }
+ bool operator != (const DxsoRegSwizzle& other) const { return m_mask != other.m_mask; }
+
+ private:
+
+ uint8_t m_mask;
+
+ };
+
+ const DxsoRegSwizzle IdentitySwizzle{ 0, 1, 2, 3 };
+
+ struct DxsoBaseRegister {
+ DxsoRegisterId id = { DxsoRegisterType::Temp, 0 };
+ bool centroid = false;
+ bool partialPrecision = false;
+ bool saturate = false;
+ DxsoRegModifier modifier = DxsoRegModifier::None;
+ DxsoRegMask mask = IdentityWriteMask;
+ DxsoRegSwizzle swizzle = IdentitySwizzle;
+ int8_t shift = 0;
+ };
+
+ struct DxsoRegister : public DxsoBaseRegister {
+ bool hasRelative = false;
+ DxsoBaseRegister relative;
+ };
+
+ struct DxsoSemantic {
+ DxsoUsage usage;
+ uint32_t usageIndex;
+
+ bool operator== (const DxsoSemantic& b) const;
+ bool operator!= (const DxsoSemantic& b) const;
+ };
+
+ struct DxsoDeclaration {
+ DxsoSemantic semantic;
+
+ DxsoTextureType textureType;
+ };
+
+ union DxsoDefinition {
+ float float32[4];
+ int32_t int32[4];
+
+ // Not a type we actually use in compiler, but used for decoding.
+ uint32_t uint32[4];
+ };
+
+ struct DxsoInstructionContext {
+ uint32_t instructionIdx;
+
+ DxsoShaderInstruction instruction;
+
+ DxsoRegister pred;
+
+ DxsoRegister dst;
+ std::array<
+ DxsoRegister,
+ DxsoMaxOperandCount> src;
+
+ DxsoDefinition def;
+
+ DxsoDeclaration dcl;
+ };
+
+ class DxsoDecodeContext {
+
+ public:
+
+ DxsoDecodeContext(const DxsoProgramInfo& programInfo)
+ : m_programInfo( programInfo ) {
+ m_ctx.instructionIdx = 0;
+ }
+
+ /**
+ * \brief Retrieves current instruction context
+ *
+ * This is only valid after a call to \ref decode.
+ * \returns Reference to last decoded instruction & its context
+ */
+ const DxsoInstructionContext& getInstructionContext() const {
+ return m_ctx;
+ }
+
+ const DxsoProgramInfo& getProgramInfo() const {
+ return m_programInfo;
+ }
+
+ /**
+ * \brief Decodes an instruction
+ *
+ * This also advances the given code slice by the
+ * number of dwords consumed by the instruction.
+ * \param [in] code Code slice
+ */
+ bool decodeInstruction(DxsoCodeIter& iter);
+
+ private:
+
+ uint32_t decodeInstructionLength(uint32_t token);
+
+ void decodeBaseRegister(
+ DxsoBaseRegister& reg,
+ uint32_t token);
+ void decodeGenericRegister(
+ DxsoRegister& reg,
+ uint32_t token);
+ void decodeRelativeRegister(
+ DxsoBaseRegister& reg,
+ uint32_t token);
+
+ // Returns whether an extra token was read.
+ bool decodeDestinationRegister(DxsoCodeIter& iter);
+ bool decodeSourceRegister(uint32_t i, DxsoCodeIter& iter);
+ void decodePredicateRegister(DxsoCodeIter& iter);
+
+ void decodeDeclaration(DxsoCodeIter& iter);
+ void decodeDefinition(DxsoOpcode opcode, DxsoCodeIter& iter);
+
+ bool relativeAddressingUsesToken(DxsoInstructionArgumentType type);
+
+ const DxsoProgramInfo& m_programInfo;
+
+ DxsoInstructionContext m_ctx;
+
+ };
+
+ std::ostream& operator << (std::ostream& os, DxsoUsage usage);
+
+} \ No newline at end of file