/////////////////////////////////////////////////////////////////////////////// // // // DxbcUtil.cpp // // Copyright (C) Microsoft Corporation. All rights reserved. // // This file is distributed under the University of Illinois Open Source // // License. See LICENSE.TXT for details. // // // // Utilities to convert from DXBC to DXIL. // // // /////////////////////////////////////////////////////////////////////////////// #include "dxc/Support/Global.h" #include "dxc/DXIL/DxilSampler.h" #include "dxc/DXIL/DxilResource.h" #include "llvm/Support/Casting.h" #include "llvm/IR/LLVMContext.h" #include "llvm/IR/Type.h" #include "llvm/IR/Instructions.h" #include "Support/DXIncludes.h" #include "DxbcUtil.h" using namespace llvm; namespace hlsl { //------------------------------------------------------------------------------ // // CMask methods. // CMask::CMask() : m_Mask(0) { } CMask::CMask(BYTE Mask) : m_Mask(Mask) { DXASSERT(Mask <= DXBC::kAllCompMask, "otherwise the caller did not check"); } CMask::CMask(BYTE c0, BYTE c1, BYTE c2, BYTE c3) { DXASSERT(c0<=1 && c1<=1 && c2<=1 && c3<=1, "otherwise the caller did not check"); m_Mask = c0 | (c1<<1) | (c2<<2) | (c3<<3); } CMask::CMask(BYTE StartComp, BYTE NumComp) { DXASSERT(StartComp> c) & 1; } return n; } BYTE CMask::GetNumActiveRangeComps() const { DXASSERT(m_Mask <= DXBC::kAllCompMask, "otherwise the caller did not check"); if ((m_Mask & DXBC::kAllCompMask) == 0) return 0; BYTE FirstComp = 0; for (BYTE c = 0; c < DXBC::kWidth; c++) { if (m_Mask & (1 << c)) { FirstComp = c; break; } } BYTE LastComp = 0; for (BYTE c1 = 0; c1 < DXBC::kWidth; c1++) { BYTE c = DXBC::kWidth - 1 - c1; if (m_Mask & (1 << c)) { LastComp = c; break; } } return LastComp - FirstComp + 1; } BYTE CMask::MakeMask(BYTE c0, BYTE c1, BYTE c2, BYTE c3) { return CMask(c0,c1,c2,c3).ToByte(); } CMask CMask::MakeXYZWMask() { return CMask(DXBC::kAllCompMask); } CMask CMask::MakeFirstNCompMask(BYTE n) { switch(n) { case 0: return CMask(0,0,0,0); case 1: return CMask(1,0,0,0); case 2: return CMask(1,1,0,0); case 3: return CMask(1,1,1,0); default: DXASSERT(n == 4, "otherwise the caller did not pass the right number of components"); return CMask(1,1,1,1); } } CMask CMask::MakeCompMask(BYTE Component) { DXASSERT(Component < DXBC::kWidth, "otherwise the caller should have checked that the mask is non-zero"); return CMask((BYTE)(1 << Component)); } CMask CMask::MakeXMask() { return MakeCompMask(0); } bool CMask::IsValidDoubleMask(const CMask &Mask) { BYTE b = Mask.ToByte(); return b == 0xF || b == 0xC || b == 0x3; } CMask CMask::GetMaskForDoubleOperation(const CMask &Mask) { switch (Mask.GetNumActiveComps()) { case 0: return CMask(0,0,0,0); case 1: return CMask(1,1,0,0); case 2: return CMask(1,1,1,1); } DXASSERT(false, "otherwise missed a case"); return CMask(); } BYTE CMask::GetFirstActiveComp() const { DXASSERT(m_Mask > 0, "otherwise the caller should have checked that the mask is non-zero"); for (BYTE c = 0; c < DXBC::kWidth; c++) { if ((m_Mask >> c) & 1) return c; } return _UI8_MAX; } CMask CMask::FromDXBC(const unsigned DxbcMask) { return CMask(DxbcMask >> D3D10_SB_OPERAND_4_COMPONENT_MASK_SHIFT); } //------------------------------------------------------------------------------ // // OperandValue methods. // OperandValue::OperandValue() { m_pVal[0] = m_pVal[1] = m_pVal[2] = m_pVal[3] = nullptr; } OperandValue::PValue &OperandValue::operator[](BYTE c) { DXASSERT_NOMSG(c < DXBC::kWidth); return m_pVal[c]; } const OperandValue::PValue &OperandValue::operator[](BYTE c) const { DXASSERT_NOMSG(c < DXBC::kWidth); DXASSERT(m_pVal[c] != nullptr, "otherwise required component value has not been set"); return m_pVal[c]; } //------------------------------------------------------------------------------ // // OperandValue methods. // OperandValueHelper::OperandValueHelper() : m_pOpValue(nullptr) , m_Index(DXBC::kWidth) { m_Components[0] = m_Components[1] = m_Components[2] = m_Components[3] = kBadComp; } OperandValueHelper::OperandValueHelper(OperandValue &OpValue, const CMask &Mask, const D3D10ShaderBinary::COperandBase &O) : m_pOpValue(&OpValue) { switch (O.m_ComponentSelection) { case D3D10_SB_OPERAND_4_COMPONENT_SWIZZLE_MODE: Initialize(Mask, O.m_Swizzle); break; case D3D10_SB_OPERAND_4_COMPONENT_SELECT_1_MODE: { BYTE Swizzle[DXBC::kWidth] = { (BYTE)O.m_ComponentName, (BYTE)O.m_ComponentName, (BYTE)O.m_ComponentName, (BYTE)O.m_ComponentName }; Initialize(Mask, Swizzle); break; } case D3D10_SB_OPERAND_4_COMPONENT_MASK_MODE: { BYTE Swizzle[DXBC::kWidth] = { (BYTE)D3D10_SB_4_COMPONENT_X, (BYTE)D3D10_SB_4_COMPONENT_Y, (BYTE)D3D10_SB_4_COMPONENT_Z, (BYTE)D3D10_SB_4_COMPONENT_W }; Initialize(Mask, Swizzle); break; } default: DXASSERT_DXBC(false); } } void OperandValueHelper::Initialize(const CMask &Mask, const BYTE CompSwizzle[DXBC::kWidth]) { DXASSERT(Mask.GetNumActiveComps() > 0, "otherwise the caller passed incorrect mask"); for (BYTE c = 0; c < DXBC::kWidth; c++) { DXASSERT(m_pOpValue->m_pVal[c] == nullptr, "otherwise the caller passed a stale/corrupt OpValue"); if (Mask.IsSet(c)) m_Components[c] = CompSwizzle[c]; else m_Components[c] = kBadComp; } for (m_Index = 0; m_Index < DXBC::kWidth; m_Index++) if (m_Components[m_Index] != kBadComp) break; DXASSERT_NOMSG(m_Index < DXBC::kWidth); } BYTE OperandValueHelper::GetComp() const { return (m_Index < DXBC::kWidth) ? m_Components[m_Index] : kBadComp; } bool OperandValueHelper::IsDone() const { return m_Index == DXBC::kWidth; } void OperandValueHelper::Advance() { if (IsDone()) { DXASSERT(false, "otherwise Advance got called past the last active component, which is not the intended use"); return; } // 1. Look for the next component that needs a value. // 2. Disable m_Components[c] that are equal to Comp to iterate only through unique components. BYTE Comp = m_Components[m_Index]; DXASSERT_NOMSG(Comp < DXBC::kWidth); m_Components[m_Index] = kBadComp; BYTE StartComp = m_Index + 1; m_Index = DXBC::kWidth; for (BYTE c = StartComp; c < DXBC::kWidth; c++) { if (m_Components[c] == Comp) { m_Components[c] = kBadComp; } else if (m_Components[c] != kBadComp) { if (m_Index == DXBC::kWidth) m_Index = c; } } } void OperandValueHelper::SetValue(llvm::Value *pValue) { DXASSERT(m_Index < DXBC::kWidth, "otherwise the client uses the instance after all unique components have been set"); DXASSERT(m_pOpValue->m_pVal[m_Index] == nullptr, "otherwise the client tried to redefine a value, which is not the intended use"); BYTE Comp = m_Components[m_Index]; DXASSERT_NOMSG(Comp < DXBC::kWidth); for (BYTE c = m_Index; c < DXBC::kWidth; c++) { if (m_Components[c] == Comp) { DXASSERT_NOMSG(m_pOpValue->m_pVal[c] == nullptr); m_pOpValue->m_pVal[c] = pValue; } } } //------------------------------------------------------------------------------ // // DXBC namespace functions. // namespace DXBC { ShaderModel::Kind GetShaderModelKind(D3D10_SB_TOKENIZED_PROGRAM_TYPE Type) { switch (Type) { case D3D10_SB_PIXEL_SHADER: return ShaderModel::Kind::Pixel; case D3D10_SB_VERTEX_SHADER: return ShaderModel::Kind::Vertex; case D3D10_SB_GEOMETRY_SHADER: return ShaderModel::Kind::Geometry; case D3D11_SB_HULL_SHADER: return ShaderModel::Kind::Hull; case D3D11_SB_DOMAIN_SHADER: return ShaderModel::Kind::Domain; case D3D11_SB_COMPUTE_SHADER: return ShaderModel::Kind::Compute; default: return ShaderModel::Kind::Invalid; } } bool IsFlagDisableOptimizations (unsigned Flags) { return (Flags & D3D11_1_SB_GLOBAL_FLAG_SKIP_OPTIMIZATION) != 0; } bool IsFlagDisableMathRefactoring (unsigned Flags) { return (Flags & D3D10_SB_GLOBAL_FLAG_REFACTORING_ALLOWED) == 0; } bool IsFlagEnableDoublePrecision (unsigned Flags) { return (Flags & D3D11_SB_GLOBAL_FLAG_ENABLE_DOUBLE_PRECISION_FLOAT_OPS) != 0; } bool IsFlagForceEarlyDepthStencil (unsigned Flags) { return (Flags & D3D11_SB_GLOBAL_FLAG_FORCE_EARLY_DEPTH_STENCIL) != 0; } bool IsFlagEnableRawAndStructuredBuffers(unsigned Flags) { return (Flags & D3D11_SB_GLOBAL_FLAG_ENABLE_RAW_AND_STRUCTURED_BUFFERS) != 0; } bool IsFlagEnableMinPrecision (unsigned Flags) { return (Flags & D3D11_1_SB_GLOBAL_FLAG_ENABLE_MINIMUM_PRECISION) != 0; } bool IsFlagEnableDoubleExtensions (unsigned Flags) { return (Flags & D3D11_1_SB_GLOBAL_FLAG_ENABLE_DOUBLE_EXTENSIONS) != 0; } bool IsFlagEnableMSAD (unsigned Flags) { return (Flags & D3D11_1_SB_GLOBAL_FLAG_ENABLE_SHADER_EXTENSIONS) != 0; } bool IsFlagAllResourcesBound (unsigned Flags) { return (Flags & D3D12_SB_GLOBAL_FLAG_ALL_RESOURCES_BOUND) != 0; } InterpolationMode::Kind GetInterpolationModeKind(D3D_INTERPOLATION_MODE Mode) { switch (Mode) { case D3D_INTERPOLATION_UNDEFINED: return InterpolationMode::Kind::Undefined; case D3D_INTERPOLATION_CONSTANT: return InterpolationMode::Kind::Constant; case D3D_INTERPOLATION_LINEAR: return InterpolationMode::Kind::Linear; case D3D_INTERPOLATION_LINEAR_CENTROID: return InterpolationMode::Kind::LinearCentroid; case D3D_INTERPOLATION_LINEAR_NOPERSPECTIVE: return InterpolationMode::Kind::LinearNoperspective; case D3D_INTERPOLATION_LINEAR_NOPERSPECTIVE_CENTROID: return InterpolationMode::Kind::LinearNoperspectiveCentroid; case D3D_INTERPOLATION_LINEAR_SAMPLE: return InterpolationMode::Kind::LinearSample; case D3D_INTERPOLATION_LINEAR_NOPERSPECTIVE_SAMPLE: return InterpolationMode::Kind::LinearNoperspectiveSample; } DXASSERT(false, "otherwise the caller did not check the range"); return InterpolationMode::Kind::Invalid; } D3D10_SB_OPERAND_TYPE GetOperandRegType(Semantic::Kind Kind, bool IsOutput) { switch (Kind) { case Semantic::Kind::Coverage: if (IsOutput) return D3D10_SB_OPERAND_TYPE_OUTPUT_COVERAGE_MASK; else return D3D11_SB_OPERAND_TYPE_INPUT_COVERAGE_MASK; case Semantic::Kind::InnerCoverage: return D3D11_SB_OPERAND_TYPE_INNER_COVERAGE; case Semantic::Kind::PrimitiveID: return D3D10_SB_OPERAND_TYPE_INPUT_PRIMITIVEID; case Semantic::Kind::Depth: return D3D10_SB_OPERAND_TYPE_OUTPUT_DEPTH; case Semantic::Kind::DepthLessEqual: return D3D11_SB_OPERAND_TYPE_OUTPUT_DEPTH_LESS_EQUAL; case Semantic::Kind::DepthGreaterEqual: return D3D11_SB_OPERAND_TYPE_OUTPUT_DEPTH_GREATER_EQUAL; case Semantic::Kind::StencilRef: return D3D11_SB_OPERAND_TYPE_OUTPUT_STENCIL_REF; } DXASSERT(false, "otherwise the caller passed wrong semantic type"); return D3D10_SB_OPERAND_TYPE_TEMP; } DxilResource::Kind GetResourceKind(D3D10_SB_RESOURCE_DIMENSION ResType) { switch (ResType) { case D3D10_SB_RESOURCE_DIMENSION_UNKNOWN: return DxilResource::Kind::Invalid; case D3D10_SB_RESOURCE_DIMENSION_BUFFER: return DxilResource::Kind::TypedBuffer; case D3D10_SB_RESOURCE_DIMENSION_TEXTURE1D: return DxilResource::Kind::Texture1D; case D3D10_SB_RESOURCE_DIMENSION_TEXTURE2D: return DxilResource::Kind::Texture2D; case D3D10_SB_RESOURCE_DIMENSION_TEXTURE2DMS: return DxilResource::Kind::Texture2DMS; case D3D10_SB_RESOURCE_DIMENSION_TEXTURE3D: return DxilResource::Kind::Texture3D; case D3D10_SB_RESOURCE_DIMENSION_TEXTURECUBE: return DxilResource::Kind::TextureCube; case D3D10_SB_RESOURCE_DIMENSION_TEXTURE1DARRAY: return DxilResource::Kind::Texture1DArray; case D3D10_SB_RESOURCE_DIMENSION_TEXTURE2DARRAY: return DxilResource::Kind::Texture2DArray; case D3D10_SB_RESOURCE_DIMENSION_TEXTURE2DMSARRAY: return DxilResource::Kind::Texture2DMSArray; case D3D10_SB_RESOURCE_DIMENSION_TEXTURECUBEARRAY: return DxilResource::Kind::TextureCubeArray; case D3D11_SB_RESOURCE_DIMENSION_RAW_BUFFER: return DxilResource::Kind::RawBuffer; case D3D11_SB_RESOURCE_DIMENSION_STRUCTURED_BUFFER: return DxilResource::Kind::RawBuffer; } DXASSERT(false, "otherwise the caller did not check the range"); return DxilResource::Kind::Invalid; } BYTE GetNumResCoords(DxilResource::Kind ResKind) { switch (ResKind) { case DxilResource::Kind::Texture1D: return 1; case DxilResource::Kind::Texture2D: return 2; case DxilResource::Kind::Texture2DMS: return 2; case DxilResource::Kind::Texture3D: return 3; case DxilResource::Kind::TextureCube: return 3; case DxilResource::Kind::Texture1DArray: return 2; case DxilResource::Kind::Texture2DArray: return 3; case DxilResource::Kind::Texture2DMSArray: return 3; case DxilResource::Kind::TextureCubeArray: return 4; case DxilResource::Kind::TypedBuffer: return 1; case DxilResource::Kind::RawBuffer: return 1; } DXASSERT(false, "otherwise the caller did not pass correct resource kind"); return 0; } BYTE GetNumResOffsets(DxilResource::Kind ResKind) { switch (ResKind) { case DxilResource::Kind::Texture1D: return 1; case DxilResource::Kind::Texture2D: return 2; case DxilResource::Kind::Texture2DMS: return 2; case DxilResource::Kind::Texture3D: return 3; case DxilResource::Kind::TextureCube: return 3; case DxilResource::Kind::Texture1DArray: return 1; case DxilResource::Kind::Texture2DArray: return 2; case DxilResource::Kind::Texture2DMSArray: return 2; case DxilResource::Kind::TextureCubeArray: return 3; case DxilResource::Kind::TypedBuffer: return 0; case DxilResource::Kind::RawBuffer: return 0; } DXASSERT(false, "otherwise the caller did not pass correct resource kind"); return 0; } CompType GetCompType(D3D_REGISTER_COMPONENT_TYPE CompTy) { switch (CompTy) { case D3D_REGISTER_COMPONENT_FLOAT32: return CompType::getF32(); case D3D_REGISTER_COMPONENT_SINT32: return CompType::getI32(); case D3D_REGISTER_COMPONENT_UINT32: return CompType::getU32(); } DXASSERT(false, "incorrect component type value"); return CompType(); } CompType GetCompTypeWithMinPrec(D3D_REGISTER_COMPONENT_TYPE BaseCompTy, D3D11_SB_OPERAND_MIN_PRECISION MinPrec) { switch (BaseCompTy) { case D3D_REGISTER_COMPONENT_FLOAT32: switch (MinPrec) { case D3D11_SB_OPERAND_MIN_PRECISION_DEFAULT: return CompType::getF32(); case D3D11_SB_OPERAND_MIN_PRECISION_FLOAT_16: __fallthrough; case D3D11_SB_OPERAND_MIN_PRECISION_FLOAT_2_8: return CompType::getF16(); } break; case D3D_REGISTER_COMPONENT_SINT32: switch (MinPrec) { case D3D11_SB_OPERAND_MIN_PRECISION_DEFAULT: return CompType::getI32(); case D3D11_SB_OPERAND_MIN_PRECISION_SINT_16: return CompType::getI16(); case D3D11_SB_OPERAND_MIN_PRECISION_UINT_16: return CompType::getU16(); } break; case D3D_REGISTER_COMPONENT_UINT32: switch (MinPrec) { case D3D11_SB_OPERAND_MIN_PRECISION_DEFAULT: return CompType::getU32(); case D3D11_SB_OPERAND_MIN_PRECISION_SINT_16: return CompType::getI16(); case D3D11_SB_OPERAND_MIN_PRECISION_UINT_16: return CompType::getU16(); } break; } DXASSERT(false, "otherwise incorrect combination of type and min-precision"); return CompType(); } CompType GetCompTypeWithMinPrec(CompType BaseCompTy, D3D11_SB_OPERAND_MIN_PRECISION MinPrec) { switch (BaseCompTy.GetKind()) { case CompType::Kind::F32: switch (MinPrec) { case D3D11_SB_OPERAND_MIN_PRECISION_DEFAULT: return CompType::getF32(); case D3D11_SB_OPERAND_MIN_PRECISION_FLOAT_16: __fallthrough; case D3D11_SB_OPERAND_MIN_PRECISION_FLOAT_2_8: return CompType::getF16(); } break; case CompType::Kind::I32: switch (MinPrec) { case D3D11_SB_OPERAND_MIN_PRECISION_DEFAULT: return CompType::getI32(); case D3D11_SB_OPERAND_MIN_PRECISION_SINT_16: return CompType::getI16(); case D3D11_SB_OPERAND_MIN_PRECISION_UINT_16: return CompType::getU16(); } break; case CompType::Kind::U32: switch (MinPrec) { case D3D11_SB_OPERAND_MIN_PRECISION_DEFAULT: return CompType::getU32(); case D3D11_SB_OPERAND_MIN_PRECISION_SINT_16: return CompType::getI16(); case D3D11_SB_OPERAND_MIN_PRECISION_UINT_16: return CompType::getU16(); } break; case CompType::Kind::F64: return CompType::getF64(); } DXASSERT(false, "otherwise incorrect combination of type and min-precision"); return CompType(); } static CompType GetFullPrecCompType(CompType CompTy) { switch (CompTy.GetKind()) { case CompType::Kind::F16: return CompType::getF32(); case CompType::Kind::I16: return CompType::getI32(); case CompType::Kind::U16: return CompType::getU32(); default: return CompTy; } } CompType GetCompTypeFromMinPrec(D3D11_SB_OPERAND_MIN_PRECISION MinPrec, CompType DefaultPrecCompType) { switch (MinPrec) { case D3D11_SB_OPERAND_MIN_PRECISION_DEFAULT: return GetFullPrecCompType(DefaultPrecCompType); case D3D11_SB_OPERAND_MIN_PRECISION_FLOAT_16: __fallthrough; case D3D11_SB_OPERAND_MIN_PRECISION_FLOAT_2_8: return CompType::getF16(); case D3D11_SB_OPERAND_MIN_PRECISION_SINT_16: return CompType::getI16(); case D3D11_SB_OPERAND_MIN_PRECISION_UINT_16: return CompType::getU16(); default: DXASSERT_DXBC(false); return GetFullPrecCompType(DefaultPrecCompType); } } CompType GetResCompType(D3D10_SB_RESOURCE_RETURN_TYPE CompTy) { switch(CompTy) { case D3D10_SB_RETURN_TYPE_UNORM: return CompType::getF32(); case D3D10_SB_RETURN_TYPE_SNORM: return CompType::getF32(); case D3D10_SB_RETURN_TYPE_SINT: return CompType::getI32(); case D3D10_SB_RETURN_TYPE_UINT: return CompType::getU32(); case D3D10_SB_RETURN_TYPE_FLOAT: return CompType::getF32(); case D3D10_SB_RETURN_TYPE_MIXED: return CompType::getInvalid(); case D3D11_SB_RETURN_TYPE_DOUBLE: return CompType::getF64(); case D3D11_SB_RETURN_TYPE_CONTINUED: return CompType::getInvalid(); case D3D11_SB_RETURN_TYPE_UNUSED: return CompType::getInvalid(); default: DXASSERT(false, "invalid comp type"); return CompType::getInvalid(); } } CompType GetDeclResCompType(D3D10_SB_RESOURCE_RETURN_TYPE CompTy) { switch(CompTy) { case D3D10_SB_RETURN_TYPE_UNORM: return CompType::getUNormF32(); case D3D10_SB_RETURN_TYPE_SNORM: return CompType::getSNormF32(); case D3D10_SB_RETURN_TYPE_SINT: return CompType::getI32(); case D3D10_SB_RETURN_TYPE_UINT: return CompType::getU32(); case D3D10_SB_RETURN_TYPE_FLOAT: return CompType::getF32(); case D3D10_SB_RETURN_TYPE_MIXED: return CompType::getInvalid(); case D3D11_SB_RETURN_TYPE_DOUBLE: return CompType::getF64(); case D3D11_SB_RETURN_TYPE_CONTINUED: return CompType::getInvalid(); case D3D11_SB_RETURN_TYPE_UNUSED: return CompType::getInvalid(); default: DXASSERT(false, "invalid comp type"); return CompType::getInvalid(); } } static const char s_ComponentName[kWidth] = { 'x', 'y', 'z', 'w' }; char GetCompName(BYTE c) { DXASSERT(c < kWidth, "otherwise the caller did not pass the right component value"); return s_ComponentName[c]; } DxilSampler::SamplerKind GetSamplerKind(D3D10_SB_SAMPLER_MODE Mode) { switch(Mode) { case D3D10_SB_SAMPLER_MODE_DEFAULT: return DxilSampler::SamplerKind::Default; case D3D10_SB_SAMPLER_MODE_COMPARISON: return DxilSampler::SamplerKind::Comparison; case D3D10_SB_SAMPLER_MODE_MONO: return DxilSampler::SamplerKind::Mono; } DXASSERT(false, "otherwise the caller did not pass the right Mode"); return DxilSampler::SamplerKind::Invalid; } unsigned GetRegIndex(unsigned Reg, unsigned Comp) { return Reg * 4 + Comp; } DXIL::AtomicBinOpCode GetAtomicBinOp(D3D10_SB_OPCODE_TYPE DxbcOpCode) { switch (DxbcOpCode) { case D3D11_SB_OPCODE_ATOMIC_IADD: return DXIL::AtomicBinOpCode::Add; case D3D11_SB_OPCODE_ATOMIC_AND: return DXIL::AtomicBinOpCode::And; case D3D11_SB_OPCODE_ATOMIC_OR: return DXIL::AtomicBinOpCode::Or; case D3D11_SB_OPCODE_ATOMIC_XOR: return DXIL::AtomicBinOpCode::Xor; case D3D11_SB_OPCODE_ATOMIC_IMAX: return DXIL::AtomicBinOpCode::IMax; case D3D11_SB_OPCODE_ATOMIC_IMIN: return DXIL::AtomicBinOpCode::IMin; case D3D11_SB_OPCODE_ATOMIC_UMAX: return DXIL::AtomicBinOpCode::UMax; case D3D11_SB_OPCODE_ATOMIC_UMIN: return DXIL::AtomicBinOpCode::UMin; case D3D11_SB_OPCODE_IMM_ATOMIC_EXCH: return DXIL::AtomicBinOpCode::Exchange; case D3D11_SB_OPCODE_IMM_ATOMIC_IADD: return DXIL::AtomicBinOpCode::Add; case D3D11_SB_OPCODE_IMM_ATOMIC_AND: return DXIL::AtomicBinOpCode::And; case D3D11_SB_OPCODE_IMM_ATOMIC_OR: return DXIL::AtomicBinOpCode::Or; case D3D11_SB_OPCODE_IMM_ATOMIC_XOR: return DXIL::AtomicBinOpCode::Xor; case D3D11_SB_OPCODE_IMM_ATOMIC_IMAX: return DXIL::AtomicBinOpCode::IMax; case D3D11_SB_OPCODE_IMM_ATOMIC_IMIN: return DXIL::AtomicBinOpCode::IMin; case D3D11_SB_OPCODE_IMM_ATOMIC_UMAX: return DXIL::AtomicBinOpCode::UMax; case D3D11_SB_OPCODE_IMM_ATOMIC_UMIN: return DXIL::AtomicBinOpCode::UMin; case D3D11_SB_OPCODE_ATOMIC_CMP_STORE: case D3D11_SB_OPCODE_IMM_ATOMIC_CMP_EXCH: default: DXASSERT(false, "otherwise the caller did not pass the right OpCode"); } return DXIL::AtomicBinOpCode::Invalid; } llvm::AtomicRMWInst::BinOp GetLlvmAtomicBinOp(D3D10_SB_OPCODE_TYPE DxbcOpCode) { switch (DxbcOpCode) { case D3D11_SB_OPCODE_ATOMIC_IADD: return llvm::AtomicRMWInst::Add; case D3D11_SB_OPCODE_ATOMIC_AND: return llvm::AtomicRMWInst::And; case D3D11_SB_OPCODE_ATOMIC_OR: return llvm::AtomicRMWInst::Or; case D3D11_SB_OPCODE_ATOMIC_XOR: return llvm::AtomicRMWInst::Xor; case D3D11_SB_OPCODE_ATOMIC_IMAX: return llvm::AtomicRMWInst::Max; case D3D11_SB_OPCODE_ATOMIC_IMIN: return llvm::AtomicRMWInst::Min; case D3D11_SB_OPCODE_ATOMIC_UMAX: return llvm::AtomicRMWInst::UMax; case D3D11_SB_OPCODE_ATOMIC_UMIN: return llvm::AtomicRMWInst::UMin; case D3D11_SB_OPCODE_IMM_ATOMIC_EXCH: return llvm::AtomicRMWInst::Xchg; case D3D11_SB_OPCODE_IMM_ATOMIC_IADD: return llvm::AtomicRMWInst::Add; case D3D11_SB_OPCODE_IMM_ATOMIC_AND: return llvm::AtomicRMWInst::And; case D3D11_SB_OPCODE_IMM_ATOMIC_OR: return llvm::AtomicRMWInst::Or; case D3D11_SB_OPCODE_IMM_ATOMIC_XOR: return llvm::AtomicRMWInst::Xor; case D3D11_SB_OPCODE_IMM_ATOMIC_IMAX: return llvm::AtomicRMWInst::Max; case D3D11_SB_OPCODE_IMM_ATOMIC_IMIN: return llvm::AtomicRMWInst::Min; case D3D11_SB_OPCODE_IMM_ATOMIC_UMAX: return llvm::AtomicRMWInst::UMax; case D3D11_SB_OPCODE_IMM_ATOMIC_UMIN: return llvm::AtomicRMWInst::UMin; case D3D11_SB_OPCODE_ATOMIC_CMP_STORE: case D3D11_SB_OPCODE_IMM_ATOMIC_CMP_EXCH: default: DXASSERT(false, "otherwise the caller did not pass the right OpCode"); } return llvm::AtomicRMWInst::BAD_BINOP; } bool AtomicBinOpHasReturn(D3D10_SB_OPCODE_TYPE DxbcOpCode) { switch (DxbcOpCode) { case D3D11_SB_OPCODE_ATOMIC_AND: case D3D11_SB_OPCODE_ATOMIC_OR: case D3D11_SB_OPCODE_ATOMIC_XOR: case D3D11_SB_OPCODE_ATOMIC_IADD: case D3D11_SB_OPCODE_ATOMIC_IMAX: case D3D11_SB_OPCODE_ATOMIC_IMIN: case D3D11_SB_OPCODE_ATOMIC_UMAX: case D3D11_SB_OPCODE_ATOMIC_UMIN: case D3D11_SB_OPCODE_ATOMIC_CMP_STORE: return false; case D3D11_SB_OPCODE_IMM_ATOMIC_IADD: case D3D11_SB_OPCODE_IMM_ATOMIC_AND: case D3D11_SB_OPCODE_IMM_ATOMIC_OR: case D3D11_SB_OPCODE_IMM_ATOMIC_XOR: case D3D11_SB_OPCODE_IMM_ATOMIC_EXCH: case D3D11_SB_OPCODE_IMM_ATOMIC_IMAX: case D3D11_SB_OPCODE_IMM_ATOMIC_IMIN: case D3D11_SB_OPCODE_IMM_ATOMIC_UMAX: case D3D11_SB_OPCODE_IMM_ATOMIC_UMIN: case D3D11_SB_OPCODE_IMM_ATOMIC_CMP_EXCH: return true; } DXASSERT(false, "otherwise the caller did not pass the right OpCode"); return false; } bool IsCompareExchAtomicBinOp(D3D10_SB_OPCODE_TYPE DxbcOpCode) { switch (DxbcOpCode) { case D3D11_SB_OPCODE_ATOMIC_CMP_STORE: case D3D11_SB_OPCODE_IMM_ATOMIC_CMP_EXCH: return true; case D3D11_SB_OPCODE_ATOMIC_AND: case D3D11_SB_OPCODE_ATOMIC_OR: case D3D11_SB_OPCODE_ATOMIC_XOR: case D3D11_SB_OPCODE_ATOMIC_IADD: case D3D11_SB_OPCODE_ATOMIC_IMAX: case D3D11_SB_OPCODE_ATOMIC_IMIN: case D3D11_SB_OPCODE_ATOMIC_UMAX: case D3D11_SB_OPCODE_ATOMIC_UMIN: case D3D11_SB_OPCODE_IMM_ATOMIC_IADD: case D3D11_SB_OPCODE_IMM_ATOMIC_AND: case D3D11_SB_OPCODE_IMM_ATOMIC_OR: case D3D11_SB_OPCODE_IMM_ATOMIC_XOR: case D3D11_SB_OPCODE_IMM_ATOMIC_EXCH: case D3D11_SB_OPCODE_IMM_ATOMIC_IMAX: case D3D11_SB_OPCODE_IMM_ATOMIC_IMIN: case D3D11_SB_OPCODE_IMM_ATOMIC_UMAX: case D3D11_SB_OPCODE_IMM_ATOMIC_UMIN: return false; } DXASSERT(false, "otherwise the caller did not pass the right OpCode"); return false; } bool HasFeedback(D3D10_SB_OPCODE_TYPE OpCode) { switch (OpCode) { case D3DWDDM1_3_SB_OPCODE_GATHER4_FEEDBACK: case D3DWDDM1_3_SB_OPCODE_GATHER4_C_FEEDBACK: case D3DWDDM1_3_SB_OPCODE_GATHER4_PO_FEEDBACK: case D3DWDDM1_3_SB_OPCODE_GATHER4_PO_C_FEEDBACK: case D3DWDDM1_3_SB_OPCODE_LD_FEEDBACK: case D3DWDDM1_3_SB_OPCODE_LD_MS_FEEDBACK: case D3DWDDM1_3_SB_OPCODE_LD_UAV_TYPED_FEEDBACK: case D3DWDDM1_3_SB_OPCODE_LD_RAW_FEEDBACK: case D3DWDDM1_3_SB_OPCODE_LD_STRUCTURED_FEEDBACK: case D3DWDDM1_3_SB_OPCODE_SAMPLE_L_FEEDBACK: case D3DWDDM1_3_SB_OPCODE_SAMPLE_C_LZ_FEEDBACK: case D3DWDDM1_3_SB_OPCODE_SAMPLE_CLAMP_FEEDBACK: case D3DWDDM1_3_SB_OPCODE_SAMPLE_B_CLAMP_FEEDBACK: case D3DWDDM1_3_SB_OPCODE_SAMPLE_D_CLAMP_FEEDBACK: case D3DWDDM1_3_SB_OPCODE_SAMPLE_C_CLAMP_FEEDBACK: return true; } return false; } unsigned GetResourceSlot(D3D10_SB_OPCODE_TYPE OpCode) { switch (OpCode) { case D3D11_SB_OPCODE_STORE_UAV_TYPED: case D3D11_SB_OPCODE_STORE_RAW: case D3D11_SB_OPCODE_STORE_STRUCTURED: case D3D11_SB_OPCODE_ATOMIC_AND: case D3D11_SB_OPCODE_ATOMIC_OR: case D3D11_SB_OPCODE_ATOMIC_XOR: case D3D11_SB_OPCODE_ATOMIC_IADD: case D3D11_SB_OPCODE_ATOMIC_IMAX: case D3D11_SB_OPCODE_ATOMIC_IMIN: case D3D11_SB_OPCODE_ATOMIC_UMAX: case D3D11_SB_OPCODE_ATOMIC_UMIN: case D3D11_SB_OPCODE_ATOMIC_CMP_STORE: return 0; case D3D11_SB_OPCODE_IMM_ATOMIC_IADD: case D3D11_SB_OPCODE_IMM_ATOMIC_AND: case D3D11_SB_OPCODE_IMM_ATOMIC_OR: case D3D11_SB_OPCODE_IMM_ATOMIC_XOR: case D3D11_SB_OPCODE_IMM_ATOMIC_EXCH: case D3D11_SB_OPCODE_IMM_ATOMIC_IMAX: case D3D11_SB_OPCODE_IMM_ATOMIC_IMIN: case D3D11_SB_OPCODE_IMM_ATOMIC_UMAX: case D3D11_SB_OPCODE_IMM_ATOMIC_UMIN: case D3D11_SB_OPCODE_IMM_ATOMIC_CMP_EXCH: case D3D10_1_SB_OPCODE_SAMPLE_INFO: case D3D10_1_SB_OPCODE_SAMPLE_POS: return 1; case D3D10_SB_OPCODE_SAMPLE: case D3D10_SB_OPCODE_SAMPLE_B: case D3D10_SB_OPCODE_SAMPLE_L: case D3D10_SB_OPCODE_SAMPLE_D: case D3D10_SB_OPCODE_SAMPLE_C: case D3D10_SB_OPCODE_SAMPLE_C_LZ: case D3D10_SB_OPCODE_LD: case D3D10_SB_OPCODE_LD_MS: case D3D11_SB_OPCODE_LD_UAV_TYPED: case D3D11_SB_OPCODE_LD_RAW: case D3D10_SB_OPCODE_RESINFO: case D3D10_1_SB_OPCODE_LOD: case D3D10_1_SB_OPCODE_GATHER4: case D3D11_SB_OPCODE_GATHER4_C: return 2; case D3DWDDM1_3_SB_OPCODE_SAMPLE_CLAMP_FEEDBACK: case D3DWDDM1_3_SB_OPCODE_SAMPLE_B_CLAMP_FEEDBACK: case D3DWDDM1_3_SB_OPCODE_SAMPLE_L_FEEDBACK: case D3DWDDM1_3_SB_OPCODE_SAMPLE_D_CLAMP_FEEDBACK: case D3DWDDM1_3_SB_OPCODE_SAMPLE_C_CLAMP_FEEDBACK: case D3DWDDM1_3_SB_OPCODE_SAMPLE_C_LZ_FEEDBACK: case D3DWDDM1_3_SB_OPCODE_LD_FEEDBACK: case D3DWDDM1_3_SB_OPCODE_LD_MS_FEEDBACK: case D3DWDDM1_3_SB_OPCODE_LD_UAV_TYPED_FEEDBACK: case D3DWDDM1_3_SB_OPCODE_LD_RAW_FEEDBACK: case D3D11_SB_OPCODE_LD_STRUCTURED: case D3DWDDM1_3_SB_OPCODE_GATHER4_FEEDBACK: case D3DWDDM1_3_SB_OPCODE_GATHER4_C_FEEDBACK: case D3D11_SB_OPCODE_GATHER4_PO: case D3D11_SB_OPCODE_GATHER4_PO_C: return 3; case D3DWDDM1_3_SB_OPCODE_LD_STRUCTURED_FEEDBACK: case D3DWDDM1_3_SB_OPCODE_GATHER4_PO_FEEDBACK: case D3DWDDM1_3_SB_OPCODE_GATHER4_PO_C_FEEDBACK: return 4; } DXASSERT_NOMSG(false); return 0; } DXIL::BarrierMode GetBarrierMode(bool bSyncThreadGroup, bool bUAVFenceGlobal, bool bUAVFenceThreadGroup, bool bTGSMFence) { unsigned M = 0; if (bSyncThreadGroup) M |= (unsigned)DXIL::BarrierMode::SyncThreadGroup; if (bUAVFenceGlobal) M |= (unsigned)DXIL::BarrierMode::UAVFenceGlobal; if (bUAVFenceThreadGroup) M |= (unsigned)DXIL::BarrierMode::UAVFenceThreadGroup; if (bTGSMFence) M |= (unsigned)DXIL::BarrierMode::TGSMFence; return (DXIL::BarrierMode)M; } DXIL::InputPrimitive GetInputPrimitive(D3D10_SB_PRIMITIVE Primitive) { switch (Primitive) { case D3D10_SB_PRIMITIVE_UNDEFINED: return DXIL::InputPrimitive::Undefined; case D3D10_SB_PRIMITIVE_POINT: return DXIL::InputPrimitive::Point; case D3D10_SB_PRIMITIVE_LINE: return DXIL::InputPrimitive::Line; case D3D10_SB_PRIMITIVE_TRIANGLE: return DXIL::InputPrimitive::Triangle; case D3D10_SB_PRIMITIVE_LINE_ADJ: return DXIL::InputPrimitive::LineWithAdjacency; case D3D10_SB_PRIMITIVE_TRIANGLE_ADJ: return DXIL::InputPrimitive::TriangleWithAdjacency; case D3D11_SB_PRIMITIVE_1_CONTROL_POINT_PATCH: return DXIL::InputPrimitive::ControlPointPatch1; case D3D11_SB_PRIMITIVE_2_CONTROL_POINT_PATCH: return DXIL::InputPrimitive::ControlPointPatch2; case D3D11_SB_PRIMITIVE_3_CONTROL_POINT_PATCH: return DXIL::InputPrimitive::ControlPointPatch3; case D3D11_SB_PRIMITIVE_4_CONTROL_POINT_PATCH: return DXIL::InputPrimitive::ControlPointPatch4; case D3D11_SB_PRIMITIVE_5_CONTROL_POINT_PATCH: return DXIL::InputPrimitive::ControlPointPatch5; case D3D11_SB_PRIMITIVE_6_CONTROL_POINT_PATCH: return DXIL::InputPrimitive::ControlPointPatch6; case D3D11_SB_PRIMITIVE_7_CONTROL_POINT_PATCH: return DXIL::InputPrimitive::ControlPointPatch7; case D3D11_SB_PRIMITIVE_8_CONTROL_POINT_PATCH: return DXIL::InputPrimitive::ControlPointPatch8; case D3D11_SB_PRIMITIVE_9_CONTROL_POINT_PATCH: return DXIL::InputPrimitive::ControlPointPatch9; case D3D11_SB_PRIMITIVE_10_CONTROL_POINT_PATCH: return DXIL::InputPrimitive::ControlPointPatch10; case D3D11_SB_PRIMITIVE_11_CONTROL_POINT_PATCH: return DXIL::InputPrimitive::ControlPointPatch11; case D3D11_SB_PRIMITIVE_12_CONTROL_POINT_PATCH: return DXIL::InputPrimitive::ControlPointPatch12; case D3D11_SB_PRIMITIVE_13_CONTROL_POINT_PATCH: return DXIL::InputPrimitive::ControlPointPatch13; case D3D11_SB_PRIMITIVE_14_CONTROL_POINT_PATCH: return DXIL::InputPrimitive::ControlPointPatch14; case D3D11_SB_PRIMITIVE_15_CONTROL_POINT_PATCH: return DXIL::InputPrimitive::ControlPointPatch15; case D3D11_SB_PRIMITIVE_16_CONTROL_POINT_PATCH: return DXIL::InputPrimitive::ControlPointPatch16; case D3D11_SB_PRIMITIVE_17_CONTROL_POINT_PATCH: return DXIL::InputPrimitive::ControlPointPatch17; case D3D11_SB_PRIMITIVE_18_CONTROL_POINT_PATCH: return DXIL::InputPrimitive::ControlPointPatch18; case D3D11_SB_PRIMITIVE_19_CONTROL_POINT_PATCH: return DXIL::InputPrimitive::ControlPointPatch19; case D3D11_SB_PRIMITIVE_20_CONTROL_POINT_PATCH: return DXIL::InputPrimitive::ControlPointPatch20; case D3D11_SB_PRIMITIVE_21_CONTROL_POINT_PATCH: return DXIL::InputPrimitive::ControlPointPatch21; case D3D11_SB_PRIMITIVE_22_CONTROL_POINT_PATCH: return DXIL::InputPrimitive::ControlPointPatch22; case D3D11_SB_PRIMITIVE_23_CONTROL_POINT_PATCH: return DXIL::InputPrimitive::ControlPointPatch23; case D3D11_SB_PRIMITIVE_24_CONTROL_POINT_PATCH: return DXIL::InputPrimitive::ControlPointPatch24; case D3D11_SB_PRIMITIVE_25_CONTROL_POINT_PATCH: return DXIL::InputPrimitive::ControlPointPatch25; case D3D11_SB_PRIMITIVE_26_CONTROL_POINT_PATCH: return DXIL::InputPrimitive::ControlPointPatch26; case D3D11_SB_PRIMITIVE_27_CONTROL_POINT_PATCH: return DXIL::InputPrimitive::ControlPointPatch27; case D3D11_SB_PRIMITIVE_28_CONTROL_POINT_PATCH: return DXIL::InputPrimitive::ControlPointPatch28; case D3D11_SB_PRIMITIVE_29_CONTROL_POINT_PATCH: return DXIL::InputPrimitive::ControlPointPatch29; case D3D11_SB_PRIMITIVE_30_CONTROL_POINT_PATCH: return DXIL::InputPrimitive::ControlPointPatch30; case D3D11_SB_PRIMITIVE_31_CONTROL_POINT_PATCH: return DXIL::InputPrimitive::ControlPointPatch31; case D3D11_SB_PRIMITIVE_32_CONTROL_POINT_PATCH: return DXIL::InputPrimitive::ControlPointPatch32; } DXASSERT_NOMSG(false); return DXIL::InputPrimitive::Undefined; } DXIL::PrimitiveTopology GetPrimitiveTopology(D3D10_SB_PRIMITIVE_TOPOLOGY Topology) { switch(Topology) { case D3D10_SB_PRIMITIVE_TOPOLOGY_UNDEFINED: return DXIL::PrimitiveTopology::Undefined; case D3D10_SB_PRIMITIVE_TOPOLOGY_POINTLIST: return DXIL::PrimitiveTopology::PointList; case D3D10_SB_PRIMITIVE_TOPOLOGY_LINELIST: return DXIL::PrimitiveTopology::LineList; case D3D10_SB_PRIMITIVE_TOPOLOGY_LINESTRIP: return DXIL::PrimitiveTopology::LineStrip; case D3D10_SB_PRIMITIVE_TOPOLOGY_TRIANGLELIST: return DXIL::PrimitiveTopology::TriangleList; case D3D10_SB_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP: return DXIL::PrimitiveTopology::TriangleStrip; case D3D10_SB_PRIMITIVE_TOPOLOGY_LINELIST_ADJ: __fallthrough; // The ADJ versions are redundant in DXBC and are ot used, probably put there by mistake. case D3D10_SB_PRIMITIVE_TOPOLOGY_LINESTRIP_ADJ: __fallthrough; case D3D10_SB_PRIMITIVE_TOPOLOGY_TRIANGLELIST_ADJ: __fallthrough; case D3D10_SB_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP_ADJ: __fallthrough; } IFTBOOL(false, DXC_E_INCORRECT_DXBC); return DXIL::PrimitiveTopology::Undefined; } const char *GetD3D10SBName(D3D10_SB_NAME D3DName) { switch (D3DName) { case D3D10_SB_NAME_UNDEFINED: return "undefined"; case D3D10_SB_NAME_POSITION: return "SV_Position"; case D3D10_SB_NAME_CLIP_DISTANCE: return "SV_ClipDistance"; case D3D10_SB_NAME_CULL_DISTANCE: return "SV_CullDistance"; case D3D10_SB_NAME_RENDER_TARGET_ARRAY_INDEX: return "SV_RenderTargetArrayIndex"; case D3D10_SB_NAME_VIEWPORT_ARRAY_INDEX: return "SV_ViewportArrayIndex"; case D3D10_SB_NAME_VERTEX_ID: return "SV_VertexID"; case D3D10_SB_NAME_PRIMITIVE_ID: return "SV_PrimitiveID"; case D3D10_SB_NAME_INSTANCE_ID: return "SV_InstanceID"; case D3D10_SB_NAME_IS_FRONT_FACE: return "SV_IsFrontFace"; case D3D10_SB_NAME_SAMPLE_INDEX: return "SV_SampleIndex"; case D3D11_SB_NAME_FINAL_QUAD_U_EQ_0_EDGE_TESSFACTOR: case D3D11_SB_NAME_FINAL_QUAD_V_EQ_0_EDGE_TESSFACTOR: case D3D11_SB_NAME_FINAL_QUAD_U_EQ_1_EDGE_TESSFACTOR: case D3D11_SB_NAME_FINAL_QUAD_V_EQ_1_EDGE_TESSFACTOR: case D3D11_SB_NAME_FINAL_TRI_U_EQ_0_EDGE_TESSFACTOR: case D3D11_SB_NAME_FINAL_TRI_V_EQ_0_EDGE_TESSFACTOR: case D3D11_SB_NAME_FINAL_TRI_W_EQ_0_EDGE_TESSFACTOR: case D3D11_SB_NAME_FINAL_LINE_DETAIL_TESSFACTOR: case D3D11_SB_NAME_FINAL_LINE_DENSITY_TESSFACTOR: return "SV_TessFactor"; case D3D11_SB_NAME_FINAL_QUAD_U_INSIDE_TESSFACTOR: case D3D11_SB_NAME_FINAL_QUAD_V_INSIDE_TESSFACTOR: case D3D11_SB_NAME_FINAL_TRI_INSIDE_TESSFACTOR: return "SV_InsideTessFactor"; default: IFT(DXC_E_INCORRECT_DXBC); return "unknown"; } } unsigned GetD3D10SBSemanticIndex(D3D10_SB_NAME D3DName) { switch (D3DName) { case D3D10_SB_NAME_UNDEFINED: case D3D10_SB_NAME_POSITION: case D3D10_SB_NAME_CLIP_DISTANCE: case D3D10_SB_NAME_CULL_DISTANCE: case D3D10_SB_NAME_RENDER_TARGET_ARRAY_INDEX: case D3D10_SB_NAME_VIEWPORT_ARRAY_INDEX: case D3D10_SB_NAME_VERTEX_ID: case D3D10_SB_NAME_PRIMITIVE_ID: case D3D10_SB_NAME_INSTANCE_ID: case D3D10_SB_NAME_IS_FRONT_FACE: case D3D10_SB_NAME_SAMPLE_INDEX: return 0; case D3D11_SB_NAME_FINAL_QUAD_U_EQ_0_EDGE_TESSFACTOR: return 0; case D3D11_SB_NAME_FINAL_QUAD_V_EQ_0_EDGE_TESSFACTOR: return 1; case D3D11_SB_NAME_FINAL_QUAD_U_EQ_1_EDGE_TESSFACTOR: return 2; case D3D11_SB_NAME_FINAL_QUAD_V_EQ_1_EDGE_TESSFACTOR: return 3; case D3D11_SB_NAME_FINAL_QUAD_U_INSIDE_TESSFACTOR: return 0; case D3D11_SB_NAME_FINAL_QUAD_V_INSIDE_TESSFACTOR: return 1; case D3D11_SB_NAME_FINAL_TRI_U_EQ_0_EDGE_TESSFACTOR: return 0; case D3D11_SB_NAME_FINAL_TRI_V_EQ_0_EDGE_TESSFACTOR: return 1; case D3D11_SB_NAME_FINAL_TRI_W_EQ_0_EDGE_TESSFACTOR: return 2; case D3D11_SB_NAME_FINAL_TRI_INSIDE_TESSFACTOR: return 0; case D3D11_SB_NAME_FINAL_LINE_DETAIL_TESSFACTOR: return 0; case D3D11_SB_NAME_FINAL_LINE_DENSITY_TESSFACTOR: return 1; default: return 0; } } D3D_REGISTER_COMPONENT_TYPE GetD3DRegCompType(D3D10_SB_NAME D3DName) { switch (D3DName) { case D3D10_SB_NAME_POSITION: case D3D10_SB_NAME_CLIP_DISTANCE: case D3D10_SB_NAME_CULL_DISTANCE: return D3D_REGISTER_COMPONENT_FLOAT32; case D3D10_SB_NAME_RENDER_TARGET_ARRAY_INDEX: case D3D10_SB_NAME_VIEWPORT_ARRAY_INDEX: case D3D10_SB_NAME_VERTEX_ID: case D3D10_SB_NAME_PRIMITIVE_ID: case D3D10_SB_NAME_INSTANCE_ID: case D3D10_SB_NAME_IS_FRONT_FACE: case D3D10_SB_NAME_SAMPLE_INDEX: return D3D_REGISTER_COMPONENT_UINT32; case D3D10_SB_NAME_UNDEFINED: // this shpild not be called for an undefined name. case D3D11_SB_NAME_FINAL_QUAD_U_EQ_0_EDGE_TESSFACTOR: case D3D11_SB_NAME_FINAL_QUAD_V_EQ_0_EDGE_TESSFACTOR: case D3D11_SB_NAME_FINAL_QUAD_U_EQ_1_EDGE_TESSFACTOR: case D3D11_SB_NAME_FINAL_QUAD_V_EQ_1_EDGE_TESSFACTOR: case D3D11_SB_NAME_FINAL_QUAD_U_INSIDE_TESSFACTOR: case D3D11_SB_NAME_FINAL_QUAD_V_INSIDE_TESSFACTOR: case D3D11_SB_NAME_FINAL_TRI_U_EQ_0_EDGE_TESSFACTOR: case D3D11_SB_NAME_FINAL_TRI_V_EQ_0_EDGE_TESSFACTOR: case D3D11_SB_NAME_FINAL_TRI_W_EQ_0_EDGE_TESSFACTOR: case D3D11_SB_NAME_FINAL_TRI_INSIDE_TESSFACTOR: case D3D11_SB_NAME_FINAL_LINE_DETAIL_TESSFACTOR: case D3D11_SB_NAME_FINAL_LINE_DENSITY_TESSFACTOR: default: IFT(DXC_E_INCORRECT_DXBC); return D3D_REGISTER_COMPONENT_UNKNOWN; } } const char *GetSemanticNameFromD3DName(D3D_NAME D3DName) { switch (D3DName) { case D3D_NAME_UNDEFINED: return "undefined"; case D3D_NAME_POSITION: return "SV_Position"; case D3D_NAME_CLIP_DISTANCE: return "SV_ClipDistance"; case D3D_NAME_CULL_DISTANCE: return "SV_CullDistance"; case D3D_NAME_RENDER_TARGET_ARRAY_INDEX: return "SV_RenderTargetArrayIndex"; case D3D_NAME_VIEWPORT_ARRAY_INDEX: return "SV_ViewportArrayIndex"; case D3D_NAME_VERTEX_ID: return "SV_VertexID"; case D3D_NAME_PRIMITIVE_ID: return "SV_PrimitiveID"; case D3D_NAME_INSTANCE_ID: return "SV_InstanceID"; case D3D_NAME_IS_FRONT_FACE: return "SV_IsFrontFace"; case D3D_NAME_SAMPLE_INDEX: return "SV_SampleIndex"; case D3D_NAME_FINAL_QUAD_EDGE_TESSFACTOR: return "SV_TessFactor"; case D3D_NAME_FINAL_QUAD_INSIDE_TESSFACTOR: return "SV_InsideTessFactor"; case D3D_NAME_FINAL_TRI_EDGE_TESSFACTOR: return "SV_TessFactor"; case D3D_NAME_FINAL_TRI_INSIDE_TESSFACTOR: return "SV_InsideTessFactor"; case D3D_NAME_FINAL_LINE_DETAIL_TESSFACTOR: return "SV_TessFactor"; case D3D_NAME_FINAL_LINE_DENSITY_TESSFACTOR: return "SV_TessFactor"; case D3D_NAME_TARGET: return "SV_Target"; case D3D_NAME_DEPTH: return "SV_Depth"; case D3D_NAME_COVERAGE: return "SV_Coverage"; case D3D_NAME_DEPTH_GREATER_EQUAL: return "SV_DepthGreaterEqual"; case D3D_NAME_DEPTH_LESS_EQUAL: return "SV_DepthLessEqual"; case D3D_NAME_STENCIL_REF: return "SV_StencilRef"; case D3D_NAME_INNER_COVERAGE: return "SV_InnerCoverage"; default: DXASSERT_NOMSG(false); return "undefined"; } } unsigned GetSemanticIndexFromD3DName(D3D_NAME D3DName) { switch (D3DName) { case D3D_NAME_UNDEFINED: case D3D_NAME_POSITION: case D3D_NAME_CLIP_DISTANCE: case D3D_NAME_CULL_DISTANCE: case D3D_NAME_RENDER_TARGET_ARRAY_INDEX: case D3D_NAME_VIEWPORT_ARRAY_INDEX: case D3D_NAME_VERTEX_ID: case D3D_NAME_PRIMITIVE_ID: case D3D_NAME_INSTANCE_ID: case D3D_NAME_IS_FRONT_FACE: case D3D_NAME_SAMPLE_INDEX: case D3D_NAME_FINAL_QUAD_EDGE_TESSFACTOR: case D3D_NAME_FINAL_QUAD_INSIDE_TESSFACTOR: case D3D_NAME_FINAL_TRI_EDGE_TESSFACTOR: case D3D_NAME_FINAL_TRI_INSIDE_TESSFACTOR: case D3D_NAME_TARGET: case D3D_NAME_DEPTH: case D3D_NAME_COVERAGE: case D3D_NAME_DEPTH_GREATER_EQUAL: case D3D_NAME_DEPTH_LESS_EQUAL: case D3D_NAME_STENCIL_REF: case D3D_NAME_INNER_COVERAGE: return UINT_MAX; case D3D_NAME_FINAL_LINE_DETAIL_TESSFACTOR: return 0; case D3D_NAME_FINAL_LINE_DENSITY_TESSFACTOR: return 1; default: DXASSERT_NOMSG(false); return UINT_MAX; } } DXIL::TessellatorDomain GetTessellatorDomain(D3D11_SB_TESSELLATOR_DOMAIN TessDomain) { switch (TessDomain) { case D3D11_SB_TESSELLATOR_DOMAIN_UNDEFINED: return DXIL::TessellatorDomain::Undefined; case D3D11_SB_TESSELLATOR_DOMAIN_ISOLINE: return DXIL::TessellatorDomain::IsoLine; case D3D11_SB_TESSELLATOR_DOMAIN_TRI: return DXIL::TessellatorDomain::Tri; case D3D11_SB_TESSELLATOR_DOMAIN_QUAD: return DXIL::TessellatorDomain::Quad; } IFTBOOL(false, DXC_E_INCORRECT_DXBC); return DXIL::TessellatorDomain::Undefined; } DXIL::TessellatorPartitioning GetTessellatorPartitioning(D3D11_SB_TESSELLATOR_PARTITIONING TessPartitioning) { switch (TessPartitioning) { case D3D11_SB_TESSELLATOR_PARTITIONING_UNDEFINED: return DXIL::TessellatorPartitioning::Undefined; case D3D11_SB_TESSELLATOR_PARTITIONING_INTEGER: return DXIL::TessellatorPartitioning::Integer; case D3D11_SB_TESSELLATOR_PARTITIONING_POW2: return DXIL::TessellatorPartitioning::Pow2; case D3D11_SB_TESSELLATOR_PARTITIONING_FRACTIONAL_ODD: return DXIL::TessellatorPartitioning::FractionalOdd; case D3D11_SB_TESSELLATOR_PARTITIONING_FRACTIONAL_EVEN: return DXIL::TessellatorPartitioning::FractionalEven; } IFTBOOL(false, DXC_E_INCORRECT_DXBC); return DXIL::TessellatorPartitioning::Undefined; } DXIL::TessellatorOutputPrimitive GetTessellatorOutputPrimitive(D3D11_SB_TESSELLATOR_OUTPUT_PRIMITIVE TessOutputPrimitive) { switch (TessOutputPrimitive) { case D3D11_SB_TESSELLATOR_OUTPUT_UNDEFINED: return DXIL::TessellatorOutputPrimitive::Undefined; case D3D11_SB_TESSELLATOR_OUTPUT_POINT: return DXIL::TessellatorOutputPrimitive::Point; case D3D11_SB_TESSELLATOR_OUTPUT_LINE: return DXIL::TessellatorOutputPrimitive::Line; case D3D11_SB_TESSELLATOR_OUTPUT_TRIANGLE_CW: return DXIL::TessellatorOutputPrimitive::TriangleCW; case D3D11_SB_TESSELLATOR_OUTPUT_TRIANGLE_CCW: return DXIL::TessellatorOutputPrimitive::TriangleCCW; } IFTBOOL(false, DXC_E_INCORRECT_DXBC); return DXIL::TessellatorOutputPrimitive::Undefined; } } // namespace DXBC //------------------------------------------------------------------------------ // // Asserts to match DXBC and DXIL constant values. // using namespace DXIL; #define MSG "Constant value mismatch between DXBC and DXIL" static_assert(kMaxTempRegCount == D3D11_COMMONSHADER_TEMP_REGISTER_COUNT, MSG); static_assert(kMaxCBufferSize == D3D10_REQ_CONSTANT_BUFFER_ELEMENT_COUNT, MSG); static_assert((int)DxilSampler::SamplerKind::Default == D3D10_SB_SAMPLER_MODE_DEFAULT, MSG); static_assert((int)DxilSampler::SamplerKind::Comparison == D3D10_SB_SAMPLER_MODE_COMPARISON, MSG); static_assert((int)DxilSampler::SamplerKind::Mono == D3D10_SB_SAMPLER_MODE_MONO, MSG); static_assert(D3D10_SB_4_COMPONENT_X == 0, MSG); static_assert(D3D10_SB_4_COMPONENT_Y == 1, MSG); static_assert(D3D10_SB_4_COMPONENT_Z == 2, MSG); static_assert(D3D10_SB_4_COMPONENT_W == 3, MSG); static_assert(D3D_MIN_PRECISION_DEFAULT == D3D11_SB_OPERAND_MIN_PRECISION_DEFAULT, MSG); static_assert(D3D_MIN_PRECISION_FLOAT_16 == D3D11_SB_OPERAND_MIN_PRECISION_FLOAT_16, MSG); static_assert(D3D_MIN_PRECISION_FLOAT_2_8 == D3D11_SB_OPERAND_MIN_PRECISION_FLOAT_2_8, MSG); static_assert(D3D_MIN_PRECISION_SINT_16 == D3D11_SB_OPERAND_MIN_PRECISION_SINT_16, MSG); static_assert(D3D_MIN_PRECISION_UINT_16 == D3D11_SB_OPERAND_MIN_PRECISION_UINT_16, MSG); } // namespace hlsl