|
23 | 23 | #include "clang/AST/RecursiveASTVisitor.h" |
24 | 24 | #include "clang/AST/Type.h" |
25 | 25 | #include "clang/Basic/TargetOptions.h" |
| 26 | +#include "clang/Frontend/FrontendDiagnostic.h" |
26 | 27 | #include "llvm/ADT/SmallString.h" |
27 | 28 | #include "llvm/ADT/SmallVector.h" |
28 | 29 | #include "llvm/Frontend/HLSL/RootSignatureMetadata.h" |
@@ -565,47 +566,78 @@ static llvm::Value *createSPIRVBuiltinLoad(IRBuilder<> &B, llvm::Module &M, |
565 | 566 | return B.CreateLoad(Ty, GV); |
566 | 567 | } |
567 | 568 |
|
568 | | -llvm::Value *CGHLSLRuntime::emitInputSemantic(IRBuilder<> &B, |
569 | | - const ParmVarDecl &D, |
570 | | - llvm::Type *Ty) { |
571 | | - assert(D.hasAttrs() && "Entry parameter missing annotation attribute!"); |
572 | | - if (D.hasAttr<HLSLSV_GroupIndexAttr>()) { |
| 569 | +llvm::Value * |
| 570 | +CGHLSLRuntime::emitSystemSemanticLoad(IRBuilder<> &B, llvm::Type *Type, |
| 571 | + const clang::DeclaratorDecl *Decl, |
| 572 | + SemanticInfo &ActiveSemantic) { |
| 573 | + if (isa<HLSLSV_GroupIndexAttr>(ActiveSemantic.Semantic)) { |
573 | 574 | llvm::Function *GroupIndex = |
574 | 575 | CGM.getIntrinsic(getFlattenedThreadIdInGroupIntrinsic()); |
575 | 576 | return B.CreateCall(FunctionCallee(GroupIndex)); |
576 | 577 | } |
577 | | - if (D.hasAttr<HLSLSV_DispatchThreadIDAttr>()) { |
| 578 | + |
| 579 | + if (isa<HLSLSV_DispatchThreadIDAttr>(ActiveSemantic.Semantic)) { |
578 | 580 | llvm::Intrinsic::ID IntrinID = getThreadIdIntrinsic(); |
579 | 581 | llvm::Function *ThreadIDIntrinsic = |
580 | 582 | llvm::Intrinsic::isOverloaded(IntrinID) |
581 | 583 | ? CGM.getIntrinsic(IntrinID, {CGM.Int32Ty}) |
582 | 584 | : CGM.getIntrinsic(IntrinID); |
583 | | - return buildVectorInput(B, ThreadIDIntrinsic, Ty); |
| 585 | + return buildVectorInput(B, ThreadIDIntrinsic, Type); |
584 | 586 | } |
585 | | - if (D.hasAttr<HLSLSV_GroupThreadIDAttr>()) { |
| 587 | + |
| 588 | + if (isa<HLSLSV_GroupThreadIDAttr>(ActiveSemantic.Semantic)) { |
586 | 589 | llvm::Intrinsic::ID IntrinID = getGroupThreadIdIntrinsic(); |
587 | 590 | llvm::Function *GroupThreadIDIntrinsic = |
588 | 591 | llvm::Intrinsic::isOverloaded(IntrinID) |
589 | 592 | ? CGM.getIntrinsic(IntrinID, {CGM.Int32Ty}) |
590 | 593 | : CGM.getIntrinsic(IntrinID); |
591 | | - return buildVectorInput(B, GroupThreadIDIntrinsic, Ty); |
| 594 | + return buildVectorInput(B, GroupThreadIDIntrinsic, Type); |
592 | 595 | } |
593 | | - if (D.hasAttr<HLSLSV_GroupIDAttr>()) { |
| 596 | + |
| 597 | + if (isa<HLSLSV_GroupIDAttr>(ActiveSemantic.Semantic)) { |
594 | 598 | llvm::Intrinsic::ID IntrinID = getGroupIdIntrinsic(); |
595 | 599 | llvm::Function *GroupIDIntrinsic = |
596 | 600 | llvm::Intrinsic::isOverloaded(IntrinID) |
597 | 601 | ? CGM.getIntrinsic(IntrinID, {CGM.Int32Ty}) |
598 | 602 | : CGM.getIntrinsic(IntrinID); |
599 | | - return buildVectorInput(B, GroupIDIntrinsic, Ty); |
| 603 | + return buildVectorInput(B, GroupIDIntrinsic, Type); |
600 | 604 | } |
601 | | - if (D.hasAttr<HLSLSV_PositionAttr>()) { |
602 | | - if (getArch() == llvm::Triple::spirv) |
603 | | - return createSPIRVBuiltinLoad(B, CGM.getModule(), Ty, "sv_position", |
604 | | - /* BuiltIn::Position */ 0); |
605 | | - llvm_unreachable("SV_Position semantic not implemented for this target."); |
| 605 | + |
| 606 | + if (HLSLSV_PositionAttr *S = |
| 607 | + dyn_cast<HLSLSV_PositionAttr>(ActiveSemantic.Semantic)) { |
| 608 | + if (CGM.getTriple().getEnvironment() == Triple::EnvironmentType::Pixel) |
| 609 | + return createSPIRVBuiltinLoad(B, CGM.getModule(), Type, |
| 610 | + S->getAttrName()->getName(), |
| 611 | + /* BuiltIn::FragCoord */ 15); |
606 | 612 | } |
607 | | - assert(false && "Unhandled parameter attribute"); |
608 | | - return nullptr; |
| 613 | + |
| 614 | + llvm_unreachable("non-handled system semantic. FIXME."); |
| 615 | +} |
| 616 | + |
| 617 | +llvm::Value * |
| 618 | +CGHLSLRuntime::handleScalarSemanticLoad(IRBuilder<> &B, llvm::Type *Type, |
| 619 | + const clang::DeclaratorDecl *Decl, |
| 620 | + SemanticInfo &ActiveSemantic) { |
| 621 | + |
| 622 | + if (!ActiveSemantic.Semantic) { |
| 623 | + ActiveSemantic.Semantic = Decl->getAttr<HLSLSemanticAttr>(); |
| 624 | + if (!ActiveSemantic.Semantic) { |
| 625 | + CGM.getDiags().Report(Decl->getInnerLocStart(), |
| 626 | + diag::err_hlsl_semantic_missing); |
| 627 | + return nullptr; |
| 628 | + } |
| 629 | + ActiveSemantic.Index = ActiveSemantic.Semantic->getSemanticIndex(); |
| 630 | + } |
| 631 | + |
| 632 | + return emitSystemSemanticLoad(B, Type, Decl, ActiveSemantic); |
| 633 | +} |
| 634 | + |
| 635 | +llvm::Value * |
| 636 | +CGHLSLRuntime::handleSemanticLoad(IRBuilder<> &B, llvm::Type *Type, |
| 637 | + const clang::DeclaratorDecl *Decl, |
| 638 | + SemanticInfo &ActiveSemantic) { |
| 639 | + assert(!Type->isStructTy()); |
| 640 | + return handleScalarSemanticLoad(B, Type, Decl, ActiveSemantic); |
609 | 641 | } |
610 | 642 |
|
611 | 643 | void CGHLSLRuntime::emitEntryFunction(const FunctionDecl *FD, |
@@ -650,8 +682,10 @@ void CGHLSLRuntime::emitEntryFunction(const FunctionDecl *FD, |
650 | 682 | Args.emplace_back(PoisonValue::get(Param.getType())); |
651 | 683 | continue; |
652 | 684 | } |
| 685 | + |
653 | 686 | const ParmVarDecl *PD = FD->getParamDecl(Param.getArgNo() - SRetOffset); |
654 | | - Args.push_back(emitInputSemantic(B, *PD, Param.getType())); |
| 687 | + SemanticInfo ActiveSemantic = {nullptr, 0}; |
| 688 | + Args.push_back(handleSemanticLoad(B, Param.getType(), PD, ActiveSemantic)); |
655 | 689 | } |
656 | 690 |
|
657 | 691 | CallInst *CI = B.CreateCall(FunctionCallee(Fn), Args, OB); |
|
0 commit comments