Add passes to legalization to preserve source line info when generated.

This commit is contained in:
Greg Fischer 2018-11-28 11:10:27 -07:00
parent b23d232ec5
commit 5620a2f95e
4 changed files with 220 additions and 0 deletions

View File

@ -152,6 +152,13 @@ void SpirvToolsLegalize(const glslang::TIntermediate&, std::vector<unsigned int>
out << std::endl;
});
// If debug (specifically source line info) is being generated, propagate
// line information into all SPIR-V instructions. This avoids loss of
// information when instructions are deleted or moved. Later, remove
// redundant information to minimize final SPRIR-V size.
if (options->generateDebugInfo) {
optimizer.RegisterPass(spvtools::CreatePropagateLineInfoPass());
}
optimizer.RegisterPass(spvtools::CreateDeadBranchElimPass());
optimizer.RegisterPass(spvtools::CreateMergeReturnPass());
optimizer.RegisterPass(spvtools::CreateInlineExhaustivePass());
@ -180,6 +187,9 @@ void SpirvToolsLegalize(const glslang::TIntermediate&, std::vector<unsigned int>
}
optimizer.RegisterPass(spvtools::CreateAggressiveDCEPass());
optimizer.RegisterPass(spvtools::CreateCFGCleanupPass());
if (options->generateDebugInfo) {
optimizer.RegisterPass(spvtools::CreateRedundantLineInfoElimPass());
}
optimizer.Run(spirv.data(), spirv.size(), &spirv);
}

View File

@ -0,0 +1,146 @@
hlsl.pp.line4.frag
// Module Version 10000
// Generated by (magic number): 80007
// Id's are bound by 115
Capability Shader
2: ExtInstImport "GLSL.std.450"
MemoryModel Logical GLSL450
EntryPoint Fragment 5 "MainPs" 70 74
ExecutionMode 5 OriginUpperLeft
1: String "hlsl.pp.line4.frag"
17: String "C:\\Users\\Greg\\shaders\\line\\foo4.frag"
32: String "C:\\Users\\Greg\\shaders\\line\\u1.h"
Source HLSL 500 1 "// OpModuleProcessed auto-map-locations
// OpModuleProcessed auto-map-bindings
// OpModuleProcessed entry-point MainPs
// OpModuleProcessed client vulkan100
// OpModuleProcessed target-env vulkan1.0
// OpModuleProcessed keep-uncalled
// OpModuleProcessed hlsl-offsets
#line 1
#line 1 "C:\\Users\\Greg\\shaders\\line\\foo4.frag"
Texture2D g_tColor [ 128 ] ;
layout ( push_constant ) cbuffer PerViewConstantBuffer_t
{
uint g_nDataIdx ;
uint g_nDataIdx2 ;
bool g_B ;
} ;
#line 12
SamplerState g_sAniso ;
struct PS_INPUT
{
float2 vTextureCoords : TEXCOORD2 ;
} ;
struct PS_OUTPUT
{
float4 vColor : SV_Target0 ;
} ;
PS_OUTPUT MainPs ( PS_INPUT i )
{
PS_OUTPUT ps_output ;
uint u ;
if ( g_B )
#line 1 "C:\\Users\\Greg\\shaders\\line\\u1.h"
u = g_nDataIdx ;
#line 31 "C:\\Users\\Greg\\shaders\\line\\foo4.frag"
else
u = g_nDataIdx2 ;
ps_output . vColor = g_tColor [ u ] . Sample ( g_sAniso , i . vTextureCoords . xy ) ;
return ps_output ;
}
"
Name 5 "MainPs"
Name 19 "PerViewConstantBuffer_t"
MemberName 19(PerViewConstantBuffer_t) 0 "g_nDataIdx"
MemberName 19(PerViewConstantBuffer_t) 1 "g_nDataIdx2"
MemberName 19(PerViewConstantBuffer_t) 2 "g_B"
Name 21 ""
Name 48 "g_tColor"
Name 55 "g_sAniso"
Name 70 "i.vTextureCoords"
Name 74 "@entryPointOutput.vColor"
MemberDecorate 19(PerViewConstantBuffer_t) 0 Offset 0
MemberDecorate 19(PerViewConstantBuffer_t) 1 Offset 4
MemberDecorate 19(PerViewConstantBuffer_t) 2 Offset 8
Decorate 19(PerViewConstantBuffer_t) Block
Decorate 48(g_tColor) DescriptorSet 0
Decorate 48(g_tColor) Binding 0
Decorate 55(g_sAniso) DescriptorSet 0
Decorate 55(g_sAniso) Binding 0
Decorate 70(i.vTextureCoords) Location 0
Decorate 74(@entryPointOutput.vColor) Location 0
3: TypeVoid
4: TypeFunction 3
7: TypeFloat 32
8: TypeVector 7(float) 2
11: TypeVector 7(float) 4
18: TypeInt 32 0
19(PerViewConstantBuffer_t): TypeStruct 18(int) 18(int) 18(int)
20: TypePointer PushConstant 19(PerViewConstantBuffer_t)
21: 20(ptr) Variable PushConstant
22: TypeInt 32 1
23: 22(int) Constant 2
24: TypePointer PushConstant 18(int)
27: TypeBool
28: 18(int) Constant 0
35: 22(int) Constant 0
39: 22(int) Constant 1
44: TypeImage 7(float) 2D sampled format:Unknown
45: 18(int) Constant 128
46: TypeArray 44 45
47: TypePointer UniformConstant 46
48(g_tColor): 47(ptr) Variable UniformConstant
50: TypePointer UniformConstant 44
53: TypeSampler
54: TypePointer UniformConstant 53
55(g_sAniso): 54(ptr) Variable UniformConstant
57: TypeSampledImage 44
69: TypePointer Input 8(fvec2)
70(i.vTextureCoords): 69(ptr) Variable Input
73: TypePointer Output 11(fvec4)
74(@entryPointOutput.vColor): 73(ptr) Variable Output
5(MainPs): 3 Function None 4
6: Label
Line 17 25 0
71: 8(fvec2) Load 70(i.vTextureCoords)
Line 17 29 0
82: 24(ptr) AccessChain 21 23
83: 18(int) Load 82
84: 27(bool) INotEqual 83 28
SelectionMerge 85 None
BranchConditional 84 86 87
86: Label
Line 32 1 0
88: 24(ptr) AccessChain 21 35
89: 18(int) Load 88
Branch 85
87: Label
Line 17 32 0
90: 24(ptr) AccessChain 21 39
91: 18(int) Load 90
Branch 85
85: Label
114: 18(int) Phi 89 86 91 87
Line 17 33 0
93: 50(ptr) AccessChain 48(g_tColor) 114
94: 44 Load 93
95: 53 Load 55(g_sAniso)
96: 57 SampledImage 94 95
99: 11(fvec4) ImageSampleImplicitLod 96 71
Line 17 25 0
Store 74(@entryPointOutput.vColor) 99
Return
FunctionEnd

