| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | |
| | |
| | |
| |
|
| | #if ENABLE_OPT |
| |
|
| | #include <cstdio> |
| | #include <iostream> |
| |
|
| | #include "SpvTools.h" |
| | #include "spirv-tools/optimizer.hpp" |
| |
|
| | namespace glslang { |
| |
|
| | |
| | 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: |
| | switch (spvVersion.spv) { |
| | case EShTargetSpv_1_0: |
| | case EShTargetSpv_1_1: |
| | case EShTargetSpv_1_2: |
| | case EShTargetSpv_1_3: |
| | return spv_target_env::SPV_ENV_VULKAN_1_1; |
| | case EShTargetSpv_1_4: |
| | return spv_target_env::SPV_ENV_VULKAN_1_1_SPIRV_1_4; |
| | default: |
| | logger->missingFunctionality("Target version for SPIRV-Tools validator"); |
| | return spv_target_env::SPV_ENV_VULKAN_1_1; |
| | } |
| | case glslang::EShTargetVulkan_1_2: |
| | return spv_target_env::SPV_ENV_VULKAN_1_2; |
| | case glslang::EShTargetVulkan_1_3: |
| | return spv_target_env::SPV_ENV_VULKAN_1_3; |
| | 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; |
| | } |
| |
|
| | |
| | void OptimizerMesssageConsumer(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; |
| | } |
| |
|
| | |
| | void SpirvToolsDisassemble(std::ostream& out, const std::vector<unsigned int>& spirv) |
| | { |
| | SpirvToolsDisassemble(out, spirv, spv_target_env::SPV_ENV_UNIVERSAL_1_3); |
| | } |
| |
|
| | |
| | void SpirvToolsDisassemble(std::ostream& out, const std::vector<unsigned int>& spirv, |
| | spv_target_env requested_context) |
| | { |
| | |
| | spv_context context = spvContextCreate(requested_context); |
| | 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); |
| |
|
| | |
| | if (diagnostic == nullptr) |
| | out << text->str; |
| | else |
| | spvDiagnosticPrint(diagnostic); |
| |
|
| | |
| | spvDiagnosticDestroy(diagnostic); |
| | spvContextDestroy(context); |
| | } |
| |
|
| | |
| | void SpirvToolsValidate(const glslang::TIntermediate& intermediate, std::vector<unsigned int>& spirv, |
| | spv::SpvBuildLogger* logger, bool prelegalization) |
| | { |
| | |
| | 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()); |
| | spvValidatorOptionsSetBeforeHlslLegalization(options, prelegalization); |
| | spvValidatorOptionsSetScalarBlockLayout(options, intermediate.usingScalarBlockLayout()); |
| | spvValidatorOptionsSetWorkgroupScalarBlockLayout(options, intermediate.usingScalarBlockLayout()); |
| | spvValidateWithOptions(context, options, &binary, &diagnostic); |
| |
|
| | |
| | if (diagnostic != nullptr) { |
| | logger->error("SPIRV-Tools Validation Errors"); |
| | logger->error(diagnostic->error); |
| | } |
| |
|
| | |
| | spvValidatorOptionsDestroy(options); |
| | spvDiagnosticDestroy(diagnostic); |
| | spvContextDestroy(context); |
| | } |
| |
|
| | |
| | void SpirvToolsTransform(const glslang::TIntermediate& intermediate, std::vector<unsigned int>& spirv, |
| | spv::SpvBuildLogger* logger, const SpvOptions* options) |
| | { |
| | spv_target_env target_env = MapToSpirvToolsEnv(intermediate.getSpv(), logger); |
| |
|
| | spvtools::Optimizer optimizer(target_env); |
| | optimizer.SetMessageConsumer(OptimizerMesssageConsumer); |
| |
|
| | |
| | |
| | |
| | |
| | if (options->stripDebugInfo) { |
| | optimizer.RegisterPass(spvtools::CreateStripDebugInfoPass()); |
| | } |
| | optimizer.RegisterPass(spvtools::CreateWrapOpKillPass()); |
| | optimizer.RegisterPass(spvtools::CreateDeadBranchElimPass()); |
| | 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()); |
| | optimizer.RegisterPass(spvtools::CreateInterpolateFixupPass()); |
| | if (options->optimizeSize) { |
| | optimizer.RegisterPass(spvtools::CreateRedundancyEliminationPass()); |
| | optimizer.RegisterPass(spvtools::CreateEliminateDeadInputComponentsSafePass()); |
| | } |
| | optimizer.RegisterPass(spvtools::CreateAggressiveDCEPass()); |
| | optimizer.RegisterPass(spvtools::CreateCFGCleanupPass()); |
| |
|
| | spvtools::OptimizerOptions spvOptOptions; |
| | optimizer.SetTargetEnv(MapToSpirvToolsEnv(intermediate.getSpv(), logger)); |
| | spvOptOptions.set_run_validator(false); |
| | optimizer.Run(spirv.data(), spirv.size(), &spirv, spvOptOptions); |
| | } |
| |
|
| | bool SpirvToolsAnalyzeDeadOutputStores(spv_target_env target_env, std::vector<unsigned int>& spirv, |
| | std::unordered_set<uint32_t>* live_locs, |
| | std::unordered_set<uint32_t>* live_builtins, |
| | spv::SpvBuildLogger*) |
| | { |
| | spvtools::Optimizer optimizer(target_env); |
| | optimizer.SetMessageConsumer(OptimizerMesssageConsumer); |
| |
|
| | optimizer.RegisterPass(spvtools::CreateAnalyzeLiveInputPass(live_locs, live_builtins)); |
| |
|
| | spvtools::OptimizerOptions spvOptOptions; |
| | optimizer.SetTargetEnv(target_env); |
| | spvOptOptions.set_run_validator(false); |
| | return optimizer.Run(spirv.data(), spirv.size(), &spirv, spvOptOptions); |
| | } |
| |
|
| | void SpirvToolsEliminateDeadOutputStores(spv_target_env target_env, std::vector<unsigned int>& spirv, |
| | std::unordered_set<uint32_t>* live_locs, |
| | std::unordered_set<uint32_t>* live_builtins, |
| | spv::SpvBuildLogger*) |
| | { |
| | spvtools::Optimizer optimizer(target_env); |
| | optimizer.SetMessageConsumer(OptimizerMesssageConsumer); |
| |
|
| | optimizer.RegisterPass(spvtools::CreateEliminateDeadOutputStoresPass(live_locs, live_builtins)); |
| | optimizer.RegisterPass(spvtools::CreateAggressiveDCEPass(false, true)); |
| | optimizer.RegisterPass(spvtools::CreateEliminateDeadOutputComponentsPass()); |
| | optimizer.RegisterPass(spvtools::CreateAggressiveDCEPass(false, true)); |
| |
|
| | spvtools::OptimizerOptions spvOptOptions; |
| | optimizer.SetTargetEnv(target_env); |
| | spvOptOptions.set_run_validator(false); |
| | optimizer.Run(spirv.data(), spirv.size(), &spirv, spvOptOptions); |
| | } |
| |
|
| | void SpirvToolsEliminateDeadInputComponents(spv_target_env target_env, std::vector<unsigned int>& spirv, |
| | spv::SpvBuildLogger*) |
| | { |
| | spvtools::Optimizer optimizer(target_env); |
| | optimizer.SetMessageConsumer(OptimizerMesssageConsumer); |
| |
|
| | optimizer.RegisterPass(spvtools::CreateEliminateDeadInputComponentsPass()); |
| | optimizer.RegisterPass(spvtools::CreateAggressiveDCEPass()); |
| |
|
| | spvtools::OptimizerOptions spvOptOptions; |
| | optimizer.SetTargetEnv(target_env); |
| | spvOptOptions.set_run_validator(false); |
| | optimizer.Run(spirv.data(), spirv.size(), &spirv, spvOptOptions); |
| | } |
| |
|
| | |
| | |
| | |
| | void SpirvToolsStripDebugInfo(const glslang::TIntermediate& intermediate, |
| | std::vector<unsigned int>& spirv, spv::SpvBuildLogger* logger) |
| | { |
| | spv_target_env target_env = MapToSpirvToolsEnv(intermediate.getSpv(), logger); |
| |
|
| | spvtools::Optimizer optimizer(target_env); |
| | optimizer.SetMessageConsumer(OptimizerMesssageConsumer); |
| |
|
| | optimizer.RegisterPass(spvtools::CreateStripDebugInfoPass()); |
| |
|
| | spvtools::OptimizerOptions spvOptOptions; |
| | optimizer.SetTargetEnv(MapToSpirvToolsEnv(intermediate.getSpv(), logger)); |
| | spvOptOptions.set_run_validator(false); |
| | optimizer.Run(spirv.data(), spirv.size(), &spirv, spvOptOptions); |
| | } |
| |
|
| | }; |
| |
|
| | #endif |
| |
|