mirror of
https://github.com/KhronosGroup/glslang
synced 2024-11-09 20:10:06 +00:00
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:
parent
44dd6a00c3
commit
cd1f169c6a
@ -25,6 +25,7 @@ matrix:
|
|||||||
# scripts that run after cloning repository
|
# scripts that run after cloning repository
|
||||||
install:
|
install:
|
||||||
- git clone https://github.com/google/googletest.git External/googletest
|
- git clone https://github.com/google/googletest.git External/googletest
|
||||||
|
- update_glslang_sources.py
|
||||||
|
|
||||||
build:
|
build:
|
||||||
parallel: true # enable MSBuild parallel builds
|
parallel: true # enable MSBuild parallel builds
|
||||||
|
1
.gitignore
vendored
1
.gitignore
vendored
@ -7,3 +7,4 @@ TAGS
|
|||||||
build/
|
build/
|
||||||
Test/localResults/
|
Test/localResults/
|
||||||
External/googletest
|
External/googletest
|
||||||
|
External/spirv-tools
|
||||||
|
@ -55,6 +55,7 @@ install:
|
|||||||
|
|
||||||
before_script:
|
before_script:
|
||||||
- git clone --depth=1 https://github.com/google/googletest.git External/googletest
|
- git clone --depth=1 https://github.com/google/googletest.git External/googletest
|
||||||
|
- update_glslang_sources.py
|
||||||
|
|
||||||
script:
|
script:
|
||||||
- mkdir build && cd build
|
- 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
|
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
|
#### 3) Configure
|
||||||
|
|
||||||
Assume the source directory is `$SOURCE_DIR` and
|
Assume the source directory is `$SOURCE_DIR` and
|
||||||
|
@ -52,6 +52,16 @@ namespace spv {
|
|||||||
#endif
|
#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
|
// Glslang includes
|
||||||
#include "../glslang/MachineIndependent/localintermediate.h"
|
#include "../glslang/MachineIndependent/localintermediate.h"
|
||||||
#include "../glslang/MachineIndependent/SymbolTable.h"
|
#include "../glslang/MachineIndependent/SymbolTable.h"
|
||||||
@ -5960,6 +5970,12 @@ void OutputSpvHex(const std::vector<unsigned int>& spirv, const char* baseName,
|
|||||||
out.close();
|
out.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef ENABLE_OPT
|
||||||
|
void errHandler(const std::string& str) {
|
||||||
|
std::cerr << str << std::endl;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
//
|
//
|
||||||
// Set up the glslang traversal
|
// Set up the glslang traversal
|
||||||
//
|
//
|
||||||
@ -5988,6 +6004,49 @@ void GlslangToSpv(const glslang::TIntermediate& intermediate, std::vector<unsign
|
|||||||
it.finishSpv();
|
it.finishSpv();
|
||||||
it.dumpSpv(spirv);
|
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();
|
glslang::GetThreadPoolAllocator().pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -48,8 +48,11 @@
|
|||||||
namespace glslang {
|
namespace glslang {
|
||||||
|
|
||||||
struct SpvOptions {
|
struct SpvOptions {
|
||||||
SpvOptions() : generateDebugInfo(false) { }
|
SpvOptions() : generateDebugInfo(false), disableOptimizer(true),
|
||||||
|
optimizeSize(false) { }
|
||||||
bool generateDebugInfo;
|
bool generateDebugInfo;
|
||||||
|
bool disableOptimizer;
|
||||||
|
bool optimizeSize;
|
||||||
};
|
};
|
||||||
|
|
||||||
void GetSpirvVersion(std::string&);
|
void GetSpirvVersion(std::string&);
|
||||||
|
@ -95,6 +95,8 @@ enum TOptions {
|
|||||||
EOptionAutoMapLocations = (1 << 25),
|
EOptionAutoMapLocations = (1 << 25),
|
||||||
EOptionDebug = (1 << 26),
|
EOptionDebug = (1 << 26),
|
||||||
EOptionStdin = (1 << 27),
|
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':
|
case 'I':
|
||||||
IncludeDirectoryList.push_back(getStringOperand("-I<dir> include path"));
|
IncludeDirectoryList.push_back(getStringOperand("-I<dir> include path"));
|
||||||
break;
|
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':
|
case 'S':
|
||||||
if (argc <= 1)
|
if (argc <= 1)
|
||||||
Error("no <stage> specified for -S");
|
Error("no <stage> specified for -S");
|
||||||
@ -882,6 +896,8 @@ void CompileAndLinkShaderUnits(std::vector<ShaderCompUnit> compUnits)
|
|||||||
glslang::SpvOptions spvOptions;
|
glslang::SpvOptions spvOptions;
|
||||||
if (Options & EOptionDebug)
|
if (Options & EOptionDebug)
|
||||||
spvOptions.generateDebugInfo = true;
|
spvOptions.generateDebugInfo = true;
|
||||||
|
spvOptions.disableOptimizer = Options & EOptionOptimizeDisable;
|
||||||
|
spvOptions.optimizeSize = Options & EOptionOptimizeSize;
|
||||||
glslang::GlslangToSpv(*program.getIntermediate((EShLanguage)stage), spirv, &logger, &spvOptions);
|
glslang::GlslangToSpv(*program.getIntermediate((EShLanguage)stage), spirv, &logger, &spvOptions);
|
||||||
|
|
||||||
// Dump the spv to a file or stdout, etc., but only if not doing
|
// 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"
|
" -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"
|
" -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"
|
" 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"
|
" -S <stage> uses specified stage rather than parsing the file extension\n"
|
||||||
" choices for <stage> are vert, tesc, tese, geom, frag, or comp\n"
|
" choices for <stage> are vert, tesc, tese, geom, frag, or comp\n"
|
||||||
" -U<macro> undefine a pre-processor macro\n"
|
" -U<macro> undefine a pre-processor macro\n"
|
||||||
|
46
Test/baseLegalResults/hlsl.aliasOpaque.frag.out
Normal file
46
Test/baseLegalResults/hlsl.aliasOpaque.frag.out
Normal file
@ -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
|
65
Test/baseLegalResults/hlsl.flattenOpaque.frag.out
Normal file
65
Test/baseLegalResults/hlsl.flattenOpaque.frag.out
Normal file
@ -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
|
70
Test/baseLegalResults/hlsl.flattenOpaqueInit.vert.out
Normal file
70
Test/baseLegalResults/hlsl.flattenOpaqueInit.vert.out
Normal file
@ -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
|
43
Test/baseLegalResults/hlsl.flattenOpaqueInitMix.vert.out
Normal file
43
Test/baseLegalResults/hlsl.flattenOpaqueInitMix.vert.out
Normal file
@ -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...
|
echo Running reflection...
|
||||||
$EXE -l -q -C reflection.vert > $TARGETDIR/reflection.vert.out
|
$EXE -l -q -C reflection.vert > $TARGETDIR/reflection.vert.out
|
||||||
diff -b $BASEDIR/reflection.vert.out $TARGETDIR/reflection.vert.out || HASERROR=1
|
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
|
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
|
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
|
diff -b $BASEDIR/hlsl.automap.frag.out $TARGETDIR/hlsl.automap.frag.out || HASERROR=1
|
||||||
|
|
||||||
#
|
#
|
||||||
@ -56,14 +56,14 @@ fi
|
|||||||
# entry point renaming tests
|
# entry point renaming tests
|
||||||
#
|
#
|
||||||
echo Running 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
|
diff -b $BASEDIR/hlsl.entry.rename.frag.out $TARGETDIR/hlsl.entry.rename.frag.out || HASERROR=1
|
||||||
|
|
||||||
#
|
#
|
||||||
# Testing ill-defined uncalled function
|
# Testing ill-defined uncalled function
|
||||||
#
|
#
|
||||||
echo Running 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
|
diff -b $BASEDIR/hlsl.deadFunctionMissingBody.vert.out $TARGETDIR/hlsl.deadFunctionMissingBody.vert.out || HASERROR=1
|
||||||
|
|
||||||
if [ $HASERROR -eq 0 ]
|
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
|
diff -b $BASEDIR/spv.hlslOffsets.vert.out $TARGETDIR/spv.hlslOffsets.vert.out || HASERROR=1
|
||||||
|
|
||||||
echo Running hlsl offsets
|
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
|
diff -b $BASEDIR/hlsl.hlslOffset.vert.out $TARGETDIR/hlsl.hlslOffset.vert.out || HASERROR=1
|
||||||
|
|
||||||
#
|
#
|
||||||
# Testing --resource-set-binding
|
# Testing --resource-set-binding
|
||||||
#
|
#
|
||||||
echo Configuring HLSL descriptor set and binding number manually
|
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
|
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
|
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
|
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
|
-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
|
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 \
|
$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
|
diff -b $BASEDIR/spv.hlslDebugInfo.frag.out $TARGETDIR/spv.hlslDebugInfo.frag.out || HASERROR=1
|
||||||
|
|
||||||
#
|
#
|
||||||
# Testing Includer
|
# Testing Includer
|
||||||
#
|
#
|
||||||
echo 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
|
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
|
diff -b $BASEDIR/hlsl.includeNegative.vert.out $TARGETDIR/hlsl.includeNegative.vert.out || HASERROR=1
|
||||||
$EXE -l -i include.vert > $TARGETDIR/include.vert.out
|
$EXE -l -i include.vert > $TARGETDIR/include.vert.out
|
||||||
diff -b $BASEDIR/include.vert.out $TARGETDIR/include.vert.out || HASERROR=1
|
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
|
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"
|
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
|
$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
|
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
|
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 HlslCompileTest = GlslangTest<::testing::TestWithParam<FileNameEntryPointPair>>;
|
||||||
using HlslCompileAndFlattenTest = 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
|
// Compiling HLSL to pre-legalized SPIR-V under Vulkan semantics. Expected
|
||||||
// generate both AST and SPIR-V.
|
// to successfully generate both AST and SPIR-V.
|
||||||
TEST_P(HlslCompileTest, FromFile)
|
TEST_P(HlslCompileTest, FromFile)
|
||||||
{
|
{
|
||||||
loadFileCompileAndCheck(GlobalTestSettings.testRoot, GetParam().fileName,
|
loadFileCompileAndCheck(GlobalTestSettings.testRoot, GetParam().fileName,
|
||||||
@ -76,6 +77,16 @@ TEST_P(HlslCompileAndFlattenTest, FromFile)
|
|||||||
Target::BothASTAndSpv, GetParam().entryPoint);
|
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
|
// clang-format off
|
||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(
|
||||||
ToSpirv, HlslCompileTest,
|
ToSpirv, HlslCompileTest,
|
||||||
@ -353,7 +364,20 @@ INSTANTIATE_TEST_CASE_P(
|
|||||||
}),
|
}),
|
||||||
FileNameAsCustomTestSuffix
|
FileNameAsCustomTestSuffix
|
||||||
);
|
);
|
||||||
|
|
||||||
// clang-format on
|
// 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
|
} // anonymous namespace
|
||||||
} // namespace glslangtest
|
} // namespace glslangtest
|
||||||
|
@ -198,7 +198,8 @@ public:
|
|||||||
const std::string shaderName, const std::string& code,
|
const std::string shaderName, const std::string& code,
|
||||||
const std::string& entryPointName, EShMessages controls,
|
const std::string& entryPointName, EShMessages controls,
|
||||||
bool flattenUniformArrays = false,
|
bool flattenUniformArrays = false,
|
||||||
EShTextureSamplerTransformMode texSampTransMode = EShTexSampTransKeep)
|
EShTextureSamplerTransformMode texSampTransMode = EShTexSampTransKeep,
|
||||||
|
bool disableOptimizer = true)
|
||||||
{
|
{
|
||||||
const EShLanguage kind = GetShaderStage(GetSuffix(shaderName));
|
const EShLanguage kind = GetShaderStage(GetSuffix(shaderName));
|
||||||
|
|
||||||
@ -217,8 +218,10 @@ public:
|
|||||||
|
|
||||||
if (success && (controls & EShMsgSpvRules)) {
|
if (success && (controls & EShMsgSpvRules)) {
|
||||||
std::vector<uint32_t> spirv_binary;
|
std::vector<uint32_t> spirv_binary;
|
||||||
|
glslang::SpvOptions options;
|
||||||
|
options.disableOptimizer = disableOptimizer;
|
||||||
glslang::GlslangToSpv(*program.getIntermediate(kind),
|
glslang::GlslangToSpv(*program.getIntermediate(kind),
|
||||||
spirv_binary, &logger);
|
spirv_binary, &logger, &options);
|
||||||
|
|
||||||
std::ostringstream disassembly_stream;
|
std::ostringstream disassembly_stream;
|
||||||
spv::Parameterize();
|
spv::Parameterize();
|
||||||
@ -381,18 +384,20 @@ public:
|
|||||||
Source source,
|
Source source,
|
||||||
Semantics semantics,
|
Semantics semantics,
|
||||||
Target target,
|
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 inputFname = testDir + "/" + testName;
|
||||||
const std::string expectedOutputFname =
|
const std::string expectedOutputFname =
|
||||||
testDir + "/baseResults/" + testName + ".out";
|
testDir + baseDir + testName + ".out";
|
||||||
std::string input, expectedOutput;
|
std::string input, expectedOutput;
|
||||||
|
|
||||||
tryLoadFile(inputFname, "input", &input);
|
tryLoadFile(inputFname, "input", &input);
|
||||||
tryLoadFile(expectedOutputFname, "expected output", &expectedOutput);
|
tryLoadFile(expectedOutputFname, "expected output", &expectedOutput);
|
||||||
|
|
||||||
const EShMessages controls = DeriveOptions(source, semantics, target);
|
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.
|
// Generate the hybrid output in the way of glslangValidator.
|
||||||
std::ostringstream stream;
|
std::ostringstream stream;
|
||||||
|
18
known_good.json
Normal file
18
known_good.json
Normal file
@ -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"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
151
update_glslang_sources.py
Executable file
151
update_glslang_sources.py
Executable file
@ -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()
|
Loading…
Reference in New Issue
Block a user