Enable HLSL legalization

Also added known-good mechanism to fetch latest validated spirv-tools.
Also added -Od and -Os to disable optimizer and optimize for size.

Fetching spirv-tools is optional for both glsl and hlsl. Legalization
of hlsl is done by default if spirv-opt is present at cmake time.
Optimization for glsl is currently done through the option -Os.

Legalization testing is currently only done on four existing shaders.
A separate baseLegalResults directory holds those results. All previous
testing is done with the optimizer disabled.
This commit is contained in:
GregF
2017-09-21 18:40:22 -06:00
parent 44dd6a00c3
commit cd1f169c6a
16 changed files with 536 additions and 23 deletions

View File

@@ -52,6 +52,16 @@ namespace spv {
#endif
}
#ifdef ENABLE_OPT
#include "spirv-tools/optimizer.hpp"
#include "message.h"
#include "SPVRemapper.h"
#endif
#ifdef ENABLE_OPT
using namespace spvtools;
#endif
// Glslang includes
#include "../glslang/MachineIndependent/localintermediate.h"
#include "../glslang/MachineIndependent/SymbolTable.h"
@@ -5960,6 +5970,12 @@ void OutputSpvHex(const std::vector<unsigned int>& spirv, const char* baseName,
out.close();
}
#ifdef ENABLE_OPT
void errHandler(const std::string& str) {
std::cerr << str << std::endl;
}
#endif
//
// Set up the glslang traversal
//
@@ -5988,6 +6004,49 @@ void GlslangToSpv(const glslang::TIntermediate& intermediate, std::vector<unsign
it.finishSpv();
it.dumpSpv(spirv);
#ifdef ENABLE_OPT
// 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) {
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) {
std::cerr << StringifyMessage(level, source, position, message)
<< std::endl;
});
optimizer.RegisterPass(CreateInlineExhaustivePass());
optimizer.RegisterPass(CreateLocalAccessChainConvertPass());
optimizer.RegisterPass(CreateLocalSingleBlockLoadStoreElimPass());
optimizer.RegisterPass(CreateLocalSingleStoreElimPass());
optimizer.RegisterPass(CreateInsertExtractElimPass());
optimizer.RegisterPass(CreateAggressiveDCEPass());
optimizer.RegisterPass(CreateDeadBranchElimPass());
optimizer.RegisterPass(CreateBlockMergePass());
optimizer.RegisterPass(CreateLocalMultiStoreElimPass());
optimizer.RegisterPass(CreateInsertExtractElimPass());
optimizer.RegisterPass(CreateAggressiveDCEPass());
// TODO(greg-lunarg): Add this when AMD driver issues are resolved
// if (options->optimizeSize)
// optimizer.RegisterPass(CreateCommonUniformElimPass());
if (!optimizer.Run(spirv.data(), spirv.size(), &spirv))
return;
// Remove dead module-level objects: functions, types, vars
// TODO(greg-lunarg): Switch to spirv-opt versions when available
spv::spirvbin_t Remapper(0);
Remapper.registerErrorHandler(errHandler);
Remapper.remap(spirv, spv::spirvbin_t::DCE_ALL);
}
#endif
glslang::GetThreadPoolAllocator().pop();
}