@@ -57,6 +57,7 @@ const char DxilMDHelper::kDxilTempAllocaMDName[] = "dx.temp
5757const char DxilMDHelper::kDxilNonUniformAttributeMDName [] = " dx.nonuniform" ;
5858const char DxilMDHelper::kHLDxilResourceAttributeMDName [] = " dx.hl.resource.attribute" ;
5959const char DxilMDHelper::kDxilValidatorVersionMDName [] = " dx.valver" ;
60+ const char DxilMDHelper::kDxilDxrPayloadAnnotationsMDName [] = " dx.dxrPayloadAnnotations" ;
6061
6162// This named metadata is not valid in final module (should be moved to DxilContainer)
6263const char DxilMDHelper::kDxilRootSignatureMDName [] = " dx.rootSignature" ;
@@ -77,14 +78,15 @@ const char DxilMDHelper::kDxilSourceArgsOldMDName[] = "llvm.db
7778// This is reflection-only metadata
7879const char DxilMDHelper::kDxilCountersMDName [] = " dx.counters" ;
7980
80- static std::array<const char *, 7 > DxilMDNames = { {
81+ static std::array<const char *, 8 > DxilMDNames = { {
8182 DxilMDHelper::kDxilVersionMDName ,
8283 DxilMDHelper::kDxilShaderModelMDName ,
8384 DxilMDHelper::kDxilEntryPointsMDName ,
8485 DxilMDHelper::kDxilResourcesMDName ,
8586 DxilMDHelper::kDxilTypeSystemMDName ,
8687 DxilMDHelper::kDxilValidatorVersionMDName ,
8788 DxilMDHelper::kDxilViewIdStateMDName ,
89+ DxilMDHelper::kDxilDxrPayloadAnnotationsMDName ,
8890}};
8991
9092DxilMDHelper::DxilMDHelper (Module *pModule, std::unique_ptr<ExtraPropertyHelper> EPH)
@@ -850,6 +852,130 @@ void DxilMDHelper::LoadDxilTypeSystem(DxilTypeSystem &TypeSystem) {
850852 }
851853}
852854
855+ void DxilMDHelper::EmitDxrPayloadAnnotations (DxilTypeSystem &TypeSystem) {
856+ auto &TypeMap = TypeSystem.GetPayloadAnnotationMap ();
857+ vector<Metadata *> MDVals;
858+ MDVals.emplace_back (Uint32ToConstMD (kDxilPayloadAnnotationStructTag )); // Tag
859+ unsigned GVIdx = 0 ;
860+ for (auto it = TypeMap.begin (); it != TypeMap.end (); ++it, GVIdx++) {
861+ StructType *pStructType = const_cast <StructType *>(it->first );
862+ DxilPayloadAnnotation *pA = it->second .get ();
863+ // Emit struct type field annotations.
864+ Metadata *pMD = EmitDxrPayloadStructAnnotation (*pA);
865+
866+ MDVals.push_back (ValueAsMetadata::get (UndefValue::get (pStructType)));
867+ MDVals.push_back (pMD);
868+ }
869+
870+ NamedMDNode *pDxrPayloadAnnotationsMD = m_pModule->getNamedMetadata (kDxilDxrPayloadAnnotationsMDName );
871+ if (pDxrPayloadAnnotationsMD != nullptr ) {
872+ m_pModule->eraseNamedMetadata (pDxrPayloadAnnotationsMD);
873+ }
874+
875+ if (MDVals.size () > 1 ) {
876+ pDxrPayloadAnnotationsMD = m_pModule->getOrInsertNamedMetadata (kDxilDxrPayloadAnnotationsMDName );
877+ pDxrPayloadAnnotationsMD->addOperand (MDNode::get (m_Ctx, MDVals));
878+ }
879+ }
880+
881+ Metadata *
882+ DxilMDHelper::EmitDxrPayloadStructAnnotation (const DxilPayloadAnnotation &SA) {
883+ vector<Metadata *> MDVals;
884+ MDVals.reserve (SA.GetNumFields ());
885+ MDVals.resize (SA.GetNumFields ());
886+
887+ const StructType* STy = SA.GetStructType ();
888+ for (unsigned i = 0 ; i < SA.GetNumFields (); i++) {
889+ MDVals[i] = EmitDxrPayloadFieldAnnotation (SA.GetFieldAnnotation (i), STy->getElementType (i));
890+ }
891+
892+ return MDNode::get (m_Ctx, MDVals);
893+ }
894+
895+ void DxilMDHelper::LoadDxrPayloadAccessQualifiers (const MDOperand &MDO,
896+ DxilPayloadFieldAnnotation &FA) {
897+ unsigned fieldBitmask = ConstMDToInt32 (MDO);
898+ if (fieldBitmask & ~DXIL::PayloadAccessQualifierValidMask) {
899+ DXASSERT (false , " Unknown payload access qualifier bits set" );
900+ m_bExtraMetadata = true ;
901+ }
902+ fieldBitmask &= DXIL::PayloadAccessQualifierValidMask;
903+ FA.SetPayloadFieldQualifierMask (fieldBitmask);
904+ }
905+
906+ void DxilMDHelper::LoadDxrPayloadFieldAnnoation (
907+ const MDOperand &MDO, DxilPayloadFieldAnnotation &FA) {
908+ IFTBOOL (MDO.get () != nullptr , DXC_E_INCORRECT_DXIL_METADATA);
909+ const MDTuple *pTupleMD = dyn_cast<MDTuple>(MDO.get ()); // Tag-Value list.
910+ IFTBOOL (pTupleMD != nullptr , DXC_E_INCORRECT_DXIL_METADATA);
911+ IFTBOOL ((pTupleMD->getNumOperands () & 0x1 ) == 0 , DXC_E_INCORRECT_DXIL_METADATA);
912+
913+ for (unsigned i = 0 ; i < pTupleMD->getNumOperands (); i += 2 ) {
914+ unsigned Tag = ConstMDToUint32 (pTupleMD->getOperand (i));
915+ const MDOperand &MDO = pTupleMD->getOperand (i + 1 );
916+ IFTBOOL (MDO.get () != nullptr , DXC_E_INCORRECT_DXIL_METADATA);
917+
918+ switch (Tag) {
919+ case kDxilPayloadFieldAnnotationAccessTag :
920+ LoadDxrPayloadAccessQualifiers (MDO, FA);
921+ break ;
922+ default :
923+ DXASSERT (false , " Unknown payload field annotation tag" );
924+ m_bExtraMetadata = true ;
925+ break ;
926+ }
927+ }
928+ }
929+
930+ void DxilMDHelper::LoadDxrPayloadFieldAnnoations (const MDOperand &MDO,
931+ DxilPayloadAnnotation &SA) {
932+ IFTBOOL (MDO.get () != nullptr , DXC_E_INCORRECT_DXIL_METADATA);
933+ const MDTuple *pTupleMD = dyn_cast<MDTuple>(MDO.get ());
934+ IFTBOOL (pTupleMD != nullptr , DXC_E_INCORRECT_DXIL_METADATA);
935+ IFTBOOL (pTupleMD->getNumOperands () == SA.GetNumFields (),
936+ DXC_E_INCORRECT_DXIL_METADATA);
937+ for (unsigned i = 0 ; i < SA.GetNumFields (); ++i) {
938+ LoadDxrPayloadFieldAnnoation (pTupleMD->getOperand (i), SA.GetFieldAnnotation (i));
939+ }
940+ }
941+
942+ void DxilMDHelper::LoadDxrPayloadAnnotationNode (const llvm::MDTuple &MDT,
943+ DxilTypeSystem &TypeSystem) {
944+ unsigned Tag = ConstMDToUint32 (MDT.getOperand (0 ));
945+ IFTBOOL (Tag == kDxilPayloadAnnotationStructTag , DXC_E_INCORRECT_DXIL_METADATA)
946+ IFTBOOL ((MDT.getNumOperands () & 0x1 ) == 1 , DXC_E_INCORRECT_DXIL_METADATA);
947+
948+ Constant *pGV = dyn_cast<Constant>(ValueMDToValue (MDT.getOperand (1 )));
949+ IFTBOOL (pGV != nullptr , DXC_E_INCORRECT_DXIL_METADATA);
950+ StructType *pGVType = dyn_cast<StructType>(pGV->getType ());
951+ IFTBOOL (pGVType != nullptr , DXC_E_INCORRECT_DXIL_METADATA);
952+
953+ // Check if this struct is already part of the DXIL Type System
954+ DxilPayloadAnnotation *pPA = TypeSystem.AddPayloadAnnotation (pGVType);
955+
956+ LoadDxrPayloadFieldAnnoations (MDT.getOperand (2 ), *pPA);
957+ }
958+
959+ void DxilMDHelper::LoadDxrPayloadAnnotations (DxilTypeSystem &TypeSystem) {
960+ NamedMDNode *pDxilPayloadAnnotationsMD =
961+ m_pModule->getNamedMetadata (kDxilDxrPayloadAnnotationsMDName );
962+ if (pDxilPayloadAnnotationsMD == nullptr )
963+ return ;
964+
965+ if (DXIL::CompareVersions (m_MinValMajor, m_MinValMinor, 1 , 6 ) < 0 ) {
966+ DXASSERT (false , " payload access qualifier emitted for dxil version < 1.6" );
967+ m_bExtraMetadata = true ;
968+ }
969+ DXASSERT (pDxilPayloadAnnotationsMD->getNumOperands () != 0 , " empty metadata node?" );
970+
971+ for (unsigned i = 0 ; i < pDxilPayloadAnnotationsMD->getNumOperands (); i++) {
972+ const MDTuple *pTupleMD =
973+ dyn_cast<MDTuple>(pDxilPayloadAnnotationsMD->getOperand (i));
974+ IFTBOOL (pTupleMD != nullptr , DXC_E_INCORRECT_DXIL_METADATA);
975+ LoadDxrPayloadAnnotationNode (*pTupleMD, TypeSystem);
976+ }
977+ }
978+
853979Metadata *DxilMDHelper::EmitDxilTemplateArgAnnotation (const DxilTemplateArgAnnotation &annotation) {
854980 SmallVector<Metadata *, 2 > MDVals;
855981 if (annotation.IsType ()) {
@@ -1065,6 +1191,7 @@ Metadata *DxilMDHelper::EmitDxilFieldAnnotation(const DxilFieldAnnotation &FA) {
10651191 return MDNode::get (m_Ctx, MDVals);
10661192}
10671193
1194+
10681195void DxilMDHelper::LoadDxilFieldAnnotation (const MDOperand &MDO, DxilFieldAnnotation &FA) {
10691196 IFTBOOL (MDO.get () != nullptr , DXC_E_INCORRECT_DXIL_METADATA);
10701197 const MDTuple *pTupleMD = dyn_cast<MDTuple>(MDO.get ());
@@ -1116,6 +1243,17 @@ void DxilMDHelper::LoadDxilFieldAnnotation(const MDOperand &MDO, DxilFieldAnnota
11161243 }
11171244}
11181245
1246+ Metadata *
1247+ DxilMDHelper::EmitDxrPayloadFieldAnnotation (const DxilPayloadFieldAnnotation &FA, Type* fieldType) {
1248+ vector<Metadata *> MDVals; // Tag-Value list.
1249+ MDVals.emplace_back (Uint32ToConstMD (kDxilPayloadFieldAnnotationAccessTag ));
1250+
1251+ auto mask = FA.GetPayloadFieldQualifierMask ();
1252+ MDVals.emplace_back (Uint32ToConstMD (mask));
1253+
1254+ return MDNode::get (m_Ctx, MDVals);
1255+ }
1256+
11191257const Function *DxilMDHelper::LoadDxilFunctionProps (const MDTuple *pProps,
11201258 hlsl::DxilFunctionProps *props) {
11211259 unsigned idx = 0 ;
0 commit comments