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:
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user