bgfx/src/shader_dxbc.h

671 lines
11 KiB
C++

/*
* Copyright 2011-2018 Branimir Karadzic. All rights reserved.
* License: https://github.com/bkaradzic/bgfx#license-bsd-2-clause
*/
#ifndef BGFX_SHADER_DXBC_H
#define BGFX_SHADER_DXBC_H
#include <bx/readerwriter.h>
#define DXBC_CHUNK_HEADER BX_MAKEFOURCC('D', 'X', 'B', 'C')
namespace bgfx
{
struct DxbcOpcode
{
enum Enum
{
ADD,
AND,
BREAK,
BREAKC,
CALL,
CALLC,
CASE,
CONTINUE,
CONTINUEC,
CUT,
DEFAULT,
DERIV_RTX,
DERIV_RTY,
DISCARD,
DIV,
DP2,
DP3,
DP4,
ELSE,
EMIT,
EMITTHENCUT,
ENDIF,
ENDLOOP,
ENDSWITCH,
EQ,
EXP,
FRC,
FTOI,
FTOU,
GE,
IADD,
IF,
IEQ,
IGE,
ILT,
IMAD,
IMAX,
IMIN,
IMUL,
INE,
INEG,
ISHL,
ISHR,
ITOF,
LABEL,
LD,
LD_MS,
LOG,
LOOP,
LT,
MAD,
MIN,
MAX,
CUSTOMDATA,
MOV,
MOVC,
MUL,
NE,
NOP,
NOT,
OR,
RESINFO,
RET,
RETC,
ROUND_NE,
ROUND_NI,
ROUND_PI,
ROUND_Z,
RSQ,
SAMPLE,
SAMPLE_C,
SAMPLE_C_LZ,
SAMPLE_L,
SAMPLE_D,
SAMPLE_B,
SQRT,
SWITCH,
SINCOS,
UDIV,
ULT,
UGE,
UMUL,
UMAD,
UMAX,
UMIN,
USHR,
UTOF,
XOR,
DCL_RESOURCE,
DCL_CONSTANT_BUFFER,
DCL_SAMPLER,
DCL_INDEX_RANGE,
DCL_GS_OUTPUT_PRIMITIVE_TOPOLOGY,
DCL_GS_INPUT_PRIMITIVE,
DCL_MAX_OUTPUT_VERTEX_COUNT,
DCL_INPUT,
DCL_INPUT_SGV,
DCL_INPUT_SIV,
DCL_INPUT_PS,
DCL_INPUT_PS_SGV,
DCL_INPUT_PS_SIV,
DCL_OUTPUT,
DCL_OUTPUT_SGV,
DCL_OUTPUT_SIV,
DCL_TEMPS,
DCL_INDEXABLE_TEMP,
DCL_GLOBAL_FLAGS,
UnknownD3D10,
LOD,
GATHER4,
SAMPLE_POS,
SAMPLE_INFO,
UnknownD3D10_1,
HS_DECLS,
HS_CONTROL_POINT_PHASE,
HS_FORK_PHASE,
HS_JOIN_PHASE,
EMIT_STREAM,
CUT_STREAM,
EMITTHENCUT_STREAM,
INTERFACE_CALL,
BUFINFO,
DERIV_RTX_COARSE,
DERIV_RTX_FINE,
DERIV_RTY_COARSE,
DERIV_RTY_FINE,
GATHER4_C,
GATHER4_PO,
GATHER4_PO_C,
RCP,
F32TOF16,
F16TOF32,
UADDC,
USUBB,
COUNTBITS,
FIRSTBIT_HI,
FIRSTBIT_LO,
FIRSTBIT_SHI,
UBFE,
IBFE,
BFI,
BFREV,
SWAPC,
DCL_STREAM,
DCL_FUNCTION_BODY,
DCL_FUNCTION_TABLE,
DCL_INTERFACE,
DCL_INPUT_CONTROL_POINT_COUNT,
DCL_OUTPUT_CONTROL_POINT_COUNT,
DCL_TESS_DOMAIN,
DCL_TESS_PARTITIONING,
DCL_TESS_OUTPUT_PRIMITIVE,
DCL_HS_MAX_TESSFACTOR,
DCL_HS_FORK_PHASE_INSTANCE_COUNT,
DCL_HS_JOIN_PHASE_INSTANCE_COUNT,
DCL_THREAD_GROUP,
DCL_UNORDERED_ACCESS_VIEW_TYPED,
DCL_UNORDERED_ACCESS_VIEW_RAW,
DCL_UNORDERED_ACCESS_VIEW_STRUCTURED,
DCL_THREAD_GROUP_SHARED_MEMORY_RAW,
DCL_THREAD_GROUP_SHARED_MEMORY_STRUCTURED,
DCL_RESOURCE_RAW,
DCL_RESOURCE_STRUCTURED,
LD_UAV_TYPED,
STORE_UAV_TYPED,
LD_RAW,
STORE_RAW,
LD_STRUCTURED,
STORE_STRUCTURED,
ATOMIC_AND,
ATOMIC_OR,
ATOMIC_XOR,
ATOMIC_CMP_STORE,
ATOMIC_IADD,
ATOMIC_IMAX,
ATOMIC_IMIN,
ATOMIC_UMAX,
ATOMIC_UMIN,
IMM_ATOMIC_ALLOC,
IMM_ATOMIC_CONSUME,
IMM_ATOMIC_IADD,
IMM_ATOMIC_AND,
IMM_ATOMIC_OR,
IMM_ATOMIC_XOR,
IMM_ATOMIC_EXCH,
IMM_ATOMIC_CMP_EXCH,
IMM_ATOMIC_IMAX,
IMM_ATOMIC_IMIN,
IMM_ATOMIC_UMAX,
IMM_ATOMIC_UMIN,
SYNC,
DADD,
DMAX,
DMIN,
DMUL,
DEQ,
DGE,
DLT,
DNE,
DMOV,
DMOVC,
DTOF,
FTOD,
EVAL_SNAPPED,
EVAL_SAMPLE_INDEX,
EVAL_CENTROID,
DCL_GS_INSTANCE_COUNT,
ABORT,
DEBUG_BREAK,
UnknownD3D11,
DDIV,
DFMA,
DRCP,
MSAD,
DTOI,
DTOU,
ITOD,
UTOD,
Count
};
};
const char* getName(DxbcOpcode::Enum _opcode);
struct DxbcBuiltin
{
// D3D_NAME
// https://msdn.microsoft.com/en-us/library/windows/desktop/ff728724%28v=vs.85%29.aspx
// mesa/src/gallium/state_trackers/d3d1x/d3d1xshader/defs/svs.txt
enum Enum
{
Undefined,
Position,
ClipDistance,
CullDistance,
RenderTargetArrayIndex,
ViewportArrayIndex,
VertexId,
PrimitiveId,
InstanceId,
IsFrontFace,
SampleIndex,
FinalQuadUEq0EdgeTessFactor,
FinalQuadVEq0EdgeTessFactor,
FinalQuadUEq1EdgeTessFactor,
FinalQuadVEq1EdgeTessFactor,
FinalQuadUInsideTessFactor,
FinalQuadVInsideTessFactor,
FinalTriUEq0EdgeTessFactor,
FinalTriVEq0EdgeTessFactor,
FinalTriWEq0EdgeTessFactor,
FinalTriInsideTessFactor,
FinalLineDetailTessFactor,
FinalLineDensityTessFactor,
Target = 64,
Depth,
Coverage,
DepthGreaterEqual,
DepthLessEqual,
StencilRef,
InnerCoverage,
};
};
struct DxbcResourceDim
{
// D3D_SRV_DIMENSION
// https://msdn.microsoft.com/en-us/library/windows/desktop/ff728736%28v=vs.85%29.aspx
// mesa/src/gallium/state_trackers/d3d1x/d3d1xshader/defs/targets.txt
enum Enum
{
Unknown,
Buffer,
Texture1D,
Texture2D,
Texture2DMS,
Texture3D,
TextureCube,
Texture1DArray,
Texture2DArray,
Texture2DMSArray,
TextureCubearray,
RawBuffer,
StructuredBuffer,
Count
};
};
struct DxbcInterpolation
{
enum Enum
{
Unknown,
Constant,
Linear,
LinearCentroid,
LinearNoPerspective,
LinearNoPerspectiveCentroid,
LinearSample,
LinearNoPerspectiveSample,
Count
};
};
struct DxbcResourceReturnType
{
enum Enum
{
Unorm,
Snorm,
Sint,
Uint,
Float,
Mixed,
Double,
Continued,
Unused,
Count
};
};
struct DxbcComponentType
{
enum Enum
{
Unknown,
Uint32,
Int32,
Float,
Count
};
};
struct DxbcPrecision
{
enum Enum
{
Default,
Half,
Float2_8,
Reserved,
Int16,
Uint16,
Any16 = 0xf0,
Any10 = 0xf1,
};
};
struct DxbcOperandType
{
enum Enum
{
Temp,
Input,
Output,
TempArray,
Imm32,
Imm64,
Sampler,
Resource,
ConstantBuffer,
ImmConstantBuffer,
Label,
PrimitiveID,
OutputDepth,
Null,
Rasterizer,
CoverageMask,
Stream,
FunctionBody,
FunctionTable,
Interface,
FunctionInput,
FunctionOutput,
OutputControlPointId,
InputForkInstanceId,
InputJoinInstanceId,
InputControlPoint,
OutputControlPoint,
InputPatchConstant,
InputDomainPoint,
ThisPointer,
UnorderedAccessView,
ThreadGroupSharedMemory,
InputThreadId,
InputThreadGroupId,
InputThreadIdInGroup,
InputCoverageMask,
InputThreadIdInGroupFlattened,
InputGsInstanceId,
OutputDepthGreaterEqual,
OutputDepthLessEqual,
CycleCounter,
Count
};
};
struct DxbcOperandAddrMode
{
enum Enum
{
Imm32,
Imm64,
Reg,
RegImm32,
RegImm64,
Count
};
};
struct DxbcOperandMode
{
enum Enum
{
Mask,
Swizzle,
Scalar,
Count
};
};
struct DxbcOperandModifier
{
enum Enum
{
None,
Neg,
Abs,
AbsNeg,
Count
};
};
struct DxbcCustomDataClass
{
enum Enum
{
Comment,
DebugInfo,
Opaque,
ImmConstantBuffer,
ShaderMessage,
ClipPlaneConstantMappingsForDx9,
Count
};
};
struct DxbcSubOperand
{
DxbcSubOperand()
: type(DxbcOperandType::Temp)
, mode(0)
, modeBits(0)
, num(0)
, numAddrModes(0)
, addrMode(0)
, regIndex(0)
{
}
DxbcOperandType::Enum type;
uint8_t mode;
uint8_t modeBits;
uint8_t num;
uint8_t numAddrModes;
uint8_t addrMode;
uint32_t regIndex;
};
struct DxbcOperand
{
DxbcOperand()
: type(DxbcOperandType::Temp)
, mode(DxbcOperandMode::Mask)
, modeBits(0)
, num(0)
, modifier(DxbcOperandModifier::None)
, numAddrModes(0)
{
bx::memSet(addrMode, 0, sizeof(addrMode) );
bx::memSet(regIndex, 0, sizeof(regIndex) );
bx::memSet(un.imm64, 0, sizeof(un.imm64) );
}
DxbcOperandType::Enum type;
DxbcOperandMode::Enum mode;
uint8_t modeBits;
uint8_t num;
DxbcOperandModifier::Enum modifier;
uint8_t numAddrModes;
uint8_t addrMode[3];
uint32_t regIndex[3];
DxbcSubOperand subOperand[3];
union
{
uint32_t imm32[4];
uint64_t imm64[4];
} un;
};
struct DxbcInstruction
{
DxbcInstruction() { /* not pod */ }
struct ExtendedType
{
enum Enum
{
Empty,
SampleControls,
ResourceDim,
ResourceReturnType,
Count
};
};
DxbcOpcode::Enum opcode;
uint32_t value[3];
uint32_t length;
uint8_t numOperands;
ExtendedType::Enum extended[3];
//
DxbcResourceDim::Enum srv;
uint8_t samples;
//
DxbcInterpolation::Enum interpolation;
//
bool shadow;
bool mono;
//
bool allowRefactoring;
bool fp64;
bool earlyDepth;
bool enableBuffers;
bool skipOptimization;
bool enableMinPrecision;
bool enableDoubleExtensions;
bool enableShaderExtensions;
//
bool threadsInGroup;
bool sharedMemory;
bool uavGroup;
bool uavGlobal;
//
DxbcResourceReturnType::Enum retType;
bool saturate;
uint8_t testNZ;
//
uint8_t sampleOffsets[3];
uint8_t resourceTarget;
uint8_t resourceStride;
DxbcResourceReturnType::Enum resourceReturnTypes[4];
DxbcOperand operand[6];
DxbcCustomDataClass::Enum customDataClass;
stl::vector<uint32_t> customData;
};
int32_t read(bx::ReaderI* _reader, DxbcInstruction& _instruction, bx::Error* _err);
int32_t write(bx::WriterI* _writer, const DxbcInstruction& _instruction, bx::Error* _err);
int32_t toString(char* _out, int32_t _size, const DxbcInstruction& _instruction);
struct DxbcSignature
{
DxbcSignature() { /* not pod */ }
struct Element
{
stl::string name;
uint32_t semanticIndex;
DxbcBuiltin::Enum valueType;
DxbcComponentType::Enum componentType;
uint32_t registerIndex;
uint8_t mask;
uint8_t readWriteMask;
uint8_t stream;
};
uint32_t key;
stl::vector<Element> elements;
};
int32_t read(bx::ReaderSeekerI* _reader, DxbcSignature& _signature, bx::Error* _err);
int32_t write(bx::WriterI* _writer, const DxbcSignature& _signature, bx::Error* _err);
struct DxbcShader
{
uint32_t version;
stl::vector<uint8_t> byteCode;
bool shex;
bool aon9;
};
int32_t read(bx::ReaderSeekerI* _reader, DxbcShader& _shader, bx::Error* _err);
int32_t write(bx::WriterI* _writer, const DxbcShader& _shader, bx::Error* _err);
typedef bool (*DxbcParseFn)(uint32_t _offset, const DxbcInstruction& _instruction, void* _userData);
void parse(const DxbcShader& _src, DxbcParseFn _fn, void* _userData, bx::Error* _err = NULL);
typedef void (*DxbcFilterFn)(DxbcInstruction& _instruction, void* _userData);
void filter(DxbcShader& _dst, const DxbcShader& _src, DxbcFilterFn _fn, void* _userData, bx::Error* _err = NULL);
struct DxbcContext
{
struct Header
{
uint32_t magic;
uint8_t hash[16];
uint32_t version;
uint32_t size;
uint32_t numChunks;
};
Header header;
DxbcSignature inputSignature;
DxbcSignature outputSignature;
DxbcShader shader;
};
int32_t read(bx::ReaderSeekerI* _reader, DxbcContext& _dxbc, bx::Error* _err);
int32_t write(bx::WriterSeekerI* _writer, const DxbcContext& _dxbc, bx::Error* _err);
/// Calculate DXBC hash from data.
void dxbcHash(const void* _data, uint32_t _size, void* _digest);
} // namespace bgfx
#endif // BGFX_SHADER_DXBC_H