diff --git a/SPIRV/CMakeLists.txt b/SPIRV/CMakeLists.txt
index 1e5513c735619fe3fa8e39a5c8d63576c0427f60..bf2be167e7ea86e571f09aef5f87a16e6e2060c9 100755
--- a/SPIRV/CMakeLists.txt
+++ b/SPIRV/CMakeLists.txt
@@ -60,6 +60,7 @@ if(ENABLE_OPT)
         PRIVATE ${spirv-tools_SOURCE_DIR}/source
     )
     target_link_libraries(SPIRV glslang SPIRV-Tools-opt)
+    target_include_directories(SPIRV PUBLIC ../External)
 else()
     target_link_libraries(SPIRV glslang)
 endif(ENABLE_OPT)
diff --git a/SPIRV/disassemble.cpp b/SPIRV/disassemble.cpp
index b432e65d0f031c2c3fc3b3bd7560cd7805cab52f..16770c47868ddf6de4ee740e5b74de817d0ea7f3 100755
--- a/SPIRV/disassemble.cpp
+++ b/SPIRV/disassemble.cpp
@@ -716,4 +716,25 @@ void Disassemble(std::ostream& out, const std::vector<unsigned int>& stream)
     SpirvStream.processInstructions();
 }
 
+#if ENABLE_OPT
+
+#include "spirv-tools/source/disassemble.h"
+
+// Use the SPIRV-Tools disassembler to print SPIR-V.
+void SpirvToolsDisassemble(std::ostream& out, const std::vector<unsigned int>& spirv)
+{
+    spv_context context = spvContextCreate(SPV_ENV_UNIVERSAL_1_3);
+    spv_text text;
+    spv_diagnostic diagnostic = nullptr;
+    spvBinaryToText(context, &spirv.front(), spirv.size(),
+        SPV_BINARY_TO_TEXT_OPTION_FRIENDLY_NAMES | SPV_BINARY_TO_TEXT_OPTION_INDENT,
+        &text, &diagnostic);
+    if (diagnostic == nullptr)
+        out << text->str;
+    else
+        spvDiagnosticPrint(diagnostic);
+}
+
+#endif
+
 }; // end namespace spv
diff --git a/SPIRV/disassemble.h b/SPIRV/disassemble.h
index 47cef65a57395f7da44464247866b5e64de7e57e..bdde5cb4e6c10185d0e7b44059ab53829bffaf52 100755
--- a/SPIRV/disassemble.h
+++ b/SPIRV/disassemble.h
@@ -45,8 +45,12 @@
 
 namespace spv {
 
+    // disassemble with glslang custom disassembler
     void Disassemble(std::ostream& out, const std::vector<unsigned int>&);
 
+    // disassemble with SPIRV-Tools disassembler
+    void SpirvToolsDisassemble(std::ostream& out, const std::vector<unsigned int>& stream);
+
 };  // end namespace spv
 
 #endif // disassembler_H
diff --git a/StandAlone/CMakeLists.txt b/StandAlone/CMakeLists.txt
index d500121df5b9cd2df0bf212ce28b643e97f2bb3d..5cea53d9f64e1c0b78e95e4f93743e4ebc93fff4 100755
--- a/StandAlone/CMakeLists.txt
+++ b/StandAlone/CMakeLists.txt
@@ -33,6 +33,7 @@ endif(WIN32)
 
 target_link_libraries(glslangValidator ${LIBRARIES})
 target_link_libraries(spirv-remap ${LIBRARIES})
+target_include_directories(glslangValidator PUBLIC ../External)
 
 if(WIN32)
     source_group("Source" FILES ${SOURCES})
diff --git a/StandAlone/StandAlone.cpp b/StandAlone/StandAlone.cpp
old mode 100644
new mode 100755
index 6736dbcbf3fc963c12550f22ca6ec770e7937a7f..549cb0dd91f1084bec7a7478e35577e4dec84c63
--- a/StandAlone/StandAlone.cpp
+++ b/StandAlone/StandAlone.cpp
@@ -102,6 +102,7 @@ enum TOptions {
     EOptionDumpBareVersion      = (1 << 31),
 };
 bool targetHlslFunctionality1 = false;
+bool SpvToolsDisassembler = false;
 
 //
 // Return codes from main/exit().
@@ -506,6 +507,8 @@ void ProcessArguments(std::vector<std::unique_ptr<glslang::TWorkItem>>& workItem
                         sourceEntryPointName = argv[1];
                         bumpArg();
                         break;
+                    } else if (lowerword == "spirv-dis") {
+                        SpvToolsDisassembler = true;
                     } else if (lowerword == "stdin") {
                         Options |= EOptionStdin;
                         shaderStageName = argv[1];
@@ -982,9 +985,15 @@ void CompileAndLinkShaderUnits(std::vector<ShaderCompUnit> compUnits)
                         } else {
                             glslang::OutputSpvBin(spirv, GetBinaryName((EShLanguage)stage));
                         }
-                        if (Options & EOptionHumanReadableSpv) {
+#if ENABLE_OPT
+                        if (SpvToolsDisassembler)
+                            spv::SpirvToolsDisassemble(std::cout, spirv);
+#else
+                        if (SpvToolsDisassembler)
+                            printf("SPIRV-Tools is not enabled; use -H for human readable SPIR-V\n");
+#endif
+                        if (!SpvToolsDisassembler && (Options & EOptionHumanReadableSpv))
                             spv::Disassemble(std::cout, spirv);
-                        }
                     }
                 }
             }
@@ -1405,6 +1414,8 @@ void usage()
            "  --shift-UBO-binding [stage] [num set]... per-descriptor-set shift values\n"
            "  --shift-cbuffer-binding [stage] num  synonym for --shift-UBO-binding\n"
            "  --shift-cbuffer-binding [stage] [num set]... per-descriptor-set shift values\n"
+           "  --spirv-dis                          output standard form disassembly; works only\n"
+           "                                       when a SPIR-V generation option is also used\n"
            "  --sub [stage] num                    synonym for --shift-UBO-binding\n"
            "  --source-entrypoint <name>           the given shader source function is\n"
            "                                       renamed to be the <name> given in -e\n"