text: #pragma once
  
  #include "dxbc_enums.h"
  
  namespace dxvk {
    
    constexpr size_t DxbcMaxInterfaceRegs = 32;
    constexpr size_t DxbcMaxOperandCount  = 8;
    
    /**
     * \brief Operand kind
     * 
     * In the instruction format definition, this specified
     * whether an operand uses an actual operand token, or
     * whether it is stored as an immediate value.
     */
    enum class DxbcOperandKind {
      DstReg, ///< Destination register
      SrcReg, ///< Source register
      Imm32,  ///< Constant number
    };
    
    /**
     * \brief Instruction class
     * 
     * Instructions with a similar format are grouped into
     * instruction classes in order to make implementing
     * new instructions easier.
     */
    enum class DxbcInstClass {
      Declaration,        ///< Interface or resource declaration
      CustomData,         ///< Immediate constant buffer
      ControlFlow,        ///< Control flow instructions
      GeometryEmit,       ///< Special geometry shader instructions
      Atomic,             ///< Atomic operations
      AtomicCounter,      ///< Atomic counter operations
      Barrier,            ///< Execution or memory barrier
      BitExtract,         ///< Bit field extract operations
      BitInsert,          ///< Bit field insert operations
      BitScan,            ///< Bit scan operations
      BufferQuery,        ///< Buffer query instruction
      BufferLoad,         ///< Structured or raw buffer load
      BufferStore,        ///< Structured or raw buffer store
      ConvertFloat16,     ///< 16-bit float packing/unpacking
      ConvertFloat64,     ///< 64-bit float conversion
      HullShaderPhase,    ///< Hull shader phase declaration
      HullShaderInstCnt,  ///< Hull shader phase instance count
      Interpolate,        ///< Input attribute interpolation
      NoOperation,        ///< The most useful instruction class
      TextureQuery,       ///< Texture query instruction
      TextureQueryLod,    ///< Texture LOD query instruction
      TextureQueryMs,     ///< Multisample texture query
      TextureQueryMsPos,  ///< Sample position query
      TextureFetch,       ///< Texture fetch instruction
      TextureGather,      ///< Texture gather instruction
      TextureSample,      ///< Texture sampling instruction
      TypedUavLoad,       ///< Typed UAV load
      TypedUavStore,      ///< Typed UAV store
      VectorAlu,          ///< Component-wise vector instructions
      VectorCmov,         ///< Component-wise conditional move
      VectorCmp,          ///< Component-wise vector comparison
      VectorDeriv,        ///< Vector derivatives
      VectorDot,          ///< Dot product instruction
      VectorIdiv,         ///< Component-wise integer division
      VectorImul,         ///< Component-wise integer multiplication
      VectorShift,        ///< Bit shift operations on vectors
      VectorSinCos,       ///< Sine and Cosine instruction
      Undefined,          ///< Instruction code not defined
    };
    
    /**
     * \brief Instruction operand format
     * 
     * Stores the kind and the expected data type
     * of an operand. Used when parsing instructions.
     */
    struct DxbcInstOperandFormat {
      DxbcOperandKind kind;
      DxbcScalarType  type;
    };
    
    /**
     * \brief Instruction format
     * 
     * Defines the instruction class as well as
     * the format of the insttruction operands.
     */
    struct DxbcInstFormat {
      uint32_t              operandCount      = 0;
      DxbcInstClass         instructionClass  = DxbcInstClass::Undefined;
      DxbcInstOperandFormat operands[DxbcMaxOperandCount];
    };
    
    /**
     * \brief Retrieves instruction format info
     * 
     * \param [in] opcode The opcode to retrieve
     * \returns Instruction format info
     */
    DxbcInstFormat dxbcInstructionFormat(DxbcOpcode opcode);
    
  }