SPV: Isolate SPIRV-tools glue to its own file.

This commit is contained in:
John Kessenich
2018-08-23 15:17:10 -06:00
parent cc14f2d329
commit 717c80a9de
10 changed files with 279 additions and 174 deletions

View File

@@ -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<unsign
GlslangToSpv(intermediate, spirv, &logger, options);
}
#if ENABLE_OPT
// 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;
}
// Apply the SPIRV-Tools validator to generated SPIR-V.
void SpirvToolsValidate(const glslang::TIntermediate& intermediate, std::vector<unsigned int>& 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<unsigned int>& 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<unsigned int>& spirv,
spv::SpvBuildLogger* logger, SpvOptions* options)
{
@@ -7144,10 +7019,12 @@ void GlslangToSpv(const glslang::TIntermediate& intermediate, std::vector<unsign
// If from HLSL, run spirv-opt to "legalize" the SPIR-V for Vulkan
// eg. forward and remove memory writes of opaque types.
if ((intermediate.getSource() == EShSourceHlsl || options->optimizeSize) &&
!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();