Browse Source

[spirv] Handle function definitions in cbuffer/tbuffer (#1015)

These function definitions are like normal file-scope ones.
Lei Zhang 7 years ago
parent
commit
878441553f

+ 6 - 4
tools/clang/lib/SPIRV/DeclResultIdMapper.cpp

@@ -452,8 +452,9 @@ uint32_t DeclResultIdMapper::createVarOfExplicitLayoutStruct(
   uint32_t fieldIndex = 0;
   for (const auto *subDecl : decl->decls()) {
     // Ignore implicit generated struct declarations/constructors/destructors.
-    // Ignore embedded struct/union/class/enum decls.
-    if (subDecl->isImplicit() || isa<TagDecl>(subDecl))
+    // Ignore embedded struct/union/class/enum/function decls.
+    if (subDecl->isImplicit() || isa<TagDecl>(subDecl) ||
+        isa<FunctionDecl>(subDecl))
       continue;
 
     // The field can only be FieldDecl (for normal structs) or VarDecl (for
@@ -509,8 +510,9 @@ uint32_t DeclResultIdMapper::createCTBuffer(const HLSLBufferDecl *decl) {
   int index = 0;
   for (const auto *subDecl : decl->decls()) {
     // Ignore implicit generated struct declarations/constructors/destructors.
-    // Ignore embedded struct/union/class/enum decls.
-    if (subDecl->isImplicit() || isa<TagDecl>(subDecl))
+    // Ignore embedded struct/union/class/enum/function decls.
+    if (subDecl->isImplicit() || isa<TagDecl>(subDecl) ||
+        isa<FunctionDecl>(subDecl))
       continue;
 
     const auto *varDecl = cast<VarDecl>(subDecl);

+ 2 - 2
tools/clang/lib/SPIRV/TypeTranslator.cpp

@@ -800,8 +800,8 @@ TypeTranslator::getLayoutDecorations(const DeclContext *decl, LayoutRule rule) {
 
   for (const auto *field : decl->decls()) {
     // Ignore implicit generated struct declarations/constructors/destructors.
-    // Ignore embedded struct/union/class/enum decls.
-    if (field->isImplicit() || isa<TagDecl>(field))
+    // Ignore embedded struct/union/class/enum/function decls.
+    if (field->isImplicit() || isa<TagDecl>(field) || isa<FunctionDecl>(field))
       continue;
 
     // The field can only be FieldDecl (for normal structs) or VarDecl (for

+ 23 - 0
tools/clang/test/CodeGenSPIRV/fn.ctbuffer.hlsl

@@ -0,0 +1,23 @@
+// Run: %dxc -T ps_6_0 -E main
+
+// CHECK: %type_MyCBuffer = OpTypeStruct %v4float
+// CHECK: %type_MyTBuffer = OpTypeStruct %float
+cbuffer MyCBuffer {
+    float4 cb_val;
+
+// CHECK:      %get_cb_val = OpFunction %v4float None {{%\d+}}
+// CHECK:         {{%\d+}} = OpAccessChain %_ptr_Uniform_v4float %var_MyCBuffer %int_0
+    float4 get_cb_val() { return cb_val; }
+}
+
+tbuffer MyTBuffer {
+    float tb_val;
+
+// CHECK:      %get_tb_val = OpFunction %float None {{%\d+}}
+// CHECK:         {{%\d+}} = OpAccessChain %_ptr_Uniform_float %var_MyTBuffer %int_0
+    float get_tb_val() { return tb_val; }
+}
+
+float4 main() : SV_Target {
+    return get_cb_val() * get_tb_val();
+}

+ 1 - 0
tools/clang/unittests/SPIRV/CodeGenSPIRVTest.cpp

@@ -390,6 +390,7 @@ TEST_F(FileTest, FunctionInOutParamVector) {
 TEST_F(FileTest, FunctionFowardDeclaration) {
   runFileTest("fn.foward-declaration.hlsl");
 }
+TEST_F(FileTest, FunctionInCTBuffer) { runFileTest("fn.ctbuffer.hlsl"); }
 
 // For OO features
 TEST_F(FileTest, StructMethodCall) { runFileTest("oo.struct.method.hlsl"); }