Skip to content

[HLSL] Remove HLSLResource attribute #130342

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Mar 17, 2025
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 0 additions & 27 deletions clang/include/clang/Basic/Attr.td
Original file line number Diff line number Diff line change
Expand Up @@ -4819,33 +4819,6 @@ def HLSLShader : InheritableAttr {
}];
}

def HLSLResource : InheritableAttr {
let Spellings = [];
let Subjects = SubjectList<[Struct]>;
let LangOpts = [HLSL];
let Args = [
EnumArgument<
"ResourceKind", "llvm::hlsl::ResourceKind",
/*is_string=*/0,
[
"Texture1D", "Texture2D", "Texture2DMS", "Texture3D", "TextureCube",
"Texture1DArray", "Texture2DArray", "Texture2DMSArray",
"TextureCubeArray", "TypedBuffer", "RawBuffer", "StructuredBuffer",
"CBuffer", "Sampler", "TBuffer", "RTAccelerationStructure",
"FeedbackTexture2D", "FeedbackTexture2DArray"
],
[
"Texture1D", "Texture2D", "Texture2DMS", "Texture3D", "TextureCube",
"Texture1DArray", "Texture2DArray", "Texture2DMSArray",
"TextureCubeArray", "TypedBuffer", "RawBuffer", "StructuredBuffer",
"CBuffer", "Sampler", "TBuffer", "RTAccelerationStructure",
"FeedbackTexture2D", "FeedbackTexture2DArray"
],
/*opt=*/0, /*fake=*/0, /*isExternalType=*/1, /*isCovered=*/0>
];
let Documentation = [InternalOnly];
}

def HLSLROV : TypeAttr {
let Spellings = [CXX11<"hlsl", "is_rov">];
let LangOpts = [HLSL];
Expand Down
3 changes: 0 additions & 3 deletions clang/lib/CodeGen/CGDeclCXX.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1071,9 +1071,6 @@ void CodeGenFunction::GenerateCXXGlobalVarDeclInitFunc(llvm::Function *Fn,
EmitCXXGlobalVarDeclInit(*D, Addr, PerformInit);
}

if (getLangOpts().HLSL)
CGM.getHLSLRuntime().annotateHLSLResource(D, Addr);

FinishFunction();
}

Expand Down
129 changes: 0 additions & 129 deletions clang/lib/CodeGen/CGHLSLRuntime.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -260,135 +260,6 @@ void CGHLSLRuntime::finishCodeGen() {
generateGlobalCtorDtorCalls();
}

void CGHLSLRuntime::addBufferResourceAnnotation(llvm::GlobalVariable *GV,
llvm::hlsl::ResourceClass RC,
llvm::hlsl::ResourceKind RK,
bool IsROV,
llvm::hlsl::ElementType ET,
BufferResBinding &Binding) {
llvm::Module &M = CGM.getModule();

NamedMDNode *ResourceMD = nullptr;
switch (RC) {
case llvm::hlsl::ResourceClass::UAV:
ResourceMD = M.getOrInsertNamedMetadata("hlsl.uavs");
break;
case llvm::hlsl::ResourceClass::SRV:
ResourceMD = M.getOrInsertNamedMetadata("hlsl.srvs");
break;
case llvm::hlsl::ResourceClass::CBuffer:
ResourceMD = M.getOrInsertNamedMetadata("hlsl.cbufs");
break;
default:
assert(false && "Unsupported buffer type!");
return;
}
assert(ResourceMD != nullptr &&
"ResourceMD must have been set by the switch above.");

llvm::hlsl::FrontendResource Res(
GV, RK, ET, IsROV, Binding.Reg.value_or(UINT_MAX), Binding.Space);
ResourceMD->addOperand(Res.getMetadata());
}

