@@ -1644,6 +1644,46 @@ static unsigned getSemanticFlagValidMask(const ShaderModel *pSM) {
16441644 return static_cast <unsigned >(hlsl::DXIL::BarrierSemanticFlag::ValidMask);
16451645}
16461646
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 + 1U ) || !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+
16471687static void ValidateDxilOperationCallInProfile (CallInst *CI,
16481688 DXIL::OpCode Opcode,
16491689 const ShaderModel *pSM,
@@ -1910,6 +1950,76 @@ static void ValidateDxilOperationCallInProfile(CallInst *CI,
19101950 CI, ValidationRule::InstrMayReorderThreadUndefCoherenceHintParam);
19111951 } break ;
19121952
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+
19132023 case DXIL::OpCode::AtomicBinOp:
19142024 case DXIL::OpCode::AtomicCompareExchange: {
19152025 Type *pOverloadType = OP::GetOverloadType (Opcode, CI->getCalledFunction ());
0 commit comments