diff --git a/StandAlone/StandAlone.cpp b/StandAlone/StandAlone.cpp index 871788e1d..ab8d904d0 100644 --- a/StandAlone/StandAlone.cpp +++ b/StandAlone/StandAlone.cpp @@ -555,6 +555,12 @@ void ProcessArguments(std::vector>& 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") { diff --git a/Test/420.frag b/Test/420.frag index d3020b364..4c0b15fc7 100644 --- a/Test/420.frag +++ b/Test/420.frag @@ -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 diff --git a/Test/baseResults/420.frag.out b/Test/baseResults/420.frag.out index 1a7586a72..19b5c9b93 100644 --- a/Test/baseResults/420.frag.out +++ b/Test/baseResults/420.frag.out @@ -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}) diff --git a/Test/baseResults/hlsl.automap.frag.out b/Test/baseResults/hlsl.automap.frag.out index 7691b8982..240e67a98 100644 --- a/Test/baseResults/hlsl.automap.frag.out +++ b/Test/baseResults/hlsl.automap.frag.out @@ -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: diff --git a/Test/baseResults/hlsl.reflection.binding.frag.out b/Test/baseResults/hlsl.reflection.binding.frag.out index a13e575aa..e559dd368 100644 --- a/Test/baseResults/hlsl.reflection.binding.frag.out +++ b/Test/baseResults/hlsl.reflection.binding.frag.out @@ -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: diff --git a/Test/baseResults/hlsl.reflection.vert.out b/Test/baseResults/hlsl.reflection.vert.out index 1b3cb5145..796784ba7 100644 --- a/Test/baseResults/hlsl.reflection.vert.out +++ b/Test/baseResults/hlsl.reflection.vert.out @@ -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: diff --git a/Test/baseResults/hlsl.shift.per-set.frag.out b/Test/baseResults/hlsl.shift.per-set.frag.out index 60e2ecc1c..ad0b7e0bd 100644 --- a/Test/baseResults/hlsl.shift.per-set.frag.out +++ b/Test/baseResults/hlsl.shift.per-set.frag.out @@ -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: diff --git a/Test/baseResults/reflection.linked.options.out b/Test/baseResults/reflection.linked.options.out index af07bbd70..a0e45ede0 100644 --- a/Test/baseResults/reflection.linked.options.out +++ b/Test/baseResults/reflection.linked.options.out @@ -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 diff --git a/Test/baseResults/reflection.linked.out b/Test/baseResults/reflection.linked.out index b1b2b3cdd..387421855 100644 --- a/Test/baseResults/reflection.linked.out +++ b/Test/baseResults/reflection.linked.out @@ -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: diff --git a/Test/baseResults/reflection.options.vert.out b/Test/baseResults/reflection.options.vert.out index 3f4a27166..d68bf379e 100644 --- a/Test/baseResults/reflection.options.vert.out +++ b/Test/baseResults/reflection.options.vert.out @@ -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 diff --git a/Test/baseResults/reflection.vert.out b/Test/baseResults/reflection.vert.out index 612a0b9ae..84f690f62 100644 --- a/Test/baseResults/reflection.vert.out +++ b/Test/baseResults/reflection.vert.out @@ -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: diff --git a/Test/runtests b/Test/runtests index 1a7c7c941..5dd76cea4 100755 --- a/Test/runtests +++ b/Test/runtests @@ -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 diff --git a/glslang/Include/glslang_c_shader_types.h b/glslang/Include/glslang_c_shader_types.h index 15bf1e14f..d01a115f6 100644 --- a/glslang/Include/glslang_c_shader_types.h +++ b/glslang/Include/glslang_c_shader_types.h @@ -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; diff --git a/glslang/MachineIndependent/iomapper.cpp b/glslang/MachineIndependent/iomapper.cpp index 4e409e06a..fadcb1bf9 100644 --- a/glslang/MachineIndependent/iomapper.cpp +++ b/glslang/MachineIndependent/iomapper.cpp @@ -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(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 { diff --git a/glslang/MachineIndependent/linkValidate.cpp b/glslang/MachineIndependent/linkValidate.cpp index 045d45e3c..96ea46876 100755 --- a/glslang/MachineIndependent/linkValidate.cpp +++ b/glslang/MachineIndependent/linkValidate.cpp @@ -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; } diff --git a/glslang/MachineIndependent/reflection.cpp b/glslang/MachineIndependent/reflection.cpp index 55caa1f44..d394cf01f 100644 --- a/glslang/MachineIndependent/reflection.cpp +++ b/glslang/MachineIndependent/reflection.cpp @@ -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& derefs, TList::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::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 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 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(stages | 1 << intermediate.getStage()); } - } else { - blockIndex = it->second; + else { + blockIndex = it->second; - if (updateStageMasks) { EShLanguageMask& stages = blocks[blockIndex].stages; stages = static_cast(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 { diff --git a/glslang/Public/ShaderLang.h b/glslang/Public/ShaderLang.h index 38693aa9d..7905b3d16 100644 --- a/glslang/Public/ShaderLang.h +++ b/glslang/Public/ShaderLang.h @@ -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;