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") {
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
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.
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:
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})
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:
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:
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:
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:
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:
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
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:
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
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
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
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:
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
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;
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 {
// 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 {
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;
}
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);
}
}
// 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:
// 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;
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)
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:
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;
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;
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,
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);
+ }
}
}
if ((reflection.options & EShReflectionSeparateBuffers) && terminalType->isAtomic())
reflection.atomicCounterUniformIndices.push_back(uniformIndex);
+ variables.back().topLevelArraySize = topLevelArraySize;
variables.back().topLevelArrayStride = topLevelArrayStride;
if ((reflection.options & EShReflectionAllBlockVariables) && active) {
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);
- }
}
}
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);
+
+ 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);
+ 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());
}
{
if (base->getQualifier().storage == EvqUniform) {
if (base->getBasicType() == EbtBlock) {
- if (reflection.options & EShReflectionSharedStd140Blocks) {
+ if (reflection.options & EShReflectionSharedStd140UBO) {
addUniform(*base);
}
} else {
}
}
+ // #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);
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 {
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;
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;