42
Test/hlsl.pp.line4.frag Normal file
View File

@ -0,0 +1,42 @@
#line 1 "C:\\Users\\Greg\\shaders\\line\\foo4.frag"
Texture2D g_tColor [ 128 ] ;
layout ( push_constant ) cbuffer PerViewConstantBuffer_t
{
uint g_nDataIdx ;
uint g_nDataIdx2 ;
bool g_B ;
} ;
#line 12
SamplerState g_sAniso ;
struct PS_INPUT
{
float2 vTextureCoords : TEXCOORD2 ;
} ;
struct PS_OUTPUT
{
float4 vColor : SV_Target0 ;
} ;
PS_OUTPUT MainPs ( PS_INPUT i )
{
PS_OUTPUT ps_output ;
uint u ;
if ( g_B )
#line 1 "C:\\Users\\Greg\\shaders\\line\\u1.h"
u = g_nDataIdx ;
#line 31 "C:\\Users\\Greg\\shaders\\line\\foo4.frag"
else
u = g_nDataIdx2 ;
ps_output . vColor = g_tColor [ u ] . Sample ( g_sAniso , i . vTextureCoords . xy ) ;
return ps_output ;
}

View File

@ -63,6 +63,7 @@ using HlslCompileAndFlattenTest = GlslangTest<::testing::TestWithParam<FileNameE
using HlslLegalizeTest = GlslangTest<::testing::TestWithParam<FileNameEntryPointPair>>;
using HlslDebugTest = GlslangTest<::testing::TestWithParam<FileNameEntryPointPair>>;
using HlslDX9CompatibleTest = GlslangTest<::testing::TestWithParam<FileNameEntryPointPair>>;
using HlslLegalDebugTest = GlslangTest<::testing::TestWithParam<FileNameEntryPointPair>>;
// Compiling HLSL to pre-legalized SPIR-V under Vulkan semantics. Expected
// to successfully generate both AST and SPIR-V.
@ -115,6 +116,17 @@ TEST_P(HlslDX9CompatibleTest, FromFile)
EShMessages::EShMsgHlslDX9Compatible);
}
// Compiling HLSL to legalized SPIR-V with debug instructions. Expected to
// successfully generate SPIR-V with debug instructions preserved through
// legalization, particularly line info.
TEST_P(HlslLegalDebugTest, FromFile)
{
loadFileCompileAndCheck(GlobalTestSettings.testRoot, GetParam().fileName,
Source::HLSL, Semantics::Vulkan, glslang::EShTargetVulkan_1_0,
Target::Spv, true, GetParam().entryPoint,
"/baseResults/", true, true);
}
// clang-format off
INSTANTIATE_TEST_CASE_P(
ToSpirv, HlslCompileTest,
@ -474,6 +486,16 @@ INSTANTIATE_TEST_CASE_P(
}),
FileNameAsCustomTestSuffix
);
// clang-format off
INSTANTIATE_TEST_CASE_P(
ToSpirv, HlslLegalDebugTest,
::testing::ValuesIn(std::vector<FileNameEntryPointPair>{
{"hlsl.pp.line4.frag", "MainPs"}
}),
FileNameAsCustomTestSuffix
);
// clang-format on
} // anonymous namespace