Browse Source

Support share memory struct as input call arg by copy in. (#473)

Xiang Li 8 years ago
parent
commit
a642cb002e

+ 24 - 5
tools/clang/lib/CodeGen/CGHLSLMS.cpp

@@ -5847,18 +5847,35 @@ void CGMSHLSLRuntime::EmitHLSLOutParamConversionInit(
     const std::function<void(const VarDecl *, llvm::Value *)> &TmpArgMap) {
   // Special case: skip first argument of CXXOperatorCall (it is "this").
   unsigned ArgsToSkip = isa<CXXOperatorCallExpr>(E) ? 1 : 0;
-
   for (uint32_t i = 0; i < FD->getNumParams(); i++) {
     const ParmVarDecl *Param = FD->getParamDecl(i);
     const Expr *Arg = E->getArg(i+ArgsToSkip);
     QualType ParamTy = Param->getType().getNonReferenceType();
 
-    if (!Param->isModifierOut())
-      continue;
+    if (!Param->isModifierOut()) {
+      if (!ParamTy->isAggregateType() || hlsl::IsHLSLMatType(ParamTy))
+        continue;
+    }
 
     // get original arg
     LValue argLV = CGF.EmitLValue(Arg);
 
+    if (!Param->isModifierOut()) {
+      bool isDefaultAddrSpace = true;
+      if (argLV.isSimple()) {
+        isDefaultAddrSpace =
+            argLV.getAddress()->getType()->getPointerAddressSpace() ==
+            DXIL::kDefaultAddrSpace;
+      }
+      bool isHLSLIntrinsic = false;
+      if (const FunctionDecl *Callee = E->getDirectCallee()) {
+        isHLSLIntrinsic = Callee->hasAttr<HLSLIntrinsicAttr>();
+      }
+      // Copy in arg which is not default address space and not on hlsl intrinsic.
+      if (isDefaultAddrSpace || isHLSLIntrinsic)
+        continue;
+    }
+
     // create temp Var
     VarDecl *tmpArg =
         VarDecl::Create(CGF.getContext(), const_cast<FunctionDecl *>(FD),
@@ -5902,8 +5919,10 @@ void CGMSHLSLRuntime::EmitHLSLOutParamConversionInit(
                                     CGF.getContext());
 
     // save for cast after call
-    castArgList.emplace_back(tmpLV);
-    castArgList.emplace_back(argLV);
+    if (Param->isModifierOut()) {
+      castArgList.emplace_back(tmpLV);
+      castArgList.emplace_back(argLV);
+    }
 
     bool isObject = HLModule::IsHLSLObjectType(
         tmpArgAddr->getType()->getPointerElementType());

+ 35 - 0
tools/clang/test/CodeGenHLSL/shader-compat-suite/share_mem_arg.hlsl

@@ -0,0 +1,35 @@
+// RUN: %dxc -E main -T cs_6_0 %s | FileCheck %s
+
+// Make sure different address space arg works.
+
+// CHECK: @"\01?sT@@3PAUT@@A.0" = addrspace(3) global [8 x float]
+// CHECK: @"\01?sT@@3PAUT@@A.1" = addrspace(3) global [8 x i32]
+
+struct T {
+  float a;
+  int b;
+};
+
+StructuredBuffer<T> buf;
+RWStructuredBuffer<T> buf2;
+
+T test ( T t1) {
+  T t;
+  t.a = t1.a + 1;
+  t.b = t1.b + 2;
+  return t;
+}
+
+groupshared T sT[ 8 ];
+
+
+[numthreads(8, 8, 1)]
+void main( uint3 tid : SV_DispatchThreadID) {
+  if (tid.x == 0) {
+    for (uint i=0;i<8;i++)
+      sT[i] = buf[i];
+  }
+  T t = test(sT[tid.y%8]);
+  buf2[tid.x] = t;
+}
+