浏览代码

Merged PR 24: Require payload/attribute/param structs for ray shaders. (MD CHANGE)

Require payload/attribute/param structs for ray shaders. (MD CHANGE)
Tex Riddell 7 年之前
父节点
当前提交
6e6f8dbdf6
共有 43 个文件被更改,包括 372 次插入277 次删除
  1. 6 3
      include/dxc/HLSL/DxilFunctionProps.h
  2. 17 13
      lib/HLSL/DxilMetadataHelper.cpp
  3. 2 0
      tools/clang/include/clang/AST/HlslTypes.h
  4. 34 0
      tools/clang/lib/AST/HlslTypes.cpp
  5. 75 71
      tools/clang/lib/CodeGen/CGHLSLMS.cpp
  6. 0 20
      tools/clang/test/CodeGenHLSL/quick-test/lib_anyhit_2_payload_attr.hlsl
  7. 0 12
      tools/clang/test/CodeGenHLSL/quick-test/lib_anyhit_in_payload.hlsl
  8. 0 11
      tools/clang/test/CodeGenHLSL/quick-test/lib_anyhit_inout_attr.hlsl
  9. 0 18
      tools/clang/test/CodeGenHLSL/quick-test/lib_anyhit_order.hlsl
  10. 0 11
      tools/clang/test/CodeGenHLSL/quick-test/lib_anyhit_param.hlsl
  11. 0 11
      tools/clang/test/CodeGenHLSL/quick-test/lib_callable_in.hlsl
  12. 0 22
      tools/clang/test/CodeGenHLSL/quick-test/lib_closesthit_2_payload_attr.hlsl
  13. 0 11
      tools/clang/test/CodeGenHLSL/quick-test/lib_closesthit_in_payload.hlsl
  14. 0 11
      tools/clang/test/CodeGenHLSL/quick-test/lib_closesthit_inout_attr.hlsl
  15. 0 17
      tools/clang/test/CodeGenHLSL/quick-test/lib_closesthit_order.hlsl
  16. 0 11
      tools/clang/test/CodeGenHLSL/quick-test/lib_closesthit_param.hlsl
  17. 0 12
      tools/clang/test/CodeGenHLSL/quick-test/lib_miss_2payload.hlsl
  18. 17 0
      tools/clang/test/CodeGenHLSL/quick-test/raytracing_anyhit_in_payload.hlsl
  19. 16 0
      tools/clang/test/CodeGenHLSL/quick-test/raytracing_anyhit_inout_attr.hlsl
  20. 12 0
      tools/clang/test/CodeGenHLSL/quick-test/raytracing_anyhit_no_attr.hlsl
  21. 8 0
      tools/clang/test/CodeGenHLSL/quick-test/raytracing_anyhit_no_payload.hlsl
  22. 2 3
      tools/clang/test/CodeGenHLSL/quick-test/raytracing_anyhit_out.hlsl
  23. 23 0
      tools/clang/test/CodeGenHLSL/quick-test/raytracing_anyhit_param.hlsl
  24. 1 1
      tools/clang/test/CodeGenHLSL/quick-test/raytracing_callable_2param.hlsl
  25. 7 0
      tools/clang/test/CodeGenHLSL/quick-test/raytracing_callable_in.hlsl
  26. 1 1
      tools/clang/test/CodeGenHLSL/quick-test/raytracing_callable_out.hlsl
  27. 7 7
      tools/clang/test/CodeGenHLSL/quick-test/raytracing_callable_ret.hlsl
  28. 15 0
      tools/clang/test/CodeGenHLSL/quick-test/raytracing_callable_udt.hlsl
  29. 16 0
      tools/clang/test/CodeGenHLSL/quick-test/raytracing_closesthit_in_payload.hlsl
  30. 16 0
      tools/clang/test/CodeGenHLSL/quick-test/raytracing_closesthit_inout_attr.hlsl
  31. 11 0
      tools/clang/test/CodeGenHLSL/quick-test/raytracing_closesthit_no_attr.hlsl
  32. 7 0
      tools/clang/test/CodeGenHLSL/quick-test/raytracing_closesthit_no_payload.hlsl
  33. 24 0
      tools/clang/test/CodeGenHLSL/quick-test/raytracing_closesthit_numeric.hlsl
  34. 2 3
      tools/clang/test/CodeGenHLSL/quick-test/raytracing_closesthit_out.hlsl
  35. 23 0
      tools/clang/test/CodeGenHLSL/quick-test/raytracing_closesthit_param.hlsl
  36. 1 1
      tools/clang/test/CodeGenHLSL/quick-test/raytracing_intersection_param.hlsl
  37. 1 1
      tools/clang/test/CodeGenHLSL/quick-test/raytracing_miss_extra.hlsl
  38. 1 1
      tools/clang/test/CodeGenHLSL/quick-test/raytracing_miss_in.hlsl
  39. 6 0
      tools/clang/test/CodeGenHLSL/quick-test/raytracing_miss_no_payload.hlsl
  40. 1 1
      tools/clang/test/CodeGenHLSL/quick-test/raytracing_miss_out.hlsl
  41. 8 3
      tools/clang/test/CodeGenHLSL/quick-test/raytracing_miss_ret.hlsl
  42. 11 0
      tools/clang/test/CodeGenHLSL/quick-test/raytracing_miss_udt.hlsl
  43. 1 1
      tools/clang/test/CodeGenHLSL/quick-test/raytracing_raygen_param.hlsl

+ 6 - 3
include/dxc/HLSL/DxilFunctionProps.h

@@ -58,9 +58,12 @@ struct DxilFunctionProps {
     } PS;
     } PS;
     // Ray Tracing shaders
     // Ray Tracing shaders
     struct {
     struct {
-      unsigned payloadParamCount;
-      unsigned attributeParamCount;
-    } AnyHit, ClosestHit;
+      union {
+        unsigned payloadSizeInBytes;
+        unsigned paramSizeInBytes;
+      };
+      unsigned attributeSizeInBytes;
+    } Ray;
   } ShaderProps;
   } ShaderProps;
   DXIL::ShaderKind shaderKind;
   DXIL::ShaderKind shaderKind;
   // TODO: Should we have an unmangled name here for ray tracing shaders?
   // TODO: Should we have an unmangled name here for ray tracing shaders?

+ 17 - 13
lib/HLSL/DxilMetadataHelper.cpp

@@ -957,6 +957,7 @@ Function *DxilMDHelper::LoadDxilFunctionProps(MDTuple *pProps,
   DXIL::ShaderKind shaderKind =
   DXIL::ShaderKind shaderKind =
       static_cast<DXIL::ShaderKind>(ConstMDToUint32(pProps->getOperand(idx++)));
       static_cast<DXIL::ShaderKind>(ConstMDToUint32(pProps->getOperand(idx++)));
 
 
+  bool bRayAttributes = false;
   props->shaderKind = shaderKind;
   props->shaderKind = shaderKind;
   switch (shaderKind) {
   switch (shaderKind) {
   case DXIL::ShaderKind::Compute:
   case DXIL::ShaderKind::Compute:
@@ -1008,16 +1009,16 @@ Function *DxilMDHelper::LoadDxilFunctionProps(MDTuple *pProps,
         ConstMDToUint32(pProps->getOperand(idx++));
         ConstMDToUint32(pProps->getOperand(idx++));
     break;
     break;
   case DXIL::ShaderKind::AnyHit:
   case DXIL::ShaderKind::AnyHit:
-    props->ShaderProps.AnyHit.payloadParamCount =
-      ConstMDToUint32(pProps->getOperand(idx++));
-    props->ShaderProps.AnyHit.attributeParamCount =
-      ConstMDToUint32(pProps->getOperand(idx++));
-    break;
   case DXIL::ShaderKind::ClosestHit:
   case DXIL::ShaderKind::ClosestHit:
-    props->ShaderProps.ClosestHit.payloadParamCount =
-      ConstMDToUint32(pProps->getOperand(idx++));
-    props->ShaderProps.ClosestHit.attributeParamCount =
+    bRayAttributes = true;
+  case DXIL::ShaderKind::Miss:
+  case DXIL::ShaderKind::Callable:
+    // payload/params unioned and first:
+    props->ShaderProps.Ray.payloadSizeInBytes =
       ConstMDToUint32(pProps->getOperand(idx++));
       ConstMDToUint32(pProps->getOperand(idx++));
+    if (bRayAttributes)
+      props->ShaderProps.Ray.attributeSizeInBytes =
+        ConstMDToUint32(pProps->getOperand(idx++));
     break;
     break;
   default:
   default:
     break;
     break;
@@ -1028,6 +1029,7 @@ Function *DxilMDHelper::LoadDxilFunctionProps(MDTuple *pProps,
 MDTuple *
 MDTuple *
 DxilMDHelper::EmitDxilFunctionProps(const hlsl::DxilFunctionProps *props,
 DxilMDHelper::EmitDxilFunctionProps(const hlsl::DxilFunctionProps *props,
                                     Function *F) {
                                     Function *F) {
+  bool bRayAttributes = false;
   Metadata *MDVals[30];
   Metadata *MDVals[30];
   std::fill(MDVals, MDVals + _countof(MDVals), nullptr);
   std::fill(MDVals, MDVals + _countof(MDVals), nullptr);
   unsigned valIdx = 0;
   unsigned valIdx = 0;
@@ -1071,12 +1073,14 @@ DxilMDHelper::EmitDxilFunctionProps(const hlsl::DxilFunctionProps *props,
     MDVals[valIdx++] = BoolToConstMD(props->ShaderProps.PS.EarlyDepthStencil);
     MDVals[valIdx++] = BoolToConstMD(props->ShaderProps.PS.EarlyDepthStencil);
     break;
     break;
   case DXIL::ShaderKind::AnyHit:
   case DXIL::ShaderKind::AnyHit:
-    MDVals[valIdx++] = Uint32ToConstMD(props->ShaderProps.AnyHit.payloadParamCount);
-    MDVals[valIdx++] = Uint32ToConstMD(props->ShaderProps.AnyHit.attributeParamCount);
-    break;
   case DXIL::ShaderKind::ClosestHit:
   case DXIL::ShaderKind::ClosestHit:
-    MDVals[valIdx++] = Uint32ToConstMD(props->ShaderProps.ClosestHit.payloadParamCount);
-    MDVals[valIdx++] = Uint32ToConstMD(props->ShaderProps.ClosestHit.attributeParamCount);
+    bRayAttributes = true;
+  case DXIL::ShaderKind::Miss:
+  case DXIL::ShaderKind::Callable:
+    // payload/params unioned and first:
+    MDVals[valIdx++] = Uint32ToConstMD(props->ShaderProps.Ray.payloadSizeInBytes);
+    if (bRayAttributes)
+      MDVals[valIdx++] = Uint32ToConstMD(props->ShaderProps.Ray.attributeSizeInBytes);
     break;
     break;
   default:
   default:
     break;
     break;

+ 2 - 0
tools/clang/include/clang/AST/HlslTypes.h

@@ -371,6 +371,8 @@ bool IsHLSLLineStreamType(clang::QualType type);
 bool IsHLSLTriangleStreamType(clang::QualType type);
 bool IsHLSLTriangleStreamType(clang::QualType type);
 bool IsHLSLStreamOutputType(clang::QualType type);
 bool IsHLSLStreamOutputType(clang::QualType type);
 bool IsHLSLResourceType(clang::QualType type);
 bool IsHLSLResourceType(clang::QualType type);
+bool IsHLSLNumeric(clang::QualType type);
+bool IsHLSLNumericUserDefinedType(clang::QualType type);
 clang::QualType GetHLSLResourceResultType(clang::QualType type);
 clang::QualType GetHLSLResourceResultType(clang::QualType type);
 bool IsIncompleteHLSLResourceArrayType(clang::ASTContext& context, clang::QualType type);
 bool IsIncompleteHLSLResourceArrayType(clang::ASTContext& context, clang::QualType type);
 clang::QualType GetHLSLInputPatchElementType(clang::QualType type);
 clang::QualType GetHLSLInputPatchElementType(clang::QualType type);

+ 34 - 0
tools/clang/lib/AST/HlslTypes.cpp

@@ -90,6 +90,40 @@ bool IsHLSLVecType(clang::QualType type) {
   return false;
   return false;
 }
 }
 
 
+bool IsHLSLNumeric(clang::QualType type) {
+  const clang::Type *Ty = type.getCanonicalType().getTypePtr();
+  if (isa<RecordType>(Ty)) {
+    if (IsHLSLVecMatType(type))
+      return true;
+    return IsHLSLNumericUserDefinedType(type);
+  } else if (type->isArrayType()) {
+    return IsHLSLNumeric(QualType(type->getArrayElementTypeNoTypeQual(), 0));
+  }
+  return Ty->isBuiltinType();
+}
+
+bool IsHLSLNumericUserDefinedType(clang::QualType type) {
+  const clang::Type *Ty = type.getCanonicalType().getTypePtr();
+  if (const RecordType *RT = dyn_cast<RecordType>(Ty)) {
+    const RecordDecl *RD = RT->getDecl();
+    if (isa<ClassTemplateSpecializationDecl>(RD)) {
+      return false;   // UDT are not templates
+    }
+    // TODO: avoid check by name
+    StringRef name = RD->getName();
+    if (name == "ByteAddressBuffer" ||
+        name == "RWByteAddressBuffer" ||
+        name == "RaytracingAccelerationStructure")
+      return false;
+    for (auto member : RD->fields()) {
+      if (!IsHLSLNumeric(member->getType()))
+        return false;
+    }
+    return true;
+  }
+  return false;
+}
+
 /// Checks whether the pAttributes indicate a parameter is inout or out; if
 /// Checks whether the pAttributes indicate a parameter is inout or out; if
 /// inout, pIsIn will be set to true.
 /// inout, pIsIn will be set to true.
 bool IsParamAttributedAsOut(_In_opt_ clang::AttributeList *pAttributes,
 bool IsParamAttributedAsOut(_In_opt_ clang::AttributeList *pAttributes,

+ 75 - 71
tools/clang/lib/CodeGen/CGHLSLMS.cpp

@@ -1528,9 +1528,10 @@ void CGMSHLSLRuntime::AddHLSLFunctionInfo(Function *F, const FunctionDecl *FD) {
   if (FD->hasAttr<HLSLPreciseAttr>())
   if (FD->hasAttr<HLSLPreciseAttr>())
     retTyAnnotation.SetPrecise();
     retTyAnnotation.SetPrecise();
 
 
-  // flattened parameter count for payload and attributes for AnyHit and ClosestHit shaders:
-  unsigned payloadParamCount = 0;
-  unsigned attributeParamCount = 0;
+  if (isRay) {
+    funcProps->ShaderProps.Ray.payloadSizeInBytes = 0;
+    funcProps->ShaderProps.Ray.attributeSizeInBytes = 0;
+  }
 
 
   for (; ArgNo < F->arg_size(); ++ArgNo, ++ParmIdx) {
   for (; ArgNo < F->arg_size(); ++ArgNo, ++ParmIdx) {
     DxilParameterAnnotation &paramAnnotation =
     DxilParameterAnnotation &paramAnnotation =
@@ -1705,13 +1706,6 @@ void CGMSHLSLRuntime::AddHLSLFunctionInfo(Function *F, const FunctionDecl *FD) {
 
 
     // Validate Ray Tracing function parameter (some validation may be pushed into front end)
     // Validate Ray Tracing function parameter (some validation may be pushed into front end)
     if (isRay) {
     if (isRay) {
-      StringRef semanticName;
-      unsigned int semanticIndex = 0;
-      if (paramAnnotation.HasSemanticString()) {
-        Semantic::DecomposeNameAndIndex(paramAnnotation.GetSemanticStringRef(),
-          &semanticName, &semanticIndex);
-      }
-
       switch (funcProps->shaderKind) {
       switch (funcProps->shaderKind) {
       case DXIL::ShaderKind::RayGeneration:
       case DXIL::ShaderKind::RayGeneration:
       case DXIL::ShaderKind::Intersection:
       case DXIL::ShaderKind::Intersection:
@@ -1723,59 +1717,36 @@ void CGMSHLSLRuntime::AddHLSLFunctionInfo(Function *F, const FunctionDecl *FD) {
         break;
         break;
       case DXIL::ShaderKind::AnyHit:
       case DXIL::ShaderKind::AnyHit:
       case DXIL::ShaderKind::ClosestHit:
       case DXIL::ShaderKind::ClosestHit:
-        // AnyHit & ClosestHit may have zero or one inout SV_RayPayload and
-        //  zero or one in SV_IntersectionAttributes parameters, in that order only.
-        // Number of flattened elements for each of these is stored
-        //  in payloadParamCount/attributeParamCount.
-        if (!paramAnnotation.HasSemanticString()) {
+        if (0 == ArgNo && dxilInputQ != DxilParamInputQual::Inout) {
           Diags.Report(parmDecl->getLocation(), Diags.getCustomDiagID(
           Diags.Report(parmDecl->getLocation(), Diags.getCustomDiagID(
             DiagnosticsEngine::Error,
             DiagnosticsEngine::Error,
-            "parameter must have SV_RayPayload or SV_IntersectionAttributes semantic"));
-        } else {
-          // compare semantic with allowed names and verify number is 0
-          bool bPayload = semanticName.compare_lower("sv_raypayload") == 0;
-          bool bAttr = semanticName.compare_lower("sv_intersectionattributes") == 0;
-          if (bPayload || bAttr) {
-            unsigned int &flattened =
-              bPayload ? payloadParamCount : attributeParamCount;
-            if (flattened > 0) {
-              Diags.Report(paramSemanticLoc, Diags.getCustomDiagID(
-                DiagnosticsEngine::Error, "only one %0 parameter allowed"))
-                  << (bPayload ? "ray payload" : "intersection attributes");
-            } else {
-              if (bPayload && attributeParamCount) {
-                Diags.Report(parmDecl->getLocation(), Diags.getCustomDiagID(
-                  DiagnosticsEngine::Error,
-                  "ray payload must be before intersection attributes"));
-              }
-              // TODO: count flattened elements for parameter
-              flattened = 1;  // FIX THIS
-            }
-            if (semanticIndex > 0) {
-              Diags.Report(paramSemanticLoc, Diags.getCustomDiagID(
-                DiagnosticsEngine::Error, "semantic index must be 0"));
-            }
-            if (bPayload && dxilInputQ != DxilParamInputQual::Inout) {
-              Diags.Report(parmDecl->getLocation(), Diags.getCustomDiagID(
-                DiagnosticsEngine::Error,
-                "ray payload parameter must be inout"));
-            } else if (bAttr && dxilInputQ != DxilParamInputQual::In) {
-              Diags.Report(parmDecl->getLocation(), Diags.getCustomDiagID(
-                DiagnosticsEngine::Error,
-                "intersection attributes parameter must be in"));
-            }
-          } else {
-            Diags.Report(paramSemanticLoc, Diags.getCustomDiagID(
+            "ray payload parameter must be inout"));
+        } else if (1 == ArgNo && dxilInputQ != DxilParamInputQual::In) {
+          Diags.Report(parmDecl->getLocation(), Diags.getCustomDiagID(
+            DiagnosticsEngine::Error,
+            "intersection attributes parameter must be in"));
+        } else if (ArgNo > 1) {
+          Diags.Report(parmDecl->getLocation(), Diags.getCustomDiagID(
+            DiagnosticsEngine::Error,
+            "too many parameters, expected payload and attributes parameters only."));
+        }
+        if (ArgNo < 2) {
+          if (!IsHLSLNumericUserDefinedType(parmDecl->getType())) {
+            Diags.Report(parmDecl->getLocation(), Diags.getCustomDiagID(
               DiagnosticsEngine::Error,
               DiagnosticsEngine::Error,
-              "semantic must be SV_RayPayload or SV_IntersectionAttributes"));
+              "payload and attribute structures must be user defined types with only numeric contents."));
+          } else {
+            DataLayout DL(&this->TheModule);
+            unsigned size = DL.getTypeAllocSize(F->getFunctionType()->getFunctionParamType(ArgNo));
+            if (0 == ArgNo)
+              funcProps->ShaderProps.Ray.payloadSizeInBytes = size;
+            else
+              funcProps->ShaderProps.Ray.attributeSizeInBytes = size;
           }
           }
         }
         }
         break;
         break;
       case DXIL::ShaderKind::Miss:
       case DXIL::ShaderKind::Miss:
-        // Miss shader may have zero or one inout payload param only
-        //  semantic should be SV_RayPayload
-        //  (though we could ignore semantic, leaving it optional)
-        if (ParmIdx > 0) {
+        if (ArgNo > 0) {
           Diags.Report(parmDecl->getLocation(), Diags.getCustomDiagID(
           Diags.Report(parmDecl->getLocation(), Diags.getCustomDiagID(
             DiagnosticsEngine::Error,
             DiagnosticsEngine::Error,
             "only one parameter (ray payload) allowed for miss shader"));
             "only one parameter (ray payload) allowed for miss shader"));
@@ -1784,18 +1755,20 @@ void CGMSHLSLRuntime::AddHLSLFunctionInfo(Function *F, const FunctionDecl *FD) {
             DiagnosticsEngine::Error,
             DiagnosticsEngine::Error,
             "ray payload parameter must be declared inout"));
             "ray payload parameter must be declared inout"));
         }
         }
-        if (paramAnnotation.HasSemanticString() &&
-            (semanticName.compare_lower("sv_raypayload") != 0 ||
-             semanticIndex != 0)) {
-          Diags.Report(paramSemanticLoc, Diags.getCustomDiagID(
-            DiagnosticsEngine::Error,
-            "semantic must be SV_RayPayload with optional index of 0"));
+        if (ArgNo < 1) {
+          if (!IsHLSLNumericUserDefinedType(parmDecl->getType())) {
+            Diags.Report(parmDecl->getLocation(), Diags.getCustomDiagID(
+              DiagnosticsEngine::Error,
+              "ray payload parameter must be a user defined type with only numeric contents."));
+          } else {
+            DataLayout DL(&this->TheModule);
+            unsigned size = DL.getTypeAllocSize(F->getFunctionType()->getFunctionParamType(ArgNo));
+            funcProps->ShaderProps.Ray.payloadSizeInBytes = size;
+          }
         }
         }
         break;
         break;
       case DXIL::ShaderKind::Callable:
       case DXIL::ShaderKind::Callable:
-        // Callable may have zero or one UDT parameter input
-        //  (ignore semantic if present)
-        if (ParmIdx > 0) {
+        if (ArgNo > 0) {
           Diags.Report(parmDecl->getLocation(), Diags.getCustomDiagID(
           Diags.Report(parmDecl->getLocation(), Diags.getCustomDiagID(
             DiagnosticsEngine::Error,
             DiagnosticsEngine::Error,
             "only one parameter allowed for callable shader"));
             "only one parameter allowed for callable shader"));
@@ -1804,6 +1777,17 @@ void CGMSHLSLRuntime::AddHLSLFunctionInfo(Function *F, const FunctionDecl *FD) {
             DiagnosticsEngine::Error,
             DiagnosticsEngine::Error,
             "callable parameter must be declared inout"));
             "callable parameter must be declared inout"));
         }
         }
+        if (ArgNo < 1) {
+          if (!IsHLSLNumericUserDefinedType(parmDecl->getType())) {
+            Diags.Report(parmDecl->getLocation(), Diags.getCustomDiagID(
+              DiagnosticsEngine::Error,
+              "callable parameter must be a user defined type with only numeric contents."));
+          } else {
+            DataLayout DL(&this->TheModule);
+            unsigned size = DL.getTypeAllocSize(F->getFunctionType()->getFunctionParamType(ArgNo));
+            funcProps->ShaderProps.Ray.paramSizeInBytes = size;
+          }
+        }
         break;
         break;
       }
       }
     }
     }
@@ -1826,12 +1810,32 @@ void CGMSHLSLRuntime::AddHLSLFunctionInfo(Function *F, const FunctionDecl *FD) {
     Diags.Report(FD->getLocation(), DiagID);
     Diags.Report(FD->getLocation(), DiagID);
   }
   }
 
 
-  if (funcProps->IsAnyHit()) {
-    funcProps->ShaderProps.AnyHit.payloadParamCount = payloadParamCount;
-    funcProps->ShaderProps.AnyHit.attributeParamCount = attributeParamCount;
-  } else if (funcProps->IsClosestHit()) {
-    funcProps->ShaderProps.ClosestHit.payloadParamCount = payloadParamCount;
-    funcProps->ShaderProps.ClosestHit.attributeParamCount = attributeParamCount;
+  // If Shader is a ray shader that requires parameters, make sure size is non-zero
+  if (isRay) {
+    bool bNeedsAttributes = false;
+    bool bNeedsPayload = false;
+    switch (funcProps->shaderKind) {
+    case DXIL::ShaderKind::AnyHit:
+    case DXIL::ShaderKind::ClosestHit:
+      bNeedsAttributes = true;
+    case DXIL::ShaderKind::Miss:
+      bNeedsPayload = true;
+    case DXIL::ShaderKind::Callable:
+      if (0 == funcProps->ShaderProps.Ray.payloadSizeInBytes) {
+        unsigned DiagID = bNeedsPayload ?
+          Diags.getCustomDiagID(DiagnosticsEngine::Error,
+            "shader must include inout payload structure parameter.") :
+          Diags.getCustomDiagID(DiagnosticsEngine::Error,
+            "shader must include inout parameter structure.");
+        Diags.Report(FD->getLocation(), DiagID);
+      }
+    }
+    if (bNeedsAttributes &&
+        0 == funcProps->ShaderProps.Ray.attributeSizeInBytes) {
+      Diags.Report(FD->getLocation(), Diags.getCustomDiagID(
+        DiagnosticsEngine::Error,
+        "shader must include attributes structure parameter."));
+    }
   }
   }
 
 
   // Type annotation for parameters and return type.
   // Type annotation for parameters and return type.

+ 0 - 20
tools/clang/test/CodeGenHLSL/quick-test/lib_anyhit_2_payload_attr.hlsl

@@ -1,20 +0,0 @@
-// RUN: %dxc -T lib_6_1 %s | FileCheck %s
-
-// CHECK: error: only one ray payload parameter allowed
-// CHECK: error: semantic index must be 0
-
-struct MyPayload {
-  float4 color;
-  uint2 pos;
-};
-
-struct MyAttributes {
-  float2 bary;
-  uint id;
-};
-
-[shader("anyhit")]
-void anyhit_2_payload_attr( inout MyPayload payload : SV_RayPayload,
-                      inout MyPayload payload2 : SV_RayPayload2,
-                      in MyAttributes attr : SV_IntersectionAttributes,
-                      in MyAttributes attr2 : SV_IntersectionAttributes2 ) {}

+ 0 - 12
tools/clang/test/CodeGenHLSL/quick-test/lib_anyhit_in_payload.hlsl

@@ -1,12 +0,0 @@
-// RUN: %dxc -T lib_6_1 %s | FileCheck %s
-
-// CHECK: error: ray payload parameter must be inout
-
-struct MyPayload {
-  float4 color;
-  uint2 pos;
-};
-
-[shader("anyhit")]
-void anyhit_in_payload( in MyPayload payload : SV_RayPayload ) {}
-

+ 0 - 11
tools/clang/test/CodeGenHLSL/quick-test/lib_anyhit_inout_attr.hlsl

@@ -1,11 +0,0 @@
-// RUN: %dxc -T lib_6_1 %s | FileCheck %s
-
-// CHECK: error: intersection attributes parameter must be in
-
-struct MyAttributes {
-  float2 bary;
-  uint id;
-};
-
-[shader("anyhit")]
-void anyhit_inout_attr( inout MyAttributes attr : SV_IntersectionAttributes ) {}

+ 0 - 18
tools/clang/test/CodeGenHLSL/quick-test/lib_anyhit_order.hlsl

@@ -1,18 +0,0 @@
-// RUN: %dxc -T lib_6_1 %s | FileCheck %s
-
-// CHECK: error: ray payload must be before intersection attributes
-
-struct MyPayload {
-  float4 color;
-  uint2 pos;
-};
-
-struct MyAttributes {
-  float2 bary;
-  uint id;
-};
-
-[shader("anyhit")]
-void anyhit_order( in MyAttributes attr : SV_IntersectionAttributes,
-                   inout MyPayload payload : SV_RayPayload ) {}
-

+ 0 - 11
tools/clang/test/CodeGenHLSL/quick-test/lib_anyhit_param.hlsl

@@ -1,11 +0,0 @@
-// RUN: %dxc -T lib_6_1 %s | FileCheck %s
-
-// Fine.
-[shader("anyhit")]
-void anyhit_nop() {}
-
-// CHECK: error: return type for ray tracing shaders must be void
-// CHECK: error: parameter must have SV_RayPayload or SV_IntersectionAttributes semantic
-
-[shader("anyhit")]
-float anyhit_param( in float4 extra ) { return extra.x; }

+ 0 - 11
tools/clang/test/CodeGenHLSL/quick-test/lib_callable_in.hlsl

@@ -1,11 +0,0 @@
-// RUN: %dxc -T lib_6_1 %s | FileCheck %s
-
-// CHECK: error: callable parameter must be declared inout
-
-struct MyParam {
-  float2 coord;
-  float4 output;
-};
-
-[shader("callable")]
-void callable_in( in MyParam param ) {}

+ 0 - 22
tools/clang/test/CodeGenHLSL/quick-test/lib_closesthit_2_payload_attr.hlsl

@@ -1,22 +0,0 @@
-// RUN: %dxc -T lib_6_1 %s | FileCheck %s
-
-// CHECK: error: only one ray payload parameter allowed
-// CHECK: error: semantic index must be 0
-// CHECK: error: only one intersection attributes parameter allowed
-// CHECK: error: semantic index must be 0
-
-struct MyPayload {
-  float4 color;
-  uint2 pos;
-};
-
-struct MyAttributes {
-  float2 bary;
-  uint id;
-};
-
-[shader("closesthit")]
-void closesthit_2_payload_attr( inout MyPayload payload : SV_RayPayload,
-                                inout MyPayload payload2 : SV_RayPayload2,
-                                in MyAttributes attr : SV_IntersectionAttributes,
-                                in MyAttributes attr2 : SV_IntersectionAttributes2 ) {}

+ 0 - 11
tools/clang/test/CodeGenHLSL/quick-test/lib_closesthit_in_payload.hlsl

@@ -1,11 +0,0 @@
-// RUN: %dxc -T lib_6_1 %s | FileCheck %s
-
-// CHECK: error: ray payload parameter must be inout
-
-struct MyPayload {
-  float4 color;
-  uint2 pos;
-};
-
-[shader("closesthit")]
-void closesthit_in_payload( in MyPayload payload : SV_RayPayload ) {}

+ 0 - 11
tools/clang/test/CodeGenHLSL/quick-test/lib_closesthit_inout_attr.hlsl

@@ -1,11 +0,0 @@
-// RUN: %dxc -T lib_6_1 %s | FileCheck %s
-
-// CHECK: error: intersection attributes parameter must be in
-
-struct MyAttributes {
-  float2 bary;
-  uint id;
-};
-
-[shader("closesthit")]
-void closesthit_inout_attr( inout MyAttributes attr : SV_IntersectionAttributes ) {}

+ 0 - 17
tools/clang/test/CodeGenHLSL/quick-test/lib_closesthit_order.hlsl

@@ -1,17 +0,0 @@
-// RUN: %dxc -T lib_6_1 %s | FileCheck %s
-
-// CHECK: error: ray payload must be before intersection attributes
-
-struct MyPayload {
-  float4 color;
-  uint2 pos;
-};
-
-struct MyAttributes {
-  float2 bary;
-  uint id;
-};
-
-[shader("closesthit")]
-void closesthit_order( in MyAttributes attr : SV_IntersectionAttributes,
-                       inout MyPayload payload : SV_RayPayload ) {}

+ 0 - 11
tools/clang/test/CodeGenHLSL/quick-test/lib_closesthit_param.hlsl

@@ -1,11 +0,0 @@
-// RUN: %dxc -T lib_6_1 %s | FileCheck %s
-
-// Fine.
-[shader("closesthit")]
-void closesthit_nop() {}
-
-// CHECK: error: return type for ray tracing shaders must be void
-// CHECK: error: parameter must have SV_RayPayload or SV_IntersectionAttributes semantic
-
-[shader("closesthit")]
-float closesthit_param( in float4 extra ) { return extra.x; }

+ 0 - 12
tools/clang/test/CodeGenHLSL/quick-test/lib_miss_2payload.hlsl

@@ -1,12 +0,0 @@
-// RUN: %dxc -T lib_6_1 %s | FileCheck %s
-
-// CHECK: error: only one parameter (ray payload) allowed for miss shader
-
-struct MyPayload {
-  float4 color;
-  uint2 pos;
-};
-
-[shader("miss")]
-void miss_2payload( inout MyPayload payload : SV_RayPayload,
-                    inout MyPayload payload2 : SV_RayPayload2) {}

+ 17 - 0
tools/clang/test/CodeGenHLSL/quick-test/raytracing_anyhit_in_payload.hlsl

@@ -0,0 +1,17 @@
+// RUN: %dxc -T lib_6_3 %s | FileCheck %s
+
+// CHECK: error: ray payload parameter must be inout
+
+struct MyPayload {
+  float4 color;
+  uint2 pos;
+};
+
+struct MyAttributes {
+  float2 bary;
+  uint id;
+};
+
+[shader("anyhit")]
+void anyhit_in_payload( in MyPayload payload, MyAttributes attr ) {}
+

+ 16 - 0
tools/clang/test/CodeGenHLSL/quick-test/raytracing_anyhit_inout_attr.hlsl

@@ -0,0 +1,16 @@
+// RUN: %dxc -T lib_6_3 %s | FileCheck %s
+
+// CHECK: error: intersection attributes parameter must be in
+
+struct MyPayload {
+  float4 color;
+  uint2 pos;
+};
+
+struct MyAttributes {
+  float2 bary;
+  uint id;
+};
+
+[shader("anyhit")]
+void anyhit_inout_attr( inout MyPayload payload, inout MyAttributes attr ) {}

+ 12 - 0
tools/clang/test/CodeGenHLSL/quick-test/raytracing_anyhit_no_attr.hlsl

@@ -0,0 +1,12 @@
+// RUN: %dxc -T lib_6_3 %s | FileCheck %s
+
+// CHECK: error: shader must include attributes structure parameter
+
+struct MyPayload {
+  float4 color;
+  uint2 pos;
+};
+
+[shader("anyhit")]
+void anyhit_no_attr( inout MyPayload payload ) {}
+

+ 8 - 0
tools/clang/test/CodeGenHLSL/quick-test/raytracing_anyhit_no_payload.hlsl

@@ -0,0 +1,8 @@
+// RUN: %dxc -T lib_6_3 %s | FileCheck %s
+
+// CHECK: error: shader must include inout payload structure parameter
+// CHECK: error: shader must include attributes structure parameter
+
+[shader("anyhit")]
+void anyhit_no_payload() {}
+

+ 2 - 3
tools/clang/test/CodeGenHLSL/quick-test/lib_anyhit_out.hlsl → tools/clang/test/CodeGenHLSL/quick-test/raytracing_anyhit_out.hlsl

@@ -1,4 +1,4 @@
-// RUN: %dxc -T lib_6_1 %s | FileCheck %s
+// RUN: %dxc -T lib_6_3 %s | FileCheck %s
 
 
 // CHECK: error: ray payload parameter must be inout
 // CHECK: error: ray payload parameter must be inout
 // CHECK: error: intersection attributes parameter must be in
 // CHECK: error: intersection attributes parameter must be in
@@ -14,5 +14,4 @@ struct MyAttributes {
 };
 };
 
 
 [shader("anyhit")]
 [shader("anyhit")]
-void anyhit_out( out MyPayload payload : SV_RayPayload,
-                     out MyAttributes attr : SV_IntersectionAttributes ) {}
+void anyhit_out( out MyPayload payload, out MyAttributes attr ) {}

+ 23 - 0
tools/clang/test/CodeGenHLSL/quick-test/raytracing_anyhit_param.hlsl

@@ -0,0 +1,23 @@
+// RUN: %dxc -T lib_6_3 %s | FileCheck %s
+
+struct MyPayload {
+  float4 color;
+  uint2 pos;
+};
+
+struct MyAttributes {
+  float2 bary;
+  uint id;
+};
+
+// Fine.
+[shader("anyhit")]
+void anyhit_nop( inout MyPayload payload, MyAttributes attr ) {}
+
+// CHECK: error: return type for ray tracing shaders must be void
+// CHECK: error: ray payload parameter must be inout
+// CHECK: error: payload and attribute structures must be user defined types with only numeric contents.
+// CHECK: error: payload and attribute structures must be user defined types with only numeric contents.
+
+[shader("anyhit")]
+float anyhit_param( in float4 extra, Texture2D tex0 ) { return extra.x; }

+ 1 - 1
tools/clang/test/CodeGenHLSL/quick-test/lib_callable_2param.hlsl → tools/clang/test/CodeGenHLSL/quick-test/raytracing_callable_2param.hlsl

@@ -1,4 +1,4 @@
-// RUN: %dxc -T lib_6_1 %s | FileCheck %s
+// RUN: %dxc -T lib_6_3 %s | FileCheck %s
 
 
 // CHECK: error: only one parameter allowed for callable shader
 // CHECK: error: only one parameter allowed for callable shader
 
 

+ 7 - 0
tools/clang/test/CodeGenHLSL/quick-test/raytracing_callable_in.hlsl

@@ -0,0 +1,7 @@
+// RUN: %dxc -T lib_6_3 %s | FileCheck %s
+
+// CHECK: error: callable parameter must be declared inout
+// CHECK: error: callable parameter must be a user defined type with only numeric contents.
+
+[shader("callable")]
+void callable_in( in float4x4 param ) {}

+ 1 - 1
tools/clang/test/CodeGenHLSL/quick-test/lib_callable_out.hlsl → tools/clang/test/CodeGenHLSL/quick-test/raytracing_callable_out.hlsl

@@ -1,4 +1,4 @@
-// RUN: %dxc -T lib_6_1 %s | FileCheck %s
+// RUN: %dxc -T lib_6_3 %s | FileCheck %s
 
 
 // CHECK: error: callable parameter must be declared inout
 // CHECK: error: callable parameter must be declared inout
 
 

+ 7 - 7
tools/clang/test/CodeGenHLSL/quick-test/lib_callable_ret.hlsl → tools/clang/test/CodeGenHLSL/quick-test/raytracing_callable_ret.hlsl

@@ -1,15 +1,15 @@
-// RUN: %dxc -T lib_6_1 %s | FileCheck %s
-
-// Fine.
-[shader("callable")]
-void callable_nop() {}
-
-// CHECK: error: return type for ray tracing shaders must be void
+// RUN: %dxc -T lib_6_3 %s | FileCheck %s
 
 
 struct MyParam {
 struct MyParam {
   float2 coord;
   float2 coord;
   float4 output;
   float4 output;
 };
 };
 
 
+// Fine.
+[shader("callable")]
+void callable_nop( inout MyParam param ) {}
+
+// CHECK: error: return type for ray tracing shaders must be void
+
 [shader("callable")]
 [shader("callable")]
 float callable_ret( inout MyParam param ) { return 1.0; }
 float callable_ret( inout MyParam param ) { return 1.0; }

+ 15 - 0
tools/clang/test/CodeGenHLSL/quick-test/raytracing_callable_udt.hlsl

@@ -0,0 +1,15 @@
+// RUN: %dxc -T lib_6_3 %s | FileCheck %s
+
+// CHECK: error: callable parameter must be a user defined type with only numeric contents.
+
+struct Foo {
+  float4 vec;
+  RWByteAddressBuffer buf;
+};
+
+struct MyParams {
+  Foo foo;
+};
+
+[shader("callable")]
+void callable_udt( inout MyParams param ) {}

+ 16 - 0
tools/clang/test/CodeGenHLSL/quick-test/raytracing_closesthit_in_payload.hlsl

@@ -0,0 +1,16 @@
+// RUN: %dxc -T lib_6_3 %s | FileCheck %s
+
+// CHECK: error: ray payload parameter must be inout
+
+struct MyPayload {
+  float4 color;
+  uint2 pos;
+};
+
+struct MyAttributes {
+  float2 bary;
+  uint id;
+};
+
+[shader("closesthit")]
+void closesthit_in_payload( in MyPayload payload, MyAttributes attr ) {}

+ 16 - 0
tools/clang/test/CodeGenHLSL/quick-test/raytracing_closesthit_inout_attr.hlsl

@@ -0,0 +1,16 @@
+// RUN: %dxc -T lib_6_3 %s | FileCheck %s
+
+// CHECK: error: intersection attributes parameter must be in
+
+struct MyPayload {
+  float4 color;
+  uint2 pos;
+};
+
+struct MyAttributes {
+  float2 bary;
+  uint id;
+};
+
+[shader("closesthit")]
+void closesthit_inout_attr( inout MyPayload payload, inout MyAttributes attr ) {}

+ 11 - 0
tools/clang/test/CodeGenHLSL/quick-test/raytracing_closesthit_no_attr.hlsl

@@ -0,0 +1,11 @@
+// RUN: %dxc -T lib_6_3 %s | FileCheck %s
+
+// CHECK: error: shader must include attributes structure parameter
+
+struct MyPayload {
+  float4 color;
+  uint2 pos;
+};
+
+[shader("closesthit")]
+void closesthit_no_attr( inout MyPayload payload ) {}

+ 7 - 0
tools/clang/test/CodeGenHLSL/quick-test/raytracing_closesthit_no_payload.hlsl

@@ -0,0 +1,7 @@
+// RUN: %dxc -T lib_6_3 %s | FileCheck %s
+
+// CHECK: error: shader must include inout payload structure parameter
+// CHECK: error: shader must include attributes structure parameter
+
+[shader("closesthit")]
+void closesthit_no_payload() {}

+ 24 - 0
tools/clang/test/CodeGenHLSL/quick-test/raytracing_closesthit_numeric.hlsl

@@ -0,0 +1,24 @@
+// RUN: %dxc -enable-16bit-types -T lib_6_3 %s | FileCheck %s
+
+// CHECK: define void @"\01?closesthit_numeric
+
+struct MyNumericTest {
+  float f;
+  int i;
+  uint u;
+  half h;
+  int16_t i16;
+  float2 f2;
+  double d;
+};
+
+struct MyPayload {
+  MyNumericTest t;
+};
+
+struct MyAttributes {
+  MyNumericTest t;
+};
+
+[shader("closesthit")]
+void closesthit_numeric( inout MyPayload payload, MyAttributes attr ) {}

+ 2 - 3
tools/clang/test/CodeGenHLSL/quick-test/lib_closesthit_out.hlsl → tools/clang/test/CodeGenHLSL/quick-test/raytracing_closesthit_out.hlsl

@@ -1,4 +1,4 @@
-// RUN: %dxc -T lib_6_1 %s | FileCheck %s
+// RUN: %dxc -T lib_6_3 %s | FileCheck %s
 
 
 // CHECK: error: ray payload parameter must be inout
 // CHECK: error: ray payload parameter must be inout
 // CHECK: error: intersection attributes parameter must be in
 // CHECK: error: intersection attributes parameter must be in
@@ -14,5 +14,4 @@ struct MyAttributes {
 };
 };
 
 
 [shader("closesthit")]
 [shader("closesthit")]
-void closesthit_out( out MyPayload payload : SV_RayPayload,
-                     out MyAttributes attr : SV_IntersectionAttributes ) {}
+void closesthit_out( out MyPayload payload, out MyAttributes attr ) {}

+ 23 - 0
tools/clang/test/CodeGenHLSL/quick-test/raytracing_closesthit_param.hlsl

@@ -0,0 +1,23 @@
+// RUN: %dxc -T lib_6_3 %s | FileCheck %s
+
+struct MyPayload {
+  float4 color;
+  uint2 pos;
+};
+
+struct MyAttributes {
+  float2 bary;
+  uint id;
+};
+
+// Fine.
+[shader("closesthit")]
+void closesthit_nop( inout MyPayload payload, in MyAttributes attr ) {}
+
+// CHECK: error: return type for ray tracing shaders must be void
+// CHECK: error: ray payload parameter must be inout
+// CHECK: error: payload and attribute structures must be user defined types with only numeric contents.
+// CHECK: error: payload and attribute structures must be user defined types with only numeric contents.
+
+[shader("closesthit")]
+float closesthit_param( in bool extra, RWByteAddressBuffer buf ) { return extra.x; }

+ 1 - 1
tools/clang/test/CodeGenHLSL/quick-test/lib_intersection_param.hlsl → tools/clang/test/CodeGenHLSL/quick-test/raytracing_intersection_param.hlsl

@@ -1,4 +1,4 @@
-// RUN: %dxc -T lib_6_1 %s | FileCheck %s
+// RUN: %dxc -T lib_6_3 %s | FileCheck %s
 
 
 // CHECK: error: return type for ray tracing shaders must be void
 // CHECK: error: return type for ray tracing shaders must be void
 // CHECK: error: parameters are not allowed for intersection shader
 // CHECK: error: parameters are not allowed for intersection shader

+ 1 - 1
tools/clang/test/CodeGenHLSL/quick-test/lib_miss_extra.hlsl → tools/clang/test/CodeGenHLSL/quick-test/raytracing_miss_extra.hlsl

@@ -1,4 +1,4 @@
-// RUN: %dxc -T lib_6_1 %s | FileCheck %s
+// RUN: %dxc -T lib_6_3 %s | FileCheck %s
 
 
 // CHECK: error: only one parameter (ray payload) allowed for miss shader
 // CHECK: error: only one parameter (ray payload) allowed for miss shader
 
 

+ 1 - 1
tools/clang/test/CodeGenHLSL/quick-test/lib_miss_in.hlsl → tools/clang/test/CodeGenHLSL/quick-test/raytracing_miss_in.hlsl

@@ -1,4 +1,4 @@
-// RUN: %dxc -T lib_6_1 %s | FileCheck %s
+// RUN: %dxc -T lib_6_3 %s | FileCheck %s
 
 
 // CHECK: error: ray payload parameter must be declared inout
 // CHECK: error: ray payload parameter must be declared inout
 
 

+ 6 - 0
tools/clang/test/CodeGenHLSL/quick-test/raytracing_miss_no_payload.hlsl

@@ -0,0 +1,6 @@
+// RUN: %dxc -T lib_6_3 %s | FileCheck %s
+
+// CHECK: error: shader must include inout payload structure parameter
+
+[shader("miss")]
+void miss_no_payload() {}

+ 1 - 1
tools/clang/test/CodeGenHLSL/quick-test/lib_miss_out.hlsl → tools/clang/test/CodeGenHLSL/quick-test/raytracing_miss_out.hlsl

@@ -1,4 +1,4 @@
-// RUN: %dxc -T lib_6_1 %s | FileCheck %s
+// RUN: %dxc -T lib_6_3 %s | FileCheck %s
 
 
 // CHECK: error: ray payload parameter must be declared inout
 // CHECK: error: ray payload parameter must be declared inout
 
 

+ 8 - 3
tools/clang/test/CodeGenHLSL/quick-test/lib_miss_ret.hlsl → tools/clang/test/CodeGenHLSL/quick-test/raytracing_miss_ret.hlsl

@@ -1,10 +1,15 @@
-// RUN: %dxc -T lib_6_1 %s | FileCheck %s
+// RUN: %dxc -T lib_6_3 %s | FileCheck %s
 
 
-// CHECK: error: return type for ray tracing shaders must be void
+struct MyPayload {
+  float4 color;
+  uint2 pos;
+};
 
 
 // Fine.
 // Fine.
 [shader("miss")]
 [shader("miss")]
-void miss_nop() {}
+void miss_nop( inout MyPayload payload ) {}
+
+// CHECK: error: return type for ray tracing shaders must be void
 
 
 [shader("miss")]
 [shader("miss")]
 float miss_ret() { return 1.0; }
 float miss_ret() { return 1.0; }

+ 11 - 0
tools/clang/test/CodeGenHLSL/quick-test/raytracing_miss_udt.hlsl

@@ -0,0 +1,11 @@
+// RUN: %dxc -T lib_6_3 %s | FileCheck %s
+
+// CHECK: error: ray payload parameter must be a user defined type with only numeric contents.
+
+struct MyPayload {
+  float4 color;
+  uint2 pos;
+};
+
+[shader("miss")]
+void miss_udt( inout PointStream<MyPayload> payload ) {}

+ 1 - 1
tools/clang/test/CodeGenHLSL/quick-test/lib_raygen_param.hlsl → tools/clang/test/CodeGenHLSL/quick-test/raytracing_raygen_param.hlsl

@@ -1,4 +1,4 @@
-// RUN: %dxc -T lib_6_1 %s | FileCheck %s
+// RUN: %dxc -T lib_6_3 %s | FileCheck %s
 
 
 // CHECK: error: return type for ray tracing shaders must be void
 // CHECK: error: return type for ray tracing shaders must be void
 // CHECK: error: parameters are not allowed for raygeneration shader
 // CHECK: error: parameters are not allowed for raygeneration shader