|
@@ -199,6 +199,10 @@ private:
|
|
|
DxilTypeSystem &dxilTypeSys);
|
|
|
unsigned AddTypeAnnotation(QualType Ty, DxilTypeSystem &dxilTypeSys,
|
|
|
unsigned &arrayEltSize);
|
|
|
+ MDNode *GetOrAddResTypeMD(QualType resTy);
|
|
|
+ void ConstructFieldAttributedAnnotation(DxilFieldAnnotation &fieldAnnotation,
|
|
|
+ QualType fieldTy,
|
|
|
+ bool bDefaultRowMajor);
|
|
|
|
|
|
std::unordered_map<Constant*, DxilFieldAnnotation> m_ConstVarAnnotationMap;
|
|
|
|
|
@@ -650,7 +654,68 @@ static CompType::Kind BuiltinTyToCompTy(const BuiltinType *BTy, bool bSNorm,
|
|
|
return kind;
|
|
|
}
|
|
|
|
|
|
-static void ConstructFieldAttributedAnnotation(DxilFieldAnnotation &fieldAnnotation, QualType fieldTy, bool bDefaultRowMajor) {
|
|
|
+static DxilSampler::SamplerKind KeywordToSamplerKind(llvm::StringRef keyword) {
|
|
|
+ // TODO: refactor for faster search (switch by 1/2/3 first letters, then
|
|
|
+ // compare)
|
|
|
+ return llvm::StringSwitch<DxilSampler::SamplerKind>(keyword)
|
|
|
+ .Case("SamplerState", DxilSampler::SamplerKind::Default)
|
|
|
+ .Case("SamplerComparisonState", DxilSampler::SamplerKind::Comparison)
|
|
|
+ .Default(DxilSampler::SamplerKind::Invalid);
|
|
|
+}
|
|
|
+
|
|
|
+MDNode *CGMSHLSLRuntime::GetOrAddResTypeMD(QualType resTy) {
|
|
|
+ const RecordType *RT = resTy->getAs<RecordType>();
|
|
|
+ if (!RT)
|
|
|
+ return nullptr;
|
|
|
+ RecordDecl *RD = RT->getDecl();
|
|
|
+ SourceLocation loc = RD->getLocation();
|
|
|
+
|
|
|
+ hlsl::DxilResourceBase::Class resClass = TypeToClass(resTy);
|
|
|
+ llvm::Type *Ty = CGM.getTypes().ConvertType(resTy);
|
|
|
+ auto it = resMetadataMap.find(Ty);
|
|
|
+ if (it != resMetadataMap.end())
|
|
|
+ return it->second;
|
|
|
+
|
|
|
+ // Save resource type metadata.
|
|
|
+ switch (resClass) {
|
|
|
+ case DXIL::ResourceClass::UAV: {
|
|
|
+ DxilResource UAV;
|
|
|
+ // TODO: save globalcoherent to variable in EmitHLSLBuiltinCallExpr.
|
|
|
+ SetUAVSRV(loc, resClass, &UAV, RD);
|
|
|
+ // Set global symbol to save type.
|
|
|
+ UAV.SetGlobalSymbol(UndefValue::get(Ty));
|
|
|
+ MDNode *MD = m_pHLModule->DxilUAVToMDNode(UAV);
|
|
|
+ resMetadataMap[Ty] = MD;
|
|
|
+ return MD;
|
|
|
+ } break;
|
|
|
+ case DXIL::ResourceClass::SRV: {
|
|
|
+ DxilResource SRV;
|
|
|
+ SetUAVSRV(loc, resClass, &SRV, RD);
|
|
|
+ // Set global symbol to save type.
|
|
|
+ SRV.SetGlobalSymbol(UndefValue::get(Ty));
|
|
|
+ MDNode *MD = m_pHLModule->DxilSRVToMDNode(SRV);
|
|
|
+ resMetadataMap[Ty] = MD;
|
|
|
+ return MD;
|
|
|
+ } break;
|
|
|
+ case DXIL::ResourceClass::Sampler: {
|
|
|
+ DxilSampler S;
|
|
|
+ DxilSampler::SamplerKind kind = KeywordToSamplerKind(RD->getName());
|
|
|
+ S.SetSamplerKind(kind);
|
|
|
+ // Set global symbol to save type.
|
|
|
+ S.SetGlobalSymbol(UndefValue::get(Ty));
|
|
|
+ MDNode *MD = m_pHLModule->DxilSamplerToMDNode(S);
|
|
|
+ resMetadataMap[Ty] = MD;
|
|
|
+ return MD;
|
|
|
+ }
|
|
|
+ default:
|
|
|
+ // Skip OutputStream for GS.
|
|
|
+ return nullptr;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+void CGMSHLSLRuntime::ConstructFieldAttributedAnnotation(
|
|
|
+ DxilFieldAnnotation &fieldAnnotation, QualType fieldTy,
|
|
|
+ bool bDefaultRowMajor) {
|
|
|
QualType Ty = fieldTy;
|
|
|
if (Ty->isReferenceType())
|
|
|
Ty = Ty.getNonReferenceType();
|
|
@@ -690,6 +755,11 @@ static void ConstructFieldAttributedAnnotation(DxilFieldAnnotation &fieldAnnotat
|
|
|
if (hlsl::IsHLSLVecType(Ty))
|
|
|
EltTy = hlsl::GetHLSLVecElementType(Ty);
|
|
|
|
|
|
+ if (IsHLSLResourceType(Ty)) {
|
|
|
+ MDNode *MD = GetOrAddResTypeMD(Ty);
|
|
|
+ fieldAnnotation.SetResourceAttribute(MD);
|
|
|
+ }
|
|
|
+
|
|
|
bool bSNorm = false;
|
|
|
bool bUNorm = false;
|
|
|
|
|
@@ -711,15 +781,15 @@ static void ConstructFieldAttributedAnnotation(DxilFieldAnnotation &fieldAnnotat
|
|
|
const BuiltinType *BTy = EltTy->getAs<BuiltinType>();
|
|
|
CompType::Kind kind = BuiltinTyToCompTy(BTy, bSNorm, bUNorm);
|
|
|
fieldAnnotation.SetCompType(kind);
|
|
|
- }
|
|
|
- else if (EltTy->isEnumeralType()) {
|
|
|
+ } else if (EltTy->isEnumeralType()) {
|
|
|
const EnumType *ETy = EltTy->getAs<EnumType>();
|
|
|
QualType type = ETy->getDecl()->getIntegerType();
|
|
|
- if (const BuiltinType *BTy = dyn_cast<BuiltinType>(type->getCanonicalTypeInternal()))
|
|
|
- fieldAnnotation.SetCompType(BuiltinTyToCompTy(BTy, bSNorm, bUNorm));
|
|
|
- }
|
|
|
- else
|
|
|
- DXASSERT(!bSNorm && !bUNorm, "snorm/unorm on invalid type, validate at handleHLSLTypeAttr");
|
|
|
+ if (const BuiltinType *BTy =
|
|
|
+ dyn_cast<BuiltinType>(type->getCanonicalTypeInternal()))
|
|
|
+ fieldAnnotation.SetCompType(BuiltinTyToCompTy(BTy, bSNorm, bUNorm));
|
|
|
+ } else
|
|
|
+ DXASSERT(!bSNorm && !bUNorm,
|
|
|
+ "snorm/unorm on invalid type, validate at handleHLSLTypeAttr");
|
|
|
}
|
|
|
|
|
|
static void ConstructFieldInterpolation(DxilFieldAnnotation &fieldAnnotation,
|
|
@@ -977,15 +1047,6 @@ static DxilResource::Kind KeywordToKind(StringRef keyword) {
|
|
|
return DxilResource::Kind::Invalid;
|
|
|
}
|
|
|
|
|
|
-static DxilSampler::SamplerKind KeywordToSamplerKind(llvm::StringRef keyword) {
|
|
|
- // TODO: refactor for faster search (switch by 1/2/3 first letters, then
|
|
|
- // compare)
|
|
|
- return llvm::StringSwitch<DxilSampler::SamplerKind>(keyword)
|
|
|
- .Case("SamplerState", DxilSampler::SamplerKind::Default)
|
|
|
- .Case("SamplerComparisonState", DxilSampler::SamplerKind::Comparison)
|
|
|
- .Default(DxilSampler::SamplerKind::Invalid);
|
|
|
-}
|
|
|
-
|
|
|
void CGMSHLSLRuntime::AddHLSLFunctionInfo(Function *F, const FunctionDecl *FD) {
|
|
|
// Add hlsl intrinsic attr
|
|
|
unsigned intrinsicOpcode;
|
|
@@ -1009,34 +1070,21 @@ void CGMSHLSLRuntime::AddHLSLFunctionInfo(Function *F, const FunctionDecl *FD) {
|
|
|
// Save resource type metadata.
|
|
|
switch (resClass) {
|
|
|
case DXIL::ResourceClass::UAV: {
|
|
|
- DxilResource UAV;
|
|
|
- // TODO: save globalcoherent to variable in EmitHLSLBuiltinCallExpr.
|
|
|
- SetUAVSRV(FD->getLocation(), resClass, &UAV, RD);
|
|
|
- // Set global symbol to save type.
|
|
|
- UAV.SetGlobalSymbol(UndefValue::get(Ty));
|
|
|
- MDNode *MD = m_pHLModule->DxilUAVToMDNode(UAV);
|
|
|
+ MDNode *MD = GetOrAddResTypeMD(recordTy);
|
|
|
+ DXASSERT(MD, "else invalid resource type");
|
|
|
resMetadataMap[Ty] = MD;
|
|
|
} break;
|
|
|
case DXIL::ResourceClass::SRV: {
|
|
|
- DxilResource SRV;
|
|
|
- SetUAVSRV(FD->getLocation(), resClass, &SRV, RD);
|
|
|
- // Set global symbol to save type.
|
|
|
- SRV.SetGlobalSymbol(UndefValue::get(Ty));
|
|
|
- MDNode *Meta = m_pHLModule->DxilSRVToMDNode(SRV);
|
|
|
+ MDNode *Meta = GetOrAddResTypeMD(recordTy);
|
|
|
+ DXASSERT(Meta, "else invalid resource type");
|
|
|
resMetadataMap[Ty] = Meta;
|
|
|
if (FT->getNumParams() > 1) {
|
|
|
QualType paramTy = MD->getParamDecl(0)->getType();
|
|
|
// Add sampler type.
|
|
|
if (TypeToClass(paramTy) == DXIL::ResourceClass::Sampler) {
|
|
|
llvm::Type *Ty = FT->getParamType(1)->getPointerElementType();
|
|
|
- DxilSampler S;
|
|
|
- const RecordType *RT = paramTy->getAs<RecordType>();
|
|
|
- DxilSampler::SamplerKind kind =
|
|
|
- KeywordToSamplerKind(RT->getDecl()->getName());
|
|
|
- S.SetSamplerKind(kind);
|
|
|
- // Set global symbol to save type.
|
|
|
- S.SetGlobalSymbol(UndefValue::get(Ty));
|
|
|
- MDNode *MD = m_pHLModule->DxilSamplerToMDNode(S);
|
|
|
+ MDNode *MD = GetOrAddResTypeMD(paramTy);
|
|
|
+ DXASSERT(MD, "else invalid resource type");
|
|
|
resMetadataMap[Ty] = MD;
|
|
|
}
|
|
|
}
|