|
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