|
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" |
@@ -552,47 +553,78 @@ static llvm::Value *createSPIRVBuiltinLoad(IRBuilder<> &B, llvm::Module &M, |
552 | 553 | return B.CreateLoad(Ty, GV); |
553 | 554 | } |
554 | 555 |
|
555 | | -llvm::Value *CGHLSLRuntime::emitInputSemantic(IRBuilder<> &B, |
556 | | - const ParmVarDecl &D, |
557 | | - llvm::Type *Ty) { |
558 | | - assert(D.hasAttrs() && "Entry parameter missing annotation attribute!"); |
559 | | - if (D.hasAttr<HLSLSV_GroupIndexAttr>()) { |
| 556 | +llvm::Value * |
| 557 | +CGHLSLRuntime::emitSystemSemanticLoad(IRBuilder<> &B, llvm::Type *Type, |
| 558 | + const clang::DeclaratorDecl *Decl, |
| 559 | + SemanticInfo &ActiveSemantic) { |
| 560 | + if (isa<HLSLSV_GroupIndexAttr>(ActiveSemantic.Semantic)) { |
560 | 561 | llvm::Function *GroupIndex = |
561 | 562 | CGM.getIntrinsic(getFlattenedThreadIdInGroupIntrinsic()); |
562 | 563 | return B.CreateCall(FunctionCallee(GroupIndex)); |
563 | 564 | } |
564 | | - if (D.hasAttr<HLSLSV_DispatchThreadIDAttr>()) { |
| 565 | + |
| 566 | + if (isa<HLSLSV_DispatchThreadIDAttr>(ActiveSemantic.Semantic)) { |
565 | 567 | llvm::Intrinsic::ID IntrinID = getThreadIdIntrinsic(); |
566 | 568 | llvm::Function *ThreadIDIntrinsic = |
567 | 569 | llvm::Intrinsic::isOverloaded(IntrinID) |
568 | 570 | ? CGM.getIntrinsic(IntrinID, {CGM.Int32Ty}) |
569 | 571 | : CGM.getIntrinsic(IntrinID); |
570 | | - return buildVectorInput(B, ThreadIDIntrinsic, Ty); |
| 572 | + return buildVectorInput(B, ThreadIDIntrinsic, Type); |
571 | 573 | } |
572 | | - if (D.hasAttr<HLSLSV_GroupThreadIDAttr>()) { |
| 574 | + |
| 575 | + if (isa<HLSLSV_GroupThreadIDAttr>(ActiveSemantic.Semantic)) { |
573 | 576 | llvm::Intrinsic::ID IntrinID = getGroupThreadIdIntrinsic(); |
574 | 577 | llvm::Function *GroupThreadIDIntrinsic = |
575 | 578 | llvm::Intrinsic::isOverloaded(IntrinID) |
576 | 579 | ? CGM.getIntrinsic(IntrinID, {CGM.Int32Ty}) |
577 | 580 | : CGM.getIntrinsic(IntrinID); |
578 | | - return buildVectorInput(B, GroupThreadIDIntrinsic, Ty); |
| 581 | + return buildVectorInput(B, GroupThreadIDIntrinsic, Type); |
579 | 582 | } |
580 | | - if (D.hasAttr<HLSLSV_GroupIDAttr>()) { |
| 583 | + |
| 584 | + if (isa<HLSLSV_GroupIDAttr>(ActiveSemantic.Semantic)) { |
581 | 585 | llvm::Intrinsic::ID IntrinID = getGroupIdIntrinsic(); |
582 | 586 | llvm::Function *GroupIDIntrinsic = |
583 | 587 | llvm::Intrinsic::isOverloaded(IntrinID) |
584 | 588 | ? CGM.getIntrinsic(IntrinID, {CGM.Int32Ty}) |
585 | 589 | : CGM.getIntrinsic(IntrinID); |
586 | | - return buildVectorInput(B, GroupIDIntrinsic, Ty); |
| 590 | + return buildVectorInput(B, GroupIDIntrinsic, Type); |
587 | 591 | } |
588 | | - if (D.hasAttr<HLSLSV_PositionAttr>()) { |
589 | | - if (getArch() == llvm::Triple::spirv) |
590 | | - return createSPIRVBuiltinLoad(B, CGM.getModule(), Ty, "sv_position", |
591 | | - /* BuiltIn::Position */ 0); |
592 | | - llvm_unreachable("SV_Position semantic not implemented for this target."); |
| 592 | + |
| 593 | + if (HLSLSV_PositionAttr *S = |
| 594 | + dyn_cast<HLSLSV_PositionAttr>(ActiveSemantic.Semantic)) { |
| 595 | + if (CGM.getTriple().getEnvironment() == Triple::EnvironmentType::Pixel) |
| 596 | + return createSPIRVBuiltinLoad(B, CGM.getModule(), Type, |
| 597 | + S->getAttrName()->getName(), |
| 598 | + /* BuiltIn::FragCoord */ 15); |
593 | 599 | } |
594 | | - assert(false && "Unhandled parameter attribute"); |
595 | | - return nullptr; |
| 600 | + |
| 601 | + llvm_unreachable("non-handled system semantic. FIXME."); |
| 602 | +} |
| 603 | + |
| 604 | +llvm::Value * |
| 605 | +CGHLSLRuntime::handleScalarSemanticLoad(IRBuilder<> &B, llvm::Type *Type, |
| 606 | + const clang::DeclaratorDecl *Decl, |
| 607 | + SemanticInfo &ActiveSemantic) { |
| 608 | + |
| 609 | + if (!ActiveSemantic.Semantic) { |
| 610 | + ActiveSemantic.Semantic = Decl->getAttr<HLSLSemanticAttr>(); |
| 611 | + if (!ActiveSemantic.Semantic) { |
| 612 | + CGM.getDiags().Report(Decl->getInnerLocStart(), |
| 613 | + diag::err_hlsl_semantic_missing); |
| 614 | + return nullptr; |
| 615 | + } |
| 616 | + ActiveSemantic.Index = ActiveSemantic.Semantic->getSemanticIndex(); |
| 617 | + } |
| 618 | + |
| 619 | + return emitSystemSemanticLoad(B, Type, Decl, ActiveSemantic); |
| 620 | +} |
| 621 | + |
| 622 | +llvm::Value * |
| 623 | +CGHLSLRuntime::handleSemanticLoad(IRBuilder<> &B, llvm::Type *Type, |
| 624 | + const clang::DeclaratorDecl *Decl, |
| 625 | + SemanticInfo &ActiveSemantic) { |
| 626 | + assert(!Type->isStructTy()); |
| 627 | + return handleScalarSemanticLoad(B, Type, Decl, ActiveSemantic); |
596 | 628 | } |
597 | 629 |
|
598 | 630 | void CGHLSLRuntime::emitEntryFunction(const FunctionDecl *FD, |
@@ -637,8 +669,10 @@ void CGHLSLRuntime::emitEntryFunction(const FunctionDecl *FD, |
637 | 669 | Args.emplace_back(PoisonValue::get(Param.getType())); |
638 | 670 | continue; |
639 | 671 | } |
| 672 | + |
640 | 673 | const ParmVarDecl *PD = FD->getParamDecl(Param.getArgNo() - SRetOffset); |
641 | | - Args.push_back(emitInputSemantic(B, *PD, Param.getType())); |
| 674 | + SemanticInfo ActiveSemantic = {nullptr, 0}; |
| 675 | + Args.push_back(handleSemanticLoad(B, Param.getType(), PD, ActiveSemantic)); |
642 | 676 | } |
643 | 677 |
|
644 | 678 | CallInst *CI = B.CreateCall(FunctionCallee(Fn), Args, OB); |
|
0 commit comments