From: John Kessenich Date: Thu, 23 Aug 2018 21:17:10 +0000 (-0600) Subject: SPV: Isolate SPIRV-tools glue to its own file. X-Git-Tag: submit/tizen/20181206.072130^2~82^2~2 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=717c80a9dec2b70b0a5d3c80d6f780577b0ec7b2;p=platform%2Fupstream%2Fglslang.git SPV: Isolate SPIRV-tools glue to its own file. --- diff --git a/SPIRV/CMakeLists.txt b/SPIRV/CMakeLists.txt index 48ca7795..1997e74c 100755 --- a/SPIRV/CMakeLists.txt +++ b/SPIRV/CMakeLists.txt @@ -5,6 +5,7 @@ set(SOURCES SpvBuilder.cpp SpvPostProcess.cpp doc.cpp + SpvTools.cpp disassemble.cpp) set(SPVREMAP_SOURCES @@ -23,6 +24,7 @@ set(HEADERS SpvBuilder.h spvIR.h doc.h + SpvTools.h disassemble.h) set(SPVREMAP_HEADERS diff --git a/SPIRV/GlslangToSpv.cpp b/SPIRV/GlslangToSpv.cpp index eedb8e05..3b494790 100755 --- a/SPIRV/GlslangToSpv.cpp +++ b/SPIRV/GlslangToSpv.cpp @@ -54,15 +54,6 @@ namespace spv { #endif } -#if ENABLE_OPT - #include "spirv-tools/optimizer.hpp" - #include "spirv-tools/libspirv.h" -#endif - -#if ENABLE_OPT -using namespace spvtools; -#endif - // Glslang includes #include "../glslang/MachineIndependent/localintermediate.h" #include "../glslang/MachineIndependent/SymbolTable.h" @@ -7004,122 +6995,6 @@ void GlslangToSpv(const glslang::TIntermediate& intermediate, std::vector 0) - return spv_target_env::SPV_ENV_OPENGL_4_5; - - logger->missingFunctionality("Target version for SPIRV-Tools validator"); - return spv_target_env::SPV_ENV_UNIVERSAL_1_0; -} - -// Apply the SPIRV-Tools validator to generated SPIR-V. -void SpirvToolsValidate(const glslang::TIntermediate& intermediate, std::vector& spirv, - spv::SpvBuildLogger* logger) -{ - // validate - spv_context context = spvContextCreate(MapToSpirvToolsEnv(intermediate.getSpv(), logger)); - spv_const_binary_t binary = { spirv.data(), spirv.size() }; - spv_diagnostic diagnostic = nullptr; - spv_validator_options options = spvValidatorOptionsCreate(); - spvValidatorOptionsSetRelaxBlockLayout(options, intermediate.usingHlslOffsets()); - spvValidateWithOptions(context, options, &binary, &diagnostic); - - // report - if (diagnostic != nullptr) { - logger->error("SPIRV-Tools Validation Errors"); - logger->error(diagnostic->error); - } - - // tear down - spvValidatorOptionsDestroy(options); - spvDiagnosticDestroy(diagnostic); - spvContextDestroy(context); -} - -// Apply the SPIRV-Tools optimizer to generated SPIR-V, for the purpose of -// legalizing HLSL SPIR-V. -void SpirvToolsLegalize(const glslang::TIntermediate& intermediate, std::vector& spirv, - spv::SpvBuildLogger* logger, const SpvOptions* options) -{ - spv_target_env target_env = SPV_ENV_UNIVERSAL_1_2; - - spvtools::Optimizer optimizer(target_env); - optimizer.SetMessageConsumer( - [](spv_message_level_t level, const char *source, const spv_position_t &position, const char *message) { - auto &out = std::cerr; - switch (level) - { - case SPV_MSG_FATAL: - case SPV_MSG_INTERNAL_ERROR: - case SPV_MSG_ERROR: - out << "error: "; - break; - case SPV_MSG_WARNING: - out << "warning: "; - break; - case SPV_MSG_INFO: - case SPV_MSG_DEBUG: - out << "info: "; - break; - default: - break; - } - if (source) - { - out << source << ":"; - } - out << position.line << ":" << position.column << ":" << position.index << ":"; - if (message) - { - out << " " << message; - } - out << std::endl; - }); - - optimizer.RegisterPass(CreateMergeReturnPass()); - optimizer.RegisterPass(CreateInlineExhaustivePass()); - optimizer.RegisterPass(CreateEliminateDeadFunctionsPass()); - optimizer.RegisterPass(CreateScalarReplacementPass()); - optimizer.RegisterPass(CreateLocalAccessChainConvertPass()); - optimizer.RegisterPass(CreateLocalSingleBlockLoadStoreElimPass()); - optimizer.RegisterPass(CreateLocalSingleStoreElimPass()); - optimizer.RegisterPass(CreateSimplificationPass()); - optimizer.RegisterPass(CreateAggressiveDCEPass()); - optimizer.RegisterPass(CreateVectorDCEPass()); - optimizer.RegisterPass(CreateDeadInsertElimPass()); - optimizer.RegisterPass(CreateAggressiveDCEPass()); - optimizer.RegisterPass(CreateDeadBranchElimPass()); - optimizer.RegisterPass(CreateBlockMergePass()); - optimizer.RegisterPass(CreateLocalMultiStoreElimPass()); - optimizer.RegisterPass(CreateIfConversionPass()); - optimizer.RegisterPass(CreateSimplificationPass()); - optimizer.RegisterPass(CreateAggressiveDCEPass()); - optimizer.RegisterPass(CreateVectorDCEPass()); - optimizer.RegisterPass(CreateDeadInsertElimPass()); - if (options->optimizeSize) { - optimizer.RegisterPass(CreateRedundancyEliminationPass()); - // TODO(greg-lunarg): Add this when AMD driver issues are resolved - // optimizer.RegisterPass(CreateCommonUniformElimPass()); - } - optimizer.RegisterPass(CreateAggressiveDCEPass()); - optimizer.RegisterPass(CreateCFGCleanupPass()); - - optimizer.Run(spirv.data(), spirv.size(), &spirv); -} - -#endif - void GlslangToSpv(const glslang::TIntermediate& intermediate, std::vector& spirv, spv::SpvBuildLogger* logger, SpvOptions* options) { @@ -7144,10 +7019,12 @@ void GlslangToSpv(const glslang::TIntermediate& intermediate, std::vectoroptimizeSize) && - !options->disableOptimizer) { + if ((intermediate.getSource() == EShSourceHlsl || options->optimizeSize) && !options->disableOptimizer) SpirvToolsLegalize(intermediate, spirv, logger, options); - } + + if (options->disassemble) + glslang::SpirvToolsDisassemble(std::cout, spirv); + #endif glslang::GetThreadPoolAllocator().pop(); diff --git a/SPIRV/GlslangToSpv.h b/SPIRV/GlslangToSpv.h old mode 100644 new mode 100755 index f7f7cff6..4169c12e --- a/SPIRV/GlslangToSpv.h +++ b/SPIRV/GlslangToSpv.h @@ -38,6 +38,7 @@ #pragma warning(disable : 4464) // relative include path contains '..' #endif +#include "SpvTools.h" #include "../glslang/Include/intermediate.h" #include @@ -47,14 +48,6 @@ namespace glslang { -struct SpvOptions { - SpvOptions() : generateDebugInfo(false), disableOptimizer(true), - optimizeSize(false) { } - bool generateDebugInfo; - bool disableOptimizer; - bool optimizeSize; -}; - void GetSpirvVersion(std::string&); int GetSpirvGeneratorVersion(); void GlslangToSpv(const glslang::TIntermediate& intermediate, std::vector& spirv, diff --git a/SPIRV/SpvTools.cpp b/SPIRV/SpvTools.cpp new file mode 100755 index 00000000..7a15c874 --- /dev/null +++ b/SPIRV/SpvTools.cpp @@ -0,0 +1,188 @@ +// +// Copyright (C) 2014-2016 LunarG, Inc. +// Copyright (C) 2018 Google, Inc. +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// +// Neither the name of 3Dlabs Inc. Ltd. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. + +// +// Call into SPIRV-Tools to disassemble, validate, and optimize. +// + +#if ENABLE_OPT + +#include +#include + +#include "SpvTools.h" +#include "spirv-tools/optimizer.hpp" +#include "spirv-tools/libspirv.h" + +namespace glslang { + +// Translate glslang's view of target versioning to what SPIRV-Tools uses. +spv_target_env MapToSpirvToolsEnv(const SpvVersion& spvVersion, spv::SpvBuildLogger* logger) +{ + switch (spvVersion.vulkan) { + case glslang::EShTargetVulkan_1_0: return spv_target_env::SPV_ENV_VULKAN_1_0; + case glslang::EShTargetVulkan_1_1: return spv_target_env::SPV_ENV_VULKAN_1_1; + default: + break; + } + + if (spvVersion.openGl > 0) + return spv_target_env::SPV_ENV_OPENGL_4_5; + + logger->missingFunctionality("Target version for SPIRV-Tools validator"); + return spv_target_env::SPV_ENV_UNIVERSAL_1_0; +} + + +// Use the SPIRV-Tools disassembler to print SPIR-V. +void SpirvToolsDisassemble(std::ostream& out, const std::vector& spirv) +{ + // disassemble + spv_context context = spvContextCreate(SPV_ENV_UNIVERSAL_1_3); + spv_text text; + spv_diagnostic diagnostic = nullptr; + spvBinaryToText(context, spirv.data(), spirv.size(), + SPV_BINARY_TO_TEXT_OPTION_FRIENDLY_NAMES | SPV_BINARY_TO_TEXT_OPTION_INDENT, + &text, &diagnostic); + + // dump + if (diagnostic == nullptr) + out << text->str; + else + spvDiagnosticPrint(diagnostic); + + // teardown + spvDiagnosticDestroy(diagnostic); + spvContextDestroy(context); +} + +// Apply the SPIRV-Tools validator to generated SPIR-V. +void SpirvToolsValidate(const glslang::TIntermediate& intermediate, std::vector& spirv, + spv::SpvBuildLogger* logger) +{ + // validate + spv_context context = spvContextCreate(MapToSpirvToolsEnv(intermediate.getSpv(), logger)); + spv_const_binary_t binary = { spirv.data(), spirv.size() }; + spv_diagnostic diagnostic = nullptr; + spv_validator_options options = spvValidatorOptionsCreate(); + spvValidatorOptionsSetRelaxBlockLayout(options, intermediate.usingHlslOffsets()); + spvValidateWithOptions(context, options, &binary, &diagnostic); + + // report + if (diagnostic != nullptr) { + logger->error("SPIRV-Tools Validation Errors"); + logger->error(diagnostic->error); + } + + // tear down + spvValidatorOptionsDestroy(options); + spvDiagnosticDestroy(diagnostic); + spvContextDestroy(context); +} + +// Apply the SPIRV-Tools optimizer to generated SPIR-V, for the purpose of +// legalizing HLSL SPIR-V. +void SpirvToolsLegalize(const glslang::TIntermediate& intermediate, std::vector& spirv, + spv::SpvBuildLogger* logger, const SpvOptions* options) +{ + spv_target_env target_env = SPV_ENV_UNIVERSAL_1_2; + + spvtools::Optimizer optimizer(target_env); + optimizer.SetMessageConsumer( + [](spv_message_level_t level, const char *source, const spv_position_t &position, const char *message) { + auto &out = std::cerr; + switch (level) + { + case SPV_MSG_FATAL: + case SPV_MSG_INTERNAL_ERROR: + case SPV_MSG_ERROR: + out << "error: "; + break; + case SPV_MSG_WARNING: + out << "warning: "; + break; + case SPV_MSG_INFO: + case SPV_MSG_DEBUG: + out << "info: "; + break; + default: + break; + } + if (source) + { + out << source << ":"; + } + out << position.line << ":" << position.column << ":" << position.index << ":"; + if (message) + { + out << " " << message; + } + out << std::endl; + }); + + optimizer.RegisterPass(spvtools::CreateMergeReturnPass()); + optimizer.RegisterPass(spvtools::CreateInlineExhaustivePass()); + optimizer.RegisterPass(spvtools::CreateEliminateDeadFunctionsPass()); + optimizer.RegisterPass(spvtools::CreateScalarReplacementPass()); + optimizer.RegisterPass(spvtools::CreateLocalAccessChainConvertPass()); + optimizer.RegisterPass(spvtools::CreateLocalSingleBlockLoadStoreElimPass()); + optimizer.RegisterPass(spvtools::CreateLocalSingleStoreElimPass()); + optimizer.RegisterPass(spvtools::CreateSimplificationPass()); + optimizer.RegisterPass(spvtools::CreateAggressiveDCEPass()); + optimizer.RegisterPass(spvtools::CreateVectorDCEPass()); + optimizer.RegisterPass(spvtools::CreateDeadInsertElimPass()); + optimizer.RegisterPass(spvtools::CreateAggressiveDCEPass()); + optimizer.RegisterPass(spvtools::CreateDeadBranchElimPass()); + optimizer.RegisterPass(spvtools::CreateBlockMergePass()); + optimizer.RegisterPass(spvtools::CreateLocalMultiStoreElimPass()); + optimizer.RegisterPass(spvtools::CreateIfConversionPass()); + optimizer.RegisterPass(spvtools::CreateSimplificationPass()); + optimizer.RegisterPass(spvtools::CreateAggressiveDCEPass()); + optimizer.RegisterPass(spvtools::CreateVectorDCEPass()); + optimizer.RegisterPass(spvtools::CreateDeadInsertElimPass()); + if (options->optimizeSize) { + optimizer.RegisterPass(spvtools::CreateRedundancyEliminationPass()); + // TODO(greg-lunarg): Add this when AMD driver issues are resolved + // optimizer.RegisterPass(CreateCommonUniformElimPass()); + } + optimizer.RegisterPass(spvtools::CreateAggressiveDCEPass()); + optimizer.RegisterPass(spvtools::CreateCFGCleanupPass()); + + optimizer.Run(spirv.data(), spirv.size(), &spirv); +} + +#endif + +}; // end namespace glslang diff --git a/SPIRV/SpvTools.h b/SPIRV/SpvTools.h new file mode 100755 index 00000000..7a164387 --- /dev/null +++ b/SPIRV/SpvTools.h @@ -0,0 +1,79 @@ +// +// Copyright (C) 2014-2016 LunarG, Inc. +// Copyright (C) 2018 Google, Inc. +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// +// Neither the name of 3Dlabs Inc. Ltd. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. + +// +// Call into SPIRV-Tools to disassemble, validate, and optimize. +// + +#pragma once +#ifndef GLSLANG_SPV_TOOLS_H +#define GLSLANG_SPV_TOOLS_H + +#include +#include + +#include "../glslang/MachineIndependent/localintermediate.h" +#include "Logger.h" + +namespace glslang { + +struct SpvOptions { + SpvOptions() : generateDebugInfo(false), disableOptimizer(true), + optimizeSize(false), disassemble(false) { } + bool generateDebugInfo; + bool disableOptimizer; + bool optimizeSize; + bool disassemble; +}; + +#if ENABLE_OPT + +// Use the SPIRV-Tools disassembler to print SPIR-V. +void SpirvToolsDisassemble(std::ostream& out, const std::vector& spirv); + +// Apply the SPIRV-Tools validator to generated SPIR-V. +void SpirvToolsValidate(const glslang::TIntermediate& intermediate, std::vector& spirv, + spv::SpvBuildLogger*); + +// Apply the SPIRV-Tools optimizer to generated SPIR-V, for the purpose of +// legalizing HLSL SPIR-V. +void SpirvToolsLegalize(const glslang::TIntermediate& intermediate, std::vector& spirv, + spv::SpvBuildLogger*, const SpvOptions*); + +#endif + +}; // end namespace glslang + +#endif // GLSLANG_SPV_TOOLS_H \ No newline at end of file diff --git a/SPIRV/disassemble.cpp b/SPIRV/disassemble.cpp index b64584d9..6f316091 100755 --- a/SPIRV/disassemble.cpp +++ b/SPIRV/disassemble.cpp @@ -46,6 +46,7 @@ #include "disassemble.h" #include "doc.h" +#include "SpvTools.h" namespace spv { extern "C" { @@ -716,32 +717,4 @@ void Disassemble(std::ostream& out, const std::vector& stream) SpirvStream.processInstructions(); } -#if ENABLE_OPT - -#include "spirv-tools/libspirv.h" - -// Use the SPIRV-Tools disassembler to print SPIR-V. -void SpirvToolsDisassemble(std::ostream& out, const std::vector& spirv) -{ - // disassemble - spv_context context = spvContextCreate(SPV_ENV_UNIVERSAL_1_3); - spv_text text; - spv_diagnostic diagnostic = nullptr; - spvBinaryToText(context, spirv.data(), spirv.size(), - SPV_BINARY_TO_TEXT_OPTION_FRIENDLY_NAMES | SPV_BINARY_TO_TEXT_OPTION_INDENT, - &text, &diagnostic); - - // dump - if (diagnostic == nullptr) - out << text->str; - else - spvDiagnosticPrint(diagnostic); - - // teardown - spvDiagnosticDestroy(diagnostic); - spvContextDestroy(context); -} - -#endif - }; // end namespace spv diff --git a/SPIRV/disassemble.h b/SPIRV/disassemble.h index bdde5cb4..2a9a89b5 100755 --- a/SPIRV/disassemble.h +++ b/SPIRV/disassemble.h @@ -48,9 +48,6 @@ namespace spv { // disassemble with glslang custom disassembler void Disassemble(std::ostream& out, const std::vector&); - // disassemble with SPIRV-Tools disassembler - void SpirvToolsDisassemble(std::ostream& out, const std::vector& stream); - }; // end namespace spv #endif // disassembler_H diff --git a/StandAlone/StandAlone.cpp b/StandAlone/StandAlone.cpp index e49b26e5..35b27b21 100755 --- a/StandAlone/StandAlone.cpp +++ b/StandAlone/StandAlone.cpp @@ -978,6 +978,7 @@ void CompileAndLinkShaderUnits(std::vector compUnits) spvOptions.generateDebugInfo = true; spvOptions.disableOptimizer = (Options & EOptionOptimizeDisable) != 0; spvOptions.optimizeSize = (Options & EOptionOptimizeSize) != 0; + spvOptions.disassemble = SpvToolsDisassembler; glslang::GlslangToSpv(*program.getIntermediate((EShLanguage)stage), spirv, &logger, &spvOptions); // Dump the spv to a file or stdout, etc., but only if not doing @@ -989,13 +990,6 @@ void CompileAndLinkShaderUnits(std::vector compUnits) } else { glslang::OutputSpvBin(spirv, GetBinaryName((EShLanguage)stage)); } -#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); } diff --git a/glslang/MachineIndependent/localintermediate.h b/glslang/MachineIndependent/localintermediate.h index 143d1afe..e0dab972 100755 --- a/glslang/MachineIndependent/localintermediate.h +++ b/glslang/MachineIndependent/localintermediate.h @@ -41,6 +41,8 @@ #include "../Public/ShaderLang.h" #include "Versions.h" +#include +#include #include #include #include diff --git a/gtests/TestFixture.h b/gtests/TestFixture.h old mode 100644 new mode 100755