diff --git a/docs/DXIL.rst b/docs/DXIL.rst index a1c5055085..a55f476450 100644 --- a/docs/DXIL.rst +++ b/docs/DXIL.rst @@ -3161,6 +3161,7 @@ INSTR.OPCODERESERVED Instructions must not refe INSTR.OPCONST DXIL intrinsic requires an immediate constant operand INSTR.OPCONSTRANGE Constant values must be in-range for operation. INSTR.OPERANDRANGE DXIL intrinsic operand must be within defined range +INSTR.PARAMMULTIPLE Parameter must be a valid multiple INSTR.PTRBITCAST Pointer type bitcast must be have same size. INSTR.RESOURCECLASSFORLOAD load can only run on UAV/SRV resource. INSTR.RESOURCECLASSFORSAMPLERGATHER sample, lod and gather should be on srv resource. diff --git a/lib/DxilValidation/DxilValidation.cpp b/lib/DxilValidation/DxilValidation.cpp index 00a6b9ae14..69eb2a88f2 100644 --- a/lib/DxilValidation/DxilValidation.cpp +++ b/lib/DxilValidation/DxilValidation.cpp @@ -1644,6 +1644,46 @@ static unsigned getSemanticFlagValidMask(const ShaderModel *pSM) { return static_cast(hlsl::DXIL::BarrierSemanticFlag::ValidMask); } +StringRef GetOpCodeName(DXIL::OpCode OpCode) { + switch (OpCode) { + default: + DXASSERT(false, "Unexpected op code"); + return ""; + case DXIL::OpCode::HitObject_ObjectRayOrigin: + return "HitObject_ObjectRayOrigin"; + case DXIL::OpCode::HitObject_WorldRayDirection: + return "HitObject_WorldRayDirection"; + case DXIL::OpCode::HitObject_WorldRayOrigin: + return "HitObject_WorldRayOrigin"; + case DXIL::OpCode::HitObject_ObjectRayDirection: + return "HitObject_ObjectRayDirection"; + case DXIL::OpCode::HitObject_WorldToObject3x4: + return "HitObject_WorldToObject3x4"; + case DXIL::OpCode::HitObject_ObjectToWorld3x4: + return "HitObject_ObjectToWorld3x4"; + } +} + +static void ValidateConstantRangeUnsigned(Value *Val, StringRef Name, + uint64_t LowerBound, + uint64_t UpperBound, CallInst *CI, + DXIL::OpCode OpCode, + ValidationContext &ValCtx) { + ConstantInt *C = dyn_cast(Val); + if (!C) { + ValCtx.EmitInstrFormatError(CI, ValidationRule::InstrOpConst, + {Name, GetOpCodeName(OpCode)}); + return; + } + if (C->uge(UpperBound + 1U) || !C->uge(LowerBound)) { + std::string Range = + std::to_string(LowerBound) + "~" + std::to_string(UpperBound); + ValCtx.EmitInstrFormatError( + CI, ValidationRule::InstrOperandRange, + {Name, Range, C->getValue().toString(10, false)}); + } +} + static void ValidateDxilOperationCallInProfile(CallInst *CI, DXIL::OpCode Opcode, const ShaderModel *pSM, @@ -1910,6 +1950,76 @@ static void ValidateDxilOperationCallInProfile(CallInst *CI, CI, ValidationRule::InstrMayReorderThreadUndefCoherenceHintParam); } break; + case DXIL::OpCode::HitObject_LoadLocalRootTableConstant: { + Value *HitObject = CI->getArgOperand(1); + if (isa(HitObject)) + ValCtx.EmitInstrError(CI, ValidationRule::InstrUndefHitObject); + Value *Offset = CI->getArgOperand(2); + if (isa(Offset)) + ValCtx.EmitInstrError(CI, ValidationRule::InstrNoReadingUninitialized); + if (ConstantInt *COffset = dyn_cast(Offset)) { + if (COffset->getLimitedValue() % 4 != 0) + ValCtx.EmitInstrFormatError( + CI, ValidationRule::InstrParamMultiple, + {"offset", "4", COffset->getValue().toString(10, false)}); + } + break; + } + case DXIL::OpCode::HitObject_SetShaderTableIndex: { + Value *HitObject = CI->getArgOperand(1); + if (isa(HitObject)) + ValCtx.EmitInstrError(CI, ValidationRule::InstrUndefHitObject); + Value *RecordIndex = CI->getArgOperand(2); + if (isa(RecordIndex)) + ValCtx.EmitInstrError(CI, ValidationRule::InstrNoReadingUninitialized); + break; + } + + // Shader Execution Reordering - scalar getters + case DXIL::OpCode::HitObject_GeometryIndex: + case DXIL::OpCode::HitObject_HitKind: + case DXIL::OpCode::HitObject_InstanceID: + case DXIL::OpCode::HitObject_InstanceIndex: + case DXIL::OpCode::HitObject_IsHit: + case DXIL::OpCode::HitObject_IsMiss: + case DXIL::OpCode::HitObject_IsNop: + case DXIL::OpCode::HitObject_PrimitiveIndex: + case DXIL::OpCode::HitObject_RayFlags: + case DXIL::OpCode::HitObject_RayTCurrent: + case DXIL::OpCode::HitObject_RayTMin: + case DXIL::OpCode::HitObject_ShaderTableIndex: { + Value *HitObject = CI->getArgOperand(1); + if (isa(HitObject)) + ValCtx.EmitInstrError(CI, ValidationRule::InstrUndefHitObject); + break; + } + + // Shader Execution Reordering - vector getters + case DXIL::OpCode::HitObject_ObjectRayDirection: + case DXIL::OpCode::HitObject_ObjectRayOrigin: + case DXIL::OpCode::HitObject_WorldRayDirection: + case DXIL::OpCode::HitObject_WorldRayOrigin: { + Value *HitObject = CI->getArgOperand(1); + if (isa(HitObject)) + ValCtx.EmitInstrError(CI, ValidationRule::InstrUndefHitObject); + Value *Col = CI->getArgOperand(2); + ValidateConstantRangeUnsigned(Col, "component", 0, 2, CI, Opcode, ValCtx); + break; + } + + // Shader Execution Reordering - matrix getters + case DXIL::OpCode::HitObject_WorldToObject3x4: + case DXIL::OpCode::HitObject_ObjectToWorld3x4: { + Value *HitObject = CI->getArgOperand(1); + if (isa(HitObject)) + ValCtx.EmitInstrError(CI, ValidationRule::InstrUndefHitObject); + Value *Row = CI->getArgOperand(2); + ValidateConstantRangeUnsigned(Row, "row", 0, 2, CI, Opcode, ValCtx); + Value *Col = CI->getArgOperand(3); + ValidateConstantRangeUnsigned(Col, "column", 0, 3, CI, Opcode, ValCtx); + break; + } + case DXIL::OpCode::AtomicBinOp: case DXIL::OpCode::AtomicCompareExchange: { Type *pOverloadType = OP::GetOverloadType(Opcode, CI->getCalledFunction()); diff --git a/tools/clang/test/CodeGenDXIL/hlsl/objects/HitObject/hitobject_accessors.hlsl b/tools/clang/test/CodeGenDXIL/hlsl/objects/HitObject/hitobject_accessors.hlsl index bae2b0590c..daeabf9710 100644 --- a/tools/clang/test/CodeGenDXIL/hlsl/objects/HitObject/hitobject_accessors.hlsl +++ b/tools/clang/test/CodeGenDXIL/hlsl/objects/HitObject/hitobject_accessors.hlsl @@ -14,7 +14,7 @@ // DXIL-DAG: %{{[^ ]+}} = call i32 @dx.op.hitObject_StateScalar.i32(i32 283, %dx.types.HitObject %[[HIT]]) ; HitObject_InstanceID(hitObject) // DXIL-DAG: %{{[^ ]+}} = call i32 @dx.op.hitObject_StateScalar.i32(i32 284, %dx.types.HitObject %[[HIT]]) ; HitObject_PrimitiveIndex(hitObject) // DXIL-DAG: %{{[^ ]+}} = call i32 @dx.op.hitObject_StateScalar.i32(i32 286, %dx.types.HitObject %[[HIT]]) ; HitObject_ShaderTableIndex(hitObject) -// DXIL-DAG: %{{[^ ]+}} = call i32 @dx.op.hitObject_LoadLocalRootTableConstant(i32 288, %dx.types.HitObject %[[HIT]], i32 42) ; HitObject_LoadLocalRootTableConstant(hitObject,offset) +// DXIL-DAG: %{{[^ ]+}} = call i32 @dx.op.hitObject_LoadLocalRootTableConstant(i32 288, %dx.types.HitObject %[[HIT]], i32 40) ; HitObject_LoadLocalRootTableConstant(hitObject,offset) // DXIL-DAG: %{{[^ ]+}} = call float @dx.op.hitObject_StateVector.f32(i32 277, %dx.types.HitObject %[[HIT]], i32 0) ; HitObject_ObjectRayOrigin(hitObject,component) // DXIL-DAG: %{{[^ ]+}} = call float @dx.op.hitObject_StateVector.f32(i32 277, %dx.types.HitObject %[[HIT]], i32 1) ; HitObject_ObjectRayOrigin(hitObject,component) // DXIL-DAG: %{{[^ ]+}} = call float @dx.op.hitObject_StateVector.f32(i32 277, %dx.types.HitObject %[[HIT]], i32 2) ; HitObject_ObjectRayOrigin(hitObject,component) @@ -88,7 +88,7 @@ void main() { isum += hit.GetInstanceID(); isum += hit.GetPrimitiveIndex(); isum += hit.GetShaderTableIndex(); - isum += hit.LoadLocalRootTableConstant(42); + isum += hit.LoadLocalRootTableConstant(40); // float3 accessors vsum += hit.GetWorldRayOrigin(); diff --git a/tools/clang/test/LitDXILValidation/ser_hitobject_accessors_failing.ll b/tools/clang/test/LitDXILValidation/ser_hitobject_accessors_failing.ll new file mode 100644 index 0000000000..7270996b91 --- /dev/null +++ b/tools/clang/test/LitDXILValidation/ser_hitobject_accessors_failing.ll @@ -0,0 +1,202 @@ +; REQUIRES: dxil-1-9 +; RUN: not %dxv %s 2>&1 | FileCheck %s + +target datalayout = "e-m:e-p:32:32-i1:32-i8:32-i16:32-i32:32-i64:64-f16:32-f32:32-f64:64-n8:16:32:64" +target triple = "dxil-ms-dx" + +%dx.types.HitObject = type { i8* } + +; CHECK: Function: ?main@@YAXXZ: error: HitObject is undef. +; CHECK: note: at '%r287_ud = call %dx.types.HitObject @dx.op.hitObject_SetShaderTableIndex(i32 287, %dx.types.HitObject undef, i32 undef)' in block '#0' of function '?main@@YAXXZ'. +; CHECK: Function: ?main@@YAXXZ: error: Instructions should not read uninitialized value. +; CHECK: note: at '%r287_ud = call %dx.types.HitObject @dx.op.hitObject_SetShaderTableIndex(i32 287, %dx.types.HitObject undef, i32 undef)' in block '#0' of function '?main@@YAXXZ'. +; CHECK: Function: ?main@@YAXXZ: error: HitObject is undef. +; CHECK: note: at '%r287 = call %dx.types.HitObject @dx.op.hitObject_SetShaderTableIndex(i32 287, %dx.types.HitObject undef, i32 1)' in block '#0' of function '?main@@YAXXZ'. +; CHECK: Function: ?main@@YAXXZ: error: HitObject is undef. +; CHECK: note: at '%r271 = call i1 @dx.op.hitObject_StateScalar.i1(i32 271, %dx.types.HitObject undef)' in block '#0' of function '?main@@YAXXZ'. +; CHECK: Function: ?main@@YAXXZ: error: HitObject is undef. +; CHECK: note: at '%r270 = call i1 @dx.op.hitObject_StateScalar.i1(i32 270, %dx.types.HitObject undef)' in block '#0' of function '?main@@YAXXZ'. +; CHECK: Function: ?main@@YAXXZ: error: HitObject is undef. +; CHECK: note: at '%r269 = call i1 @dx.op.hitObject_StateScalar.i1(i32 269, %dx.types.HitObject undef)' in block '#0' of function '?main@@YAXXZ'. +; CHECK: Function: ?main@@YAXXZ: error: HitObject is undef. +; CHECK: note: at '%r286 = call i32 @dx.op.hitObject_StateScalar.i32(i32 286, %dx.types.HitObject undef)' in block '#0' of function '?main@@YAXXZ'. +; CHECK: Function: ?main@@YAXXZ: error: HitObject is undef. +; CHECK: note: at '%r285 = call i32 @dx.op.hitObject_StateScalar.i32(i32 285, %dx.types.HitObject undef)' in block '#0' of function '?main@@YAXXZ'. +; CHECK: Function: ?main@@YAXXZ: error: HitObject is undef. +; CHECK: note: at '%r284 = call i32 @dx.op.hitObject_StateScalar.i32(i32 284, %dx.types.HitObject undef)' in block '#0' of function '?main@@YAXXZ'. +; CHECK: Function: ?main@@YAXXZ: error: HitObject is undef. +; CHECK: note: at '%r283 = call i32 @dx.op.hitObject_StateScalar.i32(i32 283, %dx.types.HitObject undef)' in block '#0' of function '?main@@YAXXZ'. +; CHECK: Function: ?main@@YAXXZ: error: HitObject is undef. +; CHECK: note: at '%r282 = call i32 @dx.op.hitObject_StateScalar.i32(i32 282, %dx.types.HitObject undef)' in block '#0' of function '?main@@YAXXZ'. +; CHECK: Function: ?main@@YAXXZ: error: HitObject is undef. +; CHECK: note: at '%r281 = call i32 @dx.op.hitObject_StateScalar.i32(i32 281, %dx.types.HitObject undef)' in block '#0' of function '?main@@YAXXZ'. +; CHECK: Function: ?main@@YAXXZ: error: HitObject is undef. +; CHECK: note: at '%r272 = call i32 @dx.op.hitObject_StateScalar.i32(i32 272, %dx.types.HitObject undef)' in block '#0' of function '?main@@YAXXZ'. +; CHECK: Function: ?main@@YAXXZ: error: HitObject is undef. +; CHECK: note: at '%r288_wrongmul = call i32 @dx.op.hitObject_LoadLocalRootTableConstant(i32 288, %dx.types.HitObject undef, i32 7)' in block '#0' of function '?main@@YAXXZ'. +; CHECK: Function: ?main@@YAXXZ: error: parameter 'offset' must be a multiple of 4, got 7 +; CHECK: note: at '%r288_wrongmul = call i32 @dx.op.hitObject_LoadLocalRootTableConstant(i32 288, %dx.types.HitObject undef, i32 7)' in block '#0' of function '?main@@YAXXZ'. +; CHECK: Function: ?main@@YAXXZ: error: HitObject is undef. +; CHECK: note: at '%r288 = call i32 @dx.op.hitObject_LoadLocalRootTableConstant(i32 288, %dx.types.HitObject undef, i32 42)' in block '#0' of function '?main@@YAXXZ'. +; CHECK: Function: ?main@@YAXXZ: error: parameter 'offset' must be a multiple of 4, got 42 +; CHECK: note: at '%r288 = call i32 @dx.op.hitObject_LoadLocalRootTableConstant(i32 288, %dx.types.HitObject undef, i32 42)' in block '#0' of function '?main@@YAXXZ'. +; CHECK: Function: ?main@@YAXXZ: error: expect component between 0~2, got 3. +; CHECK: note: at '%r278_oobc = call float @dx.op.hitObject_StateVector.f32(i32 278, %dx.types.HitObject %nop, i32 3)' in block '#0' of function '?main@@YAXXZ'. +; CHECK: Function: ?main@@YAXXZ: error: component of HitObject_ObjectRayDirection must be an immediate constant. +; CHECK: note: at '%r278_dync = call float @dx.op.hitObject_StateVector.f32(i32 278, %dx.types.HitObject %nop, i32 %r272)' in block '#0' of function '?main@@YAXXZ'. +; CHECK: Function: ?main@@YAXXZ: error: HitObject is undef. +; CHECK: note: at '%r278 = call float @dx.op.hitObject_StateVector.f32(i32 278, %dx.types.HitObject undef, i32 0)' in block '#0' of function '?main@@YAXXZ'. +; CHECK: Function: ?main@@YAXXZ: error: expect component between 0~2, got 3. +; CHECK: note: at '%r277_oobc = call float @dx.op.hitObject_StateVector.f32(i32 277, %dx.types.HitObject %nop, i32 3)' in block '#0' of function '?main@@YAXXZ'. +; CHECK: Function: ?main@@YAXXZ: error: component of HitObject_ObjectRayOrigin must be an immediate constant. +; CHECK: note: at '%r277_dync = call float @dx.op.hitObject_StateVector.f32(i32 277, %dx.types.HitObject %nop, i32 %r272)' in block '#0' of function '?main@@YAXXZ'. +; CHECK: Function: ?main@@YAXXZ: error: HitObject is undef. +; CHECK: note: at '%r277 = call float @dx.op.hitObject_StateVector.f32(i32 277, %dx.types.HitObject undef, i32 0)' in block '#0' of function '?main@@YAXXZ'. +; CHECK: Function: ?main@@YAXXZ: error: expect component between 0~2, got 3. +; CHECK: note: at '%r276_oobc = call float @dx.op.hitObject_StateVector.f32(i32 276, %dx.types.HitObject %nop, i32 3)' in block '#0' of function '?main@@YAXXZ'. +; CHECK: Function: ?main@@YAXXZ: error: component of HitObject_WorldRayDirection must be an immediate constant. +; CHECK: note: at '%r276_dync = call float @dx.op.hitObject_StateVector.f32(i32 276, %dx.types.HitObject %nop, i32 %r272)' in block '#0' of function '?main@@YAXXZ'. +; CHECK: Function: ?main@@YAXXZ: error: HitObject is undef. +; CHECK: note: at '%r276 = call float @dx.op.hitObject_StateVector.f32(i32 276, %dx.types.HitObject undef, i32 0)' in block '#0' of function '?main@@YAXXZ'. +; CHECK: Function: ?main@@YAXXZ: error: expect component between 0~2, got 3. +; CHECK: note: at '%r275_oobc = call float @dx.op.hitObject_StateVector.f32(i32 275, %dx.types.HitObject %nop, i32 3)' in block '#0' of function '?main@@YAXXZ'. +; CHECK: Function: ?main@@YAXXZ: error: component of HitObject_WorldRayOrigin must be an immediate constant. +; CHECK: note: at '%r275_dync = call float @dx.op.hitObject_StateVector.f32(i32 275, %dx.types.HitObject %nop, i32 %r272)' in block '#0' of function '?main@@YAXXZ'. +; CHECK: Function: ?main@@YAXXZ: error: HitObject is undef. +; CHECK: note: at '%r275 = call float @dx.op.hitObject_StateVector.f32(i32 275, %dx.types.HitObject undef, i32 0)' in block '#0' of function '?main@@YAXXZ'. +; CHECK: Function: ?main@@YAXXZ: error: HitObject is undef. +; CHECK: note: at '%r274 = call float @dx.op.hitObject_StateScalar.f32(i32 274, %dx.types.HitObject undef)' in block '#0' of function '?main@@YAXXZ'. +; CHECK: Function: ?main@@YAXXZ: error: HitObject is undef. +; CHECK: note: at '%r273 = call float @dx.op.hitObject_StateScalar.f32(i32 273, %dx.types.HitObject undef)' in block '#0' of function '?main@@YAXXZ'. +; CHECK: Function: ?main@@YAXXZ: error: expect column between 0~3, got 4. +; CHECK: note: at '%r280_oobc = call float @dx.op.hitObject_StateMatrix.f32(i32 280, %dx.types.HitObject %nop, i32 0, i32 4)' in block '#0' of function '?main@@YAXXZ'. +; CHECK: Function: ?main@@YAXXZ: error: column of HitObject_WorldToObject3x4 must be an immediate constant. +; CHECK: note: at '%r280_dync = call float @dx.op.hitObject_StateMatrix.f32(i32 280, %dx.types.HitObject %nop, i32 0, i32 %r272)' in block '#0' of function '?main@@YAXXZ'. +; CHECK: Function: ?main@@YAXXZ: error: expect row between 0~2, got 3. +; CHECK: note: at '%r280_oobr = call float @dx.op.hitObject_StateMatrix.f32(i32 280, %dx.types.HitObject %nop, i32 3, i32 0)' in block '#0' of function '?main@@YAXXZ'. +; CHECK: Function: ?main@@YAXXZ: error: row of HitObject_WorldToObject3x4 must be an immediate constant. +; CHECK: note: at '%r280_dynr = call float @dx.op.hitObject_StateMatrix.f32(i32 280, %dx.types.HitObject %nop, i32 %r272, i32 0)' in block '#0' of function '?main@@YAXXZ'. +; CHECK: Function: ?main@@YAXXZ: error: HitObject is undef. +; CHECK: note: at '%r280 = call float @dx.op.hitObject_StateMatrix.f32(i32 280, %dx.types.HitObject undef, i32 0, i32 0)' in block '#0' of function '?main@@YAXXZ'. +; CHECK: Function: ?main@@YAXXZ: error: expect column between 0~3, got 4. +; CHECK: note: at '%r279_oobc = call float @dx.op.hitObject_StateMatrix.f32(i32 279, %dx.types.HitObject %nop, i32 0, i32 4)' in block '#0' of function '?main@@YAXXZ'. +; CHECK: Function: ?main@@YAXXZ: error: column of HitObject_ObjectToWorld3x4 must be an immediate constant. +; CHECK: note: at '%r279_dync = call float @dx.op.hitObject_StateMatrix.f32(i32 279, %dx.types.HitObject %nop, i32 0, i32 %r272)' in block '#0' of function '?main@@YAXXZ'. +; CHECK: Function: ?main@@YAXXZ: error: expect row between 0~2, got 3. +; CHECK: note: at '%r279_oobr = call float @dx.op.hitObject_StateMatrix.f32(i32 279, %dx.types.HitObject %nop, i32 3, i32 0)' in block '#0' of function '?main@@YAXXZ'. +; CHECK: Function: ?main@@YAXXZ: error: row of HitObject_ObjectToWorld3x4 must be an immediate constant. +; CHECK: note: at '%r279_dynr = call float @dx.op.hitObject_StateMatrix.f32(i32 279, %dx.types.HitObject %nop, i32 %r272, i32 0)' in block '#0' of function '?main@@YAXXZ'. +; CHECK: Function: ?main@@YAXXZ: error: HitObject is undef. +; CHECK: note: at '%r279 = call float @dx.op.hitObject_StateMatrix.f32(i32 279, %dx.types.HitObject undef, i32 0, i32 0)' in block '#0' of function '?main@@YAXXZ'. +; CHECK: Validation failed. + +; Function Attrs: nounwind +define void @"\01?main@@YAXXZ"() #0 { +%nop = call %dx.types.HitObject @dx.op.hitObject_MakeNop(i32 266) ; HitObject_MakeNop() + %r269 = call i1 @dx.op.hitObject_StateScalar.i1(i32 269, %dx.types.HitObject undef) ; HitObject_IsMiss(hitObject) + + %r270 = call i1 @dx.op.hitObject_StateScalar.i1(i32 270, %dx.types.HitObject undef) ; HitObject_IsHit(hitObject) + + %r271 = call i1 @dx.op.hitObject_StateScalar.i1(i32 271, %dx.types.HitObject undef) ; HitObject_IsNop(hitObject) + + %r272 = call i32 @dx.op.hitObject_StateScalar.i32(i32 272, %dx.types.HitObject undef) ; HitObject_RayFlags(hitObject) + + %r273 = call float @dx.op.hitObject_StateScalar.f32(i32 273, %dx.types.HitObject undef) ; HitObject_RayTMin(hitObject) + + %r274 = call float @dx.op.hitObject_StateScalar.f32(i32 274, %dx.types.HitObject undef) ; HitObject_RayTCurrent(hitObject) + + %r275 = call float @dx.op.hitObject_StateVector.f32(i32 275, %dx.types.HitObject undef, i32 0) ; HitObject_WorldRayOrigin(hitObject,component) + %r275_dync = call float @dx.op.hitObject_StateVector.f32(i32 275, %dx.types.HitObject %nop, i32 %r272) ; HitObject_WorldRayOrigin(hitObject,component) + %r275_oobc = call float @dx.op.hitObject_StateVector.f32(i32 275, %dx.types.HitObject %nop, i32 3) ; HitObject_WorldRayOrigin(hitObject,component) + + %r276 = call float @dx.op.hitObject_StateVector.f32(i32 276, %dx.types.HitObject undef, i32 0) ; HitObject_WorldRayDirection(hitObject,component) + %r276_dync = call float @dx.op.hitObject_StateVector.f32(i32 276, %dx.types.HitObject %nop, i32 %r272) ; HitObject_WorldRayDirection(hitObject,component) + %r276_oobc = call float @dx.op.hitObject_StateVector.f32(i32 276, %dx.types.HitObject %nop, i32 3) ; HitObject_WorldRayDirection(hitObject,component) + + %r277 = call float @dx.op.hitObject_StateVector.f32(i32 277, %dx.types.HitObject undef, i32 0) ; HitObject_ObjectRayOrigin(hitObject,component) + %r277_dync = call float @dx.op.hitObject_StateVector.f32(i32 277, %dx.types.HitObject %nop, i32 %r272) ; HitObject_ObjectRayOrigin(hitObject,component) + %r277_oobc = call float @dx.op.hitObject_StateVector.f32(i32 277, %dx.types.HitObject %nop, i32 3) ; HitObject_ObjectRayOrigin(hitObject,component) + + %r278 = call float @dx.op.hitObject_StateVector.f32(i32 278, %dx.types.HitObject undef, i32 0) ; HitObject_ObjectRayDirection(hitObject,component) + %r278_dync = call float @dx.op.hitObject_StateVector.f32(i32 278, %dx.types.HitObject %nop, i32 %r272) ; HitObject_ObjectRayDirection(hitObject,component) + %r278_oobc = call float @dx.op.hitObject_StateVector.f32(i32 278, %dx.types.HitObject %nop, i32 3) ; HitObject_ObjectRayDirection(hitObject,component) + + %r279 = call float @dx.op.hitObject_StateMatrix.f32(i32 279, %dx.types.HitObject undef, i32 0, i32 0) ; HitObject_ObjectToWorld3x4(hitObject,row,col) + %r279_dynr = call float @dx.op.hitObject_StateMatrix.f32(i32 279, %dx.types.HitObject %nop, i32 %r272, i32 0) ; HitObject_ObjectToWorld3x4(hitObject,row,col) + %r279_oobr = call float @dx.op.hitObject_StateMatrix.f32(i32 279, %dx.types.HitObject %nop, i32 3, i32 0) ; HitObject_ObjectToWorld3x4(hitObject,row,col) + %r279_dync = call float @dx.op.hitObject_StateMatrix.f32(i32 279, %dx.types.HitObject %nop, i32 0, i32 %r272) ; HitObject_ObjectToWorld3x4(hitObject,row,col) + %r279_oobc = call float @dx.op.hitObject_StateMatrix.f32(i32 279, %dx.types.HitObject %nop, i32 0, i32 4) ; HitObject_ObjectToWorld3x4(hitObject,row,col) + + %r280 = call float @dx.op.hitObject_StateMatrix.f32(i32 280, %dx.types.HitObject undef, i32 0, i32 0) ; HitObject_WorldToObject3x4(hitObject,row,col) + %r280_dynr = call float @dx.op.hitObject_StateMatrix.f32(i32 280, %dx.types.HitObject %nop, i32 %r272, i32 0) ; HitObject_WorldToObject3x4(hitObject,row,col) + %r280_oobr = call float @dx.op.hitObject_StateMatrix.f32(i32 280, %dx.types.HitObject %nop, i32 3, i32 0) ; HitObject_WorldToObject3x4(hitObject,row,col) + %r280_dync = call float @dx.op.hitObject_StateMatrix.f32(i32 280, %dx.types.HitObject %nop, i32 0, i32 %r272) ; HitObject_WorldToObject3x4(hitObject,row,col) + %r280_oobc = call float @dx.op.hitObject_StateMatrix.f32(i32 280, %dx.types.HitObject %nop, i32 0, i32 4) ; HitObject_WorldToObject3x4(hitObject,row,col) + + %r281 = call i32 @dx.op.hitObject_StateScalar.i32(i32 281, %dx.types.HitObject undef) ; HitObject_GeometryIndex(hitObject) + + %r282 = call i32 @dx.op.hitObject_StateScalar.i32(i32 282, %dx.types.HitObject undef) ; HitObject_InstanceIndex(hitObject) + + %r283 = call i32 @dx.op.hitObject_StateScalar.i32(i32 283, %dx.types.HitObject undef) ; HitObject_InstanceID(hitObject) + + %r284 = call i32 @dx.op.hitObject_StateScalar.i32(i32 284, %dx.types.HitObject undef) ; HitObject_PrimitiveIndex(hitObject) + + %r285 = call i32 @dx.op.hitObject_StateScalar.i32(i32 285, %dx.types.HitObject undef) ; HitObject_HitKind(hitObject) + + %r286 = call i32 @dx.op.hitObject_StateScalar.i32(i32 286, %dx.types.HitObject undef) ; HitObject_ShaderTableIndex(hitObject) + + %r287 = call %dx.types.HitObject @dx.op.hitObject_SetShaderTableIndex(i32 287, %dx.types.HitObject undef, i32 1) ; HitObject_SetShaderTableIndex(hitObject,shaderTableIndex) + %r287_ud = call %dx.types.HitObject @dx.op.hitObject_SetShaderTableIndex(i32 287, %dx.types.HitObject undef, i32 undef) ; HitObject_SetShaderTableIndex(hitObject,shaderTableIndex) + + %r288 = call i32 @dx.op.hitObject_LoadLocalRootTableConstant(i32 288, %dx.types.HitObject undef, i32 42) ; HitObject_LoadLocalRootTableConstant(hitObject,offset) + %r288_wrongmul = call i32 @dx.op.hitObject_LoadLocalRootTableConstant(i32 288, %dx.types.HitObject undef, i32 7) ; HitObject_LoadLocalRootTableConstant(hitObject,offset) + + ret void +} + +; Function Attrs: nounwind readnone +declare %dx.types.HitObject @dx.op.hitObject_MakeNop(i32) #1 + +; Function Attrs: nounwind readnone +declare %dx.types.HitObject @dx.op.hitObject_SetShaderTableIndex(i32, %dx.types.HitObject, i32) #1 + +; Function Attrs: nounwind readnone +declare i1 @dx.op.hitObject_StateScalar.i1(i32, %dx.types.HitObject) #1 + +; Function Attrs: nounwind readnone +declare i32 @dx.op.hitObject_StateScalar.i32(i32, %dx.types.HitObject) #1 + +; Function Attrs: nounwind readonly +declare i32 @dx.op.hitObject_LoadLocalRootTableConstant(i32, %dx.types.HitObject, i32) #2 + +; Function Attrs: nounwind readnone +declare float @dx.op.hitObject_StateVector.f32(i32, %dx.types.HitObject, i32) #1 + +; Function Attrs: nounwind readnone +declare float @dx.op.hitObject_StateScalar.f32(i32, %dx.types.HitObject) #1 + +; Function Attrs: nounwind readnone +declare float @dx.op.hitObject_StateMatrix.f32(i32, %dx.types.HitObject, i32, i32) #1 + +attributes #0 = { nounwind } +attributes #1 = { nounwind readnone } +attributes #2 = { nounwind readonly } +attributes #3 = { nounwind argmemonly } + +!dx.version = !{!0} +!dx.valver = !{!0} +!dx.shaderModel = !{!1} +!dx.typeAnnotations = !{!2} +!dx.entryPoints = !{!3, !4} + +!0 = !{i32 1, i32 9} +!1 = !{!"lib", i32 6, i32 9} +!2 = !{i32 1, void ()* @"\01?main@@YAXXZ", !5} +!3 = !{null, !"", null, null, !6} +!4 = !{void ()* @"\01?main@@YAXXZ", !"\01?main@@YAXXZ", null, null, !7} +!5 = !{!8} +!6 = !{i32 0, i64 0} +!7 = !{i32 8, i32 7, i32 5, !9} +!8 = !{i32 1, !10, !10} +!9 = !{i32 0} +!10 = !{} diff --git a/tools/clang/test/LitDXILValidation/ser_hitobject_accessors_passing.ll b/tools/clang/test/LitDXILValidation/ser_hitobject_accessors_passing.ll index e527125009..74cc94fb78 100644 --- a/tools/clang/test/LitDXILValidation/ser_hitobject_accessors_passing.ll +++ b/tools/clang/test/LitDXILValidation/ser_hitobject_accessors_passing.ll @@ -52,7 +52,7 @@ define void @"\01?main@@YAXXZ"() #0 { %r287 = call %dx.types.HitObject @dx.op.hitObject_SetShaderTableIndex(i32 287, %dx.types.HitObject %nop, i32 1) ; HitObject_SetShaderTableIndex(hitObject,shaderTableIndex) - %r288 = call i32 @dx.op.hitObject_LoadLocalRootTableConstant(i32 288, %dx.types.HitObject %nop, i32 42) ; HitObject_LoadLocalRootTableConstant(hitObject,offset) + %r288 = call i32 @dx.op.hitObject_LoadLocalRootTableConstant(i32 288, %dx.types.HitObject %nop, i32 16) ; HitObject_LoadLocalRootTableConstant(hitObject,offset) call void @dx.op.hitObject_Attributes.struct.AttribType(i32 289, %dx.types.HitObject %nop, %struct.AttribType* nonnull %attrs) ; HitObject_Attributes(hitObject,attributes) ret void diff --git a/tools/clang/test/SemaHLSL/hlsl/objects/HitObject/hitobject_accessors.hlsl b/tools/clang/test/SemaHLSL/hlsl/objects/HitObject/hitobject_accessors.hlsl index 7b4182b739..05aa790ad4 100644 --- a/tools/clang/test/SemaHLSL/hlsl/objects/HitObject/hitobject_accessors.hlsl +++ b/tools/clang/test/SemaHLSL/hlsl/objects/HitObject/hitobject_accessors.hlsl @@ -189,7 +189,7 @@ // FCGL: %{{[^ ]+}} = call i32 @"dx.hl.op.rn.i32 (i32, %dx.types.HitObject*)"(i32 367, %dx.types.HitObject* %[[HIT]]) // FCGL: %{{[^ ]+}} = call i32 @"dx.hl.op.rn.i32 (i32, %dx.types.HitObject*)"(i32 373, %dx.types.HitObject* %[[HIT]]) // FCGL: %{{[^ ]+}} = call i32 @"dx.hl.op.rn.i32 (i32, %dx.types.HitObject*)"(i32 377, %dx.types.HitObject* %[[HIT]]) -// FCGL: %{{[^ ]+}} = call i32 @"dx.hl.op.ro.i32 (i32, %dx.types.HitObject*, i32)"(i32 386, %dx.types.HitObject* %[[HIT]], i32 42) +// FCGL: %{{[^ ]+}} = call i32 @"dx.hl.op.ro.i32 (i32, %dx.types.HitObject*, i32)"(i32 386, %dx.types.HitObject* %[[HIT]], i32 40) // FCGL: %{{[^ ]+}} = call <3 x float> @"dx.hl.op.rn.<3 x float> (i32, %dx.types.HitObject*)"(i32 379, %dx.types.HitObject* %[[HIT]]) // FCGL: %{{[^ ]+}} = call <3 x float> @"dx.hl.op.rn.<3 x float> (i32, %dx.types.HitObject*)"(i32 378, %dx.types.HitObject* %[[HIT]]) // FCGL: %{{[^ ]+}} = call <3 x float> @"dx.hl.op.rn.<3 x float> (i32, %dx.types.HitObject*)"(i32 370, %dx.types.HitObject* %[[HIT]]) @@ -238,7 +238,7 @@ void main() { isum += hit.GetInstanceID(); isum += hit.GetPrimitiveIndex(); isum += hit.GetShaderTableIndex(); - isum += hit.LoadLocalRootTableConstant(42); + isum += hit.LoadLocalRootTableConstant(40); // float3 accessors vsum += hit.GetWorldRayOrigin(); diff --git a/utils/hct/hctdb.py b/utils/hct/hctdb.py index 6344fb5849..b1460de9b8 100644 --- a/utils/hct/hctdb.py +++ b/utils/hct/hctdb.py @@ -8298,6 +8298,11 @@ def build_valrules(self): "Instr.UndefHitObject", "HitObject is undef.", ) + self.add_valrule_msg( + "Instr.ParamMultiple", + "Parameter must be a valid multiple", + "parameter '%0' must be a multiple of %1, got %2", + ) self.add_valrule( "Instr.MayReorderThreadUndefCoherenceHintParam", "Use of undef coherence hint or num coherence hint bits in MaybeReorderThread.",