[clang] Create Texture Dimension attribute in HLSL (PR #104239)

Joshua Batista via cfe-commits cfe-commits at lists.llvm.org
Wed Aug 14 14:05:37 PDT 2024


https://github.com/bob80905 created https://github.com/llvm/llvm-project/pull/104239

This PR creates a new attribute in HLSL, "TextureDimension", which specifies the dimension of a specific texture resource. 
This PR is another necessary part of completing https://github.com/llvm/llvm-project/issues/98192
Tests were added that check this attribute gets properly placed in the AST, and for all currently defined resources (which have dimension equal to 1), the attribute was added to these resources with dimension equal to 1.


>From aaa455933d3703b84634703fd4fcb5c815aa139e Mon Sep 17 00:00:00 2001
From: Joshua Batista <jbatista at microsoft.com>
Date: Wed, 14 Aug 2024 14:02:22 -0700
Subject: [PATCH] create texture dimension attr

---
 clang/include/clang/Basic/Attr.td             |  8 ++++
 clang/include/clang/Sema/SemaHLSL.h           |  1 +
 clang/lib/Sema/HLSLExternalSemaSource.cpp     | 20 ++++++---
 clang/lib/Sema/SemaDeclAttr.cpp               |  3 ++
 clang/lib/Sema/SemaHLSL.cpp                   | 44 +++++++++++++++++++
 ...a-attribute-supported-attributes-list.test |  1 +
 .../hlsl_resource_handle_attrs.hlsl           |  2 +
 .../hlsl_texture_dimension_attr.hlsl          |  9 ++++
 .../hlsl_texture_dimension_attr_error.hlsl    | 22 ++++++++++
 9 files changed, 103 insertions(+), 7 deletions(-)
 create mode 100644 clang/test/ParserHLSL/hlsl_texture_dimension_attr.hlsl
 create mode 100644 clang/test/ParserHLSL/hlsl_texture_dimension_attr_error.hlsl

diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td
index 10a9d9e899e007..c61ec7e2a15305 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -4642,6 +4642,14 @@ def HLSLParamModifier : TypeAttr {
   let Args = [DefaultBoolArgument<"MergedSpelling", /*default*/0, /*fake*/1>];
 }
 
+def HLSLTextureDimension : InheritableAttr {
+  let Spellings = [CXX11<"hlsl", "texture_dimension">];
+  let Subjects = SubjectList<[Struct]>;
+  let LangOpts = [HLSL]; 
+  let Args = [IntArgument<"Dimension">];
+  let Documentation = [InternalOnly];
+}
+
 def RandomizeLayout : InheritableAttr {
   let Spellings = [GCC<"randomize_layout">];
   let Subjects = SubjectList<[Record]>;
diff --git a/clang/include/clang/Sema/SemaHLSL.h b/clang/include/clang/Sema/SemaHLSL.h
index d60cb2a57d4918..d9d4c8ed6eb00c 100644
--- a/clang/include/clang/Sema/SemaHLSL.h
+++ b/clang/include/clang/Sema/SemaHLSL.h
@@ -59,6 +59,7 @@ class SemaHLSL : public SemaBase {
   void handleROVAttr(Decl *D, const ParsedAttr &AL);
   void handleResourceClassAttr(Decl *D, const ParsedAttr &AL);
   void handleResourceBindingAttr(Decl *D, const ParsedAttr &AL);
+  void handleTextureDimensionAttr(Decl *D, const ParsedAttr &AL);
   void handleParamModifierAttr(Decl *D, const ParsedAttr &AL);
 
   bool CheckBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall);
diff --git a/clang/lib/Sema/HLSLExternalSemaSource.cpp b/clang/lib/Sema/HLSLExternalSemaSource.cpp
index 89a0e391920cc6..6ee9d9cae567da 100644
--- a/clang/lib/Sema/HLSLExternalSemaSource.cpp
+++ b/clang/lib/Sema/HLSLExternalSemaSource.cpp
@@ -107,7 +107,7 @@ struct BuiltinTypeDeclBuilder {
   }
 
   BuiltinTypeDeclBuilder &
-  addHandleMember(ResourceClass RC, ResourceKind RK, bool IsROV,
+  addHandleMember(ResourceClass RC, ResourceKind RK, bool IsROV, int TD,
                   AccessSpecifier Access = AccessSpecifier::AS_private) {
     if (Record->isCompleteDefinition())
       return *this;
@@ -125,8 +125,12 @@ struct BuiltinTypeDeclBuilder {
         HLSLResourceAttr::CreateImplicit(Record->getASTContext(), RK);
     Attr *ROVAttr =
         IsROV ? HLSLROVAttr::CreateImplicit(Record->getASTContext()) : nullptr;
-    addMemberVariable("h", Ty, {ResourceClassAttr, ResourceAttr, ROVAttr},
-                      Access);
+    Attr *TextureDimensionAttr =
+        HLSLTextureDimensionAttr::CreateImplicit(Record->getASTContext(), TD);
+    addMemberVariable(
+        "h", Ty,
+        {ResourceClassAttr, ResourceAttr, ROVAttr, TextureDimensionAttr},
+        Access);
 
     return *this;
   }
@@ -492,9 +496,9 @@ 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 IsROV, int TD) {
   return BuiltinTypeDeclBuilder(Decl)
-      .addHandleMember(RC, RK, IsROV)
+      .addHandleMember(RC, RK, IsROV, TD)
       .addDefaultHandleConstructor(S, RC);
 }
 
@@ -505,7 +509,8 @@ void HLSLExternalSemaSource::defineHLSLTypesWithForwardDeclarations() {
              .Record;
   onCompletion(Decl, [this](CXXRecordDecl *Decl) {
     setupBufferType(Decl, *SemaPtr, ResourceClass::UAV,
-                    ResourceKind::TypedBuffer, /*IsROV=*/false)
+                    ResourceKind::TypedBuffer, /*IsROV=*/false,
+                    /*TextureDimension*/ 1)
         .addArraySubscriptOperators()
         .completeDefinition();
   });
@@ -516,7 +521,8 @@ void HLSLExternalSemaSource::defineHLSLTypesWithForwardDeclarations() {
           .Record;
   onCompletion(Decl, [this](CXXRecordDecl *Decl) {
     setupBufferType(Decl, *SemaPtr, ResourceClass::UAV,
-                    ResourceKind::TypedBuffer, /*IsROV=*/true)
+                    ResourceKind::TypedBuffer, /*IsROV=*/true,
+                    /*TextureDimension*/ 1)
         .addArraySubscriptOperators()
         .completeDefinition();
   });
diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp
index 3b5e984f4ee773..9e90e16040129e 100644
--- a/clang/lib/Sema/SemaDeclAttr.cpp
+++ b/clang/lib/Sema/SemaDeclAttr.cpp
@@ -6910,6 +6910,9 @@ ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D, const ParsedAttr &AL,
   case ParsedAttr::AT_HLSLParamModifier:
     S.HLSL().handleParamModifierAttr(D, AL);
     break;
+  case ParsedAttr::AT_HLSLTextureDimension:
+    S.HLSL().handleTextureDimensionAttr(D, AL);
+    break;
 
   case ParsedAttr::AT_AbiTag:
     handleAbiTagAttr(S, D, AL);
diff --git a/clang/lib/Sema/SemaHLSL.cpp b/clang/lib/Sema/SemaHLSL.cpp
index e3e926465e799e..17f56d07f3d188 100644
--- a/clang/lib/Sema/SemaHLSL.cpp
+++ b/clang/lib/Sema/SemaHLSL.cpp
@@ -538,6 +538,50 @@ void SemaHLSL::handleParamModifierAttr(Decl *D, const ParsedAttr &AL) {
     D->addAttr(NewAttr);
 }
 
+int ConvertStrToTextureDimension(StringRef Str) {
+  // Str should be an integer between 1 and 3
+  unsigned Num;
+  if (Str.getAsInteger(10, Num))
+    return 0;
+  if (Num < 1 || Num > 3)
+    return 0;
+  return Num;
+}
+
+void SemaHLSL::handleTextureDimensionAttr(Decl *D, const ParsedAttr &AL) {
+  Expr *E = AL.getArgAsExpr(0);
+  if (!E) {
+    Diag(AL.getLoc(), diag::err_attribute_argument_type)
+        << AL << AANT_ArgumentConstantExpr;
+    return;
+  }
+
+  std::optional<llvm::APSInt> I = llvm::APSInt(64);
+  I = E->getIntegerConstantExpr(getASTContext());
+
+  int arg0;
+  if (I.has_value())
+    arg0 = I->getZExtValue();
+  else {
+
+    Diag(E->getExprLoc(), diag::err_attribute_argument_type)
+        << AL << AANT_ArgumentIntegerConstant;
+    return;
+  }
+
+  if (arg0 < 1 || arg0 > 3) {
+    Diag(E->getExprLoc(), diag::warn_attribute_type_not_supported)
+        << "TextureDimension" << arg0;
+    return;
+  }
+
+  HLSLTextureDimensionAttr *NewAttr =
+      HLSLTextureDimensionAttr::Create(getASTContext(), arg0, E->getExprLoc());
+
+  if (NewAttr)
+    D->addAttr(NewAttr);
+}
+
 namespace {
 
 /// This class implements HLSL availability diagnostics for default
diff --git a/clang/test/Misc/pragma-attribute-supported-attributes-list.test b/clang/test/Misc/pragma-attribute-supported-attributes-list.test
index 1a71556213bb16..a50b4ebbfc3ea7 100644
--- a/clang/test/Misc/pragma-attribute-supported-attributes-list.test
+++ b/clang/test/Misc/pragma-attribute-supported-attributes-list.test
@@ -83,6 +83,7 @@
 // CHECK-NEXT: HIPManaged (SubjectMatchRule_variable)
 // CHECK-NEXT: HLSLROV (SubjectMatchRule_record_not_is_union)
 // CHECK-NEXT: HLSLResourceClass (SubjectMatchRule_record_not_is_union)
+// CHECK-NEXT: HLSLTextureDimension (SubjectMatchRule_record_not_is_union)
 // CHECK-NEXT: Hot (SubjectMatchRule_function)
 // CHECK-NEXT: HybridPatchable (SubjectMatchRule_function)
 // CHECK-NEXT: IBAction (SubjectMatchRule_objc_method_is_instance)
diff --git a/clang/test/ParserHLSL/hlsl_resource_handle_attrs.hlsl b/clang/test/ParserHLSL/hlsl_resource_handle_attrs.hlsl
index 320d1160e761dd..bc9fd656fb205a 100644
--- a/clang/test/ParserHLSL/hlsl_resource_handle_attrs.hlsl
+++ b/clang/test/ParserHLSL/hlsl_resource_handle_attrs.hlsl
@@ -4,6 +4,7 @@
 // CHECK: -FieldDecl 0x{{[0-9a-f]+}} <<invalid sloc>> <invalid sloc> implicit referenced h 'float *'
 // CHECK: -HLSLResourceClassAttr 0x{{[0-9a-f]+}} <<invalid sloc>> Implicit UAV
 // CHECK: -HLSLResourceAttr 0x{{[0-9a-f]+}} <<invalid sloc>> Implicit TypedBuffer
+// CHECK: -HLSLTextureDimensionAttr 0x{{[0-9a-f]+}} <<invalid sloc>> Implicit 1
 RWBuffer<float> Buffer1;
 
 // CHECK: -ClassTemplateDecl 0x{{[0-9a-f]+}} <<invalid sloc>> <invalid sloc> implicit RasterizerOrderedBuffer
@@ -12,4 +13,5 @@ RWBuffer<float> Buffer1;
 // CHECK: -HLSLResourceClassAttr 0x{{[0-9a-f]+}} <<invalid sloc>> Implicit UAV
 // CHECK: -HLSLResourceAttr 0x{{[0-9a-f]+}} <<invalid sloc>> Implicit TypedBuffer
 // CHECK: -HLSLROVAttr 0x{{[0-9a-f]+}} <<invalid sloc>> Implicit
+// CHECK: -HLSLTextureDimensionAttr 0x{{[0-9a-f]+}} <<invalid sloc>> Implicit 1
 RasterizerOrderedBuffer<vector<float, 4> > BufferArray3[4] : register(u4, space1);
diff --git a/clang/test/ParserHLSL/hlsl_texture_dimension_attr.hlsl b/clang/test/ParserHLSL/hlsl_texture_dimension_attr.hlsl
new file mode 100644
index 00000000000000..1d6b644e943d76
--- /dev/null
+++ b/clang/test/ParserHLSL/hlsl_texture_dimension_attr.hlsl
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-compute -x hlsl -ast-dump -o - %s | FileCheck %s
+
+
+// CHECK: -HLSLTextureDimensionAttr 0x{{[0-9a-f]+}} <col:34> 1
+struct [[hlsl::texture_dimension(1)]] Eg1 {
+  int i;  
+};
+
+Eg1 e1;
diff --git a/clang/test/ParserHLSL/hlsl_texture_dimension_attr_error.hlsl b/clang/test/ParserHLSL/hlsl_texture_dimension_attr_error.hlsl
new file mode 100644
index 00000000000000..1a285ab8d0354d
--- /dev/null
+++ b/clang/test/ParserHLSL/hlsl_texture_dimension_attr_error.hlsl
@@ -0,0 +1,22 @@
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-compute -x hlsl -ast-dump -o - %s -verify
+
+// expected-error at +1{{'texture_dimension' attribute takes one argument}}
+struct [[hlsl::texture_dimension(3, 2)]] Eg1 {
+  int i;  
+};
+
+Eg1 e1;
+
+// expected-error at +1{{'texture_dimension' attribute takes one argument}}
+struct [[hlsl::texture_dimension]] Eg2 {
+  int i;  
+};
+
+Eg2 e2;
+
+// expected-error at +1{{use of undeclared identifier 'gibberish'}}
+struct [[hlsl::texture_dimension(gibberish)]] Eg3 {
+  int i;  
+};
+
+Eg2 e3;



More information about the cfe-commits mailing list