Merge pull request #840 from steve-lunarg/iomap-hlsl
HLSL: hlsl register class iomapping
This commit is contained in:
commit
1487db54e1
11 changed files with 429 additions and 118 deletions
|
|
@ -87,6 +87,7 @@ enum TOptions {
|
||||||
EOptionNoStorageFormat = (1 << 21),
|
EOptionNoStorageFormat = (1 << 21),
|
||||||
EOptionKeepUncalled = (1 << 22),
|
EOptionKeepUncalled = (1 << 22),
|
||||||
EOptionHlslOffsets = (1 << 23),
|
EOptionHlslOffsets = (1 << 23),
|
||||||
|
EOptionHlslIoMapping = (1 << 24),
|
||||||
};
|
};
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
@ -166,6 +167,7 @@ std::array<unsigned int, EShLangCount> baseTextureBinding;
|
||||||
std::array<unsigned int, EShLangCount> baseImageBinding;
|
std::array<unsigned int, EShLangCount> baseImageBinding;
|
||||||
std::array<unsigned int, EShLangCount> baseUboBinding;
|
std::array<unsigned int, EShLangCount> baseUboBinding;
|
||||||
std::array<unsigned int, EShLangCount> baseSsboBinding;
|
std::array<unsigned int, EShLangCount> baseSsboBinding;
|
||||||
|
std::array<unsigned int, EShLangCount> baseUavBinding;
|
||||||
|
|
||||||
//
|
//
|
||||||
// Create the default name for saving a binary if -o is not provided.
|
// Create the default name for saving a binary if -o is not provided.
|
||||||
|
|
@ -256,6 +258,7 @@ void ProcessArguments(std::vector<std::unique_ptr<glslang::TWorkItem>>& workItem
|
||||||
baseImageBinding.fill(0);
|
baseImageBinding.fill(0);
|
||||||
baseUboBinding.fill(0);
|
baseUboBinding.fill(0);
|
||||||
baseSsboBinding.fill(0);
|
baseSsboBinding.fill(0);
|
||||||
|
baseUavBinding.fill(0);
|
||||||
|
|
||||||
ExecutableName = argv[0];
|
ExecutableName = argv[0];
|
||||||
workItems.reserve(argc);
|
workItems.reserve(argc);
|
||||||
|
|
@ -285,12 +288,19 @@ void ProcessArguments(std::vector<std::unique_ptr<glslang::TWorkItem>>& workItem
|
||||||
ProcessBindingBase(argc, argv, baseImageBinding);
|
ProcessBindingBase(argc, argv, baseImageBinding);
|
||||||
} else if (lowerword == "shift-ubo-bindings" || // synonyms
|
} else if (lowerword == "shift-ubo-bindings" || // synonyms
|
||||||
lowerword == "shift-ubo-binding" ||
|
lowerword == "shift-ubo-binding" ||
|
||||||
lowerword == "sub") {
|
lowerword == "shift-cbuffer-bindings" ||
|
||||||
|
lowerword == "shift-cbuffer-binding" ||
|
||||||
|
lowerword == "sub" ||
|
||||||
|
lowerword == "scb") {
|
||||||
ProcessBindingBase(argc, argv, baseUboBinding);
|
ProcessBindingBase(argc, argv, baseUboBinding);
|
||||||
} else if (lowerword == "shift-ssbo-bindings" || // synonyms
|
} else if (lowerword == "shift-ssbo-bindings" || // synonyms
|
||||||
lowerword == "shift-ssbo-binding" ||
|
lowerword == "shift-ssbo-binding" ||
|
||||||
lowerword == "sbb") {
|
lowerword == "sbb") {
|
||||||
ProcessBindingBase(argc, argv, baseSsboBinding);
|
ProcessBindingBase(argc, argv, baseSsboBinding);
|
||||||
|
} else if (lowerword == "shift-uav-bindings" || // synonyms
|
||||||
|
lowerword == "shift-uav-binding" ||
|
||||||
|
lowerword == "suavb") {
|
||||||
|
ProcessBindingBase(argc, argv, baseUavBinding);
|
||||||
} else if (lowerword == "auto-map-bindings" || // synonyms
|
} else if (lowerword == "auto-map-bindings" || // synonyms
|
||||||
lowerword == "auto-map-binding" ||
|
lowerword == "auto-map-binding" ||
|
||||||
lowerword == "amb") {
|
lowerword == "amb") {
|
||||||
|
|
@ -326,6 +336,10 @@ void ProcessArguments(std::vector<std::unique_ptr<glslang::TWorkItem>>& workItem
|
||||||
Options |= EOptionKeepUncalled;
|
Options |= EOptionKeepUncalled;
|
||||||
} else if (lowerword == "hlsl-offsets") {
|
} else if (lowerword == "hlsl-offsets") {
|
||||||
Options |= EOptionHlslOffsets;
|
Options |= EOptionHlslOffsets;
|
||||||
|
} else if (lowerword == "hlsl-iomap" ||
|
||||||
|
lowerword == "hlsl-iomapper" ||
|
||||||
|
lowerword == "hlsl-iomapping") {
|
||||||
|
Options |= EOptionHlslIoMapping;
|
||||||
} else {
|
} else {
|
||||||
usage();
|
usage();
|
||||||
}
|
}
|
||||||
|
|
@ -577,9 +591,13 @@ void CompileAndLinkShaderUnits(std::vector<ShaderCompUnit> compUnits)
|
||||||
shader->setShiftImageBinding(baseImageBinding[compUnit.stage]);
|
shader->setShiftImageBinding(baseImageBinding[compUnit.stage]);
|
||||||
shader->setShiftUboBinding(baseUboBinding[compUnit.stage]);
|
shader->setShiftUboBinding(baseUboBinding[compUnit.stage]);
|
||||||
shader->setShiftSsboBinding(baseSsboBinding[compUnit.stage]);
|
shader->setShiftSsboBinding(baseSsboBinding[compUnit.stage]);
|
||||||
|
shader->setShiftUavBinding(baseUavBinding[compUnit.stage]);
|
||||||
shader->setFlattenUniformArrays((Options & EOptionFlattenUniformArrays) != 0);
|
shader->setFlattenUniformArrays((Options & EOptionFlattenUniformArrays) != 0);
|
||||||
shader->setNoStorageFormat((Options & EOptionNoStorageFormat) != 0);
|
shader->setNoStorageFormat((Options & EOptionNoStorageFormat) != 0);
|
||||||
|
|
||||||
|
if (Options & EOptionHlslIoMapping)
|
||||||
|
shader->setHlslIoMapping(true);
|
||||||
|
|
||||||
if (Options & EOptionAutoMapBindings)
|
if (Options & EOptionAutoMapBindings)
|
||||||
shader->setAutoMapBindings(true);
|
shader->setAutoMapBindings(true);
|
||||||
|
|
||||||
|
|
@ -982,11 +1000,15 @@ void usage()
|
||||||
" --sib [stage] num synonym for --shift-image-binding\n"
|
" --sib [stage] num synonym for --shift-image-binding\n"
|
||||||
"\n"
|
"\n"
|
||||||
" --shift-UBO-binding [stage] num set base binding number for UBOs\n"
|
" --shift-UBO-binding [stage] num set base binding number for UBOs\n"
|
||||||
|
" --shift-cbuffer-binding [stage] num synonym for --shift-UBO-binding\n"
|
||||||
" --sub [stage] num synonym for --shift-UBO-binding\n"
|
" --sub [stage] num synonym for --shift-UBO-binding\n"
|
||||||
"\n"
|
"\n"
|
||||||
" --shift-ssbo-binding [stage] num set base binding number for SSBOs\n"
|
" --shift-ssbo-binding [stage] num set base binding number for SSBOs\n"
|
||||||
" --sbb [stage] num synonym for --shift-ssbo-binding\n"
|
" --sbb [stage] num synonym for --shift-ssbo-binding\n"
|
||||||
"\n"
|
"\n"
|
||||||
|
" --shift-uav-binding [stage] num set base binding number for UAVs\n"
|
||||||
|
" --suavb [stage] num synonym for --shift-uav-binding\n"
|
||||||
|
"\n"
|
||||||
" --auto-map-bindings automatically bind uniform variables without\n"
|
" --auto-map-bindings automatically bind uniform variables without\n"
|
||||||
" explicit bindings.\n"
|
" explicit bindings.\n"
|
||||||
" --amb synonym for --auto-map-bindings\n"
|
" --amb synonym for --auto-map-bindings\n"
|
||||||
|
|
@ -1009,6 +1031,8 @@ void usage()
|
||||||
"\n"
|
"\n"
|
||||||
" --hlsl-offsets Allow block offsets to follow HLSL rules instead of GLSL rules.\n"
|
" --hlsl-offsets Allow block offsets to follow HLSL rules instead of GLSL rules.\n"
|
||||||
" Works independently of source language.\n"
|
" Works independently of source language.\n"
|
||||||
|
"\n"
|
||||||
|
" --hlsl-iomap Perform IO mapping in HLSL register space.\n"
|
||||||
);
|
);
|
||||||
|
|
||||||
exit(EFailUsage);
|
exit(EFailUsage);
|
||||||
|
|
|
||||||
29
Test/baseResults/hlsl.automap.frag.out
Normal file
29
Test/baseResults/hlsl.automap.frag.out
Normal file
|
|
@ -0,0 +1,29 @@
|
||||||
|
hlsl.automap.frag
|
||||||
|
Uniform reflection:
|
||||||
|
t1: offset -1, type 8b5d, size 1, index -1, binding 11
|
||||||
|
t2: offset -1, type 8b5e, size 1, index -1, binding 12
|
||||||
|
t3: offset -1, type 8b5f, size 1, index -1, binding 13
|
||||||
|
t4.@data: offset 0, type 8b52, size 1, index 0, binding -1
|
||||||
|
t5.@data: offset 0, type 1405, size 0, index 1, binding -1
|
||||||
|
t6: offset -1, type 8dc2, size 1, index -1, binding 16
|
||||||
|
s1: offset -1, type 0, size 1, index -1, binding 31
|
||||||
|
s2: offset -1, type 0, size 1, index -1, binding 32
|
||||||
|
u1: offset -1, type 904c, size 1, index -1, binding 41
|
||||||
|
u2: offset -1, type 904d, size 1, index -1, binding 42
|
||||||
|
u3: offset -1, type 904e, size 1, index -1, binding 43
|
||||||
|
u4: offset -1, type 9051, size 1, index -1, binding 44
|
||||||
|
u5.@data: offset 0, type 1405, size 0, index 2, binding -1
|
||||||
|
u6.@data: offset 0, type 1406, size 1, index 3, binding -1
|
||||||
|
cb1: offset 0, type 1404, size 1, index 4, binding -1
|
||||||
|
tb1: offset 0, type 1404, size 1, index 5, binding -1
|
||||||
|
|
||||||
|
Uniform block reflection:
|
||||||
|
t4: offset -1, type ffffffff, size 0, index -1, binding 14
|
||||||
|
t5: offset -1, type ffffffff, size 0, index -1, binding 15
|
||||||
|
u5: offset -1, type ffffffff, size 0, index -1, binding 45
|
||||||
|
u6: offset -1, type ffffffff, size 0, index -1, binding 46
|
||||||
|
cb: offset -1, type ffffffff, size 4, index -1, binding 51
|
||||||
|
tb: offset -1, type ffffffff, size 4, index -1, binding 17
|
||||||
|
|
||||||
|
Vertex attribute reflection:
|
||||||
|
|
||||||
|
|
@ -17,7 +17,7 @@ gl_FragCoord origin is upper left
|
||||||
0:31 Constant:
|
0:31 Constant:
|
||||||
0:31 0 (const uint)
|
0:31 0 (const uint)
|
||||||
0:31 v2: direct index for structure (layout( row_major std430) buffer 4-component vector of float)
|
0:31 v2: direct index for structure (layout( row_major std430) buffer 4-component vector of float)
|
||||||
0:31 'anon@1' (layout( row_major std430) buffer block{layout( row_major std430) buffer 4-component vector of float v2})
|
0:31 'anon@1' (layout( row_major std430) readonly buffer block{layout( row_major std430) buffer 4-component vector of float v2})
|
||||||
0:31 Constant:
|
0:31 Constant:
|
||||||
0:31 0 (const uint)
|
0:31 0 (const uint)
|
||||||
0:31 v3: direct index for structure (layout( row_major std140) uniform 4-component vector of float)
|
0:31 v3: direct index for structure (layout( row_major std140) uniform 4-component vector of float)
|
||||||
|
|
@ -25,7 +25,7 @@ gl_FragCoord origin is upper left
|
||||||
0:31 Constant:
|
0:31 Constant:
|
||||||
0:31 0 (const uint)
|
0:31 0 (const uint)
|
||||||
0:31 v4: direct index for structure (layout( row_major std430 offset=16) buffer 4-component vector of float)
|
0:31 v4: direct index for structure (layout( row_major std430 offset=16) buffer 4-component vector of float)
|
||||||
0:31 'anon@3' (layout( binding=8 row_major std430) buffer block{layout( row_major std430 offset=16) buffer 4-component vector of float v4, layout( row_major std430 offset=48) buffer int i4, layout( row_major std430 offset=60) buffer float f1, layout( row_major std430 offset=64) buffer float f3, layout( row_major std430 offset=68) buffer float f4, layout( row_major std430 offset=72) buffer float f5, layout( row_major std430) buffer float f6, layout( row_major std430) buffer float f7, layout( row_major std430) buffer 3X4 matrix of float m1, layout( column_major std430) buffer 3X4 matrix of float m2, layout( row_major std430) buffer 3X4 matrix of float m3, layout( row_major std430) buffer 3X4 matrix of float m4})
|
0:31 'anon@3' (layout( binding=8 row_major std430) readonly buffer block{layout( row_major std430 offset=16) buffer 4-component vector of float v4, layout( row_major std430 offset=48) buffer int i4, layout( row_major std430 offset=60) buffer float f1, layout( row_major std430 offset=64) buffer float f3, layout( row_major std430 offset=68) buffer float f4, layout( row_major std430 offset=72) buffer float f5, layout( row_major std430) buffer float f6, layout( row_major std430) buffer float f7, layout( row_major std430) buffer 3X4 matrix of float m1, layout( column_major std430) buffer 3X4 matrix of float m2, layout( row_major std430) buffer 3X4 matrix of float m3, layout( row_major std430) buffer 3X4 matrix of float m4})
|
||||||
0:31 Constant:
|
0:31 Constant:
|
||||||
0:31 0 (const uint)
|
0:31 0 (const uint)
|
||||||
0:30 Function Definition: PixelShaderFunction( ( temp void)
|
0:30 Function Definition: PixelShaderFunction( ( temp void)
|
||||||
|
|
@ -40,9 +40,9 @@ gl_FragCoord origin is upper left
|
||||||
0:? 'input' ( temp 4-component vector of float)
|
0:? 'input' ( temp 4-component vector of float)
|
||||||
0:? Linker Objects
|
0:? Linker Objects
|
||||||
0:? 'anon@0' (layout( row_major std140) uniform block{layout( row_major std140) uniform 4-component vector of float v1})
|
0:? 'anon@0' (layout( row_major std140) uniform block{layout( row_major std140) uniform 4-component vector of float v1})
|
||||||
0:? 'anon@1' (layout( row_major std430) buffer block{layout( row_major std430) buffer 4-component vector of float v2})
|
0:? 'anon@1' (layout( row_major std430) readonly buffer block{layout( row_major std430) buffer 4-component vector of float v2})
|
||||||
0:? 'anon@2' (layout( set=10 binding=2 row_major std140) uniform block{layout( row_major std140) uniform 4-component vector of float v3, layout( row_major std140 offset=20) uniform int i3})
|
0:? 'anon@2' (layout( set=10 binding=2 row_major std140) uniform block{layout( row_major std140) uniform 4-component vector of float v3, layout( row_major std140 offset=20) uniform int i3})
|
||||||
0:? 'anon@3' (layout( binding=8 row_major std430) buffer block{layout( row_major std430 offset=16) buffer 4-component vector of float v4, layout( row_major std430 offset=48) buffer int i4, layout( row_major std430 offset=60) buffer float f1, layout( row_major std430 offset=64) buffer float f3, layout( row_major std430 offset=68) buffer float f4, layout( row_major std430 offset=72) buffer float f5, layout( row_major std430) buffer float f6, layout( row_major std430) buffer float f7, layout( row_major std430) buffer 3X4 matrix of float m1, layout( column_major std430) buffer 3X4 matrix of float m2, layout( row_major std430) buffer 3X4 matrix of float m3, layout( row_major std430) buffer 3X4 matrix of float m4})
|
0:? 'anon@3' (layout( binding=8 row_major std430) readonly buffer block{layout( row_major std430 offset=16) buffer 4-component vector of float v4, layout( row_major std430 offset=48) buffer int i4, layout( row_major std430 offset=60) buffer float f1, layout( row_major std430 offset=64) buffer float f3, layout( row_major std430 offset=68) buffer float f4, layout( row_major std430 offset=72) buffer float f5, layout( row_major std430) buffer float f6, layout( row_major std430) buffer float f7, layout( row_major std430) buffer 3X4 matrix of float m1, layout( column_major std430) buffer 3X4 matrix of float m2, layout( row_major std430) buffer 3X4 matrix of float m3, layout( row_major std430) buffer 3X4 matrix of float m4})
|
||||||
0:? '@entryPointOutput' (layout( location=0) out 4-component vector of float)
|
0:? '@entryPointOutput' (layout( location=0) out 4-component vector of float)
|
||||||
0:? 'input' (layout( location=0) in 4-component vector of float)
|
0:? 'input' (layout( location=0) in 4-component vector of float)
|
||||||
|
|
||||||
|
|
@ -68,7 +68,7 @@ gl_FragCoord origin is upper left
|
||||||
0:31 Constant:
|
0:31 Constant:
|
||||||
0:31 0 (const uint)
|
0:31 0 (const uint)
|
||||||
0:31 v2: direct index for structure (layout( row_major std430) buffer 4-component vector of float)
|
0:31 v2: direct index for structure (layout( row_major std430) buffer 4-component vector of float)
|
||||||
0:31 'anon@1' (layout( row_major std430) buffer block{layout( row_major std430) buffer 4-component vector of float v2})
|
0:31 'anon@1' (layout( row_major std430) readonly buffer block{layout( row_major std430) buffer 4-component vector of float v2})
|
||||||
0:31 Constant:
|
0:31 Constant:
|
||||||
0:31 0 (const uint)
|
0:31 0 (const uint)
|
||||||
0:31 v3: direct index for structure (layout( row_major std140) uniform 4-component vector of float)
|
0:31 v3: direct index for structure (layout( row_major std140) uniform 4-component vector of float)
|
||||||
|
|
@ -76,7 +76,7 @@ gl_FragCoord origin is upper left
|
||||||
0:31 Constant:
|
0:31 Constant:
|
||||||
0:31 0 (const uint)
|
0:31 0 (const uint)
|
||||||
0:31 v4: direct index for structure (layout( row_major std430 offset=16) buffer 4-component vector of float)
|
0:31 v4: direct index for structure (layout( row_major std430 offset=16) buffer 4-component vector of float)
|
||||||
0:31 'anon@3' (layout( binding=8 row_major std430) buffer block{layout( row_major std430 offset=16) buffer 4-component vector of float v4, layout( row_major std430 offset=48) buffer int i4, layout( row_major std430 offset=60) buffer float f1, layout( row_major std430 offset=64) buffer float f3, layout( row_major std430 offset=68) buffer float f4, layout( row_major std430 offset=72) buffer float f5, layout( row_major std430) buffer float f6, layout( row_major std430) buffer float f7, layout( row_major std430) buffer 3X4 matrix of float m1, layout( column_major std430) buffer 3X4 matrix of float m2, layout( row_major std430) buffer 3X4 matrix of float m3, layout( row_major std430) buffer 3X4 matrix of float m4})
|
0:31 'anon@3' (layout( binding=8 row_major std430) readonly buffer block{layout( row_major std430 offset=16) buffer 4-component vector of float v4, layout( row_major std430 offset=48) buffer int i4, layout( row_major std430 offset=60) buffer float f1, layout( row_major std430 offset=64) buffer float f3, layout( row_major std430 offset=68) buffer float f4, layout( row_major std430 offset=72) buffer float f5, layout( row_major std430) buffer float f6, layout( row_major std430) buffer float f7, layout( row_major std430) buffer 3X4 matrix of float m1, layout( column_major std430) buffer 3X4 matrix of float m2, layout( row_major std430) buffer 3X4 matrix of float m3, layout( row_major std430) buffer 3X4 matrix of float m4})
|
||||||
0:31 Constant:
|
0:31 Constant:
|
||||||
0:31 0 (const uint)
|
0:31 0 (const uint)
|
||||||
0:30 Function Definition: PixelShaderFunction( ( temp void)
|
0:30 Function Definition: PixelShaderFunction( ( temp void)
|
||||||
|
|
@ -91,9 +91,9 @@ gl_FragCoord origin is upper left
|
||||||
0:? 'input' ( temp 4-component vector of float)
|
0:? 'input' ( temp 4-component vector of float)
|
||||||
0:? Linker Objects
|
0:? Linker Objects
|
||||||
0:? 'anon@0' (layout( row_major std140) uniform block{layout( row_major std140) uniform 4-component vector of float v1})
|
0:? 'anon@0' (layout( row_major std140) uniform block{layout( row_major std140) uniform 4-component vector of float v1})
|
||||||
0:? 'anon@1' (layout( row_major std430) buffer block{layout( row_major std430) buffer 4-component vector of float v2})
|
0:? 'anon@1' (layout( row_major std430) readonly buffer block{layout( row_major std430) buffer 4-component vector of float v2})
|
||||||
0:? 'anon@2' (layout( set=10 binding=2 row_major std140) uniform block{layout( row_major std140) uniform 4-component vector of float v3, layout( row_major std140 offset=20) uniform int i3})
|
0:? 'anon@2' (layout( set=10 binding=2 row_major std140) uniform block{layout( row_major std140) uniform 4-component vector of float v3, layout( row_major std140 offset=20) uniform int i3})
|
||||||
0:? 'anon@3' (layout( binding=8 row_major std430) buffer block{layout( row_major std430 offset=16) buffer 4-component vector of float v4, layout( row_major std430 offset=48) buffer int i4, layout( row_major std430 offset=60) buffer float f1, layout( row_major std430 offset=64) buffer float f3, layout( row_major std430 offset=68) buffer float f4, layout( row_major std430 offset=72) buffer float f5, layout( row_major std430) buffer float f6, layout( row_major std430) buffer float f7, layout( row_major std430) buffer 3X4 matrix of float m1, layout( column_major std430) buffer 3X4 matrix of float m2, layout( row_major std430) buffer 3X4 matrix of float m3, layout( row_major std430) buffer 3X4 matrix of float m4})
|
0:? 'anon@3' (layout( binding=8 row_major std430) readonly buffer block{layout( row_major std430 offset=16) buffer 4-component vector of float v4, layout( row_major std430 offset=48) buffer int i4, layout( row_major std430 offset=60) buffer float f1, layout( row_major std430 offset=64) buffer float f3, layout( row_major std430 offset=68) buffer float f4, layout( row_major std430 offset=72) buffer float f5, layout( row_major std430) buffer float f6, layout( row_major std430) buffer float f7, layout( row_major std430) buffer 3X4 matrix of float m1, layout( column_major std430) buffer 3X4 matrix of float m2, layout( row_major std430) buffer 3X4 matrix of float m3, layout( row_major std430) buffer 3X4 matrix of float m4})
|
||||||
0:? '@entryPointOutput' (layout( location=0) out 4-component vector of float)
|
0:? '@entryPointOutput' (layout( location=0) out 4-component vector of float)
|
||||||
0:? 'input' (layout( location=0) in 4-component vector of float)
|
0:? 'input' (layout( location=0) in 4-component vector of float)
|
||||||
|
|
||||||
|
|
@ -141,6 +141,7 @@ gl_FragCoord origin is upper left
|
||||||
MemberDecorate 14 0 Offset 0
|
MemberDecorate 14 0 Offset 0
|
||||||
Decorate 14 Block
|
Decorate 14 Block
|
||||||
Decorate 16 DescriptorSet 0
|
Decorate 16 DescriptorSet 0
|
||||||
|
MemberDecorate 23 0 NonWritable
|
||||||
MemberDecorate 23 0 Offset 0
|
MemberDecorate 23 0 Offset 0
|
||||||
Decorate 23 BufferBlock
|
Decorate 23 BufferBlock
|
||||||
Decorate 25 DescriptorSet 0
|
Decorate 25 DescriptorSet 0
|
||||||
|
|
@ -149,24 +150,36 @@ gl_FragCoord origin is upper left
|
||||||
Decorate 29(cbufName) Block
|
Decorate 29(cbufName) Block
|
||||||
Decorate 31 DescriptorSet 10
|
Decorate 31 DescriptorSet 10
|
||||||
Decorate 31 Binding 2
|
Decorate 31 Binding 2
|
||||||
|
MemberDecorate 36(tbufName) 0 NonWritable
|
||||||
MemberDecorate 36(tbufName) 0 Offset 16
|
MemberDecorate 36(tbufName) 0 Offset 16
|
||||||
|
MemberDecorate 36(tbufName) 1 NonWritable
|
||||||
MemberDecorate 36(tbufName) 1 Offset 48
|
MemberDecorate 36(tbufName) 1 Offset 48
|
||||||
|
MemberDecorate 36(tbufName) 2 NonWritable
|
||||||
MemberDecorate 36(tbufName) 2 Offset 60
|
MemberDecorate 36(tbufName) 2 Offset 60
|
||||||
|
MemberDecorate 36(tbufName) 3 NonWritable
|
||||||
MemberDecorate 36(tbufName) 3 Offset 64
|
MemberDecorate 36(tbufName) 3 Offset 64
|
||||||
|
MemberDecorate 36(tbufName) 4 NonWritable
|
||||||
MemberDecorate 36(tbufName) 4 Offset 68
|
MemberDecorate 36(tbufName) 4 Offset 68
|
||||||
|
MemberDecorate 36(tbufName) 5 NonWritable
|
||||||
MemberDecorate 36(tbufName) 5 Offset 72
|
MemberDecorate 36(tbufName) 5 Offset 72
|
||||||
|
MemberDecorate 36(tbufName) 6 NonWritable
|
||||||
MemberDecorate 36(tbufName) 6 Offset 76
|
MemberDecorate 36(tbufName) 6 Offset 76
|
||||||
|
MemberDecorate 36(tbufName) 7 NonWritable
|
||||||
MemberDecorate 36(tbufName) 7 Offset 80
|
MemberDecorate 36(tbufName) 7 Offset 80
|
||||||
MemberDecorate 36(tbufName) 8 RowMajor
|
MemberDecorate 36(tbufName) 8 RowMajor
|
||||||
|
MemberDecorate 36(tbufName) 8 NonWritable
|
||||||
MemberDecorate 36(tbufName) 8 Offset 96
|
MemberDecorate 36(tbufName) 8 Offset 96
|
||||||
MemberDecorate 36(tbufName) 8 MatrixStride 16
|
MemberDecorate 36(tbufName) 8 MatrixStride 16
|
||||||
MemberDecorate 36(tbufName) 9 ColMajor
|
MemberDecorate 36(tbufName) 9 ColMajor
|
||||||
|
MemberDecorate 36(tbufName) 9 NonWritable
|
||||||
MemberDecorate 36(tbufName) 9 Offset 160
|
MemberDecorate 36(tbufName) 9 Offset 160
|
||||||
MemberDecorate 36(tbufName) 9 MatrixStride 16
|
MemberDecorate 36(tbufName) 9 MatrixStride 16
|
||||||
MemberDecorate 36(tbufName) 10 RowMajor
|
MemberDecorate 36(tbufName) 10 RowMajor
|
||||||
|
MemberDecorate 36(tbufName) 10 NonWritable
|
||||||
MemberDecorate 36(tbufName) 10 Offset 208
|
MemberDecorate 36(tbufName) 10 Offset 208
|
||||||
MemberDecorate 36(tbufName) 10 MatrixStride 16
|
MemberDecorate 36(tbufName) 10 MatrixStride 16
|
||||||
MemberDecorate 36(tbufName) 11 RowMajor
|
MemberDecorate 36(tbufName) 11 RowMajor
|
||||||
|
MemberDecorate 36(tbufName) 11 NonWritable
|
||||||
MemberDecorate 36(tbufName) 11 Offset 272
|
MemberDecorate 36(tbufName) 11 Offset 272
|
||||||
MemberDecorate 36(tbufName) 11 MatrixStride 16
|
MemberDecorate 36(tbufName) 11 MatrixStride 16
|
||||||
Decorate 36(tbufName) BufferBlock
|
Decorate 36(tbufName) BufferBlock
|
||||||
|
|
|
||||||
|
|
@ -12,23 +12,23 @@ gl_FragCoord origin is upper left
|
||||||
0:17 add ( temp 4-component vector of float)
|
0:17 add ( temp 4-component vector of float)
|
||||||
0:17 'input' ( in 4-component vector of float)
|
0:17 'input' ( in 4-component vector of float)
|
||||||
0:17 v1: direct index for structure (layout( row_major std430 offset=16) buffer 4-component vector of float)
|
0:17 v1: direct index for structure (layout( row_major std430 offset=16) buffer 4-component vector of float)
|
||||||
0:17 'anon@0' (layout( set=3 binding=5 row_major std430) buffer block{layout( row_major std430 offset=16) buffer 4-component vector of float v1})
|
0:17 'anon@0' (layout( set=3 binding=5 row_major std430) readonly buffer block{layout( row_major std430 offset=16) buffer 4-component vector of float v1})
|
||||||
0:17 Constant:
|
0:17 Constant:
|
||||||
0:17 0 (const uint)
|
0:17 0 (const uint)
|
||||||
0:17 v5: direct index for structure (layout( row_major std430 offset=0) buffer 4-component vector of float)
|
0:17 v5: direct index for structure (layout( row_major std430 offset=0) buffer 4-component vector of float)
|
||||||
0:17 'anon@1' (layout( row_major std430 push_constant) buffer block{layout( row_major std430 offset=0) buffer 4-component vector of float v5})
|
0:17 'anon@1' (layout( row_major std430 push_constant) readonly buffer block{layout( row_major std430 offset=0) buffer 4-component vector of float v5})
|
||||||
0:17 Constant:
|
0:17 Constant:
|
||||||
0:17 0 (const uint)
|
0:17 0 (const uint)
|
||||||
0:17 v1PostLayout: direct index for structure (layout( row_major std430 offset=16) buffer 4-component vector of float)
|
0:17 v1PostLayout: direct index for structure (layout( row_major std430 offset=16) buffer 4-component vector of float)
|
||||||
0:17 'anon@2' (layout( set=4 binding=7 row_major std430) buffer block{layout( row_major std430 offset=16) buffer 4-component vector of float v1PostLayout})
|
0:17 'anon@2' (layout( set=4 binding=7 row_major std430) readonly buffer block{layout( row_major std430 offset=16) buffer 4-component vector of float v1PostLayout})
|
||||||
0:17 Constant:
|
0:17 Constant:
|
||||||
0:17 0 (const uint)
|
0:17 0 (const uint)
|
||||||
0:? Linker Objects
|
0:? Linker Objects
|
||||||
0:? 'anon@0' (layout( set=3 binding=5 row_major std430) buffer block{layout( row_major std430 offset=16) buffer 4-component vector of float v1})
|
0:? 'anon@0' (layout( set=3 binding=5 row_major std430) readonly buffer block{layout( row_major std430 offset=16) buffer 4-component vector of float v1})
|
||||||
0:? 'anon@1' (layout( row_major std430 push_constant) buffer block{layout( row_major std430 offset=0) buffer 4-component vector of float v5})
|
0:? 'anon@1' (layout( row_major std430 push_constant) readonly buffer block{layout( row_major std430 offset=0) buffer 4-component vector of float v5})
|
||||||
0:? 'specConst' ( specialization-constant const int)
|
0:? 'specConst' ( specialization-constant const int)
|
||||||
0:? 10 (const int)
|
0:? 10 (const int)
|
||||||
0:? 'anon@2' (layout( set=4 binding=7 row_major std430) buffer block{layout( row_major std430 offset=16) buffer 4-component vector of float v1PostLayout})
|
0:? 'anon@2' (layout( set=4 binding=7 row_major std430) readonly buffer block{layout( row_major std430 offset=16) buffer 4-component vector of float v1PostLayout})
|
||||||
|
|
||||||
|
|
||||||
Linked fragment stage:
|
Linked fragment stage:
|
||||||
|
|
@ -48,23 +48,23 @@ gl_FragCoord origin is upper left
|
||||||
0:17 add ( temp 4-component vector of float)
|
0:17 add ( temp 4-component vector of float)
|
||||||
0:17 'input' ( in 4-component vector of float)
|
0:17 'input' ( in 4-component vector of float)
|
||||||
0:17 v1: direct index for structure (layout( row_major std430 offset=16) buffer 4-component vector of float)
|
0:17 v1: direct index for structure (layout( row_major std430 offset=16) buffer 4-component vector of float)
|
||||||
0:17 'anon@0' (layout( set=3 binding=5 row_major std430) buffer block{layout( row_major std430 offset=16) buffer 4-component vector of float v1})
|
0:17 'anon@0' (layout( set=3 binding=5 row_major std430) readonly buffer block{layout( row_major std430 offset=16) buffer 4-component vector of float v1})
|
||||||
0:17 Constant:
|
0:17 Constant:
|
||||||
0:17 0 (const uint)
|
0:17 0 (const uint)
|
||||||
0:17 v5: direct index for structure (layout( row_major std430 offset=0) buffer 4-component vector of float)
|
0:17 v5: direct index for structure (layout( row_major std430 offset=0) buffer 4-component vector of float)
|
||||||
0:17 'anon@1' (layout( row_major std430 push_constant) buffer block{layout( row_major std430 offset=0) buffer 4-component vector of float v5})
|
0:17 'anon@1' (layout( row_major std430 push_constant) readonly buffer block{layout( row_major std430 offset=0) buffer 4-component vector of float v5})
|
||||||
0:17 Constant:
|
0:17 Constant:
|
||||||
0:17 0 (const uint)
|
0:17 0 (const uint)
|
||||||
0:17 v1PostLayout: direct index for structure (layout( row_major std430 offset=16) buffer 4-component vector of float)
|
0:17 v1PostLayout: direct index for structure (layout( row_major std430 offset=16) buffer 4-component vector of float)
|
||||||
0:17 'anon@2' (layout( set=4 binding=7 row_major std430) buffer block{layout( row_major std430 offset=16) buffer 4-component vector of float v1PostLayout})
|
0:17 'anon@2' (layout( set=4 binding=7 row_major std430) readonly buffer block{layout( row_major std430 offset=16) buffer 4-component vector of float v1PostLayout})
|
||||||
0:17 Constant:
|
0:17 Constant:
|
||||||
0:17 0 (const uint)
|
0:17 0 (const uint)
|
||||||
0:? Linker Objects
|
0:? Linker Objects
|
||||||
0:? 'anon@0' (layout( set=3 binding=5 row_major std430) buffer block{layout( row_major std430 offset=16) buffer 4-component vector of float v1})
|
0:? 'anon@0' (layout( set=3 binding=5 row_major std430) readonly buffer block{layout( row_major std430 offset=16) buffer 4-component vector of float v1})
|
||||||
0:? 'anon@1' (layout( row_major std430 push_constant) buffer block{layout( row_major std430 offset=0) buffer 4-component vector of float v5})
|
0:? 'anon@1' (layout( row_major std430 push_constant) readonly buffer block{layout( row_major std430 offset=0) buffer 4-component vector of float v5})
|
||||||
0:? 'specConst' ( specialization-constant const int)
|
0:? 'specConst' ( specialization-constant const int)
|
||||||
0:? 10 (const int)
|
0:? 10 (const int)
|
||||||
0:? 'anon@2' (layout( set=4 binding=7 row_major std430) buffer block{layout( row_major std430 offset=16) buffer 4-component vector of float v1PostLayout})
|
0:? 'anon@2' (layout( set=4 binding=7 row_major std430) readonly buffer block{layout( row_major std430 offset=16) buffer 4-component vector of float v1PostLayout})
|
||||||
|
|
||||||
// Module Version 10000
|
// Module Version 10000
|
||||||
// Generated by (magic number): 80001
|
// Generated by (magic number): 80001
|
||||||
|
|
@ -89,12 +89,15 @@ gl_FragCoord origin is upper left
|
||||||
MemberName 30(tbufName2) 0 "v1PostLayout"
|
MemberName 30(tbufName2) 0 "v1PostLayout"
|
||||||
Name 32 ""
|
Name 32 ""
|
||||||
Name 38 "specConst"
|
Name 38 "specConst"
|
||||||
|
MemberDecorate 14(tbufName) 0 NonWritable
|
||||||
MemberDecorate 14(tbufName) 0 Offset 16
|
MemberDecorate 14(tbufName) 0 Offset 16
|
||||||
Decorate 14(tbufName) BufferBlock
|
Decorate 14(tbufName) BufferBlock
|
||||||
Decorate 16 DescriptorSet 3
|
Decorate 16 DescriptorSet 3
|
||||||
Decorate 16 Binding 5
|
Decorate 16 Binding 5
|
||||||
|
MemberDecorate 23(tbufName2) 0 NonWritable
|
||||||
MemberDecorate 23(tbufName2) 0 Offset 0
|
MemberDecorate 23(tbufName2) 0 Offset 0
|
||||||
Decorate 23(tbufName2) BufferBlock
|
Decorate 23(tbufName2) BufferBlock
|
||||||
|
MemberDecorate 30(tbufName2) 0 NonWritable
|
||||||
MemberDecorate 30(tbufName2) 0 Offset 16
|
MemberDecorate 30(tbufName2) 0 Offset 16
|
||||||
Decorate 30(tbufName2) BufferBlock
|
Decorate 30(tbufName2) BufferBlock
|
||||||
Decorate 32 DescriptorSet 4
|
Decorate 32 DescriptorSet 4
|
||||||
|
|
|
||||||
57
Test/hlsl.automap.frag
Normal file
57
Test/hlsl.automap.frag
Normal file
|
|
@ -0,0 +1,57 @@
|
||||||
|
// Test register class offsets for different resource types
|
||||||
|
|
||||||
|
SamplerState s1 : register(s1);
|
||||||
|
SamplerComparisonState s2 : register(s2);
|
||||||
|
|
||||||
|
Texture1D <float4> t1 : register(t1);
|
||||||
|
Texture2D <float4> t2 : register(t2);
|
||||||
|
Texture3D <float4> t3 : register(t3);
|
||||||
|
StructuredBuffer<float4> t4 : register(t4);
|
||||||
|
ByteAddressBuffer t5 : register(t5);
|
||||||
|
Buffer<float4> t6 : register(t6);
|
||||||
|
|
||||||
|
RWTexture1D <float4> u1 : register(u1);
|
||||||
|
RWTexture2D <float4> u2 : register(u2);
|
||||||
|
RWTexture3D <float4> u3 : register(u3);
|
||||||
|
|
||||||
|
RWBuffer <float> u4 : register(u4);
|
||||||
|
RWByteAddressBuffer u5 : register(u5);
|
||||||
|
RWStructuredBuffer<float> u6 : register(u6);
|
||||||
|
AppendStructuredBuffer<float> u7 : register(u7);
|
||||||
|
ConsumeStructuredBuffer<float> u8 : register(u8);
|
||||||
|
|
||||||
|
cbuffer cb : register(b1) {
|
||||||
|
int cb1;
|
||||||
|
};
|
||||||
|
|
||||||
|
tbuffer tb : register(t7) {
|
||||||
|
int tb1;
|
||||||
|
};
|
||||||
|
|
||||||
|
float4 main() : SV_Target0
|
||||||
|
{
|
||||||
|
t1;
|
||||||
|
t2;
|
||||||
|
t3;
|
||||||
|
t4[0];
|
||||||
|
t5.Load(0);
|
||||||
|
t6;
|
||||||
|
|
||||||
|
s1;
|
||||||
|
s2;
|
||||||
|
|
||||||
|
u1;
|
||||||
|
u2;
|
||||||
|
u3;
|
||||||
|
|
||||||
|
u4[0];
|
||||||
|
u5.Load(0);
|
||||||
|
u6[0];
|
||||||
|
u7;
|
||||||
|
u8;
|
||||||
|
|
||||||
|
cb1;
|
||||||
|
tb1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
@ -35,7 +35,8 @@ $EXE -D -e flizv -l -q -C -V hlsl.reflection.vert > $TARGETDIR/hlsl.reflection.v
|
||||||
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 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
|
||||||
|
diff -b $BASEDIR/hlsl.automap.frag.out $TARGETDIR/hlsl.automap.frag.out || HASERROR=1
|
||||||
|
|
||||||
#
|
#
|
||||||
# multi-threaded test
|
# multi-threaded test
|
||||||
|
|
|
||||||
|
|
@ -1555,12 +1555,24 @@ void TShader::setSourceEntryPoint(const char* name)
|
||||||
sourceEntryPointName = name;
|
sourceEntryPointName = name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Set binding base for sampler types
|
||||||
void TShader::setShiftSamplerBinding(unsigned int base) { intermediate->setShiftSamplerBinding(base); }
|
void TShader::setShiftSamplerBinding(unsigned int base) { intermediate->setShiftSamplerBinding(base); }
|
||||||
|
// Set binding base for texture types (SRV)
|
||||||
void TShader::setShiftTextureBinding(unsigned int base) { intermediate->setShiftTextureBinding(base); }
|
void TShader::setShiftTextureBinding(unsigned int base) { intermediate->setShiftTextureBinding(base); }
|
||||||
|
// Set binding base for image types
|
||||||
void TShader::setShiftImageBinding(unsigned int base) { intermediate->setShiftImageBinding(base); }
|
void TShader::setShiftImageBinding(unsigned int base) { intermediate->setShiftImageBinding(base); }
|
||||||
|
// Set binding base for uniform buffer objects (CBV)
|
||||||
void TShader::setShiftUboBinding(unsigned int base) { intermediate->setShiftUboBinding(base); }
|
void TShader::setShiftUboBinding(unsigned int base) { intermediate->setShiftUboBinding(base); }
|
||||||
|
// Synonym for setShiftUboBinding, to match HLSL language.
|
||||||
|
void TShader::setShiftCbufferBinding(unsigned int base) { intermediate->setShiftUboBinding(base); }
|
||||||
|
// Set binding base for UAV (unordered access view)
|
||||||
|
void TShader::setShiftUavBinding(unsigned int base) { intermediate->setShiftUavBinding(base); }
|
||||||
|
// Set binding base for SSBOs
|
||||||
void TShader::setShiftSsboBinding(unsigned int base) { intermediate->setShiftSsboBinding(base); }
|
void TShader::setShiftSsboBinding(unsigned int base) { intermediate->setShiftSsboBinding(base); }
|
||||||
|
// Enables binding automapping using TIoMapper
|
||||||
void TShader::setAutoMapBindings(bool map) { intermediate->setAutoMapBindings(map); }
|
void TShader::setAutoMapBindings(bool map) { intermediate->setAutoMapBindings(map); }
|
||||||
|
// See comment above TDefaultHlslIoMapper in iomapper.cpp:
|
||||||
|
void TShader::setHlslIoMapping(bool hlslIoMap) { intermediate->setHlslIoMapping(hlslIoMap); }
|
||||||
void TShader::setFlattenUniformArrays(bool flatten) { intermediate->setFlattenUniformArrays(flatten); }
|
void TShader::setFlattenUniformArrays(bool flatten) { intermediate->setFlattenUniformArrays(flatten); }
|
||||||
void TShader::setNoStorageFormat(bool useUnknownFormat) { intermediate->setNoStorageFormat(useUnknownFormat); }
|
void TShader::setNoStorageFormat(bool useUnknownFormat) { intermediate->setNoStorageFormat(useUnknownFormat); }
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
//
|
//
|
||||||
// Copyright (C) 2016 LunarG, Inc.
|
// Copyright (C) 2016-2017 LunarG, Inc.
|
||||||
//
|
//
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
|
|
@ -310,20 +310,15 @@ private:
|
||||||
TResolverInOutAdaptor& operator=(TResolverInOutAdaptor&);
|
TResolverInOutAdaptor& operator=(TResolverInOutAdaptor&);
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
// Base class for shared TIoMapResolver services, used by several derivations.
|
||||||
* Basic implementation of glslang::TIoMapResolver that replaces the
|
struct TDefaultIoResolverBase : public glslang::TIoMapResolver
|
||||||
* previous offset behavior.
|
|
||||||
* It does the same, uses the offsets for the corresponding uniform
|
|
||||||
* types. Also respects the EOptionAutoMapBindings flag and binds
|
|
||||||
* them if needed.
|
|
||||||
*/
|
|
||||||
struct TDefaultIoResolver : public glslang::TIoMapResolver
|
|
||||||
{
|
{
|
||||||
int baseSamplerBinding;
|
int baseSamplerBinding;
|
||||||
int baseTextureBinding;
|
int baseTextureBinding;
|
||||||
int baseImageBinding;
|
int baseImageBinding;
|
||||||
int baseUboBinding;
|
int baseUboBinding;
|
||||||
int baseSsboBinding;
|
int baseSsboBinding;
|
||||||
|
int baseUavBinding;
|
||||||
bool doAutoMapping;
|
bool doAutoMapping;
|
||||||
typedef std::vector<int> TSlotSet;
|
typedef std::vector<int> TSlotSet;
|
||||||
typedef std::unordered_map<int, TSlotSet> TSlotSetMap;
|
typedef std::unordered_map<int, TSlotSet> TSlotSetMap;
|
||||||
|
|
@ -360,83 +355,9 @@ struct TDefaultIoResolver : public glslang::TIoMapResolver
|
||||||
return reserveSlot(set, base);
|
return reserveSlot(set, base);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool validateBinding(EShLanguage /*stage*/, const char* /*name*/, const glslang::TType& type, bool /*is_live*/) override
|
virtual bool validateBinding(EShLanguage /*stage*/, const char* /*name*/, const glslang::TType& type, bool /*is_live*/) override = 0;
|
||||||
{
|
|
||||||
if (type.getQualifier().hasBinding()) {
|
|
||||||
int set;
|
|
||||||
if (type.getQualifier().hasSet())
|
|
||||||
set = type.getQualifier().layoutSet;
|
|
||||||
else
|
|
||||||
set = 0;
|
|
||||||
|
|
||||||
if (type.getBasicType() == glslang::EbtSampler) {
|
virtual int resolveBinding(EShLanguage /*stage*/, const char* /*name*/, const glslang::TType& type, bool is_live) override = 0;
|
||||||
const glslang::TSampler& sampler = type.getSampler();
|
|
||||||
if (sampler.isPureSampler())
|
|
||||||
return checkEmpty(set, baseSamplerBinding + type.getQualifier().layoutBinding);
|
|
||||||
|
|
||||||
if (sampler.isTexture())
|
|
||||||
return checkEmpty(set, baseTextureBinding + type.getQualifier().layoutBinding);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (type.getQualifier().storage == EvqUniform)
|
|
||||||
return checkEmpty(set, baseUboBinding + type.getQualifier().layoutBinding);
|
|
||||||
|
|
||||||
if (type.getQualifier().storage == EvqBuffer)
|
|
||||||
return checkEmpty(set, baseSsboBinding + type.getQualifier().layoutBinding);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
int resolveBinding(EShLanguage /*stage*/, const char* /*name*/, const glslang::TType& type, bool is_live) override
|
|
||||||
{
|
|
||||||
int set;
|
|
||||||
if (type.getQualifier().hasSet())
|
|
||||||
set = type.getQualifier().layoutSet;
|
|
||||||
else
|
|
||||||
set = 0;
|
|
||||||
|
|
||||||
if (type.getQualifier().hasBinding()) {
|
|
||||||
if (type.getBasicType() == glslang::EbtSampler) {
|
|
||||||
const glslang::TSampler& sampler = type.getSampler();
|
|
||||||
if (sampler.isImage())
|
|
||||||
return reserveSlot(set, baseImageBinding + type.getQualifier().layoutBinding);
|
|
||||||
|
|
||||||
if (sampler.isPureSampler())
|
|
||||||
return reserveSlot(set, baseSamplerBinding + type.getQualifier().layoutBinding);
|
|
||||||
|
|
||||||
if (sampler.isTexture())
|
|
||||||
return reserveSlot(set, baseTextureBinding + type.getQualifier().layoutBinding);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (type.getQualifier().storage == EvqUniform)
|
|
||||||
return reserveSlot(set, baseUboBinding + type.getQualifier().layoutBinding);
|
|
||||||
|
|
||||||
if (type.getQualifier().storage == EvqBuffer)
|
|
||||||
return reserveSlot(set, baseSsboBinding + type.getQualifier().layoutBinding);
|
|
||||||
} else if (is_live && doAutoMapping) {
|
|
||||||
// find free slot, the caller did make sure it passes all vars with binding
|
|
||||||
// first and now all are passed that do not have a binding and needs one
|
|
||||||
if (type.getBasicType() == glslang::EbtSampler) {
|
|
||||||
const glslang::TSampler& sampler = type.getSampler();
|
|
||||||
if (sampler.isImage())
|
|
||||||
return getFreeSlot(set, baseImageBinding);
|
|
||||||
|
|
||||||
if (sampler.isPureSampler())
|
|
||||||
return getFreeSlot(set, baseSamplerBinding);
|
|
||||||
|
|
||||||
if (sampler.isTexture())
|
|
||||||
return getFreeSlot(set, baseTextureBinding);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (type.getQualifier().storage == EvqUniform)
|
|
||||||
return getFreeSlot(set, baseUboBinding);
|
|
||||||
|
|
||||||
if (type.getQualifier().storage == EvqBuffer)
|
|
||||||
return getFreeSlot(set, baseSsboBinding);
|
|
||||||
}
|
|
||||||
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int resolveSet(EShLanguage /*stage*/, const char* /*name*/, const glslang::TType& type, bool /*is_live*/) override
|
int resolveSet(EShLanguage /*stage*/, const char* /*name*/, const glslang::TType& type, bool /*is_live*/) override
|
||||||
{
|
{
|
||||||
|
|
@ -461,8 +382,232 @@ struct TDefaultIoResolver : public glslang::TIoMapResolver
|
||||||
{
|
{
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
static int getLayoutSet(const glslang::TType& type) {
|
||||||
|
if (type.getQualifier().hasSet())
|
||||||
|
return type.getQualifier().layoutSet;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool isSamplerType(const glslang::TType& type) {
|
||||||
|
return type.getBasicType() == glslang::EbtSampler && type.getSampler().isPureSampler();
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool isTextureType(const glslang::TType& type) {
|
||||||
|
return type.getBasicType() == glslang::EbtSampler && type.getSampler().isTexture();
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool isUboType(const glslang::TType& type) {
|
||||||
|
return type.getQualifier().storage == EvqUniform;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Basic implementation of glslang::TIoMapResolver that replaces the
|
||||||
|
* previous offset behavior.
|
||||||
|
* It does the same, uses the offsets for the corresponding uniform
|
||||||
|
* types. Also respects the EOptionAutoMapBindings flag and binds
|
||||||
|
* them if needed.
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
* Default resolver
|
||||||
|
*/
|
||||||
|
struct TDefaultIoResolver : public TDefaultIoResolverBase
|
||||||
|
{
|
||||||
|
bool validateBinding(EShLanguage /*stage*/, const char* /*name*/, const glslang::TType& type, bool /*is_live*/) override
|
||||||
|
{
|
||||||
|
if (type.getQualifier().hasBinding()) {
|
||||||
|
const int set = getLayoutSet(type);
|
||||||
|
|
||||||
|
if (isImageType(type))
|
||||||
|
return checkEmpty(set, baseImageBinding + type.getQualifier().layoutBinding);
|
||||||
|
|
||||||
|
if (isTextureType(type))
|
||||||
|
return checkEmpty(set, baseTextureBinding + type.getQualifier().layoutBinding);
|
||||||
|
|
||||||
|
if (isSsboType(type))
|
||||||
|
return checkEmpty(set, baseSsboBinding + type.getQualifier().layoutBinding);
|
||||||
|
|
||||||
|
if (isSamplerType(type))
|
||||||
|
return checkEmpty(set, baseSamplerBinding + type.getQualifier().layoutBinding);
|
||||||
|
|
||||||
|
if (isUboType(type))
|
||||||
|
return checkEmpty(set, baseUboBinding + type.getQualifier().layoutBinding);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
int resolveBinding(EShLanguage /*stage*/, const char* /*name*/, const glslang::TType& type, bool is_live) override
|
||||||
|
{
|
||||||
|
const int set = getLayoutSet(type);
|
||||||
|
|
||||||
|
if (type.getQualifier().hasBinding()) {
|
||||||
|
if (isImageType(type))
|
||||||
|
return reserveSlot(set, baseImageBinding + type.getQualifier().layoutBinding);
|
||||||
|
|
||||||
|
if (isTextureType(type))
|
||||||
|
return reserveSlot(set, baseTextureBinding + type.getQualifier().layoutBinding);
|
||||||
|
|
||||||
|
if (isSsboType(type))
|
||||||
|
return reserveSlot(set, baseSsboBinding + type.getQualifier().layoutBinding);
|
||||||
|
|
||||||
|
if (isSamplerType(type))
|
||||||
|
return reserveSlot(set, baseSamplerBinding + type.getQualifier().layoutBinding);
|
||||||
|
|
||||||
|
if (isUboType(type))
|
||||||
|
return reserveSlot(set, baseUboBinding + type.getQualifier().layoutBinding);
|
||||||
|
} else if (is_live && doAutoMapping) {
|
||||||
|
// find free slot, the caller did make sure it passes all vars with binding
|
||||||
|
// first and now all are passed that do not have a binding and needs one
|
||||||
|
|
||||||
|
if (isImageType(type))
|
||||||
|
return getFreeSlot(set, baseImageBinding);
|
||||||
|
|
||||||
|
if (isTextureType(type))
|
||||||
|
return getFreeSlot(set, baseTextureBinding);
|
||||||
|
|
||||||
|
if (isSsboType(type))
|
||||||
|
return getFreeSlot(set, baseSsboBinding);
|
||||||
|
|
||||||
|
if (isSamplerType(type))
|
||||||
|
return getFreeSlot(set, baseSamplerBinding);
|
||||||
|
|
||||||
|
if (isUboType(type))
|
||||||
|
return getFreeSlot(set, baseUboBinding);
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
static bool isImageType(const glslang::TType& type) {
|
||||||
|
return type.getBasicType() == glslang::EbtSampler && type.getSampler().isImage();
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool isSsboType(const glslang::TType& type) {
|
||||||
|
return type.getQualifier().storage == EvqBuffer;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/********************************************************************************
|
||||||
|
The following IO resolver maps types in HLSL register space, as follows:
|
||||||
|
|
||||||
|
t – for shader resource views (SRV)
|
||||||
|
TEXTURE1D
|
||||||
|
TEXTURE1DARRAY
|
||||||
|
TEXTURE2D
|
||||||
|
TEXTURE2DARRAY
|
||||||
|
TEXTURE3D
|
||||||
|
TEXTURECUBE
|
||||||
|
TEXTURECUBEARRAY
|
||||||
|
TEXTURE2DMS
|
||||||
|
TEXTURE2DMSARRAY
|
||||||
|
STRUCTUREDBUFFER
|
||||||
|
BYTEADDRESSBUFFER
|
||||||
|
BUFFER
|
||||||
|
TBUFFER
|
||||||
|
|
||||||
|
s – for samplers
|
||||||
|
SAMPLER
|
||||||
|
SAMPLER1D
|
||||||
|
SAMPLER2D
|
||||||
|
SAMPLER3D
|
||||||
|
SAMPLERCUBE
|
||||||
|
SAMPLERSTATE
|
||||||
|
SAMPLERCOMPARISONSTATE
|
||||||
|
|
||||||
|
u – for unordered access views (UAV)
|
||||||
|
RWBYTEADDRESSBUFFER
|
||||||
|
RWSTRUCTUREDBUFFER
|
||||||
|
APPENDSTRUCTUREDBUFFER
|
||||||
|
CONSUMESTRUCTUREDBUFFER
|
||||||
|
RWBUFFER
|
||||||
|
RWTEXTURE1D
|
||||||
|
RWTEXTURE1DARRAY
|
||||||
|
RWTEXTURE2D
|
||||||
|
RWTEXTURE2DARRAY
|
||||||
|
RWTEXTURE3D
|
||||||
|
|
||||||
|
b – for constant buffer views (CBV)
|
||||||
|
CBUFFER
|
||||||
|
********************************************************************************/
|
||||||
|
struct TDefaultHlslIoResolver : public TDefaultIoResolverBase
|
||||||
|
{
|
||||||
|
bool validateBinding(EShLanguage /*stage*/, const char* /*name*/, const glslang::TType& type, bool /*is_live*/) override
|
||||||
|
{
|
||||||
|
if (type.getQualifier().hasBinding()) {
|
||||||
|
const int set = getLayoutSet(type);
|
||||||
|
|
||||||
|
if (isUavType(type))
|
||||||
|
return checkEmpty(set, baseUavBinding + type.getQualifier().layoutBinding);
|
||||||
|
|
||||||
|
if (isSrvType(type))
|
||||||
|
return checkEmpty(set, baseTextureBinding + type.getQualifier().layoutBinding);
|
||||||
|
|
||||||
|
if (isSamplerType(type))
|
||||||
|
return checkEmpty(set, baseSamplerBinding + type.getQualifier().layoutBinding);
|
||||||
|
|
||||||
|
if (isUboType(type))
|
||||||
|
return checkEmpty(set, baseUboBinding + type.getQualifier().layoutBinding);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
int resolveBinding(EShLanguage /*stage*/, const char* /*name*/, const glslang::TType& type, bool is_live) override
|
||||||
|
{
|
||||||
|
const int set = getLayoutSet(type);
|
||||||
|
|
||||||
|
if (type.getQualifier().hasBinding()) {
|
||||||
|
if (isUavType(type))
|
||||||
|
return reserveSlot(set, baseUavBinding + type.getQualifier().layoutBinding);
|
||||||
|
|
||||||
|
if (isSrvType(type))
|
||||||
|
return reserveSlot(set, baseTextureBinding + type.getQualifier().layoutBinding);
|
||||||
|
|
||||||
|
if (isSamplerType(type))
|
||||||
|
return reserveSlot(set, baseSamplerBinding + type.getQualifier().layoutBinding);
|
||||||
|
|
||||||
|
if (isUboType(type))
|
||||||
|
return reserveSlot(set, baseUboBinding + type.getQualifier().layoutBinding);
|
||||||
|
} else if (is_live && doAutoMapping) {
|
||||||
|
// find free slot, the caller did make sure it passes all vars with binding
|
||||||
|
// first and now all are passed that do not have a binding and needs one
|
||||||
|
|
||||||
|
if (isUavType(type))
|
||||||
|
return getFreeSlot(set, baseUavBinding);
|
||||||
|
|
||||||
|
if (isSrvType(type))
|
||||||
|
return getFreeSlot(set, baseTextureBinding);
|
||||||
|
|
||||||
|
if (isSamplerType(type))
|
||||||
|
return getFreeSlot(set, baseSamplerBinding);
|
||||||
|
|
||||||
|
if (isUboType(type))
|
||||||
|
return getFreeSlot(set, baseUboBinding);
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
// Return true if this is a SRV (shader resource view) type:
|
||||||
|
static bool isSrvType(const glslang::TType& type) {
|
||||||
|
return isTextureType(type) || type.getQualifier().storage == EvqBuffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return true if this is a UAV (unordered access view) type:
|
||||||
|
static bool isUavType(const glslang::TType& type) {
|
||||||
|
if (type.getQualifier().readonly)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return (type.getBasicType() == glslang::EbtSampler && type.getSampler().isImage()) ||
|
||||||
|
(type.getQualifier().storage == EvqBuffer);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
// Map I/O variables to provided offsets, and make bindings for
|
// Map I/O variables to provided offsets, and make bindings for
|
||||||
// unbound but live variables.
|
// unbound but live variables.
|
||||||
//
|
//
|
||||||
|
|
@ -475,6 +620,7 @@ bool TIoMapper::addStage(EShLanguage stage, TIntermediate &intermediate, TInfoSi
|
||||||
intermediate.getShiftImageBinding() == 0 &&
|
intermediate.getShiftImageBinding() == 0 &&
|
||||||
intermediate.getShiftUboBinding() == 0 &&
|
intermediate.getShiftUboBinding() == 0 &&
|
||||||
intermediate.getShiftSsboBinding() == 0 &&
|
intermediate.getShiftSsboBinding() == 0 &&
|
||||||
|
intermediate.getShiftUavBinding() == 0 &&
|
||||||
intermediate.getAutoMapBindings() == false &&
|
intermediate.getAutoMapBindings() == false &&
|
||||||
resolver == nullptr)
|
resolver == nullptr)
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -488,15 +634,26 @@ bool TIoMapper::addStage(EShLanguage stage, TIntermediate &intermediate, TInfoSi
|
||||||
|
|
||||||
// if no resolver is provided, use the default resolver with the given shifts and auto map settings
|
// if no resolver is provided, use the default resolver with the given shifts and auto map settings
|
||||||
TDefaultIoResolver defaultResolver;
|
TDefaultIoResolver defaultResolver;
|
||||||
if (resolver == nullptr) {
|
TDefaultHlslIoResolver defaultHlslResolver;
|
||||||
defaultResolver.baseSamplerBinding = intermediate.getShiftSamplerBinding();
|
|
||||||
defaultResolver.baseTextureBinding = intermediate.getShiftTextureBinding();
|
|
||||||
defaultResolver.baseImageBinding = intermediate.getShiftImageBinding();
|
|
||||||
defaultResolver.baseUboBinding = intermediate.getShiftUboBinding();
|
|
||||||
defaultResolver.baseSsboBinding = intermediate.getShiftSsboBinding();
|
|
||||||
defaultResolver.doAutoMapping = intermediate.getAutoMapBindings();
|
|
||||||
|
|
||||||
resolver = &defaultResolver;
|
if (resolver == nullptr) {
|
||||||
|
TDefaultIoResolverBase* resolverBase;
|
||||||
|
|
||||||
|
// TODO: use a passed in IO mapper for this
|
||||||
|
if (intermediate.usingHlslIoMapping())
|
||||||
|
resolverBase = &defaultHlslResolver;
|
||||||
|
else
|
||||||
|
resolverBase = &defaultResolver;
|
||||||
|
|
||||||
|
resolverBase->baseSamplerBinding = intermediate.getShiftSamplerBinding();
|
||||||
|
resolverBase->baseTextureBinding = intermediate.getShiftTextureBinding();
|
||||||
|
resolverBase->baseImageBinding = intermediate.getShiftImageBinding();
|
||||||
|
resolverBase->baseUboBinding = intermediate.getShiftUboBinding();
|
||||||
|
resolverBase->baseSsboBinding = intermediate.getShiftSsboBinding();
|
||||||
|
resolverBase->baseUavBinding = intermediate.getShiftUavBinding();
|
||||||
|
resolverBase->doAutoMapping = intermediate.getAutoMapBindings();
|
||||||
|
|
||||||
|
resolver = resolverBase;
|
||||||
}
|
}
|
||||||
|
|
||||||
TVarLiveMap inVarMap, outVarMap, uniformVarMap;
|
TVarLiveMap inVarMap, outVarMap, uniformVarMap;
|
||||||
|
|
|
||||||
|
|
@ -175,11 +175,13 @@ public:
|
||||||
shiftImageBinding(0),
|
shiftImageBinding(0),
|
||||||
shiftUboBinding(0),
|
shiftUboBinding(0),
|
||||||
shiftSsboBinding(0),
|
shiftSsboBinding(0),
|
||||||
|
shiftUavBinding(0),
|
||||||
autoMapBindings(false),
|
autoMapBindings(false),
|
||||||
flattenUniformArrays(false),
|
flattenUniformArrays(false),
|
||||||
useUnknownFormat(false),
|
useUnknownFormat(false),
|
||||||
hlslOffsets(false),
|
hlslOffsets(false),
|
||||||
useStorageBuffer(false)
|
useStorageBuffer(false),
|
||||||
|
hlslIoMapping(false)
|
||||||
{
|
{
|
||||||
localSize[0] = 1;
|
localSize[0] = 1;
|
||||||
localSize[1] = 1;
|
localSize[1] = 1;
|
||||||
|
|
@ -212,6 +214,8 @@ public:
|
||||||
unsigned int getShiftUboBinding() const { return shiftUboBinding; }
|
unsigned int getShiftUboBinding() const { return shiftUboBinding; }
|
||||||
void setShiftSsboBinding(unsigned int shift) { shiftSsboBinding = shift; }
|
void setShiftSsboBinding(unsigned int shift) { shiftSsboBinding = shift; }
|
||||||
unsigned int getShiftSsboBinding() const { return shiftSsboBinding; }
|
unsigned int getShiftSsboBinding() const { return shiftSsboBinding; }
|
||||||
|
void setShiftUavBinding(unsigned int shift) { shiftUavBinding = shift; }
|
||||||
|
unsigned int getShiftUavBinding() const { return shiftUavBinding; }
|
||||||
void setAutoMapBindings(bool map) { autoMapBindings = map; }
|
void setAutoMapBindings(bool map) { autoMapBindings = map; }
|
||||||
bool getAutoMapBindings() const { return autoMapBindings; }
|
bool getAutoMapBindings() const { return autoMapBindings; }
|
||||||
void setFlattenUniformArrays(bool flatten) { flattenUniformArrays = flatten; }
|
void setFlattenUniformArrays(bool flatten) { flattenUniformArrays = flatten; }
|
||||||
|
|
@ -222,6 +226,8 @@ public:
|
||||||
bool usingHlslOFfsets() const { return hlslOffsets; }
|
bool usingHlslOFfsets() const { return hlslOffsets; }
|
||||||
void setUseStorageBuffer() { useStorageBuffer = true; }
|
void setUseStorageBuffer() { useStorageBuffer = true; }
|
||||||
bool usingStorageBuffer() const { return useStorageBuffer; }
|
bool usingStorageBuffer() const { return useStorageBuffer; }
|
||||||
|
void setHlslIoMapping(bool b) { hlslIoMapping = b; }
|
||||||
|
bool usingHlslIoMapping() { return hlslIoMapping; }
|
||||||
|
|
||||||
void setVersion(int v) { version = v; }
|
void setVersion(int v) { version = v; }
|
||||||
int getVersion() const { return version; }
|
int getVersion() const { return version; }
|
||||||
|
|
@ -505,11 +511,13 @@ protected:
|
||||||
unsigned int shiftImageBinding;
|
unsigned int shiftImageBinding;
|
||||||
unsigned int shiftUboBinding;
|
unsigned int shiftUboBinding;
|
||||||
unsigned int shiftSsboBinding;
|
unsigned int shiftSsboBinding;
|
||||||
|
unsigned int shiftUavBinding;
|
||||||
bool autoMapBindings;
|
bool autoMapBindings;
|
||||||
bool flattenUniformArrays;
|
bool flattenUniformArrays;
|
||||||
bool useUnknownFormat;
|
bool useUnknownFormat;
|
||||||
bool hlslOffsets;
|
bool hlslOffsets;
|
||||||
bool useStorageBuffer;
|
bool useStorageBuffer;
|
||||||
|
bool hlslIoMapping;
|
||||||
|
|
||||||
typedef std::list<TCall> TGraph;
|
typedef std::list<TCall> TGraph;
|
||||||
TGraph callGraph;
|
TGraph callGraph;
|
||||||
|
|
|
||||||
|
|
@ -303,8 +303,11 @@ public:
|
||||||
void setShiftTextureBinding(unsigned int base);
|
void setShiftTextureBinding(unsigned int base);
|
||||||
void setShiftImageBinding(unsigned int base);
|
void setShiftImageBinding(unsigned int base);
|
||||||
void setShiftUboBinding(unsigned int base);
|
void setShiftUboBinding(unsigned int base);
|
||||||
|
void setShiftUavBinding(unsigned int base);
|
||||||
|
void setShiftCbufferBinding(unsigned int base); // synonym for setShiftUboBinding
|
||||||
void setShiftSsboBinding(unsigned int base);
|
void setShiftSsboBinding(unsigned int base);
|
||||||
void setAutoMapBindings(bool map);
|
void setAutoMapBindings(bool map);
|
||||||
|
void setHlslIoMapping(bool hlslIoMap);
|
||||||
void setFlattenUniformArrays(bool flatten);
|
void setFlattenUniformArrays(bool flatten);
|
||||||
void setNoStorageFormat(bool useUnknownFormat);
|
void setNoStorageFormat(bool useUnknownFormat);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1846,13 +1846,16 @@ bool HlslGrammar::acceptStruct(TType& type, TIntermNode*& nodeList)
|
||||||
// This storage qualifier will tell us whether it's an AST
|
// This storage qualifier will tell us whether it's an AST
|
||||||
// block type or just a generic structure type.
|
// block type or just a generic structure type.
|
||||||
TStorageQualifier storageQualifier = EvqTemporary;
|
TStorageQualifier storageQualifier = EvqTemporary;
|
||||||
|
bool readonly = false;
|
||||||
|
|
||||||
// CBUFFER
|
// CBUFFER
|
||||||
if (acceptTokenClass(EHTokCBuffer))
|
if (acceptTokenClass(EHTokCBuffer)) {
|
||||||
storageQualifier = EvqUniform;
|
storageQualifier = EvqUniform;
|
||||||
// TBUFFER
|
// TBUFFER
|
||||||
else if (acceptTokenClass(EHTokTBuffer))
|
} else if (acceptTokenClass(EHTokTBuffer)) {
|
||||||
storageQualifier = EvqBuffer;
|
storageQualifier = EvqBuffer;
|
||||||
|
readonly = true;
|
||||||
|
}
|
||||||
// CLASS
|
// CLASS
|
||||||
// STRUCT
|
// STRUCT
|
||||||
else if (! acceptTokenClass(EHTokClass) && ! acceptTokenClass(EHTokStruct))
|
else if (! acceptTokenClass(EHTokClass) && ! acceptTokenClass(EHTokStruct))
|
||||||
|
|
@ -1908,6 +1911,7 @@ bool HlslGrammar::acceptStruct(TType& type, TIntermNode*& nodeList)
|
||||||
new(&type) TType(typeList, structName);
|
new(&type) TType(typeList, structName);
|
||||||
else {
|
else {
|
||||||
postDeclQualifier.storage = storageQualifier;
|
postDeclQualifier.storage = storageQualifier;
|
||||||
|
postDeclQualifier.readonly = readonly;
|
||||||
new(&type) TType(typeList, structName, postDeclQualifier); // sets EbtBlock
|
new(&type) TType(typeList, structName, postDeclQualifier); // sets EbtBlock
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue