Browse Source

Support SV_RayPayload and SV_IntersectionAttributes

Tex Riddell 7 years ago
parent
commit
9a3bbb6603
27 changed files with 458 additions and 9 deletions
  1. 12 0
      include/dxc/HLSL/DxilFunctionProps.h
  2. 20 0
      lib/HLSL/DxilMetadataHelper.cpp
  3. 121 6
      tools/clang/lib/CodeGen/CGHLSLMS.cpp
  4. 20 0
      tools/clang/test/CodeGenHLSL/quick-test/lib_anyhit_2_payload_attr.hlsl
  5. 12 0
      tools/clang/test/CodeGenHLSL/quick-test/lib_anyhit_in_payload.hlsl
  6. 11 0
      tools/clang/test/CodeGenHLSL/quick-test/lib_anyhit_inout_attr.hlsl
  7. 18 0
      tools/clang/test/CodeGenHLSL/quick-test/lib_anyhit_order.hlsl
  8. 18 0
      tools/clang/test/CodeGenHLSL/quick-test/lib_anyhit_out.hlsl
  9. 11 0
      tools/clang/test/CodeGenHLSL/quick-test/lib_anyhit_param.hlsl
  10. 12 0
      tools/clang/test/CodeGenHLSL/quick-test/lib_callable_2param.hlsl
  11. 11 0
      tools/clang/test/CodeGenHLSL/quick-test/lib_callable_in.hlsl
  12. 11 0
      tools/clang/test/CodeGenHLSL/quick-test/lib_callable_out.hlsl
  13. 15 0
      tools/clang/test/CodeGenHLSL/quick-test/lib_callable_ret.hlsl
  14. 22 0
      tools/clang/test/CodeGenHLSL/quick-test/lib_closesthit_2_payload_attr.hlsl
  15. 11 0
      tools/clang/test/CodeGenHLSL/quick-test/lib_closesthit_in_payload.hlsl
  16. 11 0
      tools/clang/test/CodeGenHLSL/quick-test/lib_closesthit_inout_attr.hlsl
  17. 17 0
      tools/clang/test/CodeGenHLSL/quick-test/lib_closesthit_order.hlsl
  18. 18 0
      tools/clang/test/CodeGenHLSL/quick-test/lib_closesthit_out.hlsl
  19. 11 0
      tools/clang/test/CodeGenHLSL/quick-test/lib_closesthit_param.hlsl
  20. 10 0
      tools/clang/test/CodeGenHLSL/quick-test/lib_intersection_param.hlsl
  21. 12 0
      tools/clang/test/CodeGenHLSL/quick-test/lib_miss_2payload.hlsl
  22. 12 0
      tools/clang/test/CodeGenHLSL/quick-test/lib_miss_extra.hlsl
  23. 11 0
      tools/clang/test/CodeGenHLSL/quick-test/lib_miss_in.hlsl
  24. 11 0
      tools/clang/test/CodeGenHLSL/quick-test/lib_miss_out.hlsl
  25. 10 0
      tools/clang/test/CodeGenHLSL/quick-test/lib_miss_ret.hlsl
  26. 10 0
      tools/clang/test/CodeGenHLSL/quick-test/lib_raygen_param.hlsl
  27. 0 3
      tools/clang/test/CodeGenHLSL/quick-test/lib_rt.hlsl

+ 12 - 0
include/dxc/HLSL/DxilFunctionProps.h

@@ -56,8 +56,14 @@ struct DxilFunctionProps {
     struct {
     struct {
       bool EarlyDepthStencil;
       bool EarlyDepthStencil;
     } PS;
     } PS;
+    // Ray Tracing shaders
+    struct {
+      unsigned payloadParamCount;
+      unsigned attributeParamCount;
+    } AnyHit, ClosestHit;
   } ShaderProps;
   } ShaderProps;
   DXIL::ShaderKind shaderKind;
   DXIL::ShaderKind shaderKind;
+  // TODO: Should we have an unmangled name here for ray tracing shaders?
   bool IsPS() const     { return shaderKind == DXIL::ShaderKind::Pixel; }
   bool IsPS() const     { return shaderKind == DXIL::ShaderKind::Pixel; }
   bool IsVS() const     { return shaderKind == DXIL::ShaderKind::Vertex; }
   bool IsVS() const     { return shaderKind == DXIL::ShaderKind::Vertex; }
   bool IsGS() const     { return shaderKind == DXIL::ShaderKind::Geometry; }
   bool IsGS() const     { return shaderKind == DXIL::ShaderKind::Geometry; }
@@ -67,6 +73,12 @@ struct DxilFunctionProps {
   bool IsGraphics() const {
   bool IsGraphics() const {
     return (shaderKind >= DXIL::ShaderKind::Pixel && shaderKind <= DXIL::ShaderKind::Domain);
     return (shaderKind >= DXIL::ShaderKind::Pixel && shaderKind <= DXIL::ShaderKind::Domain);
   }
   }
+  bool IsRayGeneration() const { return shaderKind == DXIL::ShaderKind::RayGeneration; }
+  bool IsIntersection() const { return shaderKind == DXIL::ShaderKind::Intersection; }
+  bool IsAnyHit() const { return shaderKind == DXIL::ShaderKind::AnyHit; }
+  bool IsClosestHit() const { return shaderKind == DXIL::ShaderKind::ClosestHit; }
+  bool IsMiss() const { return shaderKind == DXIL::ShaderKind::Miss; }
+  bool IsCallable() const { return shaderKind == DXIL::ShaderKind::Callable; }
   bool IsRay() const {
   bool IsRay() const {
     return (shaderKind >= DXIL::ShaderKind::RayGeneration && shaderKind <= DXIL::ShaderKind::Callable);
     return (shaderKind >= DXIL::ShaderKind::RayGeneration && shaderKind <= DXIL::ShaderKind::Callable);
   }
   }

+ 20 - 0
lib/HLSL/DxilMetadataHelper.cpp

@@ -1006,6 +1006,18 @@ Function *DxilMDHelper::LoadDxilFunctionProps(MDTuple *pProps,
     props->ShaderProps.PS.EarlyDepthStencil =
     props->ShaderProps.PS.EarlyDepthStencil =
         ConstMDToUint32(pProps->getOperand(idx++));
         ConstMDToUint32(pProps->getOperand(idx++));
     break;
     break;
+  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:
+    props->ShaderProps.ClosestHit.payloadParamCount =
+      ConstMDToUint32(pProps->getOperand(idx++));
+    props->ShaderProps.ClosestHit.attributeParamCount =
+      ConstMDToUint32(pProps->getOperand(idx++));
+    break;
   default:
   default:
     break;
     break;
   }
   }
@@ -1057,6 +1069,14 @@ DxilMDHelper::EmitDxilFunctionProps(const hlsl::DxilFunctionProps *props,
   case DXIL::ShaderKind::Pixel:
   case DXIL::ShaderKind::Pixel:
     MDVals[valIdx++] = BoolToConstMD(props->ShaderProps.PS.EarlyDepthStencil);
     MDVals[valIdx++] = BoolToConstMD(props->ShaderProps.PS.EarlyDepthStencil);
     break;
     break;
+  case DXIL::ShaderKind::AnyHit:
+    MDVals[valIdx++] = Uint32ToConstMD(props->ShaderProps.AnyHit.payloadParamCount);
+    MDVals[valIdx++] = Uint32ToConstMD(props->ShaderProps.AnyHit.attributeParamCount);
+    break;
+  case DXIL::ShaderKind::ClosestHit:
+    MDVals[valIdx++] = Uint32ToConstMD(props->ShaderProps.ClosestHit.payloadParamCount);
+    MDVals[valIdx++] = Uint32ToConstMD(props->ShaderProps.ClosestHit.attributeParamCount);
+    break;
   default:
   default:
     break;
     break;
   }
   }

+ 121 - 6
tools/clang/lib/CodeGen/CGHLSLMS.cpp

@@ -1512,11 +1512,19 @@ void CGMSHLSLRuntime::AddHLSLFunctionInfo(Function *F, const FunctionDecl *FD) {
     CheckParameterAnnotation(retTySemanticLoc, retTyAnnotation,
     CheckParameterAnnotation(retTySemanticLoc, retTyAnnotation,
                              /*isPatchConstantFunction*/ false);
                              /*isPatchConstantFunction*/ false);
   }
   }
+  if (isRay && !retTy->isVoidType()) {
+    Diags.Report(FD->getLocation(), Diags.getCustomDiagID(
+      DiagnosticsEngine::Error, "return type for ray tracing shaders must be void"));
+  }
 
 
   ConstructFieldAttributedAnnotation(retTyAnnotation, retTy, bDefaultRowMajor);
   ConstructFieldAttributedAnnotation(retTyAnnotation, retTy, bDefaultRowMajor);
   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;
+
   for (; ArgNo < F->arg_size(); ++ArgNo, ++ParmIdx) {
   for (; ArgNo < F->arg_size(); ++ArgNo, ++ParmIdx) {
     DxilParameterAnnotation &paramAnnotation =
     DxilParameterAnnotation &paramAnnotation =
         FuncAnnotation->GetParameterAnnotation(ArgNo);
         FuncAnnotation->GetParameterAnnotation(ArgNo);
@@ -1617,7 +1625,6 @@ void CGMSHLSLRuntime::AddHLSLFunctionInfo(Function *F, const FunctionDecl *FD) {
             funcProps->ShaderProps.GS.streamPrimitiveTopologies[0] ==
             funcProps->ShaderProps.GS.streamPrimitiveTopologies[0] ==
                 DXIL::PrimitiveTopology::PointList;
                 DXIL::PrimitiveTopology::PointList;
         if (!bAllPoint) {
         if (!bAllPoint) {
-          DiagnosticsEngine &Diags = CGM.getDiags();
           unsigned DiagID = Diags.getCustomDiagID(
           unsigned DiagID = Diags.getCustomDiagID(
               DiagnosticsEngine::Error, "when multiple GS output streams are "
               DiagnosticsEngine::Error, "when multiple GS output streams are "
                                         "used they must be pointlists.");
                                         "used they must be pointlists.");
@@ -1653,7 +1660,6 @@ void CGMSHLSLRuntime::AddHLSLFunctionInfo(Function *F, const FunctionDecl *FD) {
           DXIL::InputPrimitive::Undefined) {
           DXIL::InputPrimitive::Undefined) {
         funcProps->ShaderProps.GS.inputPrimitive = inputPrimitive;
         funcProps->ShaderProps.GS.inputPrimitive = inputPrimitive;
       } else if (funcProps->ShaderProps.GS.inputPrimitive != inputPrimitive) {
       } else if (funcProps->ShaderProps.GS.inputPrimitive != inputPrimitive) {
-        DiagnosticsEngine &Diags = CGM.getDiags();
         unsigned DiagID = Diags.getCustomDiagID(
         unsigned DiagID = Diags.getCustomDiagID(
             DiagnosticsEngine::Error, "input parameter conflicts with geometry "
             DiagnosticsEngine::Error, "input parameter conflicts with geometry "
                                       "specifier of previous input parameters");
                                       "specifier of previous input parameters");
@@ -1664,7 +1670,6 @@ void CGMSHLSLRuntime::AddHLSLFunctionInfo(Function *F, const FunctionDecl *FD) {
     if (GsInputArrayDim != 0) {
     if (GsInputArrayDim != 0) {
       QualType Ty = parmDecl->getType();
       QualType Ty = parmDecl->getType();
       if (!Ty->isConstantArrayType()) {
       if (!Ty->isConstantArrayType()) {
-        DiagnosticsEngine &Diags = CGM.getDiags();
         unsigned DiagID = Diags.getCustomDiagID(
         unsigned DiagID = Diags.getCustomDiagID(
             DiagnosticsEngine::Error,
             DiagnosticsEngine::Error,
             "input types for geometry shader must be constant size arrays");
             "input types for geometry shader must be constant size arrays");
@@ -1683,7 +1688,6 @@ void CGMSHLSLRuntime::AddHLSLFunctionInfo(Function *F, const FunctionDecl *FD) {
           };
           };
           DXASSERT(GsInputArrayDim < llvm::array_lengthof(primtiveNames),
           DXASSERT(GsInputArrayDim < llvm::array_lengthof(primtiveNames),
                    "Invalid array dim");
                    "Invalid array dim");
-          DiagnosticsEngine &Diags = CGM.getDiags();
           unsigned DiagID = Diags.getCustomDiagID(
           unsigned DiagID = Diags.getCustomDiagID(
               DiagnosticsEngine::Error, "array dimension for %0 must be %1");
               DiagnosticsEngine::Error, "array dimension for %0 must be %1");
           Diags.Report(parmDecl->getLocation(), DiagID)
           Diags.Report(parmDecl->getLocation(), DiagID)
@@ -1692,6 +1696,111 @@ void CGMSHLSLRuntime::AddHLSLFunctionInfo(Function *F, const FunctionDecl *FD) {
       }
       }
     }
     }
 
 
+    // Validate Ray Tracing function parameter (some validation may be pushed into front end)
+    if (isRay) {
+      StringRef semanticName;
+      unsigned int semanticIndex = 0;
+      if (paramAnnotation.HasSemanticString()) {
+        Semantic::DecomposeNameAndIndex(paramAnnotation.GetSemanticStringRef(),
+          &semanticName, &semanticIndex);
+      }
+
+      switch (funcProps->shaderKind) {
+      case DXIL::ShaderKind::RayGeneration:
+      case DXIL::ShaderKind::Intersection:
+        // RayGeneration and Intersection shaders are not allowed to have any input parameters
+        Diags.Report(parmDecl->getLocation(), Diags.getCustomDiagID(
+          DiagnosticsEngine::Error, "parameters are not allowed for %0 shader"))
+            << (funcProps->shaderKind == DXIL::ShaderKind::RayGeneration ?
+                "raygeneration" : "intersection");
+        break;
+      case DXIL::ShaderKind::AnyHit:
+      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()) {
+          Diags.Report(parmDecl->getLocation(), Diags.getCustomDiagID(
+            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(
+              DiagnosticsEngine::Error,
+              "semantic must be SV_RayPayload or SV_IntersectionAttributes"));
+          }
+        }
+        break;
+      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) {
+          Diags.Report(parmDecl->getLocation(), Diags.getCustomDiagID(
+            DiagnosticsEngine::Error,
+            "only one parameter (ray payload) allowed for miss shader"));
+        } else if (dxilInputQ != DxilParamInputQual::Inout) {
+          Diags.Report(parmDecl->getLocation(), Diags.getCustomDiagID(
+            DiagnosticsEngine::Error,
+            "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"));
+        }
+        break;
+      case DXIL::ShaderKind::Callable:
+        // Callable may have zero or one UDT parameter input
+        //  (ignore semantic if present)
+        if (ParmIdx > 0) {
+          Diags.Report(parmDecl->getLocation(), Diags.getCustomDiagID(
+            DiagnosticsEngine::Error,
+            "only one parameter allowed for callable shader"));
+        } else if (dxilInputQ != DxilParamInputQual::Inout) {
+          Diags.Report(parmDecl->getLocation(), Diags.getCustomDiagID(
+            DiagnosticsEngine::Error,
+            "callable parameter must be declared inout"));
+        }
+        break;
+      }
+    }
+
     paramAnnotation.SetParamInputQual(dxilInputQ);
     paramAnnotation.SetParamInputQual(dxilInputQ);
     if (isEntry) {
     if (isEntry) {
       CheckParameterAnnotation(paramSemanticLoc, paramAnnotation,
       CheckParameterAnnotation(paramSemanticLoc, paramAnnotation,
@@ -1700,18 +1809,24 @@ void CGMSHLSLRuntime::AddHLSLFunctionInfo(Function *F, const FunctionDecl *FD) {
   }
   }
 
 
   if (inputPatchCount > 1) {
   if (inputPatchCount > 1) {
-    DiagnosticsEngine &Diags = CGM.getDiags();
     unsigned DiagID = Diags.getCustomDiagID(
     unsigned DiagID = Diags.getCustomDiagID(
         DiagnosticsEngine::Error, "may only have one InputPatch parameter");
         DiagnosticsEngine::Error, "may only have one InputPatch parameter");
     Diags.Report(FD->getLocation(), DiagID);
     Diags.Report(FD->getLocation(), DiagID);
   }
   }
   if (outputPatchCount > 1) {
   if (outputPatchCount > 1) {
-    DiagnosticsEngine &Diags = CGM.getDiags();
     unsigned DiagID = Diags.getCustomDiagID(
     unsigned DiagID = Diags.getCustomDiagID(
         DiagnosticsEngine::Error, "may only have one OutputPatch parameter");
         DiagnosticsEngine::Error, "may only have one OutputPatch parameter");
     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;
+  }
+
   // Type annotation for parameters and return type.
   // Type annotation for parameters and return type.
   DxilTypeSystem &dxilTypeSys = m_pHLModule->GetTypeSystem();
   DxilTypeSystem &dxilTypeSys = m_pHLModule->GetTypeSystem();
   unsigned arrayEltSize = 0;
   unsigned arrayEltSize = 0;

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

@@ -0,0 +1,20 @@
+// 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 ) {}

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

@@ -0,0 +1,12 @@
+// 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 ) {}
+

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

@@ -0,0 +1,11 @@
+// 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 ) {}

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

@@ -0,0 +1,18 @@
+// 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 ) {}
+

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

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

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

@@ -0,0 +1,11 @@
+// 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; }

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

@@ -0,0 +1,12 @@
+// RUN: %dxc -T lib_6_1 %s | FileCheck %s
+
+// CHECK: error: only one parameter allowed for callable shader
+
+struct MyParam {
+  float2 coord;
+  float4 output;
+};
+
+[shader("callable")]
+void callable_2param( inout MyParam param,
+                      inout MyParam param2 ) {}

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

@@ -0,0 +1,11 @@
+// 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 ) {}

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

@@ -0,0 +1,11 @@
+// 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_out( out MyParam param ) { param = (MyParam)0; }

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

@@ -0,0 +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
+
+struct MyParam {
+  float2 coord;
+  float4 output;
+};
+
+[shader("callable")]
+float callable_ret( inout MyParam param ) { return 1.0; }

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

@@ -0,0 +1,22 @@
+// 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 ) {}

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

@@ -0,0 +1,11 @@
+// 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 ) {}

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

@@ -0,0 +1,11 @@
+// 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 ) {}

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

@@ -0,0 +1,17 @@
+// 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 ) {}

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

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

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

@@ -0,0 +1,11 @@
+// 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; }

+ 10 - 0
tools/clang/test/CodeGenHLSL/quick-test/lib_intersection_param.hlsl

@@ -0,0 +1,10 @@
+// RUN: %dxc -T lib_6_1 %s | FileCheck %s
+
+// CHECK: error: return type for ray tracing shaders must be void
+// CHECK: error: parameters are not allowed for intersection shader
+
+[shader("intersection")]
+float intersection_param(float4 extra)
+{
+  return extra.x;
+}

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

@@ -0,0 +1,12 @@
+// 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) {}

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

@@ -0,0 +1,12 @@
+// 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_extra( inout MyPayload payload : SV_RayPayload,
+                 float extra) {}

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

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

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

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

+ 10 - 0
tools/clang/test/CodeGenHLSL/quick-test/lib_miss_ret.hlsl

@@ -0,0 +1,10 @@
+// RUN: %dxc -T lib_6_1 %s | FileCheck %s
+
+// CHECK: error: return type for ray tracing shaders must be void
+
+// Fine.
+[shader("miss")]
+void miss_nop() {}
+
+[shader("miss")]
+float miss_ret() { return 1.0; }

+ 10 - 0
tools/clang/test/CodeGenHLSL/quick-test/lib_raygen_param.hlsl

@@ -0,0 +1,10 @@
+// RUN: %dxc -T lib_6_1 %s | FileCheck %s
+
+// CHECK: error: return type for ray tracing shaders must be void
+// CHECK: error: parameters are not allowed for raygeneration shader
+
+[shader("raygeneration")]
+float raygen_param(float4 extra)
+{
+  return extra.x;
+}

+ 0 - 3
tools/clang/test/CodeGenHLSL/quick-test/lib_rt.hlsl

@@ -16,9 +16,6 @@ typedef uint RAY_FLAG;
 #define RAY_FLAG_CULL_OPAQUE                  0x40
 #define RAY_FLAG_CULL_OPAQUE                  0x40
 #define RAY_FLAG_CULL_NON_OPAQUE              0x80
 #define RAY_FLAG_CULL_NON_OPAQUE              0x80
 
 
-#define SV_RayPayload RT_RayPayload
-#define SV_IntersectionAttributes RT_IntersectionAttributes
-
 struct RayDesc
 struct RayDesc
 {
 {
     float3 Origin;
     float3 Origin;