Browse Source

Implement -export-shaders-only

Tex Riddell 7 years ago
parent
commit
2d8c68a055

+ 1 - 0
include/dxc/Support/HLSLOptions.h

@@ -156,6 +156,7 @@ public:
   bool DisaseembleHex = false; //OPT_Lx
   bool DisaseembleHex = false; //OPT_Lx
   bool LegacyMacroExpansion = false; // OPT_flegacy_macro_expansion
   bool LegacyMacroExpansion = false; // OPT_flegacy_macro_expansion
   unsigned long AutoBindingSpace = UINT_MAX; // OPT_auto_binding_space
   unsigned long AutoBindingSpace = UINT_MAX; // OPT_auto_binding_space
+  bool ExportShadersOnly = false; // OPT_export_shaders_only
 
 
   bool IsRootSignatureProfile();
   bool IsRootSignatureProfile();
   bool IsLibraryProfile();
   bool IsLibraryProfile();

+ 7 - 3
include/dxc/Support/HLSLOptions.td

@@ -232,8 +232,12 @@ def rootsig_define : Separate<["-", "/"], "rootsig-define">, Group<hlslcomp_Grou
 def enable_16bit_types: Flag<["-", "/"], "enable-16bit-types">, Flags<[CoreOption, DriverOption]>, Group<hlslcomp_Group>,
 def enable_16bit_types: Flag<["-", "/"], "enable-16bit-types">, Flags<[CoreOption, DriverOption]>, Group<hlslcomp_Group>,
   HelpText<"Enable 16bit types and disable min precision types. Available in HLSL 2018 and shader model 6.2">;
   HelpText<"Enable 16bit types and disable min precision types. Available in HLSL 2018 and shader model 6.2">;
 def ignore_line_directives : Flag<["-", "/"], "ignore-line-directives">, HelpText<"Ignore line directives">, Flags<[CoreOption]>, Group<hlslcomp_Group>;
 def ignore_line_directives : Flag<["-", "/"], "ignore-line-directives">, HelpText<"Ignore line directives">, Flags<[CoreOption]>, Group<hlslcomp_Group>;
-def auto_binding_space : Separate<["-", "/"], "auto-binding-space">, Group<hlslcomp_Group>, Flags<[CoreOption]>, HelpText<"Set auto binding space - enables auto resource binding in libraries">;
-def exports : Separate<["-", "/"], "exports">, Group<hlslcomp_Group>, Flags<[CoreOption]>, HelpText<"Specify exports when compiling a library: export1[[,export1_clone,...]=internal_name][;...]">;
+def auto_binding_space : Separate<["-", "/"], "auto-binding-space">, Group<hlslcomp_Group>, Flags<[CoreOption]>,
+  HelpText<"Set auto binding space - enables auto resource binding in libraries">;
+def exports : Separate<["-", "/"], "exports">, Group<hlslcomp_Group>, Flags<[CoreOption]>,
+  HelpText<"Specify exports when compiling a library: export1[[,export1_clone,...]=internal_name][;...]">;
+def export_shaders_only : Flag<["-", "/"], "export-shaders-only">, Group<hlslcomp_Group>, Flags<[CoreOption]>,
+  HelpText<"Only export shaders when compiling a library">;
 
 
 // SPIRV Change Starts
 // SPIRV Change Starts
 def spirv : Flag<["-"], "spirv">, Group<spirv_Group>, Flags<[CoreOption, DriverOption]>,
 def spirv : Flag<["-"], "spirv">, Group<spirv_Group>, Flags<[CoreOption, DriverOption]>,
@@ -268,7 +272,7 @@ def Wno_vk_ignored_features : Joined<["-"], "Wno-vk-ignored-features">, Group<sp
 // fxc-based flags that don't match those previously defined.
 // fxc-based flags that don't match those previously defined.
 
 
 def target_profile : JoinedOrSeparate<["-", "/"], "T">, Flags<[CoreOption]>, Group<hlslcomp_Group>, MetaVarName<"<profile>">,
 def target_profile : JoinedOrSeparate<["-", "/"], "T">, Flags<[CoreOption]>, Group<hlslcomp_Group>, MetaVarName<"<profile>">,
-  HelpText<"Set target profile. \n\t<profile>: ps_6_0, ps_6_1, ps_6_2, vs_6_0, vs_6_1, vs_6_2, \n\t\t cs_6_0, cs_6_1, cs_6_2, gs_6_0, gs_6_1, gs_6_2, \n\t\t ds_6_0, ds_6_1, ds_6_2, hs_6_0, hs_6_1, hs_6_2, \n\t\t lib_6_0, lib_6_1, lib_6_2">;
+  HelpText<"Set target profile. \n\t<profile>: ps_6_0, ps_6_1, ps_6_2, ps_6_3, \n\t\t vs_6_0, vs_6_1, vs_6_2, vs_6_3, \n\t\t cs_6_0, cs_6_1, cs_6_2, cs_6_3, \n\t\t gs_6_0, gs_6_1, gs_6_2, gs_6_3, \n\t\t ds_6_0, ds_6_1, ds_6_2, ds_6_3, \n\t\t hs_6_0, hs_6_1, hs_6_2, hs_6_3, \n\t\t lib_6_3">;
 def entrypoint :  JoinedOrSeparate<["-", "/"], "E">, Flags<[CoreOption]>, Group<hlslcomp_Group>,
 def entrypoint :  JoinedOrSeparate<["-", "/"], "E">, Flags<[CoreOption]>, Group<hlslcomp_Group>,
   HelpText<"Entry point name">;
   HelpText<"Entry point name">;
 // /I <include> - already defined above
 // /I <include> - already defined above

+ 14 - 3
lib/DxcSupport/HLSLOptions.cpp

@@ -266,9 +266,19 @@ int ReadDxcOpts(const OptTable *optionTable, unsigned flagsToInclude,
       // Set entry point to impossible name.
       // Set entry point to impossible name.
       opts.EntryPoint = "lib.no::entry";
       opts.EntryPoint = "lib.no::entry";
     }
     }
-  } else if (Args.getLastArg(OPT_exports)) {
-    errors << "library profile required when using -exports option";
-    return 1;
+    if (Args.getLastArg(OPT_exports) &&
+        Args.hasFlag(OPT_export_shaders_only)) {
+      errors << "-exports option cannot be used with -export-shaders-only";
+      return 1;
+    }
+  } else {
+    if (Args.getLastArg(OPT_exports)) {
+      errors << "library profile required when using -exports option";
+      return 1;
+    } else if (Args.hasFlag(OPT_export_shaders_only)) {
+      errors << "library profile required when using -export-shaders-only option";
+      return 1;
+    }
   }
   }
 
 
   llvm::StringRef ver = Args.getLastArgValue(OPT_hlsl_version);
   llvm::StringRef ver = Args.getLastArgValue(OPT_hlsl_version);
@@ -423,6 +433,7 @@ int ReadDxcOpts(const OptTable *optionTable, unsigned flagsToInclude,
   opts.DisassembleByteOffset = Args.hasFlag(OPT_No, OPT_INVALID, false);
   opts.DisassembleByteOffset = Args.hasFlag(OPT_No, OPT_INVALID, false);
   opts.DisaseembleHex = Args.hasFlag(OPT_Lx, OPT_INVALID, false);
   opts.DisaseembleHex = Args.hasFlag(OPT_Lx, OPT_INVALID, false);
   opts.LegacyMacroExpansion = Args.hasFlag(OPT_flegacy_macro_expansion, OPT_INVALID, false);
   opts.LegacyMacroExpansion = Args.hasFlag(OPT_flegacy_macro_expansion, OPT_INVALID, false);
+  opts.ExportShadersOnly = Args.hasFlag(OPT_export_shaders_only, OPT_INVALID, false);
 
 
   if (opts.DefaultColMajor && opts.DefaultRowMajor) {
   if (opts.DefaultColMajor && opts.DefaultRowMajor) {
     errors << "Cannot specify /Zpr and /Zpc together, use /? to get usage information";
     errors << "Cannot specify /Zpr and /Zpc together, use /? to get usage information";

+ 2 - 0
tools/clang/include/clang/Frontend/CodeGenOptions.h

@@ -204,6 +204,8 @@ public:
   unsigned HLSLDefaultSpace = UINT_MAX;
   unsigned HLSLDefaultSpace = UINT_MAX;
   /// HLSLLibraryExports specifies desired exports, with optional renaming
   /// HLSLLibraryExports specifies desired exports, with optional renaming
   std::vector<std::string> HLSLLibraryExports;
   std::vector<std::string> HLSLLibraryExports;
+  /// ExportShadersOnly limits library export functions to shaders
+  bool ExportShadersOnly = false;
   // HLSL Change Ends
   // HLSL Change Ends
   /// Regular expression to select optimizations for which we should enable
   /// Regular expression to select optimizations for which we should enable
   /// optimization remarks. Transformation passes whose name matches this
   /// optimization remarks. Transformation passes whose name matches this

+ 14 - 0
tools/clang/lib/CodeGen/CGHLSLMS.cpp

@@ -4600,6 +4600,20 @@ void CGMSHLSLRuntime::FinishCodeGen() {
     }
     }
   }
   }
 
 
+  if (CGM.getCodeGenOpts().ExportShadersOnly) {
+    for (Function &f : m_pHLModule->GetModule()->functions()) {
+      // Skip declarations, intrinsics, shaders, and non-external linkage
+      if (f.isDeclaration() || f.isIntrinsic() ||
+          GetHLOpcodeGroup(&f) != HLOpcodeGroup::NotHL ||
+          m_pHLModule->HasDxilFunctionProps(&f) ||
+          m_pHLModule->IsPatchConstantShader(&f) ||
+          f.getLinkage() != GlobalValue::LinkageTypes::ExternalLinkage)
+        continue;
+      // Mark non-shader user functions as InternalLinkage
+      f.setLinkage(GlobalValue::LinkageTypes::InternalLinkage);
+    }
+  }
+
   // Disallow resource arguments in (non-entry) function exports
   // Disallow resource arguments in (non-entry) function exports
   if (m_bIsLib) {
   if (m_bIsLib) {
     for (Function &f : m_pHLModule->GetModule()->functions()) {
     for (Function &f : m_pHLModule->GetModule()->functions()) {

+ 110 - 0
tools/clang/test/CodeGenHLSL/quick-test/lib_hs_shaders_only.hlsl

@@ -0,0 +1,110 @@
+// RUN: %dxc -auto-binding-space 13 -T lib_6_3 -export-shaders-only %s | FileCheck %s
+
+// CHECK: class.Buffer
+// CHECK-NOT: unused
+// CHECK-NOT: @"\01?HSPerPatchFunc1@@YA?AUHSPerPatchData@@V?$InputPatch@UPSSceneIn@@$0BA@@@@Z"
+// CHECK: define void @"\01?HSPerPatchFunc2
+// CHECK: define void @HSMain1()
+// CHECK: define void @HSMain2()
+// CHECK: define void @HSMain3()
+// CHECK: define void @"\01?HSPerPatchFunc1@@YA?AUHSPerPatchData@@XZ"
+
+Buffer<float> T_unused;
+
+Buffer<float> GetBuffer_unused() { return T_unused; }
+
+struct PSSceneIn
+{
+  float4 pos  : SV_Position;
+  float2 tex  : TEXCOORD0;
+  float3 norm : NORMAL;
+};
+
+struct HSPerPatchData
+{
+  float edges[3] : SV_TessFactor;
+  float inside   : SV_InsideTessFactor;
+};
+
+struct HSPerPatchDataQuad
+{
+  float edges[4] : SV_TessFactor;
+  float inside[2]   : SV_InsideTessFactor;
+};
+
+// Should not be selected, since later candidate function with same name exists.
+// If selected, it should fail, since patch size mismatches HS function.
+HSPerPatchData HSPerPatchFunc1(
+  const InputPatch< PSSceneIn, 16 > points)
+{
+  HSPerPatchData d;
+
+  d.edges[0] = -5;
+  d.edges[1] = -6;
+  d.edges[2] = -7;
+  d.inside = T_unused.Load(1).x;
+
+  return d;
+}
+
+HSPerPatchDataQuad HSPerPatchFunc2(
+  const InputPatch< PSSceneIn, 4 > points)
+{
+  HSPerPatchDataQuad d;
+
+  d.edges[0] = -5;
+  d.edges[1] = -6;
+  d.edges[2] = -7;
+  d.edges[3] = -7;
+  d.inside[0] = -8;
+  d.inside[1] = -8;
+
+  return d;
+}
+
+
+[shader("hull")]
+[domain("tri")]
+[partitioning("fractional_odd")]
+[outputtopology("triangle_cw")]
+[patchconstantfunc("HSPerPatchFunc1")]
+[outputcontrolpoints(3)]
+void HSMain1( const uint id : SV_OutputControlPointID,
+              const InputPatch< PSSceneIn, 3 > points )
+{
+}
+
+[shader("hull")]
+[domain("quad")]
+[partitioning("fractional_odd")]
+[outputtopology("triangle_cw")]
+[patchconstantfunc("HSPerPatchFunc2")]
+[outputcontrolpoints(4)]
+void HSMain2( const uint id : SV_OutputControlPointID,
+              const InputPatch< PSSceneIn, 4 > points )
+{
+}
+
+[shader("hull")]
+[domain("tri")]
+[partitioning("fractional_odd")]
+[outputtopology("triangle_ccw")]
+[patchconstantfunc("HSPerPatchFunc1")]
+[outputcontrolpoints(3)]
+void HSMain3( const uint id : SV_OutputControlPointID,
+              const InputPatch< PSSceneIn, 3 > points )
+{
+}
+
+// actual selected HSPerPatchFunc1 for HSMain1 and HSMain3
+HSPerPatchData HSPerPatchFunc1()
+{
+  HSPerPatchData d;
+
+  d.edges[0] = -5;
+  d.edges[1] = -6;
+  d.edges[2] = -7;
+  d.inside = -8;
+
+  return d;
+}

+ 38 - 0
tools/clang/test/CodeGenHLSL/quick-test/lib_shaders_only.hlsl

@@ -0,0 +1,38 @@
+// RUN: %dxc -auto-binding-space 13 -T lib_6_3 -export-shaders-only %s | FileCheck %s
+
+// CHECK: %struct.Payload
+// CHECK: class.Buffer
+// CHECK-NOT: unused
+// CHECK: define void @"\01?AnyHit
+// CHECK: define void @"\01?Callable
+// CHECK: define void @PSMain()
+
+Buffer<float> T_unused;
+
+Buffer<float> GetBuffer_unused() { return T_unused; }
+float unused_nonshader_export() { return 1.0; }
+float unused_nonshader_export2() { return unused_nonshader_export(); }
+
+
+struct Payload {
+  float f;
+};
+
+[shader("anyhit")]
+void AnyHit(inout Payload p, BuiltInTriangleIntersectionAttributes a) {
+  p.f += a.barycentrics.x;
+  if (p.f > 1.0)
+    AcceptHitAndEndSearch();
+  p.f += a.barycentrics.y;
+}
+
+[shader("callable")]
+void Callable(inout Payload p) {
+  p.f += 0.2;
+}
+
+[shader("pixel")]
+float4 PSMain(float2 coord : TEXCOORD) : SV_Target {
+  return coord.xyxy;
+}
+

+ 3 - 0
tools/clang/tools/dxcompiler/dxcompilerobj.cpp

@@ -900,6 +900,9 @@ public:
 
 
     // processed export names from -exports option:
     // processed export names from -exports option:
     compiler.getCodeGenOpts().HLSLLibraryExports = Opts.Exports;
     compiler.getCodeGenOpts().HLSLLibraryExports = Opts.Exports;
+
+    // only export shader functions for library
+    compiler.getCodeGenOpts().ExportShadersOnly = Opts.ExportShadersOnly;
   }
   }
 
 
   // IDxcVersionInfo
   // IDxcVersionInfo