Sfoglia il codice sorgente

Require ConstantBuffer/TextureBuffer arguments to be structs (#1177)

fxc errors out if the template argument for ConstantBuffer or
TextureBuffer is not a struct type with "D3D12 constant/texture
buffer template element can only be a struct". This commit
enforces that behavior on dxc.
Lei Zhang 7 anni fa
parent
commit
18f9bea95e

+ 2 - 0
tools/clang/include/clang/Basic/DiagnosticSemaKinds.td

@@ -7510,6 +7510,8 @@ def err_hlsl_typeintemplateargument : Error<
   "%0 cannot be used as a type parameter">;
 def err_hlsl_typeintemplateargument_requires_scalar : Error<
   "%0 cannot be used as a type parameter where a scalar is required">;
+def err_hlsl_typeintemplateargument_requires_struct : Error<
+  "%0 cannot be used as a type parameter where a struct is required">;
 def err_hlsl_type_mismatch : Error<
   "type mismatch">;
 def err_hlsl_unsupported_array_equality_op: Error<

+ 6 - 2
tools/clang/lib/Sema/SemaHLSL.cpp

@@ -10682,8 +10682,12 @@ Decl *Sema::ActOnHLSLBufferView(Scope *bufferScope, SourceLocation KwLoc,
     const ArrayType *arrayType = declType->getAsArrayTypeUnsafe();
     declType = arrayType->getElementType();
   }
-  if (declType->isArrayType()) {
-    Diag(Loc, diag::err_hlsl_typeintemplateargument) << "array";
+  // Check to make that sure only structs are allowed as parameter types for
+  // ConstantBuffer and TextureBuffer.
+  if (!declType->isStructureType()) {
+    Diag(decl->getLocStart(),
+         diag::err_hlsl_typeintemplateargument_requires_struct)
+        << declType;
     return nullptr;
   }
 

+ 25 - 0
tools/clang/test/CodeGenHLSL/cbuffer-struct.hlsl

@@ -0,0 +1,25 @@
+// RUN: %dxc -E main -T ps_6_0 %s  | FileCheck %s
+
+class C {
+    float4 f;
+};
+
+struct S {
+    float4 f;
+};
+
+// CHECK: error: 'const int' cannot be used as a type parameter where a struct is required
+ConstantBuffer<int>      B1;
+// CHECK: error: 'const float2' cannot be used as a type parameter where a struct is required
+TextureBuffer<float2>    B2;
+// CHECK: error: 'const float3x4' cannot be used as a type parameter where a struct is required
+ConstantBuffer<float3x4> B3;
+// CHECK: error: 'const C' cannot be used as a type parameter where a struct is required
+TextureBuffer<C>         B4;
+// CHECK-NOT: const S
+ConstantBuffer<S>        B5;
+TextureBuffer<S>         B6[6];
+
+float4 main(int a : A) : SV_Target {
+  return B4.f;
+}

+ 3 - 3
tools/clang/test/CodeGenHLSL/cbuffer-structarray.hlsl

@@ -6,12 +6,12 @@ struct Foo {
 
 typedef Foo FooA[2];
 
-// CHECK: error: array cannot be used as a type parameter
+// CHECK: error: 'const FooA' (aka 'Foo const[2]') cannot be used as a type parameter where a struct is required
 ConstantBuffer<FooA> CB1;
 
-// CHECK: error: array cannot be used as a type parameter
+// CHECK: error: 'const FooA' (aka 'Foo const[2]') cannot be used as a type parameter where a struct is required
 ConstantBuffer<FooA> CB[4][3];
-// CHECK: error: array cannot be used as a type parameter
+// CHECK: error: 'const FooA' (aka 'Foo const[2]') cannot be used as a type parameter where a struct is required
 TextureBuffer<FooA> TB[4][3];
 
 float4 main(int a : A) : SV_Target

+ 5 - 0
tools/clang/unittests/HLSL/CompilerTest.cpp

@@ -937,6 +937,7 @@ public:
   TEST_METHOD(CodeGenRootSigDefine9)
   TEST_METHOD(CodeGenRootSigDefine10)
   TEST_METHOD(CodeGenRootSigDefine11)
+  TEST_METHOD(CodeGenCBufferStruct)
   TEST_METHOD(CodeGenCBufferStructArray)
   TEST_METHOD(CodeGenPatchLength)
   TEST_METHOD(PreprocessWhenValidThenOK)
@@ -5079,6 +5080,10 @@ TEST_F(CompilerTest, CodeGenRootSigDefine11) {
   CodeGenTestCheck(L"..\\CodeGenHLSL\\rootSigDefine11.hlsl");
 }
 
+TEST_F(CompilerTest, CodeGenCBufferStruct) {
+  CodeGenTestCheck(L"..\\CodeGenHLSL\\cbuffer-struct.hlsl");
+}
+
 TEST_F(CompilerTest, CodeGenCBufferStructArray) {
   CodeGenTestCheck(L"..\\CodeGenHLSL\\cbuffer-structarray.hlsl");
 }