@@ -773,7 +773,8 @@ void SemaHLSL::ActOnTopLevelFunction(FunctionDecl *FD) {
773773
774774bool SemaHLSL::determineActiveSemanticOnScalar (
775775 FunctionDecl *FD, DeclaratorDecl *OutputDecl, DeclaratorDecl *D,
776- SemanticInfo &ActiveSemantic, llvm::StringSet<> &UsedSemantics) {
776+ SemanticInfo &ActiveSemantic, llvm::StringSet<> &UsedSemantics,
777+ bool IsInput) {
777778 if (ActiveSemantic.Semantic == nullptr ) {
778779 ActiveSemantic.Semantic = D->getAttr <HLSLParsedSemanticAttr>();
779780 if (ActiveSemantic.Semantic )
@@ -792,7 +793,7 @@ bool SemaHLSL::determineActiveSemanticOnScalar(
792793 if (!A)
793794 return false ;
794795
795- checkSemanticAnnotation (FD, D, A);
796+ checkSemanticAnnotation (FD, D, A, IsInput );
796797 OutputDecl->addAttr (A);
797798
798799 unsigned Location = ActiveSemantic.Index .value_or (0 );
@@ -820,7 +821,8 @@ bool SemaHLSL::determineActiveSemantic(FunctionDecl *FD,
820821 DeclaratorDecl *OutputDecl,
821822 DeclaratorDecl *D,
822823 SemanticInfo &ActiveSemantic,
823- llvm::StringSet<> &UsedSemantics) {
824+ llvm::StringSet<> &UsedSemantics,
825+ bool IsInput) {
824826 if (ActiveSemantic.Semantic == nullptr ) {
825827 ActiveSemantic.Semantic = D->getAttr <HLSLParsedSemanticAttr>();
826828 if (ActiveSemantic.Semantic )
@@ -833,12 +835,12 @@ bool SemaHLSL::determineActiveSemantic(FunctionDecl *FD,
833835 const RecordType *RT = dyn_cast<RecordType>(T);
834836 if (!RT)
835837 return determineActiveSemanticOnScalar (FD, OutputDecl, D, ActiveSemantic,
836- UsedSemantics);
838+ UsedSemantics, IsInput );
837839
838840 const RecordDecl *RD = RT->getDecl ();
839841 for (FieldDecl *Field : RD->fields ()) {
840842 SemanticInfo Info = ActiveSemantic;
841- if (!determineActiveSemantic (FD, OutputDecl, Field, Info, UsedSemantics)) {
843+ if (!determineActiveSemantic (FD, OutputDecl, Field, Info, UsedSemantics, IsInput )) {
842844 Diag (Field->getLocation (), diag::note_hlsl_semantic_used_here) << Field;
843845 return false ;
844846 }
@@ -920,7 +922,7 @@ void SemaHLSL::CheckEntryPoint(FunctionDecl *FD) {
920922
921923 // FIXME: Verify output semantics in parameters.
922924 if (!determineActiveSemantic (FD, Param, Param, ActiveSemantic,
923- ActiveInputSemantics)) {
925+ ActiveInputSemantics, /* IsInput= */ true )) {
924926 Diag (Param->getLocation (), diag::note_previous_decl) << Param;
925927 FD->setInvalidDecl ();
926928 }
@@ -932,12 +934,13 @@ void SemaHLSL::CheckEntryPoint(FunctionDecl *FD) {
932934 if (ActiveSemantic.Semantic )
933935 ActiveSemantic.Index = ActiveSemantic.Semantic ->getSemanticIndex ();
934936 if (!FD->getReturnType ()->isVoidType ())
935- determineActiveSemantic (FD, FD, FD, ActiveSemantic, ActiveOutputSemantics);
937+ determineActiveSemantic (FD, FD, FD, ActiveSemantic, ActiveOutputSemantics, /* IsInput= */ false );
936938}
937939
938940void SemaHLSL::checkSemanticAnnotation (
939941 FunctionDecl *EntryPoint, const Decl *Param,
940- const HLSLAppliedSemanticAttr *SemanticAttr) {
942+ const HLSLAppliedSemanticAttr *SemanticAttr,
943+ bool IsInput) {
941944 auto *ShaderAttr = EntryPoint->getAttr <HLSLShaderAttr>();
942945 assert (ShaderAttr && " Entry point has no shader attribute" );
943946 llvm::Triple::EnvironmentType ST = ShaderAttr->getType ();
@@ -961,11 +964,12 @@ void SemaHLSL::checkSemanticAnnotation(
961964 }
962965
963966 if (SemanticName == " SV_POSITION" ) {
964- // TODO(#143523): allow use on other shader types & output once the overall
965- // semantic logic is implemented.
966- if (ST == llvm::Triple::Pixel)
967+ // SV_Position can is I/O for vertex shaders.
968+ // For pixel shaders, only valid as input.
969+ // Note: for SPIR-V, not backed by a builtin when used as input in a vertex shaders.
970+ if (ST == llvm::Triple::Vertex || (ST == llvm::Triple::Pixel && IsInput))
967971 return ;
968- DiagnoseAttrStageMismatch (SemanticAttr, ST, {llvm::Triple::Pixel});
972+ DiagnoseAttrStageMismatch (SemanticAttr, ST, {llvm::Triple::Pixel, llvm::Triple::Vertex });
969973 return ;
970974 }
971975
0 commit comments