зеркало из https://github.com/stride3d/xkslang.git
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:
Родитель
44dd6a00c3
Коммит
cd1f169c6a
|
@ -25,6 +25,7 @@ matrix:
|
|||
# scripts that run after cloning repository
|
||||
install:
|
||||
- git clone https://github.com/google/googletest.git External/googletest
|
||||
- update_glslang_sources.py
|
||||
|
||||
build:
|
||||
parallel: true # enable MSBuild parallel builds
|
||||
|
|
|
@ -7,3 +7,4 @@ TAGS
|
|||
build/
|
||||
Test/localResults/
|
||||
External/googletest
|
||||
External/spirv-tools
|
||||
|
|
|
@ -55,6 +55,7 @@ install:
|
|||
|
||||
before_script:
|
||||
- git clone --depth=1 https://github.com/google/googletest.git External/googletest
|
||||
- update_glslang_sources.py
|
||||
|
||||
script:
|
||||
- mkdir build && cd build
|
||||
|
|
|
@ -74,6 +74,14 @@ cd <the directory glslang was cloned to, "External" will be a subdirectory>
|
|||
git clone https://github.com/google/googletest.git External/googletest
|
||||
```
|
||||
|
||||
If you wish to assure that SPIR-V generated from HLSL is legal for Vulkan,
|
||||
or wish to invoke -Os to reduce SPIR-V size from HLSL or GLSL, install
|
||||
spirv-tools with this:
|
||||
|
||||
```bash
|
||||
./update_glslang_sources.py
|
||||
```
|
||||
|
||||
#### 3) Configure
|
||||
|
||||
Assume the source directory is `$SOURCE_DIR` and
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -48,8 +48,11 @@
|
|||
namespace glslang {
|
||||
|
||||
struct SpvOptions {
|
||||
SpvOptions() : generateDebugInfo(false) { }
|
||||
SpvOptions() : generateDebugInfo(false), disableOptimizer(true),
|
||||
optimizeSize(false) { }
|
||||
bool generateDebugInfo;
|
||||
bool disableOptimizer;
|
||||
bool optimizeSize;
|
||||
};
|
||||
|
||||
void GetSpirvVersion(std::string&);
|
||||
|
|
|
@ -95,6 +95,8 @@ enum TOptions {
|
|||
EOptionAutoMapLocations = (1 << 25),
|
||||
EOptionDebug = (1 << 26),
|
||||
EOptionStdin = (1 << 27),
|
||||
EOptionOptimizeDisable = (1 << 28),
|
||||
EOptionOptimizeSize = (1 << 29),
|
||||
};
|
||||
|
||||
//
|
||||
|
@ -528,6 +530,18 @@ void ProcessArguments(std::vector<std::unique_ptr<glslang::TWorkItem>>& workItem
|
|||
case 'I':
|
||||
IncludeDirectoryList.push_back(getStringOperand("-I<dir> include path"));
|
||||
break;
|
||||
case 'O':
|
||||
if (argv[0][2] == 'd')
|
||||
Options |= EOptionOptimizeDisable;
|
||||
else if (argv[0][2] == 's')
|
||||
#ifdef ENABLE_OPT
|
||||
Options |= EOptionOptimizeSize;
|
||||
#else
|
||||
Error("-Os not available; optimizer not linked");
|
||||
#endif
|
||||
else
|
||||
Error("unknown -O option");
|
||||
break;
|
||||
case 'S':
|
||||
if (argc <= 1)
|
||||
Error("no <stage> specified for -S");
|
||||
|
@ -882,6 +896,8 @@ void CompileAndLinkShaderUnits(std::vector<ShaderCompUnit> compUnits)
|
|||
glslang::SpvOptions spvOptions;
|
||||
if (Options & EOptionDebug)
|
||||
spvOptions.generateDebugInfo = true;
|
||||
spvOptions.disableOptimizer = Options & EOptionOptimizeDisable;
|
||||
spvOptions.optimizeSize = Options & EOptionOptimizeSize;
|
||||
glslang::GlslangToSpv(*program.getIntermediate((EShLanguage)stage), spirv, &logger, &spvOptions);
|
||||
|
||||
// Dump the spv to a file or stdout, etc., but only if not doing
|
||||
|
@ -1201,6 +1217,8 @@ void usage()
|
|||
" -H print human readable form of SPIR-V; turns on -V\n"
|
||||
" -I<dir> add dir to the include search path; includer's directory\n"
|
||||
" is searched first, followed by left-to-right order of -I\n"
|
||||
" -Od disables optimization. May cause illegal SPIR-V for HLSL.\n"
|
||||
" -Os optimizes SPIR-V to minimize size.\n"
|
||||
" -S <stage> uses specified stage rather than parsing the file extension\n"
|
||||
" choices for <stage> are vert, tesc, tese, geom, frag, or comp\n"
|
||||
" -U<macro> undefine a pre-processor macro\n"
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
hlsl.aliasOpaque.frag
|
||||
// Module Version 10000
|
||||
// Generated by (magic number): 80001
|
||||
// Id's are bound by 61
|
||||
|
||||
Capability Shader
|
||||
1: ExtInstImport "GLSL.std.450"
|
||||
MemoryModel Logical GLSL450
|
||||
EntryPoint Fragment 4 "main" 46
|
||||
ExecutionMode 4 OriginUpperLeft
|
||||
Source HLSL 500
|
||||
Name 4 "main"
|
||||
Name 36 "gss"
|
||||
Name 37 "gtex"
|
||||
Name 46 "@entryPointOutput"
|
||||
Decorate 36(gss) DescriptorSet 0
|
||||
Decorate 37(gtex) DescriptorSet 0
|
||||
Decorate 46(@entryPointOutput) Location 0
|
||||
2: TypeVoid
|
||||
3: TypeFunction 2
|
||||
6: TypeSampler
|
||||
7: TypePointer UniformConstant 6
|
||||
8: TypeFloat 32
|
||||
10: TypeImage 8(float) 2D sampled format:Unknown
|
||||
11: TypePointer UniformConstant 10
|
||||
12: TypeVector 8(float) 4
|
||||
25: TypeSampledImage 10
|
||||
27: TypeVector 8(float) 2
|
||||
28: 8(float) Constant 1045220557
|
||||
29: 8(float) Constant 1050253722
|
||||
30: 27(fvec2) ConstantComposite 28 29
|
||||
36(gss): 7(ptr) Variable UniformConstant
|
||||
37(gtex): 11(ptr) Variable UniformConstant
|
||||
39: 8(float) Constant 1077936128
|
||||
45: TypePointer Output 12(fvec4)
|
||||
46(@entryPointOutput): 45(ptr) Variable Output
|
||||
4(main): 2 Function None 3
|
||||
5: Label
|
||||
56: 10 Load 37(gtex)
|
||||
57: 6 Load 36(gss)
|
||||
58: 25 SampledImage 56 57
|
||||
59: 12(fvec4) ImageSampleImplicitLod 58 30
|
||||
60: 12(fvec4) VectorTimesScalar 59 39
|
||||
Store 46(@entryPointOutput) 60
|
||||
Return
|
||||
FunctionEnd
|
|
@ -0,0 +1,65 @@
|
|||
hlsl.flattenOpaque.frag
|
||||
// Module Version 10000
|
||||
// Generated by (magic number): 80001
|
||||
// Id's are bound by 118
|
||||
|
||||
Capability Shader
|
||||
1: ExtInstImport "GLSL.std.450"
|
||||
MemoryModel Logical GLSL450
|
||||
EntryPoint Fragment 4 "main" 83
|
||||
ExecutionMode 4 OriginUpperLeft
|
||||
Source HLSL 500
|
||||
Name 4 "main"
|
||||
Name 37 "tex"
|
||||
Name 68 "s.s2D"
|
||||
Name 73 "s2.s2D"
|
||||
Name 74 "s2.tex"
|
||||
Name 83 "@entryPointOutput"
|
||||
Decorate 37(tex) DescriptorSet 0
|
||||
Decorate 68(s.s2D) DescriptorSet 0
|
||||
Decorate 73(s2.s2D) DescriptorSet 0
|
||||
Decorate 74(s2.tex) DescriptorSet 0
|
||||
Decorate 83(@entryPointOutput) Location 0
|
||||
2: TypeVoid
|
||||
3: TypeFunction 2
|
||||
6: TypeSampler
|
||||
7: TypePointer UniformConstant 6
|
||||
8: TypeFloat 32
|
||||
9: TypeVector 8(float) 4
|
||||
14: TypeVector 8(float) 2
|
||||
21: TypeImage 8(float) 2D sampled format:Unknown
|
||||
22: TypePointer UniformConstant 21
|
||||
37(tex): 22(ptr) Variable UniformConstant
|
||||
40: TypeSampledImage 21
|
||||
42: 8(float) Constant 1045220557
|
||||
43: 8(float) Constant 1050253722
|
||||
44: 14(fvec2) ConstantComposite 42 43
|
||||
68(s.s2D): 7(ptr) Variable UniformConstant
|
||||
73(s2.s2D): 7(ptr) Variable UniformConstant
|
||||
74(s2.tex): 22(ptr) Variable UniformConstant
|
||||
82: TypePointer Output 9(fvec4)
|
||||
83(@entryPointOutput): 82(ptr) Variable Output
|
||||
4(main): 2 Function None 3
|
||||
5: Label
|
||||
97: 21 Load 37(tex)
|
||||
98: 6 Load 68(s.s2D)
|
||||
99: 40 SampledImage 97 98
|
||||
100: 9(fvec4) ImageSampleImplicitLod 99 44
|
||||
102: 21 Load 37(tex)
|
||||
103: 6 Load 68(s.s2D)
|
||||
104: 40 SampledImage 102 103
|
||||
106: 9(fvec4) ImageSampleImplicitLod 104 44
|
||||
91: 9(fvec4) FAdd 100 106
|
||||
108: 21 Load 74(s2.tex)
|
||||
109: 6 Load 73(s2.s2D)
|
||||
110: 40 SampledImage 108 109
|
||||
111: 9(fvec4) ImageSampleImplicitLod 110 44
|
||||
93: 9(fvec4) FAdd 91 111
|
||||
113: 21 Load 74(s2.tex)
|
||||
114: 6 Load 73(s2.s2D)
|
||||
115: 40 SampledImage 113 114
|
||||
117: 9(fvec4) ImageSampleImplicitLod 115 44
|
||||
95: 9(fvec4) FAdd 93 117
|
||||
Store 83(@entryPointOutput) 95
|
||||
Return
|
||||
FunctionEnd
|
|
@ -0,0 +1,70 @@
|
|||
hlsl.flattenOpaqueInit.vert
|
||||
WARNING: 0:20: '=' : cannot do member-wise aliasing for opaque members with this initializer
|
||||
|
||||
// Module Version 10000
|
||||
// Generated by (magic number): 80001
|
||||
// Id's are bound by 76
|
||||
|
||||
Capability Shader
|
||||
1: ExtInstImport "GLSL.std.450"
|
||||
MemoryModel Logical GLSL450
|
||||
EntryPoint Vertex 4 "main" 58
|
||||
Source HLSL 500
|
||||
Name 4 "main"
|
||||
Name 17 "FxaaTex"
|
||||
MemberName 17(FxaaTex) 0 "smpl"
|
||||
MemberName 17(FxaaTex) 1 "tex"
|
||||
Name 36 "g_tInputTexture_sampler"
|
||||
Name 37 "g_tInputTexture"
|
||||
Name 39 "t"
|
||||
Name 43 "flattenTemp"
|
||||
Name 45 "tex2.smpl"
|
||||
Name 50 "tex2.tex"
|
||||
Name 58 "@entryPointOutput"
|
||||
Decorate 36(g_tInputTexture_sampler) DescriptorSet 0
|
||||
Decorate 37(g_tInputTexture) DescriptorSet 0
|
||||
Decorate 58(@entryPointOutput) Location 0
|
||||
2: TypeVoid
|
||||
3: TypeFunction 2
|
||||
6: TypeSampler
|
||||
7: TypePointer UniformConstant 6
|
||||
8: TypeFloat 32
|
||||
9: TypeImage 8(float) 2D sampled format:Unknown
|
||||
10: TypePointer UniformConstant 9
|
||||
11: TypeVector 8(float) 4
|
||||
17(FxaaTex): TypeStruct 6 9
|
||||
26: TypeSampledImage 9
|
||||
28: TypeVector 8(float) 2
|
||||
29: 8(float) Constant 1050253722
|
||||
30: 8(float) Constant 1053609165
|
||||
31: 28(fvec2) ConstantComposite 29 30
|
||||
32: 8(float) Constant 0
|
||||
36(g_tInputTexture_sampler): 7(ptr) Variable UniformConstant
|
||||
37(g_tInputTexture): 10(ptr) Variable UniformConstant
|
||||
38: TypePointer UniformConstant 17(FxaaTex)
|
||||
39(t): 38(ptr) Variable UniformConstant
|
||||
43(flattenTemp): 38(ptr) Variable UniformConstant
|
||||
45(tex2.smpl): 7(ptr) Variable UniformConstant
|
||||
46: TypeInt 32 1
|
||||
47: 46(int) Constant 0
|
||||
50(tex2.tex): 10(ptr) Variable UniformConstant
|
||||
51: 46(int) Constant 1
|
||||
57: TypePointer Output 11(fvec4)
|
||||
58(@entryPointOutput): 57(ptr) Variable Output
|
||||
4(main): 2 Function None 3
|
||||
5: Label
|
||||
70: 17(FxaaTex) Load 39(t)
|
||||
Store 43(flattenTemp) 70
|
||||
63: 7(ptr) AccessChain 43(flattenTemp) 47
|
||||
64: 6 Load 63
|
||||
Store 45(tex2.smpl) 64
|
||||
65: 10(ptr) AccessChain 43(flattenTemp) 51
|
||||
66: 9 Load 65
|
||||
Store 50(tex2.tex) 66
|
||||
72: 9 Load 37(g_tInputTexture)
|
||||
73: 6 Load 36(g_tInputTexture_sampler)
|
||||
74: 26 SampledImage 72 73
|
||||
75: 11(fvec4) ImageSampleExplicitLod 74 31 Lod 32
|
||||
Store 58(@entryPointOutput) 75
|
||||
Return
|
||||
FunctionEnd
|
|
@ -0,0 +1,43 @@
|
|||
hlsl.flattenOpaqueInitMix.vert
|
||||
// Module Version 10000
|
||||
// Generated by (magic number): 80001
|
||||
// Id's are bound by 60
|
||||
|
||||
Capability Shader
|
||||
1: ExtInstImport "GLSL.std.450"
|
||||
MemoryModel Logical GLSL450
|
||||
EntryPoint Vertex 4 "main" 44
|
||||
Source HLSL 500
|
||||
Name 4 "main"
|
||||
Name 36 "g_tInputTexture_sampler"
|
||||
Name 37 "g_tInputTexture"
|
||||
Name 44 "@entryPointOutput"
|
||||
Decorate 36(g_tInputTexture_sampler) DescriptorSet 0
|
||||
Decorate 37(g_tInputTexture) DescriptorSet 0
|
||||
Decorate 44(@entryPointOutput) Location 0
|
||||
2: TypeVoid
|
||||
3: TypeFunction 2
|
||||
6: TypeSampler
|
||||
7: TypePointer UniformConstant 6
|
||||
8: TypeFloat 32
|
||||
9: TypeImage 8(float) 2D sampled format:Unknown
|
||||
10: TypePointer UniformConstant 9
|
||||
12: TypeVector 8(float) 4
|
||||
24: TypeSampledImage 9
|
||||
28: TypeVector 8(float) 2
|
||||
30: 8(float) Constant 0
|
||||
35: 8(float) Constant 1056964608
|
||||
36(g_tInputTexture_sampler): 7(ptr) Variable UniformConstant
|
||||
37(g_tInputTexture): 10(ptr) Variable UniformConstant
|
||||
43: TypePointer Output 12(fvec4)
|
||||
44(@entryPointOutput): 43(ptr) Variable Output
|
||||
4(main): 2 Function None 3
|
||||
5: Label
|
||||
53: 9 Load 37(g_tInputTexture)
|
||||
54: 6 Load 36(g_tInputTexture_sampler)
|
||||
55: 24 SampledImage 53 54
|
||||
58: 28(fvec2) CompositeConstruct 35 35
|
||||
59: 12(fvec4) ImageSampleExplicitLod 55 58 Lod 30
|
||||
Store 44(@entryPointOutput) 59
|
||||
Return
|
||||
FunctionEnd
|
|
@ -32,11 +32,11 @@ diff -b $BASEDIR/badMacroArgs.frag.out $TARGETDIR/badMacroArgs.frag.out || HASER
|
|||
echo Running reflection...
|
||||
$EXE -l -q -C reflection.vert > $TARGETDIR/reflection.vert.out
|
||||
diff -b $BASEDIR/reflection.vert.out $TARGETDIR/reflection.vert.out || HASERROR=1
|
||||
$EXE -D -e flizv -l -q -C -V hlsl.reflection.vert > $TARGETDIR/hlsl.reflection.vert.out
|
||||
$EXE -D -e flizv -l -q -C -V -Od hlsl.reflection.vert > $TARGETDIR/hlsl.reflection.vert.out
|
||||
diff -b $BASEDIR/hlsl.reflection.vert.out $TARGETDIR/hlsl.reflection.vert.out || HASERROR=1
|
||||
$EXE -D -e main -l -q -C -V hlsl.reflection.binding.frag > $TARGETDIR/hlsl.reflection.binding.frag.out
|
||||
$EXE -D -e main -l -q -C -V -Od hlsl.reflection.binding.frag > $TARGETDIR/hlsl.reflection.binding.frag.out
|
||||
diff -b $BASEDIR/hlsl.reflection.binding.frag.out $TARGETDIR/hlsl.reflection.binding.frag.out || HASERROR=1
|
||||
$EXE -D -e main -l -q --hlsl-iomap --auto-map-bindings --stb 10 --sbb 20 --ssb 30 --suavb 40 --scb 50 -D -V -e main hlsl.automap.frag > $TARGETDIR/hlsl.automap.frag.out
|
||||
$EXE -D -e main -l -q --hlsl-iomap --auto-map-bindings --stb 10 --sbb 20 --ssb 30 --suavb 40 --scb 50 -D -V -e main -Od hlsl.automap.frag > $TARGETDIR/hlsl.automap.frag.out
|
||||
diff -b $BASEDIR/hlsl.automap.frag.out $TARGETDIR/hlsl.automap.frag.out || HASERROR=1
|
||||
|
||||
#
|
||||
|
@ -56,14 +56,14 @@ fi
|
|||
# entry point renaming tests
|
||||
#
|
||||
echo Running entry-point renaming tests
|
||||
$EXE -i -H -V -D -e main_in_spv --ku --source-entrypoint main hlsl.entry.rename.frag > $TARGETDIR/hlsl.entry.rename.frag.out
|
||||
$EXE -i -H -V -D -e main_in_spv --ku --source-entrypoint main -Od hlsl.entry.rename.frag > $TARGETDIR/hlsl.entry.rename.frag.out
|
||||
diff -b $BASEDIR/hlsl.entry.rename.frag.out $TARGETDIR/hlsl.entry.rename.frag.out || HASERROR=1
|
||||
|
||||
#
|
||||
# Testing ill-defined uncalled function
|
||||
#
|
||||
echo Running ill-defined uncalled function
|
||||
$EXE -D -e main -H hlsl.deadFunctionMissingBody.vert > $TARGETDIR/hlsl.deadFunctionMissingBody.vert.out
|
||||
$EXE -D -e main -H -Od hlsl.deadFunctionMissingBody.vert > $TARGETDIR/hlsl.deadFunctionMissingBody.vert.out
|
||||
diff -b $BASEDIR/hlsl.deadFunctionMissingBody.vert.out $TARGETDIR/hlsl.deadFunctionMissingBody.vert.out || HASERROR=1
|
||||
|
||||
if [ $HASERROR -eq 0 ]
|
||||
|
@ -88,20 +88,20 @@ $EXE -i --hlsl-offsets -H spv.hlslOffsets.vert > $TARGETDIR/spv.hlslOffsets.vert
|
|||
diff -b $BASEDIR/spv.hlslOffsets.vert.out $TARGETDIR/spv.hlslOffsets.vert.out || HASERROR=1
|
||||
|
||||
echo Running hlsl offsets
|
||||
$EXE -i --hlsl-offsets -D -e main -H hlsl.hlslOffset.vert > $TARGETDIR/hlsl.hlslOffset.vert.out
|
||||
$EXE -i --hlsl-offsets -D -e main -H -Od hlsl.hlslOffset.vert > $TARGETDIR/hlsl.hlslOffset.vert.out
|
||||
diff -b $BASEDIR/hlsl.hlslOffset.vert.out $TARGETDIR/hlsl.hlslOffset.vert.out || HASERROR=1
|
||||
|
||||
#
|
||||
# Testing --resource-set-binding
|
||||
#
|
||||
echo Configuring HLSL descriptor set and binding number manually
|
||||
$EXE -V -D -e main -H hlsl.multiDescriptorSet.frag --rsb frag t0 0 0 t1 1 0 s0 0 1 s1 1 1 b0 2 0 b1 2 1 b2 2 2 > $TARGETDIR/hlsl.multiDescriptorSet.frag.out
|
||||
$EXE -V -D -e main -H -Od hlsl.multiDescriptorSet.frag --rsb frag t0 0 0 t1 1 0 s0 0 1 s1 1 1 b0 2 0 b1 2 1 b2 2 2 > $TARGETDIR/hlsl.multiDescriptorSet.frag.out
|
||||
diff -b $BASEDIR/hlsl.multiDescriptorSet.frag.out $TARGETDIR/hlsl.multiDescriptorSet.frag.out || HASERROR=1
|
||||
|
||||
$EXE -V -D -e main -H hlsl.explicitDescriptorSet.frag --hlsl-iomap --amb --ssb 10 --stb 20 --rsb 4 > $TARGETDIR/hlsl.explicitDescriptorSet.frag.out
|
||||
$EXE -V -D -e main -H -Od hlsl.explicitDescriptorSet.frag --hlsl-iomap --amb --ssb 10 --stb 20 --rsb 4 > $TARGETDIR/hlsl.explicitDescriptorSet.frag.out
|
||||
diff -b $BASEDIR/hlsl.explicitDescriptorSet.frag.out $TARGETDIR/hlsl.explicitDescriptorSet.frag.out || HASERROR=1
|
||||
|
||||
$EXE -V -D -e main -H hlsl.explicitDescriptorSet.frag --hlsl-iomap --amb --ssb 10 --stb 20 --rsb frag 3 > $TARGETDIR/hlsl.explicitDescriptorSet-2.frag.out
|
||||
$EXE -V -D -e main -H -Od hlsl.explicitDescriptorSet.frag --hlsl-iomap --amb --ssb 10 --stb 20 --rsb frag 3 > $TARGETDIR/hlsl.explicitDescriptorSet-2.frag.out
|
||||
diff -b $BASEDIR/hlsl.explicitDescriptorSet-2.frag.out $TARGETDIR/hlsl.explicitDescriptorSet-2.frag.out || HASERROR=1
|
||||
|
||||
#
|
||||
|
@ -123,20 +123,20 @@ $EXE -g --relaxed-errors --suppress-warnings --aml --hlsl-offsets --nsf \
|
|||
-G -H spv.debugInfo.frag --rsb frag 3 > $TARGETDIR/spv.debugInfo.frag.out
|
||||
diff -b $BASEDIR/spv.debugInfo.frag.out $TARGETDIR/spv.debugInfo.frag.out || HASERROR=1
|
||||
$EXE -g -D -e newMain -g --amb --aml --fua --hlsl-iomap --nsf --sib 1 --ssb 2 --sbb 3 --stb 4 --suavb 5 --sub 6 \
|
||||
--sep origMain -H spv.hlslDebugInfo.vert --rsb vert t0 0 0 > $TARGETDIR/spv.hlslDebugInfo.frag.out
|
||||
--sep origMain -H -Od spv.hlslDebugInfo.vert --rsb vert t0 0 0 > $TARGETDIR/spv.hlslDebugInfo.frag.out
|
||||
diff -b $BASEDIR/spv.hlslDebugInfo.frag.out $TARGETDIR/spv.hlslDebugInfo.frag.out || HASERROR=1
|
||||
|
||||
#
|
||||
# Testing Includer
|
||||
#
|
||||
echo Testing Includer
|
||||
$EXE -D -e main -H ../Test/hlsl.include.vert > $TARGETDIR/hlsl.include.vert.out
|
||||
$EXE -D -e main -H -Od ../Test/hlsl.include.vert > $TARGETDIR/hlsl.include.vert.out
|
||||
diff -b $BASEDIR/hlsl.include.vert.out $TARGETDIR/hlsl.include.vert.out || HASERROR=1
|
||||
$EXE -D -e main -H hlsl.includeNegative.vert > $TARGETDIR/hlsl.includeNegative.vert.out
|
||||
$EXE -D -e main -H -Od hlsl.includeNegative.vert > $TARGETDIR/hlsl.includeNegative.vert.out
|
||||
diff -b $BASEDIR/hlsl.includeNegative.vert.out $TARGETDIR/hlsl.includeNegative.vert.out || HASERROR=1
|
||||
$EXE -l -i include.vert > $TARGETDIR/include.vert.out
|
||||
diff -b $BASEDIR/include.vert.out $TARGETDIR/include.vert.out || HASERROR=1
|
||||
$EXE -D -e main -H -Iinc1/path1 -Iinc1/path2 hlsl.dashI.vert > $TARGETDIR/hlsl.dashI.vert.out
|
||||
$EXE -D -e main -H -Od -Iinc1/path1 -Iinc1/path2 hlsl.dashI.vert > $TARGETDIR/hlsl.dashI.vert.out
|
||||
diff -b $BASEDIR/hlsl.dashI.vert.out $TARGETDIR/hlsl.dashI.vert.out || HASERROR=1
|
||||
|
||||
#
|
||||
|
@ -145,7 +145,7 @@ diff -b $BASEDIR/hlsl.dashI.vert.out $TARGETDIR/hlsl.dashI.vert.out || HASERROR=
|
|||
echo "Testing -D and -U"
|
||||
$EXE -DUNDEFED -UIN_SHADER -DFOO=200 -i -l -UUNDEFED -DMUL=FOO*2 glsl.-D-U.frag > $TARGETDIR/glsl.-D-U.frag.out
|
||||
diff -b $BASEDIR/glsl.-D-U.frag.out $TARGETDIR/glsl.-D-U.frag.out || HASERROR=1
|
||||
$EXE -D -e main -V -i -DUNDEFED -UIN_SHADER -DFOO=200 -UUNDEFED hlsl.-D-U.frag > $TARGETDIR/hlsl.-D-U.frag.out
|
||||
$EXE -D -e main -V -i -DUNDEFED -UIN_SHADER -DFOO=200 -UUNDEFED -Od hlsl.-D-U.frag > $TARGETDIR/hlsl.-D-U.frag.out
|
||||
diff -b $BASEDIR/hlsl.-D-U.frag.out $TARGETDIR/hlsl.-D-U.frag.out || HASERROR=1
|
||||
|
||||
#
|
||||
|
|
|
@ -59,9 +59,10 @@ std::string FileNameAsCustomTestSuffix(
|
|||
|
||||
using HlslCompileTest = GlslangTest<::testing::TestWithParam<FileNameEntryPointPair>>;
|
||||
using HlslCompileAndFlattenTest = GlslangTest<::testing::TestWithParam<FileNameEntryPointPair>>;
|
||||
using HlslLegalizeTest = GlslangTest<::testing::TestWithParam<FileNameEntryPointPair>>;
|
||||
|
||||
// Compiling HLSL to SPIR-V under Vulkan semantics. Expected to successfully
|
||||
// generate both AST and SPIR-V.
|
||||
// Compiling HLSL to pre-legalized SPIR-V under Vulkan semantics. Expected
|
||||
// to successfully generate both AST and SPIR-V.
|
||||
TEST_P(HlslCompileTest, FromFile)
|
||||
{
|
||||
loadFileCompileAndCheck(GlobalTestSettings.testRoot, GetParam().fileName,
|
||||
|
@ -76,6 +77,16 @@ TEST_P(HlslCompileAndFlattenTest, FromFile)
|
|||
Target::BothASTAndSpv, GetParam().entryPoint);
|
||||
}
|
||||
|
||||
// Compiling HLSL to legal SPIR-V under Vulkan semantics. Expected to
|
||||
// successfully generate SPIR-V.
|
||||
TEST_P(HlslLegalizeTest, FromFile)
|
||||
{
|
||||
loadFileCompileAndCheck(GlobalTestSettings.testRoot, GetParam().fileName,
|
||||
Source::HLSL, Semantics::Vulkan,
|
||||
Target::Spv, GetParam().entryPoint,
|
||||
"/baseLegalResults/", false);
|
||||
}
|
||||
|
||||
// clang-format off
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
ToSpirv, HlslCompileTest,
|
||||
|
@ -353,7 +364,20 @@ INSTANTIATE_TEST_CASE_P(
|
|||
}),
|
||||
FileNameAsCustomTestSuffix
|
||||
);
|
||||
|
||||
// clang-format on
|
||||
|
||||
// clang-format off
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
ToSpirv, HlslLegalizeTest,
|
||||
::testing::ValuesIn(std::vector<FileNameEntryPointPair>{
|
||||
{"hlsl.aliasOpaque.frag", "main"},
|
||||
{"hlsl.flattenOpaque.frag", "main"},
|
||||
{"hlsl.flattenOpaqueInit.vert", "main"},
|
||||
{"hlsl.flattenOpaqueInitMix.vert", "main"}
|
||||
}),
|
||||
FileNameAsCustomTestSuffix
|
||||
);
|
||||
// clang-format on
|
||||
|
||||
} // anonymous namespace
|
||||
} // namespace glslangtest
|
||||
|
|
|
@ -198,7 +198,8 @@ public:
|
|||
const std::string shaderName, const std::string& code,
|
||||
const std::string& entryPointName, EShMessages controls,
|
||||
bool flattenUniformArrays = false,
|
||||
EShTextureSamplerTransformMode texSampTransMode = EShTexSampTransKeep)
|
||||
EShTextureSamplerTransformMode texSampTransMode = EShTexSampTransKeep,
|
||||
bool disableOptimizer = true)
|
||||
{
|
||||
const EShLanguage kind = GetShaderStage(GetSuffix(shaderName));
|
||||
|
||||
|
@ -217,8 +218,10 @@ public:
|
|||
|
||||
if (success && (controls & EShMsgSpvRules)) {
|
||||
std::vector<uint32_t> spirv_binary;
|
||||
glslang::SpvOptions options;
|
||||
options.disableOptimizer = disableOptimizer;
|
||||
glslang::GlslangToSpv(*program.getIntermediate(kind),
|
||||
spirv_binary, &logger);
|
||||
spirv_binary, &logger, &options);
|
||||
|
||||
std::ostringstream disassembly_stream;
|
||||
spv::Parameterize();
|
||||
|
@ -381,18 +384,20 @@ public:
|
|||
Source source,
|
||||
Semantics semantics,
|
||||
Target target,
|
||||
const std::string& entryPointName="")
|
||||
const std::string& entryPointName="",
|
||||
const std::string& baseDir="/baseResults/",
|
||||
const bool disableOptimizer = true)
|
||||
{
|
||||
const std::string inputFname = testDir + "/" + testName;
|
||||
const std::string expectedOutputFname =
|
||||
testDir + "/baseResults/" + testName + ".out";
|
||||
testDir + baseDir + testName + ".out";
|
||||
std::string input, expectedOutput;
|
||||
|
||||
tryLoadFile(inputFname, "input", &input);
|
||||
tryLoadFile(expectedOutputFname, "expected output", &expectedOutput);
|
||||
|
||||
const EShMessages controls = DeriveOptions(source, semantics, target);
|
||||
GlslangResult result = compileAndLink(testName, input, entryPointName, controls);
|
||||
GlslangResult result = compileAndLink(testName, input, entryPointName, controls, false, EShTexSampTransKeep, disableOptimizer);
|
||||
|
||||
// Generate the hybrid output in the way of glslangValidator.
|
||||
std::ostringstream stream;
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
{
|
||||
"commits" : [
|
||||
{
|
||||
"name" : "spirv-tools",
|
||||
"site" : "github",
|
||||
"subrepo" : "KhronosGroup/SPIRV-Tools",
|
||||
"subdir" : "External/spirv-tools",
|
||||
"commit" : "cf85ad1429de560eb1569cf6b36ba5a4ae5ff4be"
|
||||
},
|
||||
{
|
||||
"name" : "spirv-tools/external/spirv-headers",
|
||||
"site" : "github",
|
||||
"subrepo" : "KhronosGroup/SPIRV-Headers",
|
||||
"subdir" : "External/spirv-tools/external/spirv-headers",
|
||||
"commit" : "2bb92e6fe2c6aa410152fc6c63443f452acb1a65"
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,151 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
# Copyright 2017 The Glslang Authors. All rights reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
"""Get source files for Glslang and its dependencies from public repositories.
|
||||
"""
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
import argparse
|
||||
import json
|
||||
import distutils.dir_util
|
||||
import os.path
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
KNOWN_GOOD_FILE = 'known_good.json'
|
||||
|
||||
# Maps a site name to its hostname.
|
||||
SITE_TO_HOST = { 'github' : 'github.com' }
|
||||
|
||||
VERBOSE = True
|
||||
|
||||
|
||||
def command_output(cmd, directory, fail_ok=False):
|
||||
"""Runs a command in a directory and returns its standard output stream.
|
||||
|
||||
Captures the standard error stream.
|
||||
|
||||
Raises a RuntimeError if the command fails to launch or otherwise fails.
|
||||
"""
|
||||
if VERBOSE:
|
||||
print('In {d}: {cmd}'.format(d=directory, cmd=cmd))
|
||||
p = subprocess.Popen(cmd,
|
||||
cwd=directory,
|
||||
stdout=subprocess.PIPE)
|
||||
(stdout, _) = p.communicate()
|
||||
if p.returncode != 0 and not fail_ok:
|
||||
raise RuntimeError('Failed to run {} in {}'.format(cmd, directory))
|
||||
if VERBOSE:
|
||||
print(stdout)
|
||||
return stdout
|
||||
|
||||
|
||||
def command_retval(cmd, directory):
|
||||
"""Runs a command in a directory and returns its return value.
|
||||
|
||||
Captures the standard error stream.
|
||||
"""
|
||||
p = subprocess.Popen(cmd,
|
||||
cwd=directory,
|
||||
stdout=subprocess.PIPE)
|
||||
(stdout, _) = p.communicate()
|
||||
return p.returncode
|
||||
|
||||
|
||||
class GoodCommit(object):
|
||||
"""Represents a good commit for a repository."""
|
||||
|
||||
def __init__(self, json):
|
||||
"""Initializes this good commit object.
|
||||
|
||||
Args:
|
||||
'json': A fully populated JSON object describing the commit.
|
||||
"""
|
||||
self._json = json
|
||||
self.name = json['name']
|
||||
self.site = json['site']
|
||||
self.subrepo = json['subrepo']
|
||||
self.subdir = json['subdir'] if ('subdir' in json) else '.'
|
||||
self.commit = json['commit']
|
||||
|
||||
def GetUrl(self, style='https'):
|
||||
"""Returns the URL for the repository."""
|
||||
host = SITE_TO_HOST[self.site]
|
||||
sep = '/' if (style is 'https') else ':'
|
||||
return '{style}://{host}{sep}{subrepo}'.format(
|
||||
style=style,
|
||||
host=host,
|
||||
sep=sep,
|
||||
subrepo=self.subrepo)
|
||||
|
||||
def AddRemote(self):
|
||||
"""Add the remote 'known-good' if it does not exist."""
|
||||
print('Ignore "fatal" errors for missing known-good remote:')
|
||||
if command_retval(['git', 'remote', 'show', 'known-good'], self.subdir) != 0:
|
||||
command_output(['git', 'remote', 'add', 'known-good', self.GetUrl()], self.subdir)
|
||||
|
||||
def HasCommit(self):
|
||||
"""Check if the repository contains the known-good commit."""
|
||||
return 0 == subprocess.call(['git', 'rev-parse', '--verify', '--quiet',
|
||||
self.commit + "^{commit}"],
|
||||
cwd=self.subdir)
|
||||
|
||||
def Clone(self):
|
||||
distutils.dir_util.mkpath(self.subdir)
|
||||
command_output(['git', 'clone', self.GetUrl(), '.'], self.subdir)
|
||||
|
||||
def Fetch(self):
|
||||
command_output(['git', 'fetch', 'known-good'], self.subdir)
|
||||
|
||||
def Checkout(self):
|
||||
if not os.path.exists(os.path.join(self.subdir,'.git')):
|
||||
self.Clone()
|
||||
self.AddRemote()
|
||||
if not self.HasCommit():
|
||||
self.Fetch()
|
||||
command_output(['git', 'checkout', self.commit], self.subdir)
|
||||
|
||||
|
||||
def GetGoodCommits():
|
||||
"""Returns the latest list of GoodCommit objects."""
|
||||
with open(KNOWN_GOOD_FILE) as known_good:
|
||||
return [GoodCommit(c) for c in json.loads(known_good.read())['commits']]
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description='Get Glslang source dependencies at a known-good commit')
|
||||
parser.add_argument('--dir', dest='dir', default='.',
|
||||
help="Set target directory for Glslang source root. Default is \'.\'.")
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
commits = GetGoodCommits()
|
||||
|
||||
distutils.dir_util.mkpath(args.dir)
|
||||
print('Change directory to {d}'.format(d=args.dir))
|
||||
os.chdir(args.dir)
|
||||
|
||||
# Create the subdirectories in sorted order so that parent git repositories
|
||||
# are created first.
|
||||
for c in sorted(commits, cmp=lambda x,y: cmp(x.subdir, y.subdir)):
|
||||
print('Get {n}\n'.format(n=c.name))
|
||||
c.Checkout()
|
||||
sys.exit(0)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
Загрузка…
Ссылка в новой задаче