Add Shared/Std140 SSBO process & top-level array elements related (#2231)

* Add Shared/Std140 SSBO process & top-level array elements related
process

1.Add process options for shared/std140 ssbo, following ubo process
2.Add IO Variables reflection option, would keep all input/output
variables in reflection
3.Add Top-level related process, fix top-level array size issues,
following spec
4.Split ssbo/ubo reflection options, merge blowup expanding all into
function blowupActiveAggregate to allow other functions keep same entry
format.

Add options in StandAlone and test symbols.

1. Add options in StandAlone for std140/shared ubo/ssbo and all io variables reflection.
2. Add test for ssbo. When EShReflectionSharedStd140SSBO turns on, generated symbol and output would be different, to remind the difference. Defaultly disabled and nothing would change, nor blocking normal test.

* Add options in runtest script, refresh test results.

Add options in StandAlone:
--reflect-all-io-variables --reflect-shared-std140-ubo --reflect-shared-std140-ssbo

refresh test results.
Now the index, size of unsized array are expected.
This commit is contained in:
Chow 2020-06-04 15:47:18 +08:00 committed by GitHub
parent ff6dcca575
commit 8111268575
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 222 additions and 161 deletions

View File

@ -555,6 +555,12 @@ void ProcessArguments(std::vector<std::unique_ptr<glslang::TWorkItem>>& workItem
ReflectOptions |= EShReflectionAllBlockVariables;
} else if (lowerword == "reflect-unwrap-io-blocks") {
ReflectOptions |= EShReflectionUnwrapIOBlocks;
} else if (lowerword == "reflect-all-io-variables") {
ReflectOptions |= EShReflectionAllIOVariables;
} else if (lowerword == "reflect-shared-std140-ubo") {
ReflectOptions |= EShReflectionSharedStd140UBO;
} else if (lowerword == "reflect-shared-std140-ssbo") {
ReflectOptions |= EShReflectionSharedStd140SSBO;
} else if (lowerword == "resource-set-bindings" || // synonyms
lowerword == "resource-set-binding" ||
lowerword == "rsb") {

View File

@ -34,6 +34,21 @@ void atomicOpPass()
origu = atomicCompSwap(atomu, 10u, 8u);
}
layout(binding = 2,std430) buffer ssboElem01
{
int member01;
int memberArr01[2];
int memberUnsizedArr01[];
} ssboStd430Arr[2];
// if turns on EShReflectionSharedStd140SSBO, SPIR-V would be different
layout(binding = 3,shared) buffer ssboElem02
{
int member02;
int memberArr02[2];
int memberUnsizedArr02[];
} ssboSharedArr[2];
#extension GL_ARB_shader_storage_buffer_object : disable
layout(binding = 1,std430) buffer BufferFail // Error std430 and "buffer" block support disabled

View File

@ -4,8 +4,8 @@ ERROR: 0:11: 'layout qualifier' : can only apply depth layout to gl_FragDepth
ERROR: 0:12: 'gl_FragDepth' : cannot redeclare after use
ERROR: 0:14: 'atomic_uint' : array must be explicitly sized
ERROR: 0:17: 'imageSize' : required extension not requested: GL_ARB_shader_image_size
ERROR: 0:39: 'std430' : not supported for this version or the enabled extensions
ERROR: 0:39: '' : syntax error, unexpected IDENTIFIER, expecting LEFT_BRACE or COMMA or SEMICOLON
ERROR: 0:54: 'std430' : not supported for this version or the enabled extensions
ERROR: 0:54: '' : syntax error, unexpected IDENTIFIER, expecting LEFT_BRACE or COMMA or SEMICOLON
ERROR: 7 compilation errors. No code generated.
@ -82,6 +82,8 @@ ERROR: node is still EOpNull!
0:? 'iv2dim' ( global 2-component vector of int)
0:? 'iv2dim1' ( global 2-component vector of int)
0:? 'anon@0' (layout( binding=0 column_major std430) buffer block{layout( column_major std430 offset=0) buffer int atomi, layout( column_major std430 offset=4) buffer uint atomu})
0:? 'ssboStd430Arr' (layout( binding=2 column_major std430) buffer 2-element array of block{layout( column_major std430 offset=0) buffer int member01, layout( column_major std430 offset=4) buffer 2-element array of int memberArr01, layout( column_major std430 offset=12) buffer unsized 1-element array of int memberUnsizedArr01})
0:? 'ssboSharedArr' (layout( binding=3 column_major shared) buffer 2-element array of block{layout( column_major shared) buffer int member02, layout( column_major shared) buffer 2-element array of int memberArr02, layout( column_major shared) buffer unsized 1-element array of int memberUnsizedArr02})
Linked fragment stage:
@ -117,4 +119,6 @@ ERROR: node is still EOpNull!
0:? 'iv2dim' ( global 2-component vector of int)
0:? 'iv2dim1' ( global 2-component vector of int)
0:? 'anon@0' (layout( binding=0 column_major std430) buffer block{layout( column_major std430 offset=0) buffer int atomi, layout( column_major std430 offset=4) buffer uint atomu})
0:? 'ssboStd430Arr' (layout( binding=2 column_major std430) buffer 2-element array of block{layout( column_major std430 offset=0) buffer int member01, layout( column_major std430 offset=4) buffer 2-element array of int memberArr01, layout( column_major std430 offset=12) buffer unsized 1-element array of int memberUnsizedArr01})
0:? 'ssboSharedArr' (layout( binding=3 column_major shared) buffer 2-element array of block{layout( column_major shared) buffer int member02, layout( column_major shared) buffer 2-element array of int memberArr02, layout( column_major shared) buffer unsized 1-element array of int memberUnsizedArr02})

View File

@ -18,12 +18,12 @@ cb1: offset 0, type 1404, size 1, index 4, binding -1, stages 16
tb1: offset 0, type 1404, size 1, index 5, binding -1, stages 16
Uniform block reflection:
t4: offset -1, type ffffffff, size 0, index -1, binding 14, stages 16, numMembers 1
t5: offset -1, type ffffffff, size 0, index -1, binding 15, stages 16, numMembers 1
u5: offset -1, type ffffffff, size 0, index -1, binding 45, stages 16, numMembers 1
u6: offset -1, type ffffffff, size 0, index -1, binding 46, stages 16, numMembers 1
cb: offset -1, type ffffffff, size 4, index -1, binding 51, stages 16, numMembers 1
tb: offset -1, type ffffffff, size 4, index -1, binding 17, stages 16, numMembers 1
t4: offset -1, type ffffffff, size 16, index 0, binding 14, stages 16, numMembers 1
t5: offset -1, type ffffffff, size 4, index 1, binding 15, stages 16, numMembers 1
u5: offset -1, type ffffffff, size 4, index 2, binding 45, stages 16, numMembers 1
u6: offset -1, type ffffffff, size 4, index 3, binding 46, stages 16, numMembers 1
cb: offset -1, type ffffffff, size 4, index 4, binding 51, stages 16, numMembers 1
tb: offset -1, type ffffffff, size 4, index 5, binding 17, stages 16, numMembers 1
Buffer variable reflection:

View File

@ -12,8 +12,8 @@ c2_b: offset 16, type 1404, size 1, index 1, binding -1, stages 16
c2_c: offset 20, type 1406, size 1, index 1, binding -1, stages 16
Uniform block reflection:
cbuff1: offset -1, type ffffffff, size 24, index -1, binding 2, stages 16, numMembers 3
cbuff2: offset -1, type ffffffff, size 24, index -1, binding 3, stages 16, numMembers 3
cbuff1: offset -1, type ffffffff, size 24, index 0, binding 2, stages 16, numMembers 3
cbuff2: offset -1, type ffffffff, size 24, index 1, binding 3, stages 16, numMembers 3
Buffer variable reflection:

View File

@ -63,12 +63,12 @@ foo1: offset 0, type 1406, size 1, index 4, binding -1, stages 1
foo2: offset 0, type 1406, size 1, index 5, binding -1, stages 1
Uniform block reflection:
nameless: offset -1, type ffffffff, size 496, index -1, binding -1, stages 1, numMembers 9
$Global: offset -1, type ffffffff, size 3088, index -1, binding -1, stages 1, numMembers 106
c_nameless: offset -1, type ffffffff, size 96, index -1, binding -1, stages 1, numMembers 5
nested: offset -1, type ffffffff, size 32, index -1, binding -1, stages 1, numMembers 4
abl: offset -1, type ffffffff, size 4, index -1, binding -1, stages 1, numMembers 1
abl2: offset -1, type ffffffff, size 4, index -1, binding -1, stages 1, numMembers 1
nameless: offset -1, type ffffffff, size 496, index 0, binding -1, stages 1, numMembers 9
$Global: offset -1, type ffffffff, size 3088, index 1, binding -1, stages 1, numMembers 106
c_nameless: offset -1, type ffffffff, size 96, index 2, binding -1, stages 1, numMembers 5
nested: offset -1, type ffffffff, size 32, index 3, binding -1, stages 1, numMembers 4
abl: offset -1, type ffffffff, size 4, index 4, binding -1, stages 1, numMembers 1
abl2: offset -1, type ffffffff, size 4, index 5, binding -1, stages 1, numMembers 1
Buffer variable reflection:

View File

@ -219,12 +219,12 @@ tb1: offset 0, type 1404, size 1, index 5, binding -1, stages 16
ts6: offset -1, type 8b5f, size 1, index -1, binding 71, stages 16
Uniform block reflection:
t4: offset -1, type ffffffff, size 0, index -1, binding 21, stages 16, numMembers 1
t5: offset -1, type ffffffff, size 0, index -1, binding 22, stages 16, numMembers 1
u5: offset -1, type ffffffff, size 0, index -1, binding 44, stages 16, numMembers 1
u6: offset -1, type ffffffff, size 0, index -1, binding 34, stages 16, numMembers 1
cb: offset -1, type ffffffff, size 4, index -1, binding 51, stages 16, numMembers 1
tb: offset -1, type ffffffff, size 4, index -1, binding 27, stages 16, numMembers 1
t4: offset -1, type ffffffff, size 16, index 0, binding 21, stages 16, numMembers 1
t5: offset -1, type ffffffff, size 4, index 1, binding 22, stages 16, numMembers 1
u5: offset -1, type ffffffff, size 4, index 2, binding 44, stages 16, numMembers 1
u6: offset -1, type ffffffff, size 4, index 3, binding 34, stages 16, numMembers 1
cb: offset -1, type ffffffff, size 4, index 4, binding 51, stages 16, numMembers 1
tb: offset -1, type ffffffff, size 4, index 5, binding 27, stages 16, numMembers 1
Buffer variable reflection:

View File

@ -7,7 +7,7 @@ ubo_block.vsonly_uniform: offset 8, type 1406, size 1, index 0, binding -1, stag
ubo_block.fsonly_uniform: offset 12, type 1406, size 1, index 0, binding -1, stages 16
Uniform block reflection:
ubo_block: offset -1, type ffffffff, size 16, index -1, binding 0, stages 17, numMembers 4
ubo_block: offset -1, type ffffffff, size 16, index 0, binding 0, stages 17, numMembers 4
Buffer variable reflection:
@ -15,6 +15,8 @@ Buffer block reflection:
Pipeline input reflection:
vertin: offset 0, type 1406, size 1, index 0, binding -1, stages 1
gl_VertexID: offset 0, type 1404, size 1, index 0, binding -1, stages 1
gl_InstanceID: offset 0, type 1404, size 1, index 0, binding -1, stages 1
Pipeline output reflection:
fragout: offset 0, type 1406, size 1, index 0, binding -1, stages 16

View File

@ -6,7 +6,7 @@ ubo_block.vsonly_uniform: offset 8, type 1406, size 1, index 0, binding -1, stag
ubo_block.fsonly_uniform: offset 12, type 1406, size 1, index 0, binding -1, stages 16
Uniform block reflection:
ubo_block: offset -1, type ffffffff, size 16, index -1, binding 0, stages 17, numMembers 4
ubo_block: offset -1, type ffffffff, size 16, index 0, binding 0, stages 17, numMembers 4
Buffer variable reflection:

View File

@ -32,7 +32,7 @@ uniform_multi[3][1][0]: offset -1, type 1406, size 2, index -1, binding -1, stag
uniform_multi[3][2][0]: offset -1, type 1406, size 2, index -1, binding -1, stages 1, arrayStride 4, topLevelArrayStride 24
Uniform block reflection:
UBO: offset -1, type ffffffff, size 192, index -1, binding -1, stages 1, numMembers 7
UBO: offset -1, type ffffffff, size 192, index 0, binding -1, stages 1, numMembers 7
Buffer variable reflection:
t[0].v[0].position[0]: offset 0, type 1406, size 3, index 0, binding -1, stages 1, arrayStride 4, topLevelArrayStride 72
@ -51,18 +51,19 @@ MultipleArrays.tri[0].v[2].normal[0]: offset 60, type 1406, size 3, index 1, bin
MultipleArrays.vert[0].position[0]: offset 360, type 1406, size 3, index 1, binding -1, stages 1, arrayStride 4, topLevelArrayStride 24
MultipleArrays.vert[0].normal[0]: offset 372, type 1406, size 3, index 1, binding -1, stages 0, arrayStride 4, topLevelArrayStride 24
MultipleArrays.f[0]: offset 480, type 1406, size 5, index 1, binding -1, stages 1, arrayStride 4, topLevelArrayStride 4
ArrayedBind[0].a: offset 0, type 1406, size 1, index 4, binding -1, stages 0
ArrayedBind[0].b: offset 4, type 1406, size 1, index 4, binding -1, stages 1
ArrayedBind.a: offset 0, type 1406, size 1, index 2, binding -1, stages 0
ArrayedBind.b: offset 4, type 1406, size 1, index 2, binding -1, stages 1
Buffer block reflection:
VertexCollection: offset -1, type ffffffff, size 400, index -1, binding -1, stages 1, numMembers 7
MultipleArrays: offset -1, type ffffffff, size 500, index -1, binding -1, stages 1, numMembers 9
ArrayedBind[0]: offset -1, type ffffffff, size 8, index -1, binding -1, stages 1, numMembers 2
ArrayedBind[1]: offset -1, type ffffffff, size 8, index -1, binding -1, stages 1, numMembers 2
ArrayedBind[2]: offset -1, type ffffffff, size 8, index -1, binding -1, stages 1, numMembers 2
VertexCollection: offset -1, type ffffffff, size 400, index 0, binding -1, stages 1, numMembers 7
MultipleArrays: offset -1, type ffffffff, size 500, index 1, binding -1, stages 1, numMembers 9
ArrayedBind[0]: offset -1, type ffffffff, size 8, index 2, binding -1, stages 1, numMembers 2
ArrayedBind[1]: offset -1, type ffffffff, size 8, index 3, binding -1, stages 1, numMembers 2
ArrayedBind[2]: offset -1, type ffffffff, size 8, index 4, binding -1, stages 1, numMembers 2
Pipeline input reflection:
gl_InstanceID: offset 0, type 1404, size 1, index 0, binding -1, stages 1
gl_VertexID: offset 0, type 1404, size 1, index 0, binding -1, stages 1
Pipeline output reflection:
outval.val: offset 0, type 1406, size 1, index 0, binding -1, stages 1

View File

@ -90,8 +90,8 @@ deepA[1].d2.d1[2].b: offset -1, type 8b56, size 1, index -1, binding -1, stages
deepA[1].d2.d1[3].va: offset -1, type 8b50, size 3, index -1, binding -1, stages 1, arrayStride 8, topLevelArrayStride 176
deepA[1].d2.d1[3].b: offset -1, type 8b56, size 1, index -1, binding -1, stages 1, topLevelArrayStride 176
ufDead3: offset -1, type 1406, size 1, index -1, binding -1, stages 1
abl.foo: offset 0, type 1406, size 1, index 7, binding -1, stages 1
abl2.foo: offset 0, type 1406, size 1, index 11, binding -1, stages 1
abl.foo: offset 0, type 1406, size 1, index 4, binding -1, stages 1
abl2.foo: offset 0, type 1406, size 1, index 8, binding -1, stages 1
buf1.runtimeArray: offset 4, type 1406, size 4, index 12, binding -1, stages 1, arrayStride 4, topLevelArrayStride 4
buf2.runtimeArray.c: offset 8, type 1406, size 1, index 13, binding -1, stages 1, topLevelArrayStride 12
buf3.runtimeArray: offset 4, type 1406, size 0, index 14, binding -1, stages 1, arrayStride 4, topLevelArrayStride 4
@ -145,24 +145,24 @@ t[4].v[2].position: offset 336, type 1406, size 3, index 17, binding -1, stages
t[4].v[2].normal: offset 348, type 1406, size 3, index 17, binding -1, stages 1, arrayStride 4, topLevelArrayStride 72
Uniform block reflection:
named: offset -1, type ffffffff, size 304, index -1, binding -1, stages 1, numMembers 10
nameless: offset -1, type ffffffff, size 496, index -1, binding -1, stages 1, numMembers 9
c_nameless: offset -1, type ffffffff, size 112, index -1, binding -1, stages 1, numMembers 5
nested: offset -1, type ffffffff, size 32, index -1, binding -1, stages 1, numMembers 4
abl[0]: offset -1, type ffffffff, size 4, index -1, binding -1, stages 1, numMembers 1
abl[1]: offset -1, type ffffffff, size 4, index -1, binding -1, stages 1, numMembers 1
abl[2]: offset -1, type ffffffff, size 4, index -1, binding -1, stages 1, numMembers 1
abl[3]: offset -1, type ffffffff, size 4, index -1, binding -1, stages 1, numMembers 1
abl2[0]: offset -1, type ffffffff, size 4, index -1, binding -1, stages 1, numMembers 1
abl2[1]: offset -1, type ffffffff, size 4, index -1, binding -1, stages 1, numMembers 1
abl2[2]: offset -1, type ffffffff, size 4, index -1, binding -1, stages 1, numMembers 1
abl2[3]: offset -1, type ffffffff, size 4, index -1, binding -1, stages 1, numMembers 1
buf1: offset -1, type ffffffff, size 4, index -1, binding -1, stages 1, numMembers 2
buf2: offset -1, type ffffffff, size 4, index -1, binding -1, stages 1, numMembers 4
buf3: offset -1, type ffffffff, size 4, index -1, binding -1, stages 1, numMembers 2
buf4: offset -1, type ffffffff, size 4, index -1, binding -1, stages 1, numMembers 4
nested2: offset -1, type ffffffff, size 208, index -1, binding -1, stages 1, numMembers 15
VertexCollection: offset -1, type ffffffff, size 400, index -1, binding -1, stages 1, numMembers 31
named: offset -1, type ffffffff, size 304, index 0, binding -1, stages 1, numMembers 10
nameless: offset -1, type ffffffff, size 496, index 1, binding -1, stages 1, numMembers 9
c_nameless: offset -1, type ffffffff, size 112, index 2, binding -1, stages 1, numMembers 5
nested: offset -1, type ffffffff, size 32, index 3, binding -1, stages 1, numMembers 4
abl[0]: offset -1, type ffffffff, size 4, index 4, binding -1, stages 1, numMembers 1
abl[1]: offset -1, type ffffffff, size 4, index 5, binding -1, stages 1, numMembers 1
abl[2]: offset -1, type ffffffff, size 4, index 6, binding -1, stages 1, numMembers 1
abl[3]: offset -1, type ffffffff, size 4, index 7, binding -1, stages 1, numMembers 1
abl2[0]: offset -1, type ffffffff, size 4, index 8, binding -1, stages 1, numMembers 1
abl2[1]: offset -1, type ffffffff, size 4, index 9, binding -1, stages 1, numMembers 1
abl2[2]: offset -1, type ffffffff, size 4, index 10, binding -1, stages 1, numMembers 1
abl2[3]: offset -1, type ffffffff, size 4, index 11, binding -1, stages 1, numMembers 1
buf1: offset -1, type ffffffff, size 8, index 12, binding -1, stages 1, numMembers 2
buf2: offset -1, type ffffffff, size 16, index 13, binding -1, stages 1, numMembers 4
buf3: offset -1, type ffffffff, size 8, index 14, binding -1, stages 1, numMembers 2
buf4: offset -1, type ffffffff, size 16, index 15, binding -1, stages 1, numMembers 4
nested2: offset -1, type ffffffff, size 208, index 16, binding -1, stages 1, numMembers 15
VertexCollection: offset -1, type ffffffff, size 400, index 17, binding -1, stages 1, numMembers 31
Buffer variable reflection:

View File

@ -37,17 +37,17 @@ diff -b $BASEDIR/badMacroArgs.frag.out $TARGETDIR/badMacroArgs.frag.out || HASER
echo Running reflection...
$EXE -l -q -C reflection.vert > $TARGETDIR/reflection.vert.out
diff -b $BASEDIR/reflection.vert.out $TARGETDIR/reflection.vert.out || HASERROR=1
$EXE -l -q -C --reflect-strict-array-suffix --reflect-basic-array-suffix --reflect-intermediate-io --reflect-separate-buffers --reflect-all-block-variables --reflect-unwrap-io-blocks reflection.options.vert > $TARGETDIR/reflection.options.vert.out
$EXE -l -q -C --reflect-strict-array-suffix --reflect-basic-array-suffix --reflect-intermediate-io --reflect-separate-buffers --reflect-all-block-variables --reflect-unwrap-io-blocks --reflect-all-io-variables --reflect-shared-std140-ubo --reflect-shared-std140-ssbo reflection.options.vert > $TARGETDIR/reflection.options.vert.out
diff -b $BASEDIR/reflection.options.vert.out $TARGETDIR/reflection.options.vert.out || HASERROR=1
$EXE -l -q -C reflection.frag > $TARGETDIR/reflection.frag.out
diff -b $BASEDIR/reflection.frag.out $TARGETDIR/reflection.frag.out || HASERROR=1
$EXE -l -q -C --reflect-strict-array-suffix --reflect-basic-array-suffix --reflect-intermediate-io --reflect-separate-buffers --reflect-all-block-variables --reflect-unwrap-io-blocks reflection.frag > $TARGETDIR/reflection.options.frag.out
$EXE -l -q -C --reflect-strict-array-suffix --reflect-basic-array-suffix --reflect-intermediate-io --reflect-separate-buffers --reflect-all-block-variables --reflect-unwrap-io-blocks --reflect-all-io-variables --reflect-shared-std140-ubo --reflect-shared-std140-ssbo reflection.frag > $TARGETDIR/reflection.options.frag.out
diff -b $BASEDIR/reflection.options.frag.out $TARGETDIR/reflection.options.frag.out || HASERROR=1
$EXE -l -q -C --reflect-strict-array-suffix --reflect-basic-array-suffix --reflect-intermediate-io --reflect-separate-buffers --reflect-all-block-variables --reflect-unwrap-io-blocks reflection.options.geom > $TARGETDIR/reflection.options.geom.out
$EXE -l -q -C --reflect-strict-array-suffix --reflect-basic-array-suffix --reflect-intermediate-io --reflect-separate-buffers --reflect-all-block-variables --reflect-unwrap-io-blocks --reflect-all-io-variables --reflect-shared-std140-ubo --reflect-shared-std140-ssbo reflection.options.geom > $TARGETDIR/reflection.options.geom.out
diff -b $BASEDIR/reflection.options.geom.out $TARGETDIR/reflection.options.geom.out || HASERROR=1
$EXE -l -q -C reflection.linked.vert reflection.linked.frag > $TARGETDIR/reflection.linked.out
diff -b $BASEDIR/reflection.linked.out $TARGETDIR/reflection.linked.out || HASERROR=1
$EXE -l -q -C --reflect-strict-array-suffix --reflect-basic-array-suffix --reflect-intermediate-io --reflect-separate-buffers --reflect-all-block-variables --reflect-unwrap-io-blocks reflection.linked.vert reflection.linked.frag > $TARGETDIR/reflection.linked.options.out
$EXE -l -q -C --reflect-strict-array-suffix --reflect-basic-array-suffix --reflect-intermediate-io --reflect-separate-buffers --reflect-all-block-variables --reflect-unwrap-io-blocks --reflect-all-io-variables --reflect-shared-std140-ubo --reflect-shared-std140-ssbo reflection.linked.vert reflection.linked.frag > $TARGETDIR/reflection.linked.options.out
diff -b $BASEDIR/reflection.linked.options.out $TARGETDIR/reflection.linked.options.out || HASERROR=1
$EXE -D -Od -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

View File

@ -164,7 +164,9 @@ typedef enum {
GLSLANG_REFLECTION_SEPARATE_BUFFERS_BIT = (1 << 3),
GLSLANG_REFLECTION_ALL_BLOCK_VARIABLES_BIT = (1 << 4),
GLSLANG_REFLECTION_UNWRAP_IO_BLOCKS_BIT = (1 << 5),
GLSLANG_REFLECTION_SHARED_STD140_BLOCKS_BIT = (1 << 6),
GLSLANG_REFLECTION_ALL_IO_VARIABLES_BIT = (1 << 6),
GLSLANG_REFLECTION_SHARED_STD140_SSBO_BIT = (1 << 7),
GLSLANG_REFLECTION_SHARED_STD140_UBO_BIT = (1 << 8),
LAST_ELEMENT_MARKER(GLSLANG_REFLECTION_COUNT),
} glslang_reflection_options_t;

View File

@ -309,26 +309,43 @@ struct TSymbolValidater
TIntermSymbol* base = ent1.symbol;
const TType& type = ent1.symbol->getType();
const TString& name = entKey.first;
TString mangleName1, mangleName2;
type.appendMangledName(mangleName1);
EShLanguage stage = ent1.stage;
TString mangleName1, mangleName2;
if (currentStage != stage) {
preStage = currentStage;
currentStage = stage;
nextStage = EShLangCount;
for (int i = currentStage + 1; i < EShLangCount; i++) {
if (inVarMaps[i] != nullptr)
if (inVarMaps[i] != nullptr) {
nextStage = static_cast<EShLanguage>(i);
break;
}
}
}
if (type.getQualifier().isArrayedIo(stage)) {
TType subType(type, 0);
subType.appendMangledName(mangleName1);
} else {
type.appendMangledName(mangleName1);
}
if (base->getQualifier().storage == EvqVaryingIn) {
// validate stage in;
if (preStage == EShLangCount)
return;
if (name == "gl_PerVertex")
return;
if (outVarMaps[preStage] != nullptr) {
auto ent2 = outVarMaps[preStage]->find(name);
if (ent2 != outVarMaps[preStage]->end()) {
ent2->second.symbol->getType().appendMangledName(mangleName2);
if (ent2->second.symbol->getType().getQualifier().isArrayedIo(preStage)) {
TType subType(ent2->second.symbol->getType(), 0);
subType.appendMangledName(mangleName2);
}
else {
ent2->second.symbol->getType().appendMangledName(mangleName2);
}
if (mangleName1 == mangleName2)
return;
else {
@ -343,10 +360,18 @@ struct TSymbolValidater
// validate stage out;
if (nextStage == EShLangCount)
return;
if (name == "gl_PerVertex")
return;
if (outVarMaps[nextStage] != nullptr) {
auto ent2 = inVarMaps[nextStage]->find(name);
if (ent2 != inVarMaps[nextStage]->end()) {
ent2->second.symbol->getType().appendMangledName(mangleName2);
if (ent2->second.symbol->getType().getQualifier().isArrayedIo(nextStage)) {
TType subType(ent2->second.symbol->getType(), 0);
subType.appendMangledName(mangleName2);
}
else {
ent2->second.symbol->getType().appendMangledName(mangleName2);
}
if (mangleName1 == mangleName2)
return;
else {

View File

@ -1550,7 +1550,9 @@ int TIntermediate::getBaseAlignment(const TType& type, int& size, int& stride, T
RoundToPow2(size, alignment);
stride = size; // uses full matrix size for stride of an array of matrices (not quite what rule 6/8, but what's expected)
// uses the assumption for rule 10 in the comment above
size = stride * type.getOuterArraySize();
// use one element to represent the last member of SSBO which is unsized array
int arraySize = (type.isUnsizedArray() && (type.getOuterArraySize() == 0)) ? 1 : type.getOuterArraySize();
size = stride * arraySize;
return alignment;
}

View File

@ -107,22 +107,13 @@ public:
else
baseName = "";
if (base.getType().isArray()) {
TType derefType(base.getType(), 0);
assert(!anonymous);
for (int e = 0; e < base.getType().getCumulativeArraySize(); ++e)
blockIndex = addBlockName(blockName + "[" + String(e) + "]", derefType,
intermediate.getBlockSize(base.getType()));
}
else
blockIndex = addBlockName(blockName, base.getType(), intermediate.getBlockSize(base.getType()));
blockIndex = addBlockName(blockName, base.getType(), intermediate.getBlockSize(base.getType()));
}
// Use a degenerate (empty) set of dereferences to immediately put as at the end of
// the dereference change expected by blowUpActiveAggregate.
blowUpActiveAggregate(base.getType(), baseName, derefs, derefs.end(), offset, blockIndex, 0, 0,
base.getQualifier().storage, updateStageMasks);
blowUpActiveAggregate(base.getType(), baseName, derefs, derefs.end(), offset, blockIndex, 0, -1, 0,
base.getQualifier().storage, updateStageMasks);
}
}
@ -259,7 +250,7 @@ public:
// A value of 0 for arraySize will mean to use the full array's size.
void blowUpActiveAggregate(const TType& baseType, const TString& baseName, const TList<TIntermBinary*>& derefs,
TList<TIntermBinary*>::const_iterator deref, int offset, int blockIndex, int arraySize,
int topLevelArrayStride, TStorageQualifier baseStorage, bool active)
int topLevelArraySize, int topLevelArrayStride, TStorageQualifier baseStorage, bool active)
{
// when strictArraySuffix is enabled, we closely follow the rules from ARB_program_interface_query.
// Broadly:
@ -288,14 +279,15 @@ public:
// Visit all the indices of this array, and for each one add on the remaining dereferencing
for (int i = 0; i < std::max(visitNode->getLeft()->getType().getOuterArraySize(), 1); ++i) {
TString newBaseName = name;
if (strictArraySuffix && blockParent)
if (terminalType->getBasicType() == EbtBlock) {}
else if (strictArraySuffix && blockParent)
newBaseName.append(TString("[0]"));
else if (strictArraySuffix || baseType.getBasicType() != EbtBlock)
newBaseName.append(TString("[") + String(i) + "]");
TList<TIntermBinary*>::const_iterator nextDeref = deref;
++nextDeref;
blowUpActiveAggregate(*terminalType, newBaseName, derefs, nextDeref, offset, blockIndex, arraySize,
topLevelArrayStride, baseStorage, active);
topLevelArraySize, topLevelArrayStride, baseStorage, active);
if (offset >= 0)
offset += stride;
@ -308,9 +300,10 @@ public:
int stride = getArrayStride(baseType, visitNode->getLeft()->getType());
index = visitNode->getRight()->getAsConstantUnion()->getConstArray()[0].getIConst();
if (strictArraySuffix && blockParent) {
if (terminalType->getBasicType() == EbtBlock) {}
else if (strictArraySuffix && blockParent)
name.append(TString("[0]"));
} else if (strictArraySuffix || baseType.getBasicType() != EbtBlock) {
else if (strictArraySuffix || baseType.getBasicType() != EbtBlock) {
name.append(TString("[") + String(index) + "]");
if (offset >= 0)
@ -320,7 +313,10 @@ public:
if (topLevelArrayStride == 0)
topLevelArrayStride = stride;
blockParent = false;
// expand top-level arrays in blocks with [0] suffix
if (topLevelArrayStride != 0 && visitNode->getLeft()->getType().isArray()) {
blockParent = false;
}
break;
}
case EOpIndexDirectStruct:
@ -330,6 +326,12 @@ public:
if (name.size() > 0)
name.append(".");
name.append((*visitNode->getLeft()->getType().getStruct())[index].type->getFieldName());
// expand non top-level arrays with [x] suffix
if (visitNode->getLeft()->getType().getBasicType() != EbtBlock && terminalType->isArray())
{
blockParent = false;
}
break;
default:
break;
@ -349,14 +351,16 @@ public:
if (offset >= 0)
stride = getArrayStride(baseType, *terminalType);
if (topLevelArrayStride == 0)
topLevelArrayStride = stride;
int arrayIterateSize = std::max(terminalType->getOuterArraySize(), 1);
// for top-level arrays in blocks, only expand [0] to avoid explosion of items
if (strictArraySuffix && blockParent)
if ((strictArraySuffix && blockParent) ||
((topLevelArraySize == arrayIterateSize) && (topLevelArrayStride == 0))) {
arrayIterateSize = 1;
}
if (topLevelArrayStride == 0)
topLevelArrayStride = stride;
for (int i = 0; i < arrayIterateSize; ++i) {
TString newBaseName = name;
@ -367,7 +371,7 @@ public:
offset = baseOffset + stride * i;
blowUpActiveAggregate(derefType, newBaseName, derefs, derefs.end(), offset, blockIndex, 0,
topLevelArrayStride, baseStorage, active);
topLevelArraySize, topLevelArrayStride, baseStorage, active);
}
} else {
// Visit all members of this aggregate, and for each one,
@ -396,8 +400,31 @@ public:
arrayStride = getArrayStride(baseType, derefType);
}
blowUpActiveAggregate(derefType, newBaseName, derefs, derefs.end(), offset, blockIndex, 0,
arrayStride, baseStorage, active);
if (topLevelArraySize == -1 && arrayStride == 0 && blockParent)
topLevelArraySize = 1;
if (strictArraySuffix && blockParent) {
// if this member is an array, store the top-level array stride but start the explosion from
// the inner struct type.
if (derefType.isArray() && derefType.isStruct()) {
newBaseName.append("[0]");
auto dimSize = derefType.isUnsizedArray() ? 0 : derefType.getArraySizes()->getDimSize(0);
blowUpActiveAggregate(TType(derefType, 0), newBaseName, derefs, derefs.end(), memberOffsets[i],
blockIndex, 0, dimSize, arrayStride, terminalType->getQualifier().storage, false);
}
else if (derefType.isArray()) {
auto dimSize = derefType.isUnsizedArray() ? 0 : derefType.getArraySizes()->getDimSize(0);
blowUpActiveAggregate(derefType, newBaseName, derefs, derefs.end(), memberOffsets[i], blockIndex,
0, dimSize, 0, terminalType->getQualifier().storage, false);
}
else {
blowUpActiveAggregate(derefType, newBaseName, derefs, derefs.end(), memberOffsets[i], blockIndex,
0, 1, 0, terminalType->getQualifier().storage, false);
}
} else {
blowUpActiveAggregate(derefType, newBaseName, derefs, derefs.end(), offset, blockIndex, 0,
topLevelArraySize, arrayStride, baseStorage, active);
}
}
}
@ -433,6 +460,7 @@ public:
if ((reflection.options & EShReflectionSeparateBuffers) && terminalType->isAtomic())
reflection.atomicCounterUniformIndices.push_back(uniformIndex);
variables.back().topLevelArraySize = topLevelArraySize;
variables.back().topLevelArrayStride = topLevelArrayStride;
if ((reflection.options & EShReflectionAllBlockVariables) && active) {
@ -564,65 +592,17 @@ public:
if (! anonymous)
baseName = blockName;
if (base->getType().isArray()) {
TType derefType(base->getType(), 0);
assert(! anonymous);
for (int e = 0; e < base->getType().getCumulativeArraySize(); ++e)
blockIndex = addBlockName(blockName + "[" + String(e) + "]", derefType,
intermediate.getBlockSize(base->getType()));
baseName.append(TString("[0]"));
} else
blockIndex = addBlockName(blockName, base->getType(), intermediate.getBlockSize(base->getType()));
blockIndex = addBlockName(blockName, base->getType(), intermediate.getBlockSize(base->getType()));
if (reflection.options & EShReflectionAllBlockVariables) {
// Use a degenerate (empty) set of dereferences to immediately put as at the end of
// the dereference change expected by blowUpActiveAggregate.
TList<TIntermBinary*> derefs;
// because we don't have any derefs, the first thing blowUpActiveAggregate will do is iterate over each
// member in the struct definition. This will lose any information about whether the parent was a buffer
// block. So if we're using strict array rules which don't expand the first child of a buffer block we
// instead iterate over the children here.
const bool strictArraySuffix = (reflection.options & EShReflectionStrictArraySuffix);
bool blockParent = (base->getType().getBasicType() == EbtBlock && base->getQualifier().storage == EvqBuffer);
if (strictArraySuffix && blockParent) {
TType structDerefType(base->getType(), 0);
const TType &structType = base->getType().isArray() ? structDerefType : base->getType();
const TTypeList& typeList = *structType.getStruct();
TVector<int> memberOffsets;
memberOffsets.resize(typeList.size());
getOffsets(structType, memberOffsets);
for (int i = 0; i < (int)typeList.size(); ++i) {
TType derefType(structType, i);
TString name = baseName;
if (name.size() > 0)
name.append(".");
name.append(typeList[i].type->getFieldName());
// if this member is an array, store the top-level array stride but start the explosion from
// the inner struct type.
if (derefType.isArray() && derefType.isStruct()) {
name.append("[0]");
blowUpActiveAggregate(TType(derefType, 0), name, derefs, derefs.end(), memberOffsets[i],
blockIndex, 0, getArrayStride(structType, derefType),
base->getQualifier().storage, false);
} else {
blowUpActiveAggregate(derefType, name, derefs, derefs.end(), memberOffsets[i], blockIndex,
0, 0, base->getQualifier().storage, false);
}
}
} else {
// otherwise - if we're not using strict array suffix rules, or this isn't a block so we are
// expanding root arrays anyway, just start the iteration from the base block type.
blowUpActiveAggregate(base->getType(), baseName, derefs, derefs.end(), 0, blockIndex, 0, 0,
// otherwise - if we're not using strict array suffix rules, or this isn't a block so we are
// expanding root arrays anyway, just start the iteration from the base block type.
blowUpActiveAggregate(base->getType(), baseName, derefs, derefs.end(), 0, blockIndex, 0, -1, 0,
base->getQualifier().storage, false);
}
}
}
@ -653,31 +633,37 @@ public:
else
baseName = base->getName();
}
blowUpActiveAggregate(base->getType(), baseName, derefs, derefs.begin(), offset, blockIndex, arraySize, 0,
blowUpActiveAggregate(base->getType(), baseName, derefs, derefs.begin(), offset, blockIndex, arraySize, -1, 0,
base->getQualifier().storage, true);
}
int addBlockName(const TString& name, const TType& type, int size)
{
TReflection::TMapIndexToReflection& blocks = reflection.GetBlockMapForStorage(type.getQualifier().storage);
int blockIndex;
TReflection::TNameToIndex::const_iterator it = reflection.nameToIndex.find(name.c_str());
if (reflection.nameToIndex.find(name.c_str()) == reflection.nameToIndex.end()) {
blockIndex = (int)blocks.size();
reflection.nameToIndex[name.c_str()] = blockIndex;
blocks.push_back(TObjectReflection(name.c_str(), type, -1, -1, size, -1));
if (type.isArray()) {
TType derefType(type, 0);
for (int e = 0; e < type.getOuterArraySize(); ++e) {
uint32_t memberBlockIndex = addBlockName(name + "[" + String(e) + "]", derefType, size);
if (e == 0)
blockIndex = memberBlockIndex;
}
} else {
TReflection::TMapIndexToReflection& blocks = reflection.GetBlockMapForStorage(type.getQualifier().storage);
blocks.back().numMembers = countAggregateMembers(type);
TReflection::TNameToIndex::const_iterator it = reflection.nameToIndex.find(name.c_str());
if (reflection.nameToIndex.find(name.c_str()) == reflection.nameToIndex.end()) {
blockIndex = (int)blocks.size();
reflection.nameToIndex[name.c_str()] = blockIndex;
blocks.push_back(TObjectReflection(name.c_str(), type, -1, -1, size, blockIndex));
blocks.back().numMembers = countAggregateMembers(type);
if (updateStageMasks) {
EShLanguageMask& stages = blocks.back().stages;
stages = static_cast<EShLanguageMask>(stages | 1 << intermediate.getStage());
}
} else {
blockIndex = it->second;
else {
blockIndex = it->second;
if (updateStageMasks) {
EShLanguageMask& stages = blocks[blockIndex].stages;
stages = static_cast<EShLanguageMask>(stages | 1 << intermediate.getStage());
}
@ -1064,7 +1050,7 @@ void TReflectionTraverser::visitSymbol(TIntermSymbol* base)
{
if (base->getQualifier().storage == EvqUniform) {
if (base->getBasicType() == EbtBlock) {
if (reflection.options & EShReflectionSharedStd140Blocks) {
if (reflection.options & EShReflectionSharedStd140UBO) {
addUniform(*base);
}
} else {
@ -1072,6 +1058,13 @@ void TReflectionTraverser::visitSymbol(TIntermSymbol* base)
}
}
// #TODO add std140/layout active rules for ssbo, same with ubo.
// Storage buffer blocks will be collected and expanding in this part.
if((reflection.options & EShReflectionSharedStd140SSBO) &&
(base->getQualifier().storage == EvqBuffer && base->getBasicType() == EbtBlock &&
(base->getQualifier().layoutPacking == ElpStd140 || base->getQualifier().layoutPacking == ElpShared)))
addUniform(*base);
if ((intermediate.getStage() == reflection.firstStage && base->getQualifier().isPipeInput()) ||
(intermediate.getStage() == reflection.lastStage && base->getQualifier().isPipeOutput()))
addPipeIOVariable(*base);
@ -1182,15 +1175,23 @@ bool TReflection::addStage(EShLanguage stage, const TIntermediate& intermediate)
TIntermAggregate* linkerObjects = sequnence->getAsAggregate();
for (auto& sequnence : linkerObjects->getSequence()) {
auto pNode = sequnence->getAsSymbolNode();
if (pNode != nullptr && pNode->getQualifier().storage == EvqUniform &&
(options & EShReflectionSharedStd140Blocks)) {
if (pNode->getBasicType() == EbtBlock) {
if (pNode != nullptr) {
if ((pNode->getQualifier().storage == EvqUniform &&
(options & EShReflectionSharedStd140UBO)) ||
(pNode->getQualifier().storage == EvqBuffer &&
(options & EShReflectionSharedStd140SSBO))) {
// collect std140 and shared uniform block form AST
if (pNode->getQualifier().layoutPacking == ElpStd140 ||
pNode->getQualifier().layoutPacking == ElpShared) {
pNode->traverse(&it);
if ((pNode->getBasicType() == EbtBlock) &&
((pNode->getQualifier().layoutPacking == ElpStd140) ||
(pNode->getQualifier().layoutPacking == ElpShared))) {
pNode->traverse(&it);
}
}
else if ((options & EShReflectionAllIOVariables) &&
(pNode->getQualifier().isPipeInput() || pNode->getQualifier().isPipeOutput()))
{
pNode->traverse(&it);
}
}
}
} else {

View File

@ -271,7 +271,9 @@ typedef enum {
EShReflectionSeparateBuffers = (1 << 3), // buffer variables and buffer blocks are reflected separately
EShReflectionAllBlockVariables = (1 << 4), // reflect all variables in blocks, even if they are inactive
EShReflectionUnwrapIOBlocks = (1 << 5), // unwrap input/output blocks the same as with uniform blocks
EShReflectionSharedStd140Blocks = (1 << 6), // Apply std140/shared rules for ubo to ssbo
EShReflectionAllIOVariables = (1 << 6), // reflect all input/output variables, even if they are inactive
EShReflectionSharedStd140SSBO = (1 << 7), // Apply std140/shared rules for ubo to ssbo
EShReflectionSharedStd140UBO = (1 << 8), // Apply std140/shared rules for ubo to ssbo
LAST_ELEMENT_MARKER(EShReflectionCount),
} EShReflectionOptions;
@ -696,6 +698,7 @@ public:
int counterIndex;
int numMembers;
int arrayStride; // stride of an array variable
int topLevelArraySize; // size of the top-level variable in a storage buffer member
int topLevelArrayStride; // stride of the top-level variable in a storage buffer member
EShLanguageMask stages;