static llvm::hlsl::ElementType
calculateElementType(const ASTContext &Context, const clang::Type *ResourceTy) {
using llvm::hlsl::ElementType;

// TODO: We may need to update this when we add things like ByteAddressBuffer
// that don't have a template parameter (or, indeed, an element type).
const auto *TST = ResourceTy->getAs<TemplateSpecializationType>();
assert(TST && "Resource types must be template specializations");
ArrayRef<TemplateArgument> Args = TST->template_arguments();
assert(!Args.empty() && "Resource has no element type");

// At this point we have a resource with an element type, so we can assume
// that it's valid or we would have diagnosed the error earlier.
QualType ElTy = Args[0].getAsType();

// We should either have a basic type or a vector of a basic type.
if (const auto *VecTy = ElTy->getAs<clang::VectorType>())
ElTy = VecTy->getElementType();

if (ElTy->isSignedIntegerType()) {
switch (Context.getTypeSize(ElTy)) {
case 16:
return ElementType::I16;
case 32:
return ElementType::I32;
case 64:
return ElementType::I64;
}
} else if (ElTy->isUnsignedIntegerType()) {
switch (Context.getTypeSize(ElTy)) {
case 16:
return ElementType::U16;
case 32:
return ElementType::U32;
case 64:
return ElementType::U64;
}
} else if (ElTy->isSpecificBuiltinType(BuiltinType::Half))
return ElementType::F16;
else if (ElTy->isSpecificBuiltinType(BuiltinType::Float))
return ElementType::F32;
else if (ElTy->isSpecificBuiltinType(BuiltinType::Double))
return ElementType::F64;

// TODO: We need to handle unorm/snorm float types here once we support them
llvm_unreachable("Invalid element type for resource");
}

void CGHLSLRuntime::annotateHLSLResource(const VarDecl *D, GlobalVariable *GV) {
const Type *Ty = D->getType()->getPointeeOrArrayElementType();
if (!Ty)
return;
const auto *RD = Ty->getAsCXXRecordDecl();
if (!RD)
return;
// the resource related attributes are on the handle member
// inside the record decl
for (auto *FD : RD->fields()) {
const auto *HLSLResAttr = FD->getAttr<HLSLResourceAttr>();
const HLSLAttributedResourceType *AttrResType =
dyn_cast<HLSLAttributedResourceType>(FD->getType().getTypePtr());
if (!HLSLResAttr || !AttrResType)
continue;

llvm::hlsl::ResourceClass RC = AttrResType->getAttrs().ResourceClass;
if (RC == llvm::hlsl::ResourceClass::UAV ||
RC == llvm::hlsl::ResourceClass::SRV)
// UAVs and SRVs have already been converted to use LLVM target types,
// we can disable generating of these resource annotations. This will
// enable progress on structured buffers with user defined types this
// resource annotations code does not handle and it crashes.
// This whole function is going to be removed as soon as cbuffers are
// converted to target types (llvm/llvm-project #114126).
return;

bool IsROV = AttrResType->getAttrs().IsROV;
llvm::hlsl::ResourceKind RK = HLSLResAttr->getResourceKind();
llvm::hlsl::ElementType ET = calculateElementType(CGM.getContext(), Ty);

BufferResBinding Binding(D->getAttr<HLSLResourceBindingAttr>());
addBufferResourceAnnotation(GV, RC, RK, IsROV, ET, Binding);
}
}

CGHLSLRuntime::BufferResBinding::BufferResBinding(
HLSLResourceBindingAttr *Binding) {
if (Binding) {
llvm::APInt RegInt(64, 0);
Binding->getSlot().substr(1).getAsInteger(10, RegInt);
Reg = RegInt.getLimitedValue();
llvm::APInt SpaceInt(64, 0);
Binding->getSpace().substr(5).getAsInteger(10, SpaceInt);
Space = SpaceInt.getLimitedValue();
} else {
Space = 0;
}
}

void clang::CodeGen::CGHLSLRuntime::setHLSLEntryAttributes(
const FunctionDecl *FD, llvm::Function *Fn) {
const auto *ShaderAttr = FD->getAttr<HLSLShaderAttr>();
Expand Down
15 changes: 0 additions & 15 deletions clang/lib/CodeGen/CGHLSLRuntime.h
Original file line number Diff line number Diff line change
Expand Up @@ -125,15 +125,6 @@ class CGHLSLRuntime {
// End of reserved area for HLSL intrinsic getters.
//===----------------------------------------------------------------------===//

struct BufferResBinding {
// The ID like 2 in register(b2, space1).
std::optional<unsigned> Reg;
// The Space like 1 is register(b2, space1).
// Default value is 0.
unsigned Space;
BufferResBinding(HLSLResourceBindingAttr *Attr);
};

protected:
CodeGenModule &CGM;

Expand All @@ -148,7 +139,6 @@ class CGHLSLRuntime {
convertHLSLSpecificType(const Type *T,
SmallVector<unsigned> *Packoffsets = nullptr);

void annotateHLSLResource(const VarDecl *D, llvm::GlobalVariable *GV);
void generateGlobalCtorDtorCalls();

void addBuffer(const HLSLBufferDecl *D);
Expand All @@ -169,11 +159,6 @@ class CGHLSLRuntime {
void emitInitListOpaqueValues(CodeGenFunction &CGF, InitListExpr *E);

private:
void addBufferResourceAnnotation(llvm::GlobalVariable *GV,
llvm::hlsl::ResourceClass RC,
llvm::hlsl::ResourceKind RK, bool IsROV,
llvm::hlsl::ElementType ET,
BufferResBinding &Binding);
void emitBufferGlobalsAndMetadata(const HLSLBufferDecl *BufDecl,
llvm::GlobalVariable *BufGV);
llvm::Triple::ArchType getArch();
Expand Down
46 changes: 20 additions & 26 deletions clang/lib/Sema/HLSLExternalSemaSource.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ class BuiltinTypeDeclBuilder {
}

BuiltinTypeDeclBuilder &
addHandleMember(ResourceClass RC, ResourceKind RK, bool IsROV, bool RawBuffer,
addHandleMember(ResourceClass RC, bool IsROV, bool RawBuffer,
AccessSpecifier Access = AccessSpecifier::AS_private) {
assert(!Record->isCompleteDefinition() && "record is already complete");

Expand All @@ -150,10 +150,9 @@ class BuiltinTypeDeclBuilder {
ElementTypeInfo
? HLSLContainedTypeAttr::CreateImplicit(Ctx, ElementTypeInfo)
: nullptr};
Attr *ResourceAttr = HLSLResourceAttr::CreateImplicit(Ctx, RK);
if (CreateHLSLAttributedResourceType(SemaRef, Ctx.HLSLResourceTy, Attrs,
AttributedResTy))
addMemberVariable("__handle", AttributedResTy, {ResourceAttr}, Access);
addMemberVariable("__handle", AttributedResTy, {}, Access);
return *this;
}

Expand Down Expand Up @@ -857,10 +856,10 @@ void HLSLExternalSemaSource::defineTrivialHLSLTypes() {

/// Set up common members and attributes for buffer types
static BuiltinTypeDeclBuilder setupBufferType(CXXRecordDecl *Decl, Sema &S,
ResourceClass RC, ResourceKind RK,
bool IsROV, bool RawBuffer) {
ResourceClass RC, bool IsROV,
bool RawBuffer) {
return BuiltinTypeDeclBuilder(S, Decl)
.addHandleMember(RC, RK, IsROV, RawBuffer)
.addHandleMember(RC, IsROV, RawBuffer)
.addDefaultHandleConstructor();
}

Expand Down Expand Up @@ -999,8 +998,7 @@ void HLSLExternalSemaSource::defineHLSLTypesWithForwardDeclarations() {
.finalizeForwardDeclaration();

onCompletion(Decl, [this](CXXRecordDecl *Decl) {
setupBufferType(Decl, *SemaPtr, ResourceClass::UAV,
ResourceKind::TypedBuffer, /*IsROV=*/false,
setupBufferType(Decl, *SemaPtr, ResourceClass::UAV, /*IsROV=*/false,
/*RawBuffer=*/false)
.addArraySubscriptOperators()
.addLoadMethods()
Expand All @@ -1012,8 +1010,7 @@ void HLSLExternalSemaSource::defineHLSLTypesWithForwardDeclarations() {
.addSimpleTemplateParams({"element_type"}, StructuredBufferConcept)
.finalizeForwardDeclaration();
onCompletion(Decl, [this](CXXRecordDecl *Decl) {
setupBufferType(Decl, *SemaPtr, ResourceClass::UAV,
ResourceKind::TypedBuffer, /*IsROV=*/true,
setupBufferType(Decl, *SemaPtr, ResourceClass::UAV, /*IsROV=*/true,
/*RawBuffer=*/false)
.addArraySubscriptOperators()
.addLoadMethods()
Expand All @@ -1024,8 +1021,8 @@ void HLSLExternalSemaSource::defineHLSLTypesWithForwardDeclarations() {
.addSimpleTemplateParams({"element_type"}, StructuredBufferConcept)
.finalizeForwardDeclaration();
onCompletion(Decl, [this](CXXRecordDecl *Decl) {
setupBufferType(Decl, *SemaPtr, ResourceClass::SRV, ResourceKind::RawBuffer,
/*IsROV=*/false, /*RawBuffer=*/true)
setupBufferType(Decl, *SemaPtr, ResourceClass::SRV, /*IsROV=*/false,
/*RawBuffer=*/true)
.addArraySubscriptOperators()
.addLoadMethods()
.completeDefinition();
Expand All @@ -1035,8 +1032,8 @@ void HLSLExternalSemaSource::defineHLSLTypesWithForwardDeclarations() {
.addSimpleTemplateParams({"element_type"}, StructuredBufferConcept)
.finalizeForwardDeclaration();
onCompletion(Decl, [this](CXXRecordDecl *Decl) {
setupBufferType(Decl, *SemaPtr, ResourceClass::UAV, ResourceKind::RawBuffer,
/*IsROV=*/false, /*RawBuffer=*/true)
setupBufferType(Decl, *SemaPtr, ResourceClass::UAV, /*IsROV=*/false,
/*RawBuffer=*/true)
.addArraySubscriptOperators()
.addLoadMethods()
.addIncrementCounterMethod()
Expand All @@ -1049,8 +1046,8 @@ void HLSLExternalSemaSource::defineHLSLTypesWithForwardDeclarations() {
.addSimpleTemplateParams({"element_type"}, StructuredBufferConcept)
.finalizeForwardDeclaration();
onCompletion(Decl, [this](CXXRecordDecl *Decl) {
setupBufferType(Decl, *SemaPtr, ResourceClass::UAV, ResourceKind::RawBuffer,
/*IsROV=*/false, /*RawBuffer=*/true)
setupBufferType(Decl, *SemaPtr, ResourceClass::UAV, /*IsROV=*/false,
/*RawBuffer=*/true)
.addAppendMethod()
.completeDefinition();
});
Expand All @@ -1060,8 +1057,8 @@ void HLSLExternalSemaSource::defineHLSLTypesWithForwardDeclarations() {
.addSimpleTemplateParams({"element_type"}, StructuredBufferConcept)
.finalizeForwardDeclaration();
onCompletion(Decl, [this](CXXRecordDecl *Decl) {
setupBufferType(Decl, *SemaPtr, ResourceClass::UAV, ResourceKind::RawBuffer,
/*IsROV=*/false, /*RawBuffer=*/true)
setupBufferType(Decl, *SemaPtr, ResourceClass::UAV, /*IsROV=*/false,
/*RawBuffer=*/true)
.addConsumeMethod()
.completeDefinition();
});
Expand All @@ -1071,8 +1068,8 @@ void HLSLExternalSemaSource::defineHLSLTypesWithForwardDeclarations() {
.addSimpleTemplateParams({"element_type"}, StructuredBufferConcept)
.finalizeForwardDeclaration();
onCompletion(Decl, [this](CXXRecordDecl *Decl) {
setupBufferType(Decl, *SemaPtr, ResourceClass::UAV, ResourceKind::RawBuffer,
/*IsROV=*/true, /*RawBuffer=*/true)
setupBufferType(Decl, *SemaPtr, ResourceClass::UAV, /*IsROV=*/true,
/*RawBuffer=*/true)
.addArraySubscriptOperators()
.addLoadMethods()
.addIncrementCounterMethod()
Expand All @@ -1083,25 +1080,22 @@ void HLSLExternalSemaSource::defineHLSLTypesWithForwardDeclarations() {
Decl = BuiltinTypeDeclBuilder(*SemaPtr, HLSLNamespace, "ByteAddressBuffer")
.finalizeForwardDeclaration();
onCompletion(Decl, [this](CXXRecordDecl *Decl) {
setupBufferType(Decl, *SemaPtr, ResourceClass::SRV, ResourceKind::RawBuffer,
/*IsROV=*/false,
setupBufferType(Decl, *SemaPtr, ResourceClass::SRV, /*IsROV=*/false,
/*RawBuffer=*/true)
.completeDefinition();
});
Decl = BuiltinTypeDeclBuilder(*SemaPtr, HLSLNamespace, "RWByteAddressBuffer")
.finalizeForwardDeclaration();
onCompletion(Decl, [this](CXXRecordDecl *Decl) {
setupBufferType(Decl, *SemaPtr, ResourceClass::UAV, ResourceKind::RawBuffer,
/*IsROV=*/false,
setupBufferType(Decl, *SemaPtr, ResourceClass::UAV, /*IsROV=*/false,
/*RawBuffer=*/true)
.completeDefinition();
});
Decl = BuiltinTypeDeclBuilder(*SemaPtr, HLSLNamespace,
"RasterizerOrderedByteAddressBuffer")
.finalizeForwardDeclaration();
onCompletion(Decl, [this](CXXRecordDecl *Decl) {
setupBufferType(Decl, *SemaPtr, ResourceClass::UAV, ResourceKind::RawBuffer,
/*IsROV=*/true,
setupBufferType(Decl, *SemaPtr, ResourceClass::UAV, /*IsROV=*/true,
/*RawBuffer=*/true)
.completeDefinition();
});
Expand Down
3 changes: 0 additions & 3 deletions clang/lib/Sema/SemaHLSL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -162,10 +162,7 @@ Decl *SemaHLSL::ActOnStartBuffer(Scope *BufferScope, bool CBuffer,
// if CBuffer is false, then it's a TBuffer
auto RC = CBuffer ? llvm::hlsl::ResourceClass::CBuffer
: llvm::hlsl::ResourceClass::SRV;
auto RK = CBuffer ? llvm::hlsl::ResourceKind::CBuffer
: llvm::hlsl::ResourceKind::TBuffer;
Result->addAttr(HLSLResourceClassAttr::CreateImplicit(getASTContext(), RC));
Result->addAttr(HLSLResourceAttr::CreateImplicit(getASTContext(), RK));

SemaRef.PushOnScopeChains(Result, BufferScope);
SemaRef.PushDeclContext(BufferScope, Result);
Expand Down
1 change: 0 additions & 1 deletion clang/test/AST/HLSL/ByteAddressBuffers-AST.hlsl
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@ RESOURCE Buffer;
// CHECK-UAV-SAME{LITERAL}: [[hlsl::resource_class(UAV)]]
// CHECK-SAME{LITERAL}: [[hlsl::raw_buffer]]
// CHECK-SAME{LITERAL}: [[hlsl::contained_type(char8_t)]]
// CHECK-NEXT: HLSLResourceAttr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> Implicit RawBuffer

// CHECK-NOSUBSCRIPT-NOT: CXXMethodDecl 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> <invalid sloc> operator[] 'const element_type &(unsigned int) const'
// CHECK-NOSUBSCRIPT-NOT: CXXMethodDecl 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> <invalid sloc> operator[] 'element_type &(unsigned int)'
2 changes: 0 additions & 2 deletions clang/test/AST/HLSL/StructuredBuffers-AST.hlsl
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,6 @@ RESOURCE<float> Buffer;
// CHECK-UAV-SAME{LITERAL}: [[hlsl::resource_class(UAV)]]
// CHECK-SAME{LITERAL}: [[hlsl::raw_buffer]]
// CHECK-SAME{LITERAL}: [[hlsl::contained_type(element_type)]]
// CHECK-NEXT: HLSLResourceAttr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> Implicit RawBuffer

// CHECK-SUBSCRIPT: CXXMethodDecl 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> <invalid sloc> operator[] 'const element_type &(unsigned int) const'
// CHECK-SUBSCRIPT-NEXT: ParmVarDecl 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> <invalid sloc> Index 'unsigned int'
Expand Down Expand Up @@ -219,4 +218,3 @@ RESOURCE<float> Buffer;
// CHECK-ROV-SAME{LITERAL}: [[hlsl::is_rov]]
// CHECK-SAME{LITERAL}: [[hlsl::raw_buffer]]
// CHECK-SAME{LITERAL}: [[hlsl::contained_type(float)]]
// CHECK-NEXT: HLSLResourceAttr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> Implicit RawBuffer
2 changes: 0 additions & 2 deletions clang/test/AST/HLSL/TypedBuffers-AST.hlsl
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,6 @@ RESOURCE<float> Buffer;
// CHECK-NEXT: FieldDecl 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> <invalid sloc> implicit __handle '__hlsl_resource_t
// CHECK-UAV-SAME{LITERAL}: [[hlsl::resource_class(UAV)]]
// CHECK-SAME{LITERAL}: [[hlsl::contained_type(element_type)]]
// CHECK-NEXT: HLSLResourceAttr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> Implicit TypedBuffer

// CHECK: CXXMethodDecl 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> <invalid sloc> operator[] 'const element_type &(unsigned int) const'
// CHECK-NEXT: ParmVarDecl 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> <invalid sloc> Index 'unsigned int'
Expand Down Expand Up @@ -110,4 +109,3 @@ RESOURCE<float> Buffer;
// CHECK-NEXT: FieldDecl 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> <invalid sloc> implicit __handle '__hlsl_resource_t
// CHECK-UAV-SAME{LITERAL}: [[hlsl::resource_class(UAV)]]
// CHECK-SAME{LITERAL}: [[hlsl::contained_type(float)]]
// CHECK-NEXT: HLSLResourceAttr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> Implicit TypedBuffer
Loading