@@ -1644,6 +1644,46 @@ static unsigned getSemanticFlagValidMask(const ShaderModel *pSM) {
1644
1644
return static_cast <unsigned >(hlsl::DXIL::BarrierSemanticFlag::ValidMask);
1645
1645
}
1646
1646
1647
+ StringRef GetOpCodeName (DXIL::OpCode OpCode) {
1648
+ switch (OpCode) {
1649
+ default :
1650
+ DXASSERT (false , " Unexpected op code" );
1651
+ return " " ;
1652
+ case DXIL::OpCode::HitObject_ObjectRayOrigin:
1653
+ return " HitObject_ObjectRayOrigin" ;
1654
+ case DXIL::OpCode::HitObject_WorldRayDirection:
1655
+ return " HitObject_WorldRayDirection" ;
1656
+ case DXIL::OpCode::HitObject_WorldRayOrigin:
1657
+ return " HitObject_WorldRayOrigin" ;
1658
+ case DXIL::OpCode::HitObject_ObjectRayDirection:
1659
+ return " HitObject_ObjectRayDirection" ;
1660
+ case DXIL::OpCode::HitObject_WorldToObject3x4:
1661
+ return " HitObject_WorldToObject3x4" ;
1662
+ case DXIL::OpCode::HitObject_ObjectToWorld3x4:
1663
+ return " HitObject_ObjectToWorld3x4" ;
1664
+ }
1665
+ }
1666
+
1667
+ static void ValidateConstantRangeUnsigned (Value *Val, StringRef Name,
1668
+ uint64_t LowerBound,
1669
+ uint64_t UpperBound, CallInst *CI,
1670
+ DXIL::OpCode OpCode,
1671
+ ValidationContext &ValCtx) {
1672
+ ConstantInt *C = dyn_cast<ConstantInt>(Val);
1673
+ if (!C) {
1674
+ ValCtx.EmitInstrFormatError (CI, ValidationRule::InstrOpConst,
1675
+ {Name, GetOpCodeName (OpCode)});
1676
+ return ;
1677
+ }
1678
+ if (C->uge (UpperBound) || !C->uge (LowerBound)) {
1679
+ std::string Range =
1680
+ std::to_string (LowerBound) + " ~" + std::to_string (UpperBound);
1681
+ ValCtx.EmitInstrFormatError (
1682
+ CI, ValidationRule::InstrOperandRange,
1683
+ {Name, Range, C->getValue ().toString (10 , false )});
1684
+ }
1685
+ }
1686
+
1647
1687
static void ValidateDxilOperationCallInProfile (CallInst *CI,
1648
1688
DXIL::OpCode Opcode,
1649
1689
const ShaderModel *pSM,
@@ -1910,6 +1950,76 @@ static void ValidateDxilOperationCallInProfile(CallInst *CI,
1910
1950
CI, ValidationRule::InstrMayReorderThreadUndefCoherenceHintParam);
1911
1951
} break ;
1912
1952
1953
+ case DXIL::OpCode::HitObject_LoadLocalRootTableConstant: {
1954
+ Value *HitObject = CI->getArgOperand (1 );
1955
+ if (isa<UndefValue>(HitObject))
1956
+ ValCtx.EmitInstrError (CI, ValidationRule::InstrUndefHitObject);
1957
+ Value *Offset = CI->getArgOperand (2 );
1958
+ if (isa<UndefValue>(Offset))
1959
+ ValCtx.EmitInstrError (CI, ValidationRule::InstrNoReadingUninitialized);
1960
+ if (ConstantInt *COffset = dyn_cast<ConstantInt>(Offset)) {
1961
+ if (COffset->getLimitedValue () % 4 != 0 )
1962
+ ValCtx.EmitInstrFormatError (
1963
+ CI, ValidationRule::InstrParamMultiple,
1964
+ {" offset" , " 4" , COffset->getValue ().toString (10 , false )});
1965
+ }
1966
+ break ;
1967
+ }
1968
+ case DXIL::OpCode::HitObject_SetShaderTableIndex: {
1969
+ Value *HitObject = CI->getArgOperand (1 );
1970
+ if (isa<UndefValue>(HitObject))
1971
+ ValCtx.EmitInstrError (CI, ValidationRule::InstrUndefHitObject);
1972
+ Value *RecordIndex = CI->getArgOperand (2 );
1973
+ if (isa<UndefValue>(RecordIndex))
1974
+ ValCtx.EmitInstrError (CI, ValidationRule::InstrNoReadingUninitialized);
1975
+ break ;
1976
+ }
1977
+
1978
+ // Shader Execution Reordering - scalar getters
1979
+ case DXIL::OpCode::HitObject_GeometryIndex:
1980
+ case DXIL::OpCode::HitObject_HitKind:
1981
+ case DXIL::OpCode::HitObject_InstanceID:
1982
+ case DXIL::OpCode::HitObject_InstanceIndex:
1983
+ case DXIL::OpCode::HitObject_IsHit:
1984
+ case DXIL::OpCode::HitObject_IsMiss:
1985
+ case DXIL::OpCode::HitObject_IsNop:
1986
+ case DXIL::OpCode::HitObject_PrimitiveIndex:
1987
+ case DXIL::OpCode::HitObject_RayFlags:
1988
+ case DXIL::OpCode::HitObject_RayTCurrent:
1989
+ case DXIL::OpCode::HitObject_RayTMin:
1990
+ case DXIL::OpCode::HitObject_ShaderTableIndex: {
1991
+ Value *HitObject = CI->getArgOperand (1 );
1992
+ if (isa<UndefValue>(HitObject))
1993
+ ValCtx.EmitInstrError (CI, ValidationRule::InstrUndefHitObject);
1994
+ break ;
1995
+ }
1996
+
1997
+ // Shader Execution Reordering - vector getters
1998
+ case DXIL::OpCode::HitObject_ObjectRayDirection:
1999
+ case DXIL::OpCode::HitObject_ObjectRayOrigin:
2000
+ case DXIL::OpCode::HitObject_WorldRayDirection:
2001
+ case DXIL::OpCode::HitObject_WorldRayOrigin: {
2002
+ Value *HitObject = CI->getArgOperand (1 );
2003
+ if (isa<UndefValue>(HitObject))
2004
+ ValCtx.EmitInstrError (CI, ValidationRule::InstrUndefHitObject);
2005
+ Value *Col = CI->getArgOperand (2 );
2006
+ ValidateConstantRangeUnsigned (Col, " component" , 0 , 2 , CI, Opcode, ValCtx);
2007
+ break ;
2008
+ }
2009
+
2010
+ // Shader Execution Reordering - matrix getters
2011
+ case DXIL::OpCode::HitObject_WorldToObject3x4:
2012
+ case DXIL::OpCode::HitObject_ObjectToWorld3x4: {
2013
+ Value *HitObject = CI->getArgOperand (1 );
2014
+ if (isa<UndefValue>(HitObject))
2015
+ ValCtx.EmitInstrError (CI, ValidationRule::InstrUndefHitObject);
2016
+ Value *Row = CI->getArgOperand (2 );
2017
+ ValidateConstantRangeUnsigned (Row, " row" , 0 , 2 , CI, Opcode, ValCtx);
2018
+ Value *Col = CI->getArgOperand (3 );
2019
+ ValidateConstantRangeUnsigned (Col, " column" , 0 , 3 , CI, Opcode, ValCtx);
2020
+ break ;
2021
+ }
2022
+
1913
2023
case DXIL::OpCode::AtomicBinOp:
1914
2024
case DXIL::OpCode::AtomicCompareExchange: {
1915
2025
Type *pOverloadType = OP::GetOverloadType (Opcode, CI->getCalledFunction ());
0 commit comments