diff --git a/include/dxc/HLSL/HLOperations.h b/include/dxc/HLSL/HLOperations.h index c75318da99..933609852a 100644 --- a/include/dxc/HLSL/HLOperations.h +++ b/include/dxc/HLSL/HLOperations.h @@ -439,7 +439,8 @@ const unsigned kHitObjectMakeMissRayDescOpIdx = 4; // HitObject::TraceRay const unsigned kHitObjectTraceRay_RayDescOpIdx = 8; -const unsigned kHitObjectTraceRay_NumOp = 10; +const unsigned kHitObjectTraceRay_PayloadOpIdx = 9; +const unsigned kHitObjectTraceRay_NumOp = 13; // HitObject::FromRayQuery const unsigned kHitObjectFromRayQuery_WithAttrs_AttributeOpIdx = 4; diff --git a/lib/HLSL/HLOperationLower.cpp b/lib/HLSL/HLOperationLower.cpp index 18d003a764..d4fe5b4c99 100644 --- a/lib/HLSL/HLOperationLower.cpp +++ b/lib/HLSL/HLOperationLower.cpp @@ -5720,37 +5720,26 @@ Value *TranslateCallShader(CallInst *CI, IntrinsicOp IOP, OP::OpCode opcode, return Builder.CreateCall(F, {opArg, ShaderIndex, Parameter}); } -static unsigned LoadRayDescElementsIntoArgs(Value **Args, hlsl::OP *OP, - IRBuilder<> &Builder, - Value *RayDescPtr, unsigned Index) { +static void ExtractRayDescElementsIntoArgs(Value **Args, IRBuilder<> &Builder, + CallInst *CI, unsigned &DestIndex, + unsigned &SrcIndex) { // struct RayDesc //{ // float3 Origin; + Value *Origin = CI->getArgOperand(SrcIndex++); + Args[DestIndex++] = Builder.CreateExtractElement(Origin, (uint64_t)0); + Args[DestIndex++] = Builder.CreateExtractElement(Origin, 1); + Args[DestIndex++] = Builder.CreateExtractElement(Origin, 2); // float TMin; + Args[DestIndex++] = CI->getArgOperand(SrcIndex++); // float3 Direction; + Value *Direction = CI->getArgOperand(SrcIndex++); + Args[DestIndex++] = Builder.CreateExtractElement(Direction, (uint64_t)0); + Args[DestIndex++] = Builder.CreateExtractElement(Direction, 1); + Args[DestIndex++] = Builder.CreateExtractElement(Direction, 2); // float TMax; + Args[DestIndex++] = CI->getArgOperand(SrcIndex++); //}; - Value *ZeroIdx = OP->GetU32Const(0); - Value *Origin = Builder.CreateGEP(RayDescPtr, {ZeroIdx, ZeroIdx}); - Origin = Builder.CreateLoad(Origin); - Args[Index++] = Builder.CreateExtractElement(Origin, (uint64_t)0); - Args[Index++] = Builder.CreateExtractElement(Origin, 1); - Args[Index++] = Builder.CreateExtractElement(Origin, 2); - - Value *TMinPtr = Builder.CreateGEP(RayDescPtr, {ZeroIdx, OP->GetU32Const(1)}); - Args[Index++] = Builder.CreateLoad(TMinPtr); - - Value *DirectionPtr = - Builder.CreateGEP(RayDescPtr, {ZeroIdx, OP->GetU32Const(2)}); - Value *Direction = Builder.CreateLoad(DirectionPtr); - - Args[Index++] = Builder.CreateExtractElement(Direction, (uint64_t)0); - Args[Index++] = Builder.CreateExtractElement(Direction, 1); - Args[Index++] = Builder.CreateExtractElement(Direction, 2); - - Value *TMaxPtr = Builder.CreateGEP(RayDescPtr, {ZeroIdx, OP->GetU32Const(3)}); - Args[Index++] = Builder.CreateLoad(TMaxPtr); - return Index; } Value *TranslateTraceRay(CallInst *CI, IntrinsicOp IOP, OP::OpCode OpCode, @@ -5759,18 +5748,18 @@ Value *TranslateTraceRay(CallInst *CI, IntrinsicOp IOP, OP::OpCode OpCode, bool &Translated) { hlsl::OP *OP = &Helper.hlslOP; - Value *RayDesc = CI->getArgOperand(HLOperandIndex::kTraceRayRayDescOpIdx); - Value *PayLoad = CI->getArgOperand(HLOperandIndex::kTraceRayPayLoadOpIdx); - Value *Args[DXIL::OperandIndex::kTraceRayNumOp]; Args[0] = OP->GetU32Const(static_cast(OpCode)); - for (unsigned i = 1; i < HLOperandIndex::kTraceRayRayDescOpIdx; i++) - Args[i] = CI->getArgOperand(i); + unsigned SrcIndex = 1; + unsigned DestIndex = 1; + for (; DestIndex < HLOperandIndex::kTraceRayRayDescOpIdx; + ++DestIndex, ++SrcIndex) + Args[DestIndex] = CI->getArgOperand(SrcIndex); IRBuilder<> Builder(CI); - LoadRayDescElementsIntoArgs(Args, OP, Builder, RayDesc, - DXIL::OperandIndex::kTraceRayRayDescOpIdx); + ExtractRayDescElementsIntoArgs(Args, Builder, CI, DestIndex, SrcIndex); + Value *PayLoad = CI->getArgOperand(SrcIndex); Args[DXIL::OperandIndex::kTraceRayPayloadOpIdx] = PayLoad; Type *Ty = PayLoad->getType(); @@ -5825,25 +5814,7 @@ Value *TranslateTraceRayInline(CallInst *CI, IntrinsicOp IOP, OP::OpCode opcode, unsigned hlIndex = HLOperandIndex::kTraceRayInlineRayDescOpIdx; unsigned index = DXIL::OperandIndex::kTraceRayInlineRayDescOpIdx; - // struct RayDesc - //{ - // float3 Origin; - Value *origin = CI->getArgOperand(hlIndex++); - Args[index++] = Builder.CreateExtractElement(origin, (uint64_t)0); - Args[index++] = Builder.CreateExtractElement(origin, 1); - Args[index++] = Builder.CreateExtractElement(origin, 2); - // float TMin; - Args[index++] = CI->getArgOperand(hlIndex++); - // float3 Direction; - Value *direction = CI->getArgOperand(hlIndex++); - Args[index++] = Builder.CreateExtractElement(direction, (uint64_t)0); - Args[index++] = Builder.CreateExtractElement(direction, 1); - Args[index++] = Builder.CreateExtractElement(direction, 2); - // float TMax; - Args[index++] = CI->getArgOperand(hlIndex++); - //}; - - DXASSERT_NOMSG(index == DXIL::OperandIndex::kTraceRayInlineNumOp); + ExtractRayDescElementsIntoArgs(Args, Builder, CI, index, hlIndex); Function *F = hlslOP->GetOpFunc(opcode, Builder.getVoidTy()); @@ -6201,13 +6172,13 @@ Value *TranslateHitObjectMake(CallInst *CI, IntrinsicOp IOP, OP::OpCode Opcode, HLOperationLowerHelper &Helper, HLObjectOperationLowerHelper *ObjHelper, bool &Translated) { - hlsl::OP *HlslOP = &Helper.hlslOP; + hlsl::OP *OP = &Helper.hlslOP; IRBuilder<> Builder(CI); unsigned SrcIdx = 1; Value *HitObjectPtr = CI->getArgOperand(SrcIdx++); if (Opcode == OP::OpCode::HitObject_MakeNop) { Value *HitObject = TrivialDxilOperation( - Opcode, {nullptr}, Type::getVoidTy(CI->getContext()), CI, HlslOP); + Opcode, {nullptr}, Type::getVoidTy(CI->getContext()), CI, OP); Builder.CreateStore(HitObject, HitObjectPtr); DXASSERT( CI->use_empty(), @@ -6217,35 +6188,17 @@ Value *TranslateHitObjectMake(CallInst *CI, IntrinsicOp IOP, OP::OpCode Opcode, DXASSERT_NOMSG(CI->getNumArgOperands() == HLOperandIndex::kHitObjectMakeMiss_NumOp); - Value *RayFlags = CI->getArgOperand(SrcIdx++); - Value *MissShaderIdx = CI->getArgOperand(SrcIdx++); - DXASSERT_NOMSG(SrcIdx == HLOperandIndex::kHitObjectMakeMissRayDescOpIdx); - Value *RayDescOrigin = CI->getArgOperand(SrcIdx++); - Value *RayDescOriginX = - Builder.CreateExtractElement(RayDescOrigin, (uint64_t)0); - Value *RayDescOriginY = - Builder.CreateExtractElement(RayDescOrigin, (uint64_t)1); - Value *RayDescOriginZ = - Builder.CreateExtractElement(RayDescOrigin, (uint64_t)2); - - Value *RayDescTMin = CI->getArgOperand(SrcIdx++); - Value *RayDescDirection = CI->getArgOperand(SrcIdx++); - Value *RayDescDirectionX = - Builder.CreateExtractElement(RayDescDirection, (uint64_t)0); - Value *RayDescDirectionY = - Builder.CreateExtractElement(RayDescDirection, (uint64_t)1); - Value *RayDescDirectionZ = - Builder.CreateExtractElement(RayDescDirection, (uint64_t)2); - - Value *RayDescTMax = CI->getArgOperand(SrcIdx++); - DXASSERT_NOMSG(SrcIdx == CI->getNumArgOperands()); + const unsigned DxilNumArgs = DxilInst_HitObject_MakeMiss::arg_TMax + 1; + unsigned DestIdx = 1; + Value *Args[DxilNumArgs]; + Args[0] = nullptr; // OpCode + Args[DestIdx++] = CI->getArgOperand(SrcIdx++); // RayFlags + Args[DestIdx++] = CI->getArgOperand(SrcIdx++); // MissShaderIndex + ExtractRayDescElementsIntoArgs(Args, Builder, CI, DestIdx, SrcIdx); + DXASSERT_NOMSG(DestIdx == DxilNumArgs); - Value *OutHitObject = TrivialDxilOperation( - Opcode, - {nullptr, RayFlags, MissShaderIdx, RayDescOriginX, RayDescOriginY, - RayDescOriginZ, RayDescTMin, RayDescDirectionX, RayDescDirectionY, - RayDescDirectionZ, RayDescTMax}, - Helper.voidTy, CI, HlslOP); + Value *OutHitObject = + TrivialDxilOperation(Opcode, Args, Helper.voidTy, CI, OP); Builder.CreateStore(OutHitObject, HitObjectPtr); return nullptr; } @@ -6363,12 +6316,10 @@ Value *TranslateHitObjectTraceRay(CallInst *CI, IntrinsicOp IOP, Args[DestIdx] = CI->getArgOperand(SrcIdx); } - Value *RayDescPtr = CI->getArgOperand(SrcIdx++); - DestIdx = LoadRayDescElementsIntoArgs(Args, OP, Builder, RayDescPtr, DestIdx); + ExtractRayDescElementsIntoArgs(Args, Builder, CI, DestIdx, SrcIdx); Value *Payload = CI->getArgOperand(SrcIdx++); Args[DestIdx++] = Payload; - DXASSERT_NOMSG(SrcIdx == CI->getNumArgOperands()); DXASSERT_NOMSG(DestIdx == DxilNumArgs); Function *F = OP->GetOpFunc(OpCode, Payload->getType()); diff --git a/lib/Transforms/Scalar/ScalarReplAggregatesHLSL.cpp b/lib/Transforms/Scalar/ScalarReplAggregatesHLSL.cpp index 8bd78dd9a6..9a34558973 100644 --- a/lib/Transforms/Scalar/ScalarReplAggregatesHLSL.cpp +++ b/lib/Transforms/Scalar/ScalarReplAggregatesHLSL.cpp @@ -1539,9 +1539,7 @@ void isSafeForScalarRepl(Instruction *I, uint64_t Offset, AllocaInfo &Info) { // TODO: should we check HL parameter type for UDT overload instead of // basing on IOP? IntrinsicOp opcode = static_cast(GetHLOpcode(CI)); - if (IntrinsicOp::IOP_TraceRay == opcode || - IntrinsicOp::MOP_DxHitObject_TraceRay == opcode || - IntrinsicOp::MOP_DxHitObject_Invoke == opcode || + if (IntrinsicOp::MOP_DxHitObject_Invoke == opcode || IntrinsicOp::IOP_ReportHit == opcode || IntrinsicOp::IOP_CallShader == opcode) { return MarkUnsafe(Info, User); @@ -2756,18 +2754,25 @@ void SROA_Helper::RewriteCall(CallInst *CI) { /*loadElts*/ false); DeadInsts.push_back(CI); } break; - case IntrinsicOp::IOP_TraceRay: { - if (OldVal == - CI->getArgOperand(HLOperandIndex::kTraceRayRayDescOpIdx)) { - RewriteCallArg(CI, HLOperandIndex::kTraceRayRayDescOpIdx, - /*bIn*/ true, /*bOut*/ false); - } else { - DXASSERT(OldVal == - CI->getArgOperand(HLOperandIndex::kTraceRayPayLoadOpIdx), - "else invalid TraceRay"); - RewriteCallArg(CI, HLOperandIndex::kTraceRayPayLoadOpIdx, - /*bIn*/ true, /*bOut*/ true); + case IntrinsicOp::IOP_TraceRay: + case IntrinsicOp::MOP_DxHitObject_TraceRay: { + const int RayDescIdx = + IOP == IntrinsicOp::IOP_TraceRay + ? HLOperandIndex::kTraceRayRayDescOpIdx + : HLOperandIndex::kHitObjectTraceRay_RayDescOpIdx; + if (OldVal == CI->getArgOperand(RayDescIdx)) { + RewriteWithFlattenedHLIntrinsicCall(CI, OldVal, NewElts, + /*loadElts*/ true); + DeadInsts.push_back(CI); + break; } + // Payload will always be the last argument. Actual param index depends + // on whether RayDesc was flattened before. + const int PayloadIdx = CI->getNumArgOperands() - 1; + DXASSERT(OldVal == CI->getArgOperand(PayloadIdx), + "else invalid HitObject::TraceRay"); + RewriteCallArg(CI, PayloadIdx, + /*bIn*/ true, /*bOut*/ true); } break; case IntrinsicOp::IOP_ReportHit: { RewriteCallArg(CI, HLOperandIndex::kReportIntersectionAttributeOpIdx, @@ -2785,16 +2790,6 @@ void SROA_Helper::RewriteCall(CallInst *CI) { DeadInsts.push_back(CI); } } break; - case IntrinsicOp::MOP_TraceRayInline: { - if (OldVal == - CI->getArgOperand(HLOperandIndex::kTraceRayInlineRayDescOpIdx)) { - RewriteWithFlattenedHLIntrinsicCall(CI, OldVal, NewElts, - /*loadElts*/ true); - DeadInsts.push_back(CI); - break; - } - } - LLVM_FALLTHROUGH; case IntrinsicOp::MOP_DxHitObject_FromRayQuery: { const bool IsWithAttrs = CI->getNumArgOperands() == @@ -2817,7 +2812,15 @@ void SROA_Helper::RewriteCall(CallInst *CI) { RewriteWithFlattenedHLIntrinsicCall(CI, OldVal, NewElts, /*loadElts*/ true); DeadInsts.push_back(CI); - break; + } break; + case IntrinsicOp::MOP_TraceRayInline: { + if (OldVal == + CI->getArgOperand(HLOperandIndex::kTraceRayInlineRayDescOpIdx)) { + RewriteWithFlattenedHLIntrinsicCall(CI, OldVal, NewElts, + /*loadElts*/ true); + DeadInsts.push_back(CI); + break; + } } default: // RayQuery this pointer replacement. diff --git a/tools/clang/test/CodeGenDXIL/hlsl/objects/HitObject/multi_raydesc.hlsl b/tools/clang/test/CodeGenDXIL/hlsl/objects/HitObject/multi_raydesc.hlsl new file mode 100644 index 0000000000..b04880d026 --- /dev/null +++ b/tools/clang/test/CodeGenDXIL/hlsl/objects/HitObject/multi_raydesc.hlsl @@ -0,0 +1,42 @@ +// RUN: %dxc %s -T lib_6_9 -DHIT1=1 -DHIT2=1 -DHIT3=1 -DHIT4=1 +// RUN: %dxc %s -T lib_6_9 -DHIT1=0 -DHIT2=1 -DHIT3=1 -DHIT4=0 +// RUN: %dxc %s -T lib_6_9 -DHIT1=1 -DHIT2=0 -DHIT3=0 -DHIT4=1 +// RUN: %dxc %s -T lib_6_9 -DHIT1=1 -DHIT2=0 -DHIT3=1 -DHIT4=0 +// RUN: %dxc %s -T lib_6_9 -DHIT1=0 -DHIT2=1 -DHIT3=0 -DHIT4=1 + +struct[raypayload] PerRayData +{ + uint dummy : read(anyhit,closesthit,miss,caller) : write(anyhit,miss,closesthit,caller); +}; + +struct Attrs +{ + float2 barycentrics : BARYCENTRICS; +}; + +RaytracingAccelerationStructure topObject : register(t0); + +[shader("raygeneration")] +void raygen() +{ + RayDesc ray = {{0, 1, 2}, 3, {4, 5, 6}, 7}; + + PerRayData payload; +#if HIT1 + dx::HitObject hit1 = dx::HitObject::MakeMiss(RAY_FLAG_NONE, 0, ray); + dx::MaybeReorderThread(hit1); +#endif +#if HIT2 + dx::HitObject hit2 = dx::HitObject::TraceRay(topObject, RAY_FLAG_SKIP_TRIANGLES, 0xFF, 0, 0, 0, ray, payload); + dx::MaybeReorderThread(hit2); +#endif +#if HIT3 + RayQuery rayQuery; + rayQuery.TraceRayInline(topObject, RAY_FLAG_NONE, 0xFF, ray); + dx::HitObject hit3 = dx::HitObject::FromRayQuery(rayQuery); + dx::MaybeReorderThread(hit3); +#endif +#if HIT4 + TraceRay(topObject, RAY_FLAG_SKIP_TRIANGLES, 0xFF, 0, 0, 0, ray, payload); +#endif +} diff --git a/tools/clang/test/DXC/Passes/DxilGen/hitobject_traceinvoke_dxilgen.ll b/tools/clang/test/DXC/Passes/DxilGen/hitobject_traceinvoke_dxilgen.ll index 6f364a0161..0232ac86f2 100644 --- a/tools/clang/test/DXC/Passes/DxilGen/hitobject_traceinvoke_dxilgen.ll +++ b/tools/clang/test/DXC/Passes/DxilGen/hitobject_traceinvoke_dxilgen.ll @@ -15,12 +15,12 @@ target datalayout = "e-m:e-p:32:32-i1:32-i8:32-i16:32-i32:32-i64:64-f16:32-f32:3 target triple = "dxil-ms-dx" %struct.RaytracingAccelerationStructure = type { i32 } -%struct.RayDesc = type { <3 x float>, float, <3 x float>, float } %struct.Payload = type { <3 x float> } %dx.types.HitObject = type { i8* } %dx.types.Handle = type { i8* } %dx.types.ResourceProperties = type { i32, i32 } %"class.RWStructuredBuffer" = type { float } +%struct.RayDesc = type { <3 x float>, float, <3 x float>, float } %"class.dx::HitObject" = type { i32 } @"\01?RTAS@@3URaytracingAccelerationStructure@@A" = external global %struct.RaytracingAccelerationStructure, align 4 @@ -28,55 +28,31 @@ target triple = "dxil-ms-dx" ; Function Attrs: nounwind define void @"\01?main@@YAXXZ"() #0 { entry: - %rayDesc = alloca %struct.RayDesc, align 4 %pld = alloca %struct.Payload, align 4 +; CHECK: %[[PLDA:[^ ]+]] = alloca %struct.Payload, align 4 %hit = alloca %dx.types.HitObject, align 4 - %0 = bitcast %struct.RayDesc* %rayDesc to i8*, !dbg !31 ; line:80 col:3 - call void @llvm.lifetime.start(i64 32, i8* %0) #0, !dbg !31 ; line:80 col:3 - %Origin = getelementptr inbounds %struct.RayDesc, %struct.RayDesc* %rayDesc, i32 0, i32 0, !dbg !35 ; line:81 col:11 - store <3 x float> , <3 x float>* %Origin, align 4, !dbg !36, !tbaa !37 ; line:81 col:18 - %TMin = getelementptr inbounds %struct.RayDesc, %struct.RayDesc* %rayDesc, i32 0, i32 1, !dbg !40 ; line:82 col:11 - store float 3.000000e+00, float* %TMin, align 4, !dbg !41, !tbaa !42 ; line:82 col:16 - %Direction = getelementptr inbounds %struct.RayDesc, %struct.RayDesc* %rayDesc, i32 0, i32 2, !dbg !44 ; line:83 col:11 - store <3 x float> , <3 x float>* %Direction, align 4, !dbg !45, !tbaa !37 ; line:83 col:21 - %TMax = getelementptr inbounds %struct.RayDesc, %struct.RayDesc* %rayDesc, i32 0, i32 3, !dbg !46 ; line:84 col:11 - store float 7.000000e+00, float* %TMax, align 4, !dbg !47, !tbaa !42 ; line:84 col:16 - %1 = bitcast %struct.Payload* %pld to i8*, !dbg !48 ; line:86 col:3 - call void @llvm.lifetime.start(i64 12, i8* %1) #0, !dbg !48 ; line:86 col:3 - %dummy = getelementptr inbounds %struct.Payload, %struct.Payload* %pld, i32 0, i32 0, !dbg !49 ; line:87 col:7 - store <3 x float> , <3 x float>* %dummy, align 4, !dbg !50, !tbaa !37 ; line:87 col:13 - %2 = bitcast %dx.types.HitObject* %hit to i8*, !dbg !51 ; line:89 col:3 - call void @llvm.lifetime.start(i64 4, i8* %2) #0, !dbg !51 ; line:89 col:3 - %3 = load %struct.RaytracingAccelerationStructure, %struct.RaytracingAccelerationStructure* @"\01?RTAS@@3URaytracingAccelerationStructure@@A", !dbg !52 ; line:89 col:23 - %4 = call %dx.types.Handle @"dx.hl.createhandle..%dx.types.Handle (i32, %struct.RaytracingAccelerationStructure)"(i32 0, %struct.RaytracingAccelerationStructure %3), !dbg !52 ; line:89 col:23 - %5 = call %dx.types.Handle @"dx.hl.annotatehandle..%dx.types.Handle (i32, %dx.types.Handle, %dx.types.ResourceProperties, %struct.RaytracingAccelerationStructure)"(i32 14, %dx.types.Handle %4, %dx.types.ResourceProperties { i32 16, i32 0 }, %struct.RaytracingAccelerationStructure zeroinitializer), !dbg !52 ; line:89 col:23 - ; CHECK: %[[ORIGINPTR:[^ ]+]] = getelementptr %struct.RayDesc, %struct.RayDesc* %[[RAYDESCPTR:[^ ]+]], i32 0, i32 0 - ; CHECK: %[[ORIGIN:[^ ]+]] = load <3 x float>, <3 x float>* %[[ORIGINPTR]] - ; CHECK: %[[O0:[^ ]+]] = extractelement <3 x float> %[[ORIGIN]], i64 0 - ; CHECK: %[[O1:[^ ]+]] = extractelement <3 x float> %[[ORIGIN]], i64 1 - ; CHECK: %[[O2:[^ ]+]] = extractelement <3 x float> %[[ORIGIN]], i64 2 - ; CHECK: %[[TMINPTR:[^ ]+]] = getelementptr %struct.RayDesc, %struct.RayDesc* %[[RAYDESCPTR]], i32 0, i32 1 - ; CHECK: %[[TMIN:[^ ]+]] = load float, float* %[[TMINPTR]] - ; CHECK: %[[DIRPTR:[^ ]+]] = getelementptr %struct.RayDesc, %struct.RayDesc* %[[RAYDESCPTR]], i32 0, i32 2 - ; CHECK: %[[DIR:[^ ]+]] = load <3 x float>, <3 x float>* %[[DIRPTR]] - ; CHECK: %[[D0:[^ ]+]] = extractelement <3 x float> %[[DIR]], i64 0 - ; CHECK: %[[D1:[^ ]+]] = extractelement <3 x float> %[[DIR]], i64 1 - ; CHECK: %[[D2:[^ ]+]] = extractelement <3 x float> %[[DIR]], i64 2 - ; CHECK: %[[TMAXPTR:[^ ]+]] = getelementptr %struct.RayDesc, %struct.RayDesc* %[[RAYDESCPTR]], i32 0, i32 3 - ; CHECK: %[[TMAX:[^ ]+]] = load float, float* %[[TMAXPTR]] - ; CHECK: %[[TRACEHO:[^ ]+]] = call %dx.types.HitObject @dx.op.hitObject_TraceRay.struct.Payload(i32 262, %dx.types.Handle %5, i32 513, i32 1, i32 2, i32 4, i32 0, float %[[O0]], float %[[O1]], float %[[O2]], float %[[TMIN]], float %[[D0]], float %[[D1]], float %[[D2]], float %[[TMAX]], %struct.Payload* %pld) - call void @"dx.hl.op..void (i32, %dx.types.HitObject*, %dx.types.Handle, i32, i32, i32, i32, i32, %struct.RayDesc*, %struct.Payload*)"(i32 389, %dx.types.HitObject* %hit, %dx.types.Handle %5, i32 513, i32 1, i32 2, i32 4, i32 0, %struct.RayDesc* %rayDesc, %struct.Payload* %pld), !dbg !52 ; line:89 col:23 - ; CHECK: store %dx.types.HitObject %[[TRACEHO]], %dx.types.HitObject* %[[HOPTR:[^ ]+]] - ; CHECK: %[[INVOKEHO:[^ ]+]] = load %dx.types.HitObject, %dx.types.HitObject* %[[HOPTR]] - ; CHECK: call void @dx.op.hitObject_Invoke.struct.Payload(i32 267, %dx.types.HitObject %[[INVOKEHO]], %struct.Payload* %pld) - call void @"dx.hl.op..void (i32, %dx.types.HitObject*, %struct.Payload*)"(i32 382, %dx.types.HitObject* %hit, %struct.Payload* %pld), !dbg !53 ; line:99 col:3 - %6 = bitcast %dx.types.HitObject* %hit to i8*, !dbg !54 ; line:100 col:1 - call void @llvm.lifetime.end(i64 4, i8* %6) #0, !dbg !54 ; line:100 col:1 - %7 = bitcast %struct.Payload* %pld to i8*, !dbg !54 ; line:100 col:1 - call void @llvm.lifetime.end(i64 12, i8* %7) #0, !dbg !54 ; line:100 col:1 - %8 = bitcast %struct.RayDesc* %rayDesc to i8*, !dbg !54 ; line:100 col:1 - call void @llvm.lifetime.end(i64 32, i8* %8) #0, !dbg !54 ; line:100 col:1 - ret void, !dbg !54 ; line:100 col:1 +; CHECK: %[[HITA:[^ ]+]] = alloca %dx.types.HitObject, align 4 +; CHECK-NOT: alloca + %0 = bitcast %struct.Payload* %pld to i8*, !dbg !31 ; line:88 col:3 + call void @llvm.lifetime.start(i64 12, i8* %0) #0, !dbg !31 ; line:88 col:3 + %dummy = getelementptr inbounds %struct.Payload, %struct.Payload* %pld, i32 0, i32 0, !dbg !35 ; line:89 col:7 + store <3 x float> , <3 x float>* %dummy, align 4, !dbg !36, !tbaa !37 ; line:89 col:13 + %1 = bitcast %dx.types.HitObject* %hit to i8*, !dbg !40 ; line:91 col:3 + call void @llvm.lifetime.start(i64 4, i8* %1) #0, !dbg !40 ; line:91 col:3 + %2 = load %struct.RaytracingAccelerationStructure, %struct.RaytracingAccelerationStructure* @"\01?RTAS@@3URaytracingAccelerationStructure@@A", !dbg !41 ; line:91 col:23 + %3 = call %dx.types.Handle @"dx.hl.createhandle..%dx.types.Handle (i32, %struct.RaytracingAccelerationStructure)"(i32 0, %struct.RaytracingAccelerationStructure %2), !dbg !41 ; line:91 col:23 + %4 = call %dx.types.Handle @"dx.hl.annotatehandle..%dx.types.Handle (i32, %dx.types.Handle, %dx.types.ResourceProperties, %struct.RaytracingAccelerationStructure)"(i32 14, %dx.types.Handle %3, %dx.types.ResourceProperties { i32 16, i32 0 }, %struct.RaytracingAccelerationStructure zeroinitializer), !dbg !41 ; line:91 col:23 + call void @"dx.hl.op..void (i32, %dx.types.HitObject*, %dx.types.Handle, i32, i32, i32, i32, i32, <3 x float>, float, <3 x float>, float, %struct.Payload*)"(i32 389, %dx.types.HitObject* %hit, %dx.types.Handle %4, i32 513, i32 1, i32 2, i32 4, i32 0, <3 x float> , float 3.000000e+00, <3 x float> , float 7.000000e+00, %struct.Payload* %pld), !dbg !41 ; line:91 col:23 +; CHECK: %[[TRACEHO:[^ ]+]] = call %dx.types.HitObject @dx.op.hitObject_TraceRay.struct.Payload(i32 262, %dx.types.Handle %{{[^ ]+}}, i32 513, i32 1, i32 2, i32 4, i32 0, float 0.000000e+00, float 1.000000e+00, float 2.000000e+00, float 3.000000e+00, float 4.000000e+00, float 5.000000e+00, float 6.000000e+00, float 7.000000e+00, %struct.Payload* %[[PLDA]]) +; CHECK: store %dx.types.HitObject %[[TRACEHO]], %dx.types.HitObject* %[[HITA]] + call void @"dx.hl.op..void (i32, %dx.types.HitObject*, %struct.Payload*)"(i32 382, %dx.types.HitObject* %hit, %struct.Payload* %pld), !dbg !42 ; line:101 col:3 +; CHECK: %[[INVHIT:[^ ]+]] = load %dx.types.HitObject, %dx.types.HitObject* %[[HITA]] +; CHECK: call void @dx.op.hitObject_Invoke.struct.Payload(i32 267, %dx.types.HitObject %[[INVHIT]], %struct.Payload* %[[PLDA]]) + %5 = bitcast %dx.types.HitObject* %hit to i8*, !dbg !43 ; line:102 col:1 + call void @llvm.lifetime.end(i64 4, i8* %5) #0, !dbg !43 ; line:102 col:1 + %6 = bitcast %struct.Payload* %pld to i8*, !dbg !43 ; line:102 col:1 + call void @llvm.lifetime.end(i64 12, i8* %6) #0, !dbg !43 ; line:102 col:1 + ret void, !dbg !43 ; line:102 col:1 } ; Function Attrs: nounwind @@ -85,9 +61,6 @@ declare void @llvm.lifetime.start(i64, i8* nocapture) #0 ; Function Attrs: nounwind declare void @llvm.lifetime.end(i64, i8* nocapture) #0 -; Function Attrs: nounwind -declare void @"dx.hl.op..void (i32, %dx.types.HitObject*, %dx.types.Handle, i32, i32, i32, i32, i32, %struct.RayDesc*, %struct.Payload*)"(i32, %dx.types.HitObject*, %dx.types.Handle, i32, i32, i32, i32, i32, %struct.RayDesc*, %struct.Payload*) #0 - ; Function Attrs: nounwind readnone declare %dx.types.Handle @"dx.hl.createhandle..%dx.types.Handle (i32, %struct.RaytracingAccelerationStructure)"(i32, %struct.RaytracingAccelerationStructure) #1 @@ -97,6 +70,9 @@ declare %dx.types.Handle @"dx.hl.annotatehandle..%dx.types.Handle (i32, %dx.type ; Function Attrs: nounwind declare void @"dx.hl.op..void (i32, %dx.types.HitObject*, %struct.Payload*)"(i32, %dx.types.HitObject*, %struct.Payload*) #0 +; Function Attrs: nounwind +declare void @"dx.hl.op..void (i32, %dx.types.HitObject*, %dx.types.Handle, i32, i32, i32, i32, i32, <3 x float>, float, <3 x float>, float, %struct.Payload*)"(i32, %dx.types.HitObject*, %dx.types.Handle, i32, i32, i32, i32, i32, <3 x float>, float, <3 x float>, float, %struct.Payload*) #0 + attributes #0 = { nounwind } attributes #1 = { nounwind readnone } @@ -141,27 +117,16 @@ attributes #1 = { nounwind readnone } !28 = !{void ()* @"\01?main@@YAXXZ", i32 7} !29 = !{i32 -2147483584} !30 = !{i32 -1} -!31 = !DILocation(line: 80, column: 3, scope: !32) -!32 = !DISubprogram(name: "main", scope: !33, file: !33, line: 79, type: !34, isLocal: false, isDefinition: true, scopeLine: 79, flags: DIFlagPrototyped, isOptimized: false, function: void ()* @"\01?main@@YAXXZ") -!33 = !DIFile(filename: "tools/clang/test/CodeGenDXIL/hlsl/objects/HitObject/hitobject_traceinvoke.hlsl", directory: "") +!31 = !DILocation(line: 88, column: 3, scope: !32) +!32 = !DISubprogram(name: "main", scope: !33, file: !33, line: 81, type: !34, isLocal: false, isDefinition: true, scopeLine: 81, flags: DIFlagPrototyped, isOptimized: false, function: void ()* @"\01?main@@YAXXZ") +!33 = !DIFile(filename: "tools\5Cclang\5Ctest\5CCodeGenDXIL\5Chlsl\5Cobjects\5CHitObject\5Chitobject_traceinvoke.hlsl", directory: "") !34 = !DISubroutineType(types: !22) -!35 = !DILocation(line: 81, column: 11, scope: !32) -!36 = !DILocation(line: 81, column: 18, scope: !32) +!35 = !DILocation(line: 89, column: 7, scope: !32) +!36 = !DILocation(line: 89, column: 13, scope: !32) !37 = !{!38, !38, i64 0} !38 = !{!"omnipotent char", !39, i64 0} !39 = !{!"Simple C/C++ TBAA"} -!40 = !DILocation(line: 82, column: 11, scope: !32) -!41 = !DILocation(line: 82, column: 16, scope: !32) -!42 = !{!43, !43, i64 0} -!43 = !{!"float", !38, i64 0} -!44 = !DILocation(line: 83, column: 11, scope: !32) -!45 = !DILocation(line: 83, column: 21, scope: !32) -!46 = !DILocation(line: 84, column: 11, scope: !32) -!47 = !DILocation(line: 84, column: 16, scope: !32) -!48 = !DILocation(line: 86, column: 3, scope: !32) -!49 = !DILocation(line: 87, column: 7, scope: !32) -!50 = !DILocation(line: 87, column: 13, scope: !32) -!51 = !DILocation(line: 89, column: 3, scope: !32) -!52 = !DILocation(line: 89, column: 23, scope: !32) -!53 = !DILocation(line: 99, column: 3, scope: !32) -!54 = !DILocation(line: 100, column: 1, scope: !32) +!40 = !DILocation(line: 91, column: 3, scope: !32) +!41 = !DILocation(line: 91, column: 23, scope: !32) +!42 = !DILocation(line: 101, column: 3, scope: !32) +!43 = !DILocation(line: 102, column: 1, scope: !32) diff --git a/tools/clang/test/DXC/Passes/ScalarReplHLSL/hitobject_make_scalarrepl.ll b/tools/clang/test/DXC/Passes/ScalarReplHLSL/hitobject_make_scalarrepl.ll index 89ee886c2e..01515d56ff 100644 --- a/tools/clang/test/DXC/Passes/ScalarReplHLSL/hitobject_make_scalarrepl.ll +++ b/tools/clang/test/DXC/Passes/ScalarReplHLSL/hitobject_make_scalarrepl.ll @@ -33,7 +33,10 @@ entry: %hit = alloca %dx.types.HitObject, align 4 %tmp = alloca %dx.types.HitObject, align 4 %ray = alloca %struct.RayDesc, align 4 -; CHECK-NOT: %{{[^ ]+}} = alloca %struct.RayDesc +; CHECK: %[[pRDO:[^ ]+]] = alloca <3 x float> +; CHECK: %[[pRDTMIN:[^ ]+]] = alloca float +; CHECK: %[[pRDD:[^ ]+]] = alloca <3 x float> +; CHECK: %[[pRDTMAX:[^ ]+]] = alloca float %tmp2 = alloca %dx.types.HitObject, align 4 ; CHECK: %[[HIT0:[^ ]+]] = alloca %dx.types.HitObject, align 4 ; CHECK: %[[HIT1:[^ ]+]] = alloca %dx.types.HitObject, align 4 @@ -61,11 +64,11 @@ entry: store float 1.000000e+03, float* %8, !dbg !30 ; line:44 col:17 %9 = bitcast %dx.types.HitObject* %tmp2 to i8*, !dbg !31 ; line:45 col:3 call void @llvm.lifetime.start(i64 4, i8* %9) #0, !dbg !31 ; line:45 col:3 -; CHECK: store <3 x float> zeroinitializer, <3 x float>* %[[pRDO:[^ ]+]], -; CHECK: store float 0.000000e+00, float* %[[pRDTMIN:[^ ]+]], -; CHECK: store <3 x float> , <3 x float>* %[[pRDD:[^ ]+]], -; CHECK: store float 1.000000e+03, float* %[[pRDTMAX:[^ ]+]], -; CHECK-DAG: %[[RDO:[^ ]+]] = load <3 x float>, <3 x float>* %[[pRDO]], +; CHECK-DAG: store <3 x float> zeroinitializer, <3 x float>* %[[pRDO]], +; CHECK-DAG: store float 0.000000e+00, float* %[[pRDTMIN]], +; CHECK-DAG: store <3 x float> , <3 x float>* %[[pRDD]], +; CHECK-DAG: store float 1.000000e+03, float* %[[pRDTMAX]], +; CHECK: %[[RDO:[^ ]+]] = load <3 x float>, <3 x float>* %[[pRDO]], ; CHECK-DAG: %[[RDTMIN:[^ ]+]] = load float, float* %[[pRDTMIN]], ; CHECK-DAG: %[[RDD:[^ ]+]] = load <3 x float>, <3 x float>* %[[pRDD]], ; CHECK-DAG: %[[RDTMAX:[^ ]+]] = load float, float* %[[pRDTMAX]], diff --git a/tools/clang/test/HLSLFileCheck/pix/AnnotateVirtualRegs-Raygen.hlsl b/tools/clang/test/HLSLFileCheck/pix/AnnotateVirtualRegs-Raygen.hlsl deleted file mode 100644 index b9670bdaba..0000000000 --- a/tools/clang/test/HLSLFileCheck/pix/AnnotateVirtualRegs-Raygen.hlsl +++ /dev/null @@ -1,36 +0,0 @@ -// RUN: %dxc -Od -T lib_6_6 %s | %opt -S -dxil-annotate-with-virtual-regs | FileCheck %s - - -/* To run locally run: -%dxc -Od -T lib_6_6 %s -Fc %t.ll -%opt %t.ll -S -dxil-annotate-with-virtual-regs | FileCheck %s -*/ - -RaytracingAccelerationStructure scene : register(t0); - -struct RayPayload -{ - int3 color; -}; - -[shader("raygeneration")] -void ENTRY() -{ - RayDesc ray = {{0,0,0}, {0,0,1}, 0.05, 1000.0}; - RayPayload pld; - TraceRay(scene, 0 /*rayFlags*/, 0xFF /*rayMask*/, 0 /*sbtRecordOffset*/, 1 /*sbtRecordStride*/, 0 /*missIndex*/, ray, pld); -} - -// CHECK: {{.*}} = getelementptr inbounds %struct.RayDesc, %struct.RayDesc* {{.*}}, i32 0, i32 0, !pix-dxil-reg [[RDGEP:![0-9]+]], !pix-dxil-inst-num {{.*}} -// CHECK: {{.*}} = load i32, i32* getelementptr inbounds ([1 x i32], [1 x i32]* @dx.nothing.a, i32 0, i32 0), !pix-dxil-reg [[NothGEP:![0-9]+]], !pix-dxil-inst-num {{.*}} -// CHECK: {{.*}} = getelementptr inbounds %struct.RayDesc, %struct.RayDesc* {{.*}}, i32 0, i32 1, !pix-dxil-reg [[RDGEP2:![0-9]+]], !pix-dxil-inst-num {{.*}} -// CHECK: {{.*}} = load i32, i32* getelementptr inbounds ([1 x i32], [1 x i32]* @dx.nothing.a, i32 0, i32 0), !pix-dxil-reg [[NothGEP2:![0-9]+]], !pix-dxil-inst-num {{.*}} -// CHECK: {{.*}} = getelementptr inbounds %struct.RayDesc, %struct.RayDesc* {{.*}}, i32 0, i32 2, !pix-dxil-reg [[RDGEP3:![0-9]+]], !pix-dxil-inst-num {{.*}} -// CHECK: {{.*}} = load i32, i32* getelementptr inbounds ([1 x i32], [1 x i32]* @dx.nothing.a, i32 0, i32 0), !pix-dxil-reg [[NothGEP3:![0-9]+]], !pix-dxil-inst-num {{.*}} - -// CHECK-DAG: [[RDGEP]] = !{i32 0, i32 0} -// CHECK-DAG: [[NothGEP]] = !{i32 0, i32 11} -// CHECK-DAG: [[RDGEP2]] = !{i32 0, i32 3} -// CHECK-DAG: [[NothGEP2]] = !{i32 0, i32 12} -// CHECK-DAG: [[RDGEP3]] = !{i32 0, i32 4} -// CHECK-DAG: [[NothGEP3]] = !{i32 0, i32 13} diff --git a/tools/clang/unittests/HLSL/PixTest.cpp b/tools/clang/unittests/HLSL/PixTest.cpp index e337d2951c..e8b93458a1 100644 --- a/tools/clang/unittests/HLSL/PixTest.cpp +++ b/tools/clang/unittests/HLSL/PixTest.cpp @@ -119,7 +119,6 @@ class PixTest : public ::testing::Test { TEST_METHOD(AccessTracking_ModificationReport_SM66) TEST_METHOD(PixStructAnnotation_Lib_DualRaygen) - TEST_METHOD(PixStructAnnotation_Lib_RaygenAllocaStructAlignment) TEST_METHOD(PixStructAnnotation_Simple) TEST_METHOD(PixStructAnnotation_CopiedStruct) @@ -1455,100 +1454,6 @@ void Raygen1() } } -TEST_F(PixTest, PixStructAnnotation_Lib_RaygenAllocaStructAlignment) { - if (m_ver.SkipDxilVersion(1, 5)) - return; - - const char *hlsl = R"( - -RaytracingAccelerationStructure Scene : register(t0, space0); -RWTexture2D RenderTarget : register(u0); - -struct SceneConstantBuffer -{ - float4x4 projectionToWorld; - float4 cameraPosition; - float4 lightPosition; - float4 lightAmbientColor; - float4 lightDiffuseColor; -}; - -ConstantBuffer g_sceneCB : register(b0); - -struct RayPayload -{ - float4 color; -}; - -inline void GenerateCameraRay(uint2 index, out float3 origin, out float3 direction) -{ - float2 xy = index + 0.5f; // center in the middle of the pixel. - float2 screenPos = xy;// / DispatchRaysDimensions().xy * 2.0 - 1.0; - - // Invert Y for DirectX-style coordinates. - screenPos.y = -screenPos.y; - - // Unproject the pixel coordinate into a ray. - float4 world = /*mul(*/float4(screenPos, 0, 1)/*, g_sceneCB.projectionToWorld)*/; - - //world.xyz /= world.w; - origin = world.xyz; //g_sceneCB.cameraPosition.xyz; - direction = float3(1,0,0);//normalize(world.xyz - origin); -} - -void RaygenCommon() -{ - float3 rayDir; - float3 origin; - - // Generate a ray for a camera pixel corresponding to an index from the dispatched 2D grid. - GenerateCameraRay(DispatchRaysIndex().xy, origin, rayDir); - - // Trace the ray. - // Set the ray's extents. - RayDesc ray; - ray.Origin = origin; - ray.Direction = rayDir; - // Set TMin to a non-zero small value to avoid aliasing issues due to floating - point errors. - // TMin should be kept small to prevent missing geometry at close contact areas. - ray.TMin = 0.001; - ray.TMax = 10000.0; - RayPayload payload = { float4(0, 0, 0, 0) }; - TraceRay(Scene, RAY_FLAG_CULL_BACK_FACING_TRIANGLES, ~0, 0, 1, 0, ray, payload); - - // Write the raytraced color to the output texture. - // RenderTarget[DispatchRaysIndex().xy] = payload.color; -} - -[shader("raygeneration")] -void Raygen() -{ - RaygenCommon(); -} -)"; - - auto Testables = TestStructAnnotationCase(hlsl, L"-Od", true, L"lib_6_6"); - - // Built-in type "RayDesc" has this structure: struct { float3 Origin; float - // TMin; float3 Direction; float TMax; } This is 8 floats, with members at - // offsets 0,3,4,7 respectively. - - auto FindAtLeastOneOf = [=](char const *name, uint32_t index) { - VERIFY_IS_TRUE(std::find_if(Testables.AllocaWrites.begin(), - Testables.AllocaWrites.end(), - [&name, &index](AllocaWrite const &aw) { - return 0 == strcmp(aw.memberName.c_str(), - name) && - aw.index == index; - }) != Testables.AllocaWrites.end()); - }; - - FindAtLeastOneOf("Origin.x", 0); - FindAtLeastOneOf("TMin", 3); - FindAtLeastOneOf("Direction.x", 4); - FindAtLeastOneOf("TMax", 7); -} - TEST_F(PixTest, PixStructAnnotation_Simple) { if (m_ver.SkipDxilVersion(1, 5)) return; @@ -3437,11 +3342,10 @@ void RaygenInternalName() auto disassembly = Disassemble(output.blob); auto lines = Split(disassembly, '\n'); auto metaDataKeyToValue = FindAllocaRelatedMetadata(lines); - // To validate that the RayDesc and RayPayload instances were fully covered, - // check that there are alloca writes that cover all of them. RayPayload - // has four elements, and RayDesc has eight. + // To validate that the RayPayload instance is fully covered, + // check that there are four element to the RayPayload alloca that cover all + // of its elements. RayDesc is SROA'd in -Od, so no Alloca to test here. std::array RayPayloadElementCoverage; - std::array RayDescElementCoverage; for (auto const &write : metaDataKeyToValue.allocaWrites) { // the whole point of the changes with this test is to separate vector @@ -3452,14 +3356,10 @@ void RaygenInternalName() if (findAlloca != metaDataKeyToValue.allocaDefinitions.end()) { if (findAlloca->second.count == 4) { RayPayloadElementCoverage[write.second.offset] = true; - } else if (findAlloca->second.count == 8) { - RayDescElementCoverage[write.second.offset] = true; } } } // Check that coverage for every element was emitted: for (auto const &b : RayPayloadElementCoverage) VERIFY_IS_TRUE(b); - for (auto const &b : RayDescElementCoverage) - VERIFY_IS_TRUE(b); }