2
0
Эх сурвалжийг харах

Fixing Dxc Options (#4)

* Clean up dxc options:

setrootsignature, setprivate :
 Allow replacing existing rootsignature or private data and make a new container with new parts
(e.g dxc /dumpbin private.dxil /setprivate private.data /Fo private.new.dxil)

extractrootsignature:
Make it back compatible with fxc by returning dxil container with RTS0 part only and having the user to provide /Fo option.

Other Options:
For unimplemented options that was from fxc, ignore those options and proceed given operation.
For unimplemented options that was not from fxc, remove them for now.
Add more test cases for dxc command line operations.
Fix ISenseOption flag to have valid HLSL version check for dxc (disable 2015)

* Fix Preprocess option for dxc
Fix hcttestcmd for testing invalid rootsignature
Young Kim 8 жил өмнө
parent
commit
3a24e158ef

+ 3 - 0
include/dxc/Support/ErrorCodes.h

@@ -89,3 +89,6 @@
 
 // 0x80AA0014 - Incorrect Root Signature for shader.
 #define DXC_E_INCORRECT_ROOT_SIGNATURE                DXC_MAKE_HRESULT(DXC_SEVERITY_ERROR,FACILITY_DXC,(0x0014))
+
+// 0X80AA0015 - DXIL container is missing DebugInfo part.
+#define DXC_E_CONTAINER_MISSING_DEBUG                 DXC_MAKE_HRESULT(DXC_SEVERITY_ERROR,FACILITY_DXC,(0x0015))

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

@@ -54,6 +54,7 @@ void CheckLLVMErrorCode(const std::error_code &ec);
 #define IFTARG(x)   { if (!(x)) { throw ::hlsl::Exception(E_INVALIDARG); }}
 #define IFTLLVM(x)  { CheckLLVMErrorCode(x); }
 #define IFTMSG(x, msg) { HRESULT __hr = (x); if (DXC_FAILED(__hr)) throw ::hlsl::Exception(__hr, msg); }
+#define IFTBOOLMSG(x, y, msg) { if (!(x)) throw ::hlsl::Exception(y, msg); }
 
 // Propagate an C++ exception into an HRESULT.
 #define CATCH_CPP_ASSIGN_HRESULT() \

+ 10 - 6
include/dxc/Support/HLSLOptions.h

@@ -39,7 +39,7 @@ enum HlslFlags {
   DriverOption = (1 << 13),
   NoArgumentUnused = (1 << 14),
   CoreOption = (1 << 15),
-  ISenseOption = (1 << 15),
+  ISenseOption = (1 << 16),
 };
 
 enum ID {
@@ -93,7 +93,6 @@ public:
   llvm::StringRef EntryPoint;   // OPT_entrypoint
   llvm::StringRef ExternalFn;   // OPT_external_fn
   llvm::StringRef ExternalLib;  // OPT_external_lib
-  llvm::StringRef ExtractRootSignatureFile; // OPT_extractrootsignature
   llvm::StringRef ExtractPrivateFile; // OPT_getprivate
   llvm::StringRef ForceRootSigVer; // OPT_force_rootsig_ver
   llvm::StringRef InputFile; // OPT_INPUT
@@ -105,6 +104,7 @@ public:
   llvm::StringRef VariableName; // OPT_Vn
   llvm::StringRef PrivateSource; // OPT_setprivate
   llvm::StringRef RootSignatureSource; // OPT_setrootsignature
+  llvm::StringRef VerifyRootSignatureSource; //OPT_verifyrootsignature
 
   bool AllResourcesBound; // OPT_all_resources_bound
   bool AstDump; // OPT_ast_dump
@@ -112,7 +112,6 @@ public:
   bool CodeGenHighLevel; // OPT_fcgl
   bool DebugInfo; // OPT__SLASH_Zi
   bool DumpBin;        // OPT_dumpbin
-  bool EnableUnboundedDescriptorTables; // OPT_enable_unbounded_descriptor_tables
   bool WarningAsError; // OPT__SLASH_WX
   bool IEEEStrict;     // OPT_Gis
   bool DefaultColMajor;  // OPT_Zpc
@@ -136,9 +135,14 @@ public:
   bool DisplayIncludeProcess; // OPT__vi
   bool RecompileFromBinary; // OPT _Recompile (Recompiling the DXBC binary file not .hlsl file)
   bool StripDebug; // OPT Qstrip_debug
-  bool StripRootSignature; // OPT Qstrip_rootsignature
-  bool StripPrivate; // OPT Qstrip_priv
-  bool StripReflection; // OPT Qstrip_reflect
+  bool StripRootSignature; // OPT_Qstrip_rootsignature
+  bool StripPrivate; // OPT_Qstrip_priv
+  bool StripReflection; // OPT_Qstrip_reflect
+  bool ExtractRootSignature; // OPT_extractrootsignature
+  bool DisassembleColorCoded; // OPT_Cc
+  bool DisassembleInstNumbers; //OPT_Ni
+  bool DisassembleByteOffset; //OPT_No
+  bool DisaseembleHex; //OPT_Lx
 };
 
 /// Use this class to capture, convert and handle the lifetime for the

+ 38 - 34
include/dxc/Support/HLSLOptions.td

@@ -87,27 +87,27 @@ def H : Flag<["-"], "H">, Flags<[CoreOption]>, Group<hlslcomp_Group>,
 def I : JoinedOrSeparate<["-", "/"], "I">, Group<hlslcomp_Group>, Flags<[CoreOption]>,
     HelpText<"Add directory to include search path">;
 def O0 : Flag<["-", "/"], "O0">, Group<hlsloptz_Group>, Flags<[CoreOption]>,
-    HelpText<"Optimization Level 0 - Disables instruction reordering">;
+    HelpText<"Optimization Level 0">;
 def O1 : Flag<["-", "/"], "O1">, Group<hlsloptz_Group>, Flags<[CoreOption]>,
-    HelpText<"Optimization Level 1 - All standard optimizations">;
+    HelpText<"Optimization Level 1">;
 def O2 : Flag<["-", "/"], "O2">, Group<hlsloptz_Group>, Flags<[CoreOption]>,
-    HelpText<"Optimization Level 2 - Same as O1. Reserved for future use.">;
+    HelpText<"Optimization Level 2">;
 def O3 : Flag<["-", "/"], "O3">, Group<hlsloptz_Group>, Flags<[CoreOption]>,
-    HelpText<"Optimization Level 3 - Same as O1. Reserved for future use.">;
+    HelpText<"Optimization Level 3 (Default)">;
 def O4 : Flag<["-", "/"], "O4">, Group<hlsloptz_Group>, Flags<[CoreOption]>,
-    HelpText<"Optimization Level 4 - Same as O1. Reserved for future use.">;
+    HelpText<"Optimization Level 4">;
 def Odump : Flag<["-", "/"], "Odump">, Group<hlslcomp_Group>, Flags<[CoreOption]>,
     HelpText<"Print the optimizer commands.">;
 def Qunused_arguments : Flag<["-"], "Qunused-arguments">, Group<hlslcore_Group>, Flags<[CoreOption]>,
   HelpText<"Don't emit warning for unused driver arguments">;
 def Wall : Flag<["-"], "Wall">, Group<hlslcomp_Group>, Flags<[CoreOption]>;
 def Wdeprecated : Flag<["-"], "Wdeprecated">, Group<hlslcomp_Group>, Flags<[CoreOption]>;
-def W_Joined : Joined<["-"], "W">, Group<hlslcomp_Group>, Flags<[CoreOption]>,
-  MetaVarName<"<warning>">, HelpText<"Enable the specified warning">;
+//def W_Joined : Joined<["-"], "W">, Group<hlslcomp_Group>, Flags<[CoreOption]>,
+//  MetaVarName<"<warning>">, HelpText<"Enable the specified warning">;
 def d_Flag : Flag<["-"], "d">, Group<d_Group>;
 def d_Joined : Joined<["-"], "d">, Group<d_Group>;
-def fcolor_diagnostics : Flag<["-"], "fcolor-diagnostics">, Group<hlslcomp_Group>,
-  Flags<[CoreOption, DriverOption]>, HelpText<"Use colors in diagnostics">;
+//def fcolor_diagnostics : Flag<["-"], "fcolor-diagnostics">, Group<hlslcomp_Group>,
+//  Flags<[CoreOption, DriverOption]>, HelpText<"Use colors in diagnostics">;
 def fdiagnostics_color : Flag<["-"], "fdiagnostics-color">, Group<hlslcomp_Group>,
   Flags<[CoreOption, DriverOption]>;
 def fdiagnostics_color_EQ : Joined<["-"], "fdiagnostics-color=">, Group<hlslcomp_Group>;
@@ -117,8 +117,8 @@ def fconstexpr_depth_EQ : Joined<["-"], "fconstexpr-depth=">, Group<f_Group>;
 def fconstexpr_steps_EQ : Joined<["-"], "fconstexpr-steps=">, Group<f_Group>;
 def fconstexpr_backtrace_limit_EQ : Joined<["-"], "fconstexpr-backtrace-limit=">,
                                     Group<f_Group>;
-def fdiagnostics_show_option : Flag<["-"], "fdiagnostics-show-option">, Group<hlslcomp_Group>,
-    Flags<[CoreOption]>, HelpText<"Print option name with mappable diagnostics">;
+//def fdiagnostics_show_option : Flag<["-"], "fdiagnostics-show-option">, Group<hlslcomp_Group>,
+//    Flags<[CoreOption]>, HelpText<"Print option name with mappable diagnostics">;
 def fdiagnostics_show_category_EQ : Joined<["-"], "fdiagnostics-show-category=">, Group<hlslcomp_Group>;
 def ferror_limit_EQ : Joined<["-"], "ferror-limit=">, Group<hlslcomp_Group>, Flags<[CoreOption]>;
 
@@ -128,27 +128,29 @@ def fno_unsafe_math_optimizations : Flag<["-"], "fno-unsafe-math-optimizations">
   Group<hlsloptz_Group>;
 def fassociative_math : Flag<["-"], "fassociative-math">, Group<hlsloptz_Group>;
 def fno_associative_math : Flag<["-"], "fno-associative-math">, Group<hlsloptz_Group>;
-def freciprocal_math :
-  Flag<["-"], "freciprocal-math">, Group<hlsloptz_Group>, Flags<[CoreOption]>,
-  HelpText<"Allow division operations to be reassociated">;
+//def freciprocal_math :
+//  Flag<["-"], "freciprocal-math">, Group<hlsloptz_Group>, Flags<[CoreOption]>,
+//  HelpText<"Allow division operations to be reassociated">;
 def fno_reciprocal_math : Flag<["-"], "fno-reciprocal-math">, Group<hlsloptz_Group>;
 def ffinite_math_only : Flag<["-"], "ffinite-math-only">, Group<hlsloptz_Group>, Flags<[CoreOption]>;
 def fno_finite_math_only : Flag<["-"], "fno-finite-math-only">, Group<hlsloptz_Group>;
 def fsigned_zeros : Flag<["-"], "fsigned-zeros">, Group<hlsloptz_Group>;
-def fno_signed_zeros :
-  Flag<["-"], "fno-signed-zeros">, Group<hlsloptz_Group>, Flags<[CoreOption]>,
-  HelpText<"Allow optimizations that ignore the sign of floating point zeros">;
+//def fno_signed_zeros :
+//  Flag<["-"], "fno-signed-zeros">, Group<hlsloptz_Group>, Flags<[CoreOption]>,
+//  HelpText<"Allow optimizations that ignore the sign of floating point zeros">;
 def fhonor_nans : Flag<["-"], "fhonor-nans">, Group<hlsloptz_Group>;
 def fno_honor_nans : Flag<["-"], "fno-honor-nans">, Group<hlsloptz_Group>;
 def fhonor_infinities : Flag<["-"], "fhonor-infinities">, Group<hlsloptz_Group>;
 def fno_honor_infinities : Flag<["-"], "fno-honor-infinities">, Group<hlsloptz_Group>;
 //def ftrapping_math : Flag<["-"], "ftrapping-math">, Group<f_Group>;
 //def fno_trapping_math : Flag<["-"], "fno-trapping-math">, Group<f_Group>;
-def ffp_contract : Joined<["-"], "ffp-contract=">, Group<hlsloptz_Group>,
-  Flags<[CoreOption]>, HelpText<"Form fused FP ops (e.g. FMAs): fast (everywhere)"
-  " | on (according to FP_CONTRACT pragma, default) | off (never fuse)">;
+//def ffp_contract : Joined<["-"], "ffp-contract=">, Group<hlsloptz_Group>,
+//  Flags<[CoreOption]>, HelpText<"Form fused FP ops (e.g. FMAs): fast (everywhere)"
+//  " | on (according to FP_CONTRACT pragma, default) | off (never fuse)">;
 def flimited_precision_EQ : Joined<["-"], "flimited-precision=">, Group<hlsloptz_Group>;
 
+
+/*
 def fno_caret_diagnostics : Flag<["-"], "fno-caret-diagnostics">, Group<hlslcomp_Group>,
  Flags<[CoreOption]>;
 def fno_color_diagnostics : Flag<["-"], "fno-color-diagnostics">, Group<hlslcomp_Group>,
@@ -171,7 +173,7 @@ def freroll_loops : Flag<["-"], "freroll-loops">, Group<hlsloptz_Group>,
   HelpText<"Turn on loop reroller">, Flags<[CoreOption]>;
 def fno_reroll_loops : Flag<["-"], "fno-reroll-loops">, Group<hlsloptz_Group>,
   HelpText<"Turn off loop reroller">;
-
+*/
 def help : Flag<["-", "--", "/"], "help">, Flags<[DriverOption]>, Group<hlslcore_Group>,
   HelpText<"Display available options">;
 /*
@@ -216,7 +218,7 @@ def fcgl : Flag<["-", "/"], "fcgl">, Group<hlslcore_Group>, Flags<[CoreOption, H
 def not_use_legacy_cbuf_load : Flag<["-", "/"], "not_use_legacy_cbuf_load">, Group<hlslcomp_Group>, Flags<[CoreOption]>,
   HelpText<"Not use legacy cbuffer load">;  
 def hlsl_version : Separate<["-", "/"], "HV">, Group<hlslcomp_Group>, Flags<[CoreOption]>,
-  HelpText<"HLSL version (2015, 2016)">;
+  HelpText<"HLSL version (Only supports 2016 for now)">;
 def no_warnings : Flag<["-", "/"], "no-warnings">, Group<hlslcomp_Group>, Flags<[CoreOption]>,
   HelpText<"Suppress warnings">;
 
@@ -239,7 +241,7 @@ def VD : Flag<["-", "/"], "Vd">, Flags<[CoreOption]>, Group<hlslcomp_Group>,
 def _SLASH_Zi : Flag<["-", "/"], "Zi">, Flags<[CoreOption]>, Group<hlslcomp_Group>,
   HelpText<"Enable debug information">;
 def recompile : Flag<["-", "/"], "recompile">, Flags<[CoreOption]>, Group<hlslcomp_Group>,
-  HelpText<"recompile from Container or DXIL Bitcode file (not .hlsl file)">;
+  HelpText<"recompile from DXIL container with Debug Info or Debug Info bitcode file">;
 def Zpr : Flag<["-", "/"], "Zpr">, Flags<[CoreOption]>, Group<hlslcomp_Group>,
   HelpText<"Pack matrices in row-major order">;
 def Zpc : Flag<["-", "/"], "Zpc">, Flags<[CoreOption]>, Group<hlslcomp_Group>,
@@ -258,12 +260,12 @@ def Fc : JoinedOrSeparate<["-", "/"], "Fc">, MetaVarName<"<file>">, HelpText<"Ou
 //def Fx : JoinedOrSeparate<["-", "/"], "Fx">, MetaVarName<"<file>">, HelpText<"Output assembly code and hex listing file">;
 def Fh : JoinedOrSeparate<["-", "/"], "Fh">, MetaVarName<"<file>">, HelpText<"Output header file containing object code">, Flags<[DriverOption]>, Group<hlslcomp_Group>;
 def Fe : JoinedOrSeparate<["-", "/"], "Fe">, MetaVarName<"<file>">, HelpText<"Output warnings and errors to a specific file">, Flags<[DriverOption]>, Group<hlslcomp_Group>;
-def Fd : JoinedOrSeparate<["-", "/"], "Fd">, MetaVarName<"<file>">, HelpText<"Extract shader PDB and write to given file">, Flags<[DriverOption]>, Group<hlslcomp_Group>;
+def Fd : JoinedOrSeparate<["-", "/"], "Fd">, MetaVarName<"<file>">, HelpText<"Extract LLVM Debug IR and write to given file">, Flags<[DriverOption]>, Group<hlslcomp_Group>;
 def Vn : JoinedOrSeparate<["-", "/"], "Vn">, MetaVarName<"<name>">, HelpText<"Use <name> as variable name in header file">, Flags<[DriverOption]>, Group<hlslcomp_Group>;
-def Cc : Flag<["-", "/"], "Cc">, HelpText<"Output color coded assembly listings">, Group<hlslcomp_Group>;
-def Ni : Flag<["-", "/"], "Ni">, HelpText<"Output instruction numbers in assembly listings">, Group<hlslcomp_Group>;
-def No : Flag<["-", "/"], "No">, HelpText<"Output instruction byte offsets in assembly listings">, Group<hlslcomp_Group>;
-def Lx : Flag<["-", "/"], "Lx">, HelpText<"Output hexadecimal literals">, Group<hlslcomp_Group>;
+def Cc : Flag<["-", "/"], "Cc">, HelpText<"Output color coded assembly listings">, Group<hlslcomp_Group>, Flags<[DriverOption]>;
+def Ni : Flag<["-", "/"], "Ni">, HelpText<"Output instruction numbers in assembly listings">, Group<hlslcomp_Group>, Flags<[DriverOption]>;
+def No : Flag<["-", "/"], "No">, HelpText<"Output instruction byte offsets in assembly listings">, Group<hlslcomp_Group>, Flags<[DriverOption]>;
+def Lx : Flag<["-", "/"], "Lx">, HelpText<"Output hexadecimal literals">, Group<hlslcomp_Group>, Flags<[DriverOption]>;
 
 // In place of 'E' for clang; fxc uses 'E' for entry point.
 def P : Separate<["-", "/"], "P">, Flags<[DriverOption]>, Group<hlslutil_Group>,
@@ -274,18 +276,19 @@ def P : Separate<["-", "/"], "P">, Flags<[DriverOption]>, Group<hlslutil_Group>,
 def dumpbin : Flag<["-", "/"], "dumpbin">, Flags<[DriverOption]>, Group<hlslutil_Group>,
   HelpText<"Load a binary file rather than compiling">;
 def Qstrip_reflect : Flag<["-", "/"], "Qstrip_reflect">, Flags<[DriverOption]>, Group<hlslutil_Group>,
-  HelpText<"Strip reflection data from shader bytecode">;
+  HelpText<"Strip reflection data from shader bytecode  (must be used with /Fo <file>)">;
 def Qstrip_debug : Flag<["-", "/"], "Qstrip_debug">, Flags<[DriverOption]>, Group<hlslutil_Group>,
-  HelpText<"Strip debug information from 4_0+ shader bytecode">;
+  HelpText<"Strip debug information from 4_0+ shader bytecode  (must be used with /Fo <file>)">;
 def Qstrip_priv : Flag<["-", "/"], "Qstrip_priv">, Flags<[DriverOption]>, Group<hlslutil_Group>,
-  HelpText<"Strip private data from shader bytecode">;
+  HelpText<"Strip private data from shader bytecode  (must be used with /Fo <file>)">;
 
-def Qstrip_rootsignature : Flag<["-", "/"], "Qstrip_rootsignature">, Flags<[DriverOption]>, Group<hlslutil_Group>, HelpText<"Strip root signature data from shader bytecode">;
+def Qstrip_rootsignature : Flag<["-", "/"], "Qstrip_rootsignature">, Flags<[DriverOption]>, Group<hlslutil_Group>, HelpText<"Strip root signature data from shader bytecode  (must be used with /Fo <file>)">;
 def setrootsignature     : JoinedOrSeparate<["-", "/"], "setrootsignature">,     MetaVarName<"<file>">, Flags<[DriverOption]>, Group<hlslutil_Group>, HelpText<"Attach root signature to shader bytecode">;
-def extractrootsignature : JoinedOrSeparate<["-", "/"], "extractrootsignature">, MetaVarName<"<file>">, Flags<[DriverOption]>, Group<hlslutil_Group>, HelpText<"Extract root signature from shader bytecode">;
+def extractrootsignature : Flag<["-", "/"], "extractrootsignature">, Flags<[DriverOption]>, Group<hlslutil_Group>, HelpText<"Extract root signature from shader bytecode (must be used with /Fo <file>)">;
 def verifyrootsignature  : JoinedOrSeparate<["-", "/"], "verifyrootsignature">,  MetaVarName<"<file>">, Flags<[DriverOption]>, Group<hlslutil_Group>, HelpText<"Verify shader bytecode with root signature">;
 def force_rootsig_ver    : JoinedOrSeparate<["-", "/"], "force_rootsig_ver">,    Flags<[CoreOption]>, MetaVarName<"<profile>">, Group<hlslcomp_Group>, HelpText<"force root signature version (rootsig_1_1 if omitted)">;
 
+/*
 def shtemplate : JoinedOrSeparate<["-", "/"], "shtemplate">, MetaVarName<"<file>">, Group<hlslcomp_Group>,
   HelpText<"Template shader file for merging/matching resources">;
 def mergeUAVs : JoinedOrSeparate<["-", "/"], "mergeUAVs">, MetaVarName<"<file>">, Group<hlslcomp_Group>,
@@ -296,6 +299,7 @@ def res_may_alias : Flag<["-", "/"], "res_may_alias">, Flags<[CoreOption]>, Grou
   HelpText<"Assume that UAVs/SRVs may alias">;
 def enable_unbounded_descriptor_tables : Flag<["-", "/"], "enable_unbounded_descriptor_tables">, Flags<[CoreOption]>, Group<hlslcomp_Group>,
   HelpText<"Enables unbounded descriptor tables">;
+*/
 def all_resources_bound : Flag<["-", "/"], "all_resources_bound">, Flags<[CoreOption]>, Group<hlslcomp_Group>,
   HelpText<"Enables agressive flattening">;
 
@@ -304,7 +308,7 @@ def setprivate : JoinedOrSeparate<["-", "/"], "setprivate">, Flags<[DriverOption
 def getprivate : JoinedOrSeparate<["-", "/"], "getprivate">, Flags<[DriverOption]>, MetaVarName<"<file>">, Group<hlslutil_Group>,
   HelpText<"Save private data from shader blob">;
 
-def nologo : Flag<["-", "/"], "nologo">, Group<hlslcore_Group>,
+def nologo : Flag<["-", "/"], "nologo">, Group<hlslcore_Group>, Flags<[DriverOption]>,
   HelpText<"Suppress copyright message">;
 
 // Also removed: compress, decompress, /Gch (child effect), /Gec (back compat), /Gpp (partial precision)

+ 10 - 5
lib/DxcSupport/HLSLOptions.cpp

@@ -236,7 +236,6 @@ int ReadDxcOpts(const OptTable *optionTable, unsigned flagsToInclude,
   // OutputLibrary not supported (Fl)
   opts.AssemblyCode = Args.getLastArgValue(OPT_Fc);
   opts.DebugFile = Args.getLastArgValue(OPT_Fd);
-  opts.ExtractRootSignatureFile = Args.getLastArgValue(OPT_extractrootsignature);
   opts.ExtractPrivateFile = Args.getLastArgValue(OPT_getprivate);
   opts.OutputObject = Args.getLastArgValue(OPT_Fo);
   opts.OutputHeader = Args.getLastArgValue(OPT_Fh);
@@ -254,6 +253,7 @@ int ReadDxcOpts(const OptTable *optionTable, unsigned flagsToInclude,
   opts.ForceRootSigVer = Args.getLastArgValue(OPT_force_rootsig_ver);
   opts.PrivateSource = Args.getLastArgValue(OPT_setprivate);
   opts.RootSignatureSource = Args.getLastArgValue(OPT_setrootsignature);
+  opts.VerifyRootSignatureSource = Args.getLastArgValue(OPT_verifyrootsignature);
 
   if (!opts.ForceRootSigVer.empty() && opts.ForceRootSigVer != "rootsig_1_0" &&
       opts.ForceRootSigVer != "rootsig_1_1") {
@@ -287,7 +287,6 @@ int ReadDxcOpts(const OptTable *optionTable, unsigned flagsToInclude,
   opts.DefaultRowMajor = Args.hasFlag(OPT_Zpr, OPT_INVALID, false);
   opts.DefaultColMajor = Args.hasFlag(OPT_Zpc, OPT_INVALID, false);
   opts.DumpBin = Args.hasFlag(OPT_dumpbin, OPT_INVALID, false);
-  opts.EnableUnboundedDescriptorTables = Args.hasFlag(OPT_enable_unbounded_descriptor_tables, OPT_INVALID, false);
   opts.NotUseLegacyCBufLoad = Args.hasFlag(OPT_not_use_legacy_cbuf_load, OPT_INVALID, false);
   opts.DisplayIncludeProcess = Args.hasFlag(OPT_H, OPT_INVALID, false);
   opts.WarningAsError = Args.hasFlag(OPT__SLASH_WX, OPT_INVALID, false);
@@ -298,6 +297,12 @@ int ReadDxcOpts(const OptTable *optionTable, unsigned flagsToInclude,
   opts.StripRootSignature = Args.hasFlag(OPT_Qstrip_rootsignature, OPT_INVALID, false);
   opts.StripPrivate = Args.hasFlag(OPT_Qstrip_priv, OPT_INVALID, false);
   opts.StripReflection = Args.hasFlag(OPT_Qstrip_reflect, OPT_INVALID, false);
+  opts.ExtractRootSignature = Args.hasFlag(OPT_extractrootsignature, OPT_INVALID, false);
+  opts.DisassembleColorCoded = Args.hasFlag(OPT_Cc, OPT_INVALID, false);
+  opts.DisassembleInstNumbers = Args.hasFlag(OPT_Ni, OPT_INVALID, false);
+  opts.DisassembleByteOffset = Args.hasFlag(OPT_No, OPT_INVALID, false);
+  opts.DisaseembleHex = Args.hasFlag(OPT_Lx, OPT_INVALID, false);
+
   if (opts.DefaultColMajor && opts.DefaultRowMajor) {
     errors << "Cannot specify /Zpr and /Zpc together, use /? to get usage information";
     return 1;
@@ -318,7 +323,7 @@ int ReadDxcOpts(const OptTable *optionTable, unsigned flagsToInclude,
 
   if ((flagsToInclude & hlsl::options::DriverOption) && opts.InputFile.empty()) {
     // Input file is required in arguments only for drivers; APIs take this through an argument.
-    errors << "Required input file argument is missing.";
+    errors << "Required input file argument is missing. use -help to get more information.";
     return 1;
   }
   if (opts.OutputHeader.empty() && !opts.VariableName.empty()) {
@@ -328,7 +333,7 @@ int ReadDxcOpts(const OptTable *optionTable, unsigned flagsToInclude,
 
   if (!opts.Preprocess.empty() &&
       (!opts.OutputHeader.empty() || !opts.OutputObject.empty() ||
-       opts.OutputWarnings || !opts.OutputWarningsFile.empty())) {
+       !opts.OutputWarnings || !opts.OutputWarningsFile.empty())) {
     errors << "Preprocess cannot be specified with other options.";
     return 1;
   }
@@ -341,7 +346,7 @@ int ReadDxcOpts(const OptTable *optionTable, unsigned flagsToInclude,
     if (opts.AllResourcesBound || opts.AvoidFlowControl ||
         opts.CodeGenHighLevel || opts.DebugInfo || opts.DefaultColMajor ||
         opts.DefaultRowMajor || opts.Defines.size() != 0 ||
-        opts.DisableOptimizations || opts.EnableUnboundedDescriptorTables ||
+        opts.DisableOptimizations || 
         !opts.EntryPoint.empty() || !opts.ForceRootSigVer.empty() ||
         opts.PreferFlowControl || !opts.TargetProfile.empty()) {
       errors << "Cannot specify compilation options when reading a binary file.";

+ 200 - 38
tools/clang/tools/dxc/dxc.cpp

@@ -26,18 +26,12 @@
 //
 // Unimplemented but on roadmap:
 //
-// /getprivate  - Save private data to a file.
 // /matchUAVs   - Match template shader UAV slot allocations in the current shader
 // /mergeUAVs   - Merge UAV slot allocations of template shader and the current shader
 // /Ni          - Output instruction numbers in assembly listings
 // /No          - Output instruction byte offset in assembly listings
-// /Qstrip_debug
-// /Qstrip_priv
 // /Qstrip_reflect
-// /Qstrip_rootsignature
 // /res_may_alias
-// /setprivate
-// /setrootsignature
 // /shtemplate
 // /verifyrootsignature
 //
@@ -56,6 +50,7 @@
 #include "dxc/Support/HLSLOptions.h"
 #include "dxc/HLSL/DxilContainer.h"
 #include "dxc/HLSL/DxilShaderModel.h"
+#include "dxc/HLSL/DxilRootSignature.h"
 #include "dxc/Support/FileIOHelper.h"
 #include "dxc/Support/microcom.h"
 #include "llvm/Option/OptTable.h"
@@ -87,9 +82,13 @@ private:
   bool UpdatePartRequired();
   void WriteHeader(IDxcBlobEncoding *pDisassembly, IDxcBlob *pCode,
                    llvm::Twine &pVariableName, LPCWSTR pPath);
+  HRESULT ReadFileIntoPartContent(hlsl::DxilFourCC fourCC, LPCWSTR fileName, IDxcBlob **ppResult);
+  
   // TODO : Refactor two functions below. There are duplicate functions in DxcContext in dxa.cpp
   HRESULT GetDxcDiaTable(IDxcLibrary *pLibrary, IDxcBlob *pTargetBlob, IDiaTable **ppTable, LPCWSTR tableName);
   HRESULT FindModuleBlob(hlsl::DxilFourCC fourCC, IDxcBlob *pSource, IDxcLibrary *pLibrary, IDxcBlob **ppTargetBlob);
+  void ExtractRootSignature(IDxcBlob *pBlob, IDxcBlob **ppResult);
+  void VerifyRootSignature();
 
 public:
   DxcContext(DxcOpts &Opts, DxcDllSupport &dxcSupport)
@@ -144,19 +143,34 @@ void DxcContext::ActOnBlob(IDxcBlob *pBlob) {
 
   // Write the output blob.
   if (!m_Opts.OutputObject.empty()) {
-    CComPtr<IDxcBlob> pResult;
-    UpdatePart(pBlob, &pResult);
-    WriteBlobToFile(pResult, m_Opts.OutputObject);
+    // For backward compatability: fxc requires /Fo for /extractrootsignature
+    if (!m_Opts.ExtractRootSignature) {
+      CComPtr<IDxcBlob> pResult;
+      UpdatePart(pBlob, &pResult);
+      WriteBlobToFile(pResult, m_Opts.OutputObject);
+    }
+  }
+
+  // Verify Root Signature
+  if (!m_Opts.VerifyRootSignatureSource.empty()) {
+    VerifyRootSignature();
   }
 
   // Extract and write the PDB/debug information.
   if (!m_Opts.DebugFile.empty()) {
+    IFTBOOLMSG(m_Opts.DebugInfo, E_INVALIDARG, "/Fd specified, but no Debug Info was "
+      "found in the shader, please use the "
+      "/Zi switch to generate debug "
+      "information compiling this shader.");
+
     WritePartToFile(pBlob, hlsl::DFCC_ShaderDebugInfoDXIL, m_Opts.DebugFile);
   }
 
   // Extract and write root signature information.
-  if (!m_Opts.ExtractRootSignatureFile.empty()) {
-    WritePartToFile(pBlob, hlsl::DFCC_RootSignature, m_Opts.ExtractRootSignatureFile);
+  if (m_Opts.ExtractRootSignature) {
+    CComPtr<IDxcBlob> pRootSignatureContainer;
+    ExtractRootSignature(pBlob, &pRootSignatureContainer);
+    WriteBlobToFile(pRootSignatureContainer, m_Opts.OutputObject);
   }
 
   // Extract and write private data.
@@ -165,9 +179,12 @@ void DxcContext::ActOnBlob(IDxcBlob *pBlob) {
   }
 
   // OutputObject suppresses console dump.
-  bool needDisassembly = !m_Opts.OutputHeader.empty() ||
-                         !m_Opts.AssemblyCode.empty() ||
-                         m_Opts.OutputObject.empty();
+  bool needDisassembly =
+      !m_Opts.OutputHeader.empty() || !m_Opts.AssemblyCode.empty() ||
+      (m_Opts.OutputObject.empty() && m_Opts.DebugFile.empty() &&
+       m_Opts.ExtractPrivateFile.empty() &&
+       m_Opts.VerifyRootSignatureSource.empty() && !m_Opts.ExtractRootSignature);
+
   if (!needDisassembly)
     return;
 
@@ -216,13 +233,27 @@ void DxcContext::UpdatePart(IDxcBlob *pSource, IDxcBlob **ppResult) {
     IFT(pContainerBuilder->RemovePart(hlsl::DxilFourCC::DFCC_RootSignature));
   }
   if (!m_Opts.PrivateSource.empty()) {
-    CComPtr<IDxcBlobEncoding> privateBlob;
-    ReadFileIntoBlob(m_dxcSupport, StringRefUtf16(m_Opts.PrivateSource), &privateBlob);
+    CComPtr<IDxcBlob> privateBlob;
+    IFT(ReadFileIntoPartContent(hlsl::DxilFourCC::DFCC_PrivateData,
+                                StringRefUtf16(m_Opts.PrivateSource),
+                                &privateBlob));
+
+    // setprivate option can replace existing private part. 
+    // Try removing the private data if exists
+    pContainerBuilder->RemovePart(hlsl::DxilFourCC::DFCC_PrivateData);
     IFT(pContainerBuilder->AddPart(hlsl::DxilFourCC::DFCC_PrivateData, privateBlob));
   }
   if (!m_Opts.RootSignatureSource.empty()) {
-    CComPtr<IDxcBlobEncoding> RootSignatureBlob;
-    ReadFileIntoBlob(m_dxcSupport, StringRefUtf16(m_Opts.RootSignatureSource), &RootSignatureBlob);
+    // set rootsignature assumes that the given input is a dxil container. 
+    // We only want to add RTS0 part to the container builder. 
+    CComPtr<IDxcBlob> RootSignatureBlob;
+    IFT(ReadFileIntoPartContent(hlsl::DxilFourCC::DFCC_RootSignature,
+                                StringRefUtf16(m_Opts.RootSignatureSource),
+                                &RootSignatureBlob));
+
+    // setrootsignature option can replace existing rootsignature part
+    // Try removing rootsignature if exists
+    pContainerBuilder->RemovePart(hlsl::DxilFourCC::DFCC_RootSignature);
     IFT(pContainerBuilder->AddPart(hlsl::DxilFourCC::DFCC_RootSignature, RootSignatureBlob));
   }
   
@@ -251,6 +282,126 @@ bool DxcContext::UpdatePartRequired() {
     !m_Opts.RootSignatureSource.empty();
 }
 
+// This function reads the file from input file and constructs a blob with fourCC parts
+// Used for setprivate and setrootsignature option
+HRESULT DxcContext::ReadFileIntoPartContent(hlsl::DxilFourCC fourCC, LPCWSTR fileName, IDxcBlob **ppResult) {
+  DXASSERT(fourCC == hlsl::DxilFourCC::DFCC_PrivateData ||
+           fourCC == hlsl::DxilFourCC::DFCC_RootSignature,
+           "Otherwise we provided wrong part to read for updating part.");
+
+  // Read result, if it's private data, then return the blob
+  if (fourCC == hlsl::DxilFourCC::DFCC_PrivateData) {
+    CComPtr<IDxcBlobEncoding> pResult;
+    ReadFileIntoBlob(m_dxcSupport, fileName, &pResult);
+    *ppResult = pResult.Detach();
+  }
+
+  // If root signature, check if it's a dxil container that contains rootsignature part, then construct a blob of root signature part
+  if (fourCC == hlsl::DxilFourCC::DFCC_RootSignature) {
+    CComPtr<IDxcBlob> pResult;
+    CComHeapPtr<BYTE> pData;
+    DWORD dataSize;
+    hlsl::ReadBinaryFile(fileName, (void**)&pData, &dataSize);
+    DXASSERT(pData != nullptr, "otherwise ReadBinaryFile should throw an exception");
+    hlsl::DxilContainerHeader *pHeader = (hlsl::DxilContainerHeader*) pData.m_pData;
+    IFRBOOL(hlsl::IsDxilContainerLike(pHeader, pHeader->ContainerSizeInBytes), E_INVALIDARG);
+    hlsl::DxilPartHeader *pPartHeader = hlsl::GetDxilPartByType(pHeader, hlsl::DxilFourCC::DFCC_RootSignature);
+    IFRBOOL(pPartHeader != nullptr, E_INVALIDARG);
+    hlsl::DxcCreateBlobOnHeapCopy(hlsl::GetDxilPartData(pPartHeader), pPartHeader->PartSize, &pResult);
+    *ppResult = pResult.Detach();
+  }
+  return S_OK;
+}
+
+// Constructs a dxil container builder with only root signature part.
+// Right now IDxcContainerBuilder assumes that we are building a full dxil container,
+// but we are building a container with only rootsignature part
+void DxcContext::ExtractRootSignature(IDxcBlob *pBlob, IDxcBlob **ppResult) {
+  
+  DXASSERT_NOMSG(pBlob != nullptr && ppResult != nullptr);
+  const hlsl::DxilContainerHeader *pHeader = (hlsl::DxilContainerHeader *)(pBlob->GetBufferPointer());
+  IFTBOOL(hlsl::IsValidDxilContainer(pHeader, pHeader->ContainerSizeInBytes), DXC_E_CONTAINER_INVALID);
+  const hlsl::DxilPartHeader *pPartHeader = hlsl::GetDxilPartByType(pHeader, hlsl::DxilFourCC::DFCC_RootSignature);
+  IFTBOOL(pPartHeader != nullptr, DXC_E_MISSING_PART);
+
+  // Get new header and allocate memory for new container
+  hlsl::DxilContainerHeader newHeader;
+  uint32_t containerSize = hlsl::GetDxilContainerSizeFromParts(1, pPartHeader->PartSize);
+  hlsl::InitDxilContainer(&newHeader, 1, containerSize); 
+  CComPtr<IMalloc> pMalloc;
+  CComPtr<hlsl::AbstractMemoryStream> pMemoryStream;
+  IFT(CoGetMalloc(1, &pMalloc));
+  IFT(hlsl::CreateMemoryStream(pMalloc, &pMemoryStream));
+  ULONG cbWritten;
+
+  // Write Container Header
+  IFT(pMemoryStream->Write(&newHeader, sizeof(hlsl::DxilContainerHeader), &cbWritten));
+  IFTBOOL(cbWritten == sizeof(hlsl::DxilContainerHeader), E_OUTOFMEMORY);
+  
+  // Write Part Offset
+  uint32_t offset = sizeof(hlsl::DxilContainerHeader) + hlsl::GetOffsetTableSize(1);
+  IFT(pMemoryStream->Write(&offset, sizeof(uint32_t), &cbWritten));
+  IFTBOOL(cbWritten == sizeof(uint32_t), E_OUTOFMEMORY);
+  
+  // Write Root Signature Header
+  IFT(pMemoryStream->Write(pPartHeader, sizeof(hlsl::DxilPartHeader), &cbWritten));
+  IFTBOOL(cbWritten == sizeof(hlsl::DxilPartHeader), E_OUTOFMEMORY);
+  const char * partContent = hlsl::GetDxilPartData(pPartHeader);
+  
+  // Write Root Signature Content
+  IFT(pMemoryStream->Write(partContent, pPartHeader->PartSize, &cbWritten));
+  IFTBOOL(cbWritten == pPartHeader->PartSize, E_OUTOFMEMORY);
+  
+  // Return Result
+  CComPtr<IDxcBlob> pResult;
+  IFT(pMemoryStream->QueryInterface(&pResult));
+  *ppResult = pResult.Detach();
+}
+
+void DxcContext::VerifyRootSignature() {
+  // Get dxil container from file
+  CComPtr<IDxcBlobEncoding> pSource;
+  ReadFileIntoBlob(m_dxcSupport, StringRefUtf16(m_Opts.InputFile), &pSource);
+  hlsl::DxilContainerHeader *pSourceHeader = (hlsl::DxilContainerHeader *)pSource->GetBufferPointer();
+  IFTBOOLMSG(hlsl::IsValidDxilContainer(pSourceHeader, pSourceHeader->ContainerSizeInBytes), E_INVALIDARG, "invalid DXIL container to verify.");
+
+  // Get rootsignature from file
+  CComPtr<IDxcBlob> pRootSignature;
+
+  IFTMSG(ReadFileIntoPartContent(
+             hlsl::DxilFourCC::DFCC_RootSignature,
+             StringRefUtf16(m_Opts.VerifyRootSignatureSource), &pRootSignature),
+         "invalid root signature to verify.");
+
+  // TODO : Right now we are just going to bild a new blob with updated root signature to verify root signature
+  // Since dxil container builder will verify on its behalf. 
+  // This does unnecessary memory allocation. We can improve this later. 
+  CComPtr<IDxcContainerBuilder> pContainerBuilder;
+  IFT(m_dxcSupport.CreateInstance(CLSID_DxcContainerBuilder, &pContainerBuilder));
+  IFT(pContainerBuilder->Load(pSource));
+  // Try removing root signature if it already exists
+  pContainerBuilder->RemovePart(hlsl::DxilFourCC::DFCC_RootSignature);
+  IFT(pContainerBuilder->AddPart(hlsl::DxilFourCC::DFCC_RootSignature, pRootSignature));  
+  CComPtr<IDxcOperationResult> pOperationResult;
+  IFT(pContainerBuilder->SerializeContainer(&pOperationResult));
+  HRESULT status = E_FAIL;
+  CComPtr<IDxcBlob> pResult;
+  IFT(pOperationResult->GetStatus(&status));
+  if (FAILED(status)) {
+    if (!m_Opts.OutputWarningsFile.empty()) {
+      CComPtr<IDxcBlobEncoding> pErrors;
+      IFT(pOperationResult->GetErrorBuffer(&pErrors));
+      WriteBlobToFile(pErrors, m_Opts.OutputWarningsFile);
+    }
+    else {
+      WriteOperationErrorsToConsole(pOperationResult, m_Opts.OutputWarnings);
+    }
+  }
+  else {
+    printf("root signature verification succeeded.");
+  }
+}
+
 class DxcIncludeHandlerForInjectedSources : public IDxcIncludeHandler {
 private:
   DXC_MICROCOM_REF_FIELD(m_dwRef)
@@ -515,7 +666,7 @@ void DxcContext::DumpBinary() {
 void DxcContext::Preprocess() {
   DXASSERT(!m_Opts.Preprocess.empty(), "else option reading should have failed");
   CComPtr<IDxcCompiler> pCompiler;
-  CComPtr<IDxcOperationResult> pCompileResult;
+  CComPtr<IDxcOperationResult> pPreprocessResult;
   CComPtr<IDxcBlobEncoding> pSource;
   std::vector<LPCWSTR> args;
 
@@ -526,19 +677,14 @@ void DxcContext::Preprocess() {
 
   ReadFileIntoBlob(m_dxcSupport, StringRefUtf16(m_Opts.InputFile), &pSource);
   IFT(m_dxcSupport.CreateInstance(CLSID_DxcCompiler, &pCompiler));
-  IFT(pCompiler->Compile(pSource, StringRefUtf16(m_Opts.InputFile),
-    StringRefUtf16(m_Opts.EntryPoint),
-    StringRefUtf16(m_Opts.TargetProfile), args.data(),
-    args.size(), m_Opts.Defines.data(),
-    m_Opts.Defines.size(), pIncludeHandler, &pCompileResult));
-
-  WriteOperationErrorsToConsole(pCompileResult, m_Opts.OutputWarnings);
+  IFT(pCompiler->Preprocess(pSource, StringRefUtf16(m_Opts.InputFile), args.data(), args.size(), m_Opts.Defines.data(), m_Opts.Defines.size(), pIncludeHandler, &pPreprocessResult));
+  WriteOperationErrorsToConsole(pPreprocessResult, m_Opts.OutputWarnings);
 
   HRESULT status;
-  IFT(pCompileResult->GetStatus(&status));
+  IFT(pPreprocessResult->GetStatus(&status));
   if (SUCCEEDED(status)) {
     CComPtr<IDxcBlob> pProgram;
-    IFT(pCompileResult->GetResult(&pProgram));
+    IFT(pPreprocessResult->GetResult(&pProgram));
     WriteBlobToFile(pProgram, m_Opts.Preprocess);
   }
 }
@@ -579,7 +725,7 @@ void DxcContext::WriteHeader(IDxcBlobEncoding *pDisassembly, IDxcBlob *pCode,
   {
     std::string s;
     llvm::raw_string_ostream OS(s);
-    OS << "\r\nconst BYTE " << pVariableName << "[] = {";
+    OS << "\r\nconst unsigned char " << pVariableName << "[] = {";
     const uint8_t *pBytes = (const uint8_t *)pCode->GetBufferPointer();
     size_t len = pCode->GetBufferSize();
     s.reserve(100 + len * 6 + (len / 12) * 3); // rough estimate
@@ -614,8 +760,8 @@ HRESULT DxcContext::FindModuleBlob(hlsl::DxilFourCC fourCC, IDxcBlob *pSource, I
 
   if (hlsl::IsValidDxilContainer((hlsl::DxilContainerHeader*)pSource->GetBufferPointer(), pSource->GetBufferSize())) {
     hlsl::DxilContainerHeader *pDxilContainerHeader = (hlsl::DxilContainerHeader*)pSource->GetBufferPointer();
-    pDxilPartHeader = *std::find_if(begin(pDxilContainerHeader), end(pDxilContainerHeader), hlsl::DxilPartIsType(fourCC));
-    IFTARG(pDxilPartHeader != *end(pDxilContainerHeader));
+    pDxilPartHeader = hlsl::GetDxilPartByType(pDxilContainerHeader, fourCC);
+    IFTBOOL(pDxilPartHeader != nullptr, DXC_E_CONTAINER_MISSING_DEBUG);
   }
   if (fourCC == pDxilPartHeader->PartFourCC) {
     UINT32 pBlobSize;
@@ -680,7 +826,7 @@ int __cdecl wmain(int argc, const wchar_t **argv_) {
           ReadDxcOpts(optionTable, DxcFlags, argStrings, dxcOpts, errorStream);
       errorStream.flush();
       if (errorString.size()) {
-        fprintf(stderr, "%s", errorString.data());
+        fprintf(stderr, "dxc failed : %s", errorString.data());
       }
       if (optResult != 0) {
         return optResult;
@@ -737,15 +883,31 @@ int __cdecl wmain(int argc, const wchar_t **argv_) {
                                           // UTF-8 because we use ASCII only errors
       if (msg == nullptr || *msg == '\0') {
         if (hlslException.hr == DXC_E_DUPLICATE_PART) {
-          sprintf_s(printBuffer, _countof(printBuffer),
-                    "DXIL container already contains the given part.");
+          sprintf_s(
+              printBuffer, _countof(printBuffer),
+              "dxc failed : DXIL container already contains the given part.");
         } else if (hlslException.hr == DXC_E_MISSING_PART) {
+          sprintf_s(
+              printBuffer, _countof(printBuffer),
+              "dxc failed : DXIL container does not contain the given part.");
+        } else if (hlslException.hr == DXC_E_CONTAINER_INVALID) {
           sprintf_s(printBuffer, _countof(printBuffer),
-                    "DXIL container does not contain the given part.");
-        }
-        else {
+                    "dxc failed : Invalid DXIL container.");
+        } else if (hlslException.hr == DXC_E_CONTAINER_MISSING_DXIL) {
+          sprintf_s(printBuffer, _countof(printBuffer),
+                    "dxc failed : DXIL container is missing DXIL part.");
+        } else if (hlslException.hr == DXC_E_CONTAINER_MISSING_DEBUG) {
+          sprintf_s(printBuffer, _countof(printBuffer),
+                    "dxc failed : DXIL container is missing Debug Info part.");
+        } else if (hlslException.hr == E_OUTOFMEMORY) {
+          sprintf_s(printBuffer, _countof(printBuffer),
+                    "dxc failed : Out of Memory.");
+        } else if (hlslException.hr == E_INVALIDARG) {
+          sprintf_s(printBuffer, _countof(printBuffer),
+                    "dxc failed : Invalid argument.");
+        } else {
           sprintf_s(printBuffer, _countof(printBuffer),
-            "Compilation failed - error code 0x%08x.\n", hlslException.hr);
+            "dxc failed : error code 0x%08x.\n", hlslException.hr);
         }
         msg = printBuffer;
       }

+ 101 - 4
utils/hct/hcttestcmds.cmd

@@ -18,6 +18,25 @@ if %errorlevel% neq  0 (
   exit /b 1
 )
 
+
+dxc.exe /T ps_6_0 smoke.hlsl /Fc smoke.hlsl.c 1>nul
+if %errorlevel% neq 0 (
+  echo Failed - %CD%\dxc.exe /T ps_6_0 smoke.hlsl /Fc %CD%\smoke.hlsl.c
+  exit /b 1
+)
+
+dxc.exe /T ps_6_0 smoke.hlsl /Zi /Fd smoke.hlsl.d 2>nul
+if %errorlevel% neq 0 (
+  echo Failed - %CD%\dxc.exe /T ps_6_0 smoke.hlsl /Zi /Fd %CD%\smoke.hlsl.d
+  exit /b 1
+)
+
+dxc.exe /T ps_6_0 smoke.hlsl /Fe smoke.hlsl.e 1>nul
+if %errorlevel% neq 0 (
+  echo Failed - %CD%\dxc.exe /T ps_6_0 smoke.hlsl /Fe %CD%\smoke.hlsl.e
+  exit /b 1
+)
+
 echo Smoke test for dxc command line program ...
 dxc.exe /T ps_6_0 smoke.hlsl /Fh smoke.hlsl.h /Vn g_myvar 1> nul
 if %errorlevel% neq 0 (
@@ -36,14 +55,57 @@ if %errorlevel% neq 0 (
   exit /b 1
 )
 
+dxc.exe smoke.hlsl /P preprocessed.hlsl 1>nul
+if %errorlevel% neq 0 (
+  echo Failed to preprocess smoke.hlsl
+  exit /b 1
+)
+
+dxc.exe /T ps_6_0 smoke.hlsl -force_rootsig_ver rootsig_1_0 1>nul
+if %errorlevel% neq 0 (
+  echo Failed to compile with forcing rootsignature rootsig_1_0
+  exit /b 1
+)
+
+dxc.exe /T ps_6_0 smoke.hlsl -force_rootsig_ver rootsig_1_1 1>nul
+if %errorlevel% neq 0 (
+  echo Failed to compile with forcing rootsignature rootsig_1_1
+  exit /b 1
+)
+
+dxc.exe /T ps_6_0 smoke.hlsl -force_rootsig_ver rootsig_2_0 2>nul
+if %errorlevel% equ 0 (
+  echo rootsig_2_0 is not supported but compilation passed
+  exit /b 1
+)
+
+dxc.exe /T ps_6_0 smoke.hlsl /HV 2016 1>nul
+if %errorlevel% neq 0 (
+  echo Failed to compile with HLSL version 2016
+  exit /b 1
+)
+
+dxc.exe /T ps_6_0 smoke.hlsl /HV 2015 2>nul
+if %errorlevel% equ 0 (
+  echo Unsupported HLSL version 2015 should fail but did not fail
+  exit /b 1
+)
+
 dxc.exe /T ps_6_0 smoke.hlsl /Zi /Fo smoke.cso 1> nul
 if %errorlevel% neq 0 (
-  echo Failed to compile to binary object from %CD%\smoke.hlsl.h
+  echo Failed to compile to binary object from %CD%\smoke.hlsl
   exit /b 1
 )
+
+dxc.exe /T ps_6_0 smoke.hlsl /Zi /Fo smoke.cso /Cc /Ni /No /Lx 1> nul
+if %errorlevel% neq 0 (
+  echo Failed to compile to binary object from %CD%\smoke.hlsl with disassembly options
+  exit /b 1
+)
+
 dxc.exe -dumpbin smoke.cso 1> nul
 if %errorlevel% neq 0 (
-  echo Failed to disassemble binary object from %CD%\smoke.hlsl.h
+  echo Failed to disassemble binary object from %CD%\smoke.hlsl
   exit /b 1
 )
 
@@ -71,6 +133,7 @@ if %errorlevel% neq 0 (
   exit /b 1
 )
 
+
 dxc.exe smoke.cso /dumpbin /Qstrip_debug /Fo nodebug.cso 1>nul
 if %errorlevel% neq 0 (
   echo Failed to strip debug part from DXIL container blob
@@ -83,13 +146,35 @@ if %errorlevel% neq 0 (
   exit /b 1
 )
 
+dxc.exe smoke.cso /dumpbin /extractrootsignature /Fo rootsig.cso 1>nul
+if %errorlevel% neq 0 (
+  echo Failed to extract rootsignature from DXIL container blob
+  exit /b 1
+)
+
+dxc.exe norootsignature.cso /dumpbin /setrootsignature rootsig.cso /Fo smoke.cso 1>nul
+if %errorlevel% neq 0 (
+  echo Failed to setrootsignature to DXIL conatiner with no root signature
+  exit /b 1
+)
+
+dxc.exe smoke.cso /dumpbin /setrootsignature rootsig.cso /Fo smoke.cso 1>nul
+if %errorlevel% neq 0 (
+  echo Failed to setrootsignature to DXIL container that already contains root signature
+)
+
 echo private data > private.txt
 dxc.exe smoke.cso /dumpbin /setprivate private.txt /Fo private.cso 1>nul
 if %errorlevel% neq 0 (
-  echo Failed to set private data from DXIL container blob
+  echo Failed to set private data to DXIL container with no private data
   exit /b 1
 )
 
+dxc.exe private.cso /dumpbin /setprivate private.txt /Fo private.cso 1>nul
+if %errorlevel% neq 0 (
+  echo Failed to set private data to DXIL container that already contains private data
+)
+
 dxc.exe private.cso /dumpbin /Qstrip_priv /Fo noprivate.cso 1>nul
 if %errorlevel% neq 0 (
   echo Failed to strip private data from DXIL container blob
@@ -102,13 +187,19 @@ if %errorlevel% neq 0 (
   exit /b 1
 )
 
+findstr "private data" %CD%\private1.txt 1>nul
+if %errorlevel% neq 0 (
+  echo Failed to get private data content from DXIL container blob
+  exit /b 1
+)
+
 FC smoke.cso noprivate.cso 1>nul
 if %errorlevel% neq 0 (
   echo Appending and removing blob roundtrip failed.
   exit /b 1
 )
 
-dxc.exe private.cso /Dumpbin /Qstrip_priv /Qstrip_debug /Qstrip_rootsignature /Fo noprivdebugroot.cso 1>nul
+dxc.exe private.cso /dumpbin /Qstrip_priv /Qstrip_debug /Qstrip_rootsignature /Fo noprivdebugroot.cso 1>nul
 if %errorlevel% neq 0 (
   echo Failed to extract multiple parts from DXIL container blob
   exit /b 1
@@ -175,6 +266,10 @@ if %errorlevel% neq 0 (
 )
 
 rem Clean up.
+del %CD%\preprocessed.hlsl
+del %CD%\smoke.hlsl.c
+del %CD%\smoke.hlsl.d
+del %CD%\smoke.hlsl.e
 del %CD%\smoke.hlsl.h
 del %CD%\smoke.cso
 del %CD%\private.cso
@@ -184,5 +279,7 @@ del %CD%\noprivate.cso
 del %CD%\nodebug.cso
 del %CD%\noprivdebugroot.cso
 del %CD%\norootsignature.cso
+del %CD%\smoke.cso.inlined.ll
+del %CD%\smoke.cso.plain.ll
 
 exit /b 0