/* * 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 #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 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 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 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