Reserve unused std140 uniform block in reflection, and fix uniform block matrix layou...
authorRoy.li <lryer@msn.com>
Fri, 15 May 2020 08:26:48 +0000 (16:26 +0800)
committerGitHub <noreply@github.com>
Fri, 15 May 2020 08:26:48 +0000 (02:26 -0600)
According to the spec glsl4.60.7:
4.4.5. Uniform and Shader Storage Block Layout Qualifiers:
"The packed qualifier overrides only std140, std430, and shared; other qualifiers are inherited.
When packed is used, no shareable layout is guaranteed. The compiler and linker can optimize
memory use based on what variables actively get used and on other criteria. Offsets must be
queried, as there is no other way of guaranteeing where (and which) variables reside within the
block"

we should reserve std140 block and shared block in reflection.

According to the spec glsl4.60.7:
4.4.5. Uniform and Shader Storage Block Layout Qualifiers:
"The row_major and column_major qualifiers only affect the layout of matrices, including all
matrices contained in structures and arrays they are applied to, to all depths of nesting. These
qualifiers can be applied to other types, but will have no effect."

We need ensure all matrix block member been effect.

Support EShMsgKeepUncalled in reflection

EShMsgKeepUncalled  is a link message for link program.
We need only one option to control uncalled function optimization.
If we set EShMsgKeepUncalled as false in link time, linker won't be keep the uncall function sequence in AST,  and if we set EShMsgKeepUncalled as true in link time, linker will keep all uncalled function sequence in AST.
So, in reflecte time, we just only travers all function sequence. It make EShMsgKeepUncalled  only work at linker, and can effect reflection.

Recursively layout packing to "block member"

layout packing isn't set recursively, it causes TReflection::getOffsets doesn't work correctly.

Test/baseResults/300block.frag.out
Test/baseResults/310.inheritMemory.frag.out
Test/baseResults/hlsl.reflection.vert.out
Test/baseResults/reflection.vert.out
glslang/Include/glslang_c_shader_types.h
glslang/MachineIndependent/ParseHelper.cpp
glslang/MachineIndependent/ParseHelper.h
glslang/MachineIndependent/reflection.cpp
glslang/Public/ShaderLang.h [changed mode: 0755->0644]

index 6f7de91..e5b07dd 100644 (file)
@@ -38,7 +38,7 @@ ERROR: node is still EOpNull!
 0:44          Convert uint to float ( temp lowp float)
 0:44            direct index ( temp mediump uint)
 0:44              bv: direct index for structure (layout( column_major shared) uniform mediump 4-component vector of uint)
-0:44                'anon@0' (layout( column_major shared) uniform block{layout( column_major shared) uniform mediump 4-component vector of uint bv, layout( column_major shared) uniform mediump 2X2 matrix of float bm2, layout( column_major shared) uniform lowp isampler2D sampler, layout( column_major shared) uniform structure{ global mediump int a} t, layout( column_major shared) uniform structure{ global mediump 4-component vector of float u,  global mediump 4-component vector of uint v,  global lowp isampler3D sampler,  global mediump 3-component vector of float w,  global structure{ global mediump int a} t} fbs})
+0:44                'anon@0' (layout( column_major shared) uniform block{layout( column_major shared) uniform mediump 4-component vector of uint bv, layout( column_major shared) uniform mediump 2X2 matrix of float bm2, layout( column_major shared) uniform lowp isampler2D sampler, layout( column_major shared) uniform structure{ global mediump int a} t, layout( column_major shared) uniform structure{ global mediump 4-component vector of float u,  global mediump 4-component vector of uint v,  global lowp isampler3D sampler,  global mediump 3-component vector of float w, layout( column_major) global structure{ global mediump int a} t} fbs})
 0:44                Constant:
 0:44                  0 (const uint)
 0:44              Constant:
@@ -78,7 +78,7 @@ ERROR: node is still EOpNull!
 0:55        2 (const int)
 0:?   Linker Objects
 0:?     's' ( uniform structure{ global mediump 4-component vector of float u,  global mediump 4-component vector of uint v,  global lowp isampler3D sampler,  global mediump 3-component vector of float w,  global structure{ global mediump int a} t})
-0:?     'anon@0' (layout( column_major shared) uniform block{layout( column_major shared) uniform mediump 4-component vector of uint bv, layout( column_major shared) uniform mediump 2X2 matrix of float bm2, layout( column_major shared) uniform lowp isampler2D sampler, layout( column_major shared) uniform structure{ global mediump int a} t, layout( column_major shared) uniform structure{ global mediump 4-component vector of float u,  global mediump 4-component vector of uint v,  global lowp isampler3D sampler,  global mediump 3-component vector of float w,  global structure{ global mediump int a} t} fbs})
+0:?     'anon@0' (layout( column_major shared) uniform block{layout( column_major shared) uniform mediump 4-component vector of uint bv, layout( column_major shared) uniform mediump 2X2 matrix of float bm2, layout( column_major shared) uniform lowp isampler2D sampler, layout( column_major shared) uniform structure{ global mediump int a} t, layout( column_major shared) uniform structure{ global mediump 4-component vector of float u,  global mediump 4-component vector of uint v,  global lowp isampler3D sampler,  global mediump 3-component vector of float w, layout( column_major) global structure{ global mediump int a} t} fbs})
 0:?     'inst' (layout( column_major shared) uniform block{layout( column_major shared) uniform mediump 4-component vector of uint nbv, layout( column_major shared) uniform mediump int ni})
 0:?     'insts' (layout( column_major shared) uniform 4-element array of block{layout( column_major shared) uniform mediump 4-component vector of uint nbv, layout( column_major shared) uniform mediump int ni})
 0:?     'anon@1' (layout( column_major shared) uniform block{layout( column_major shared) uniform mediump float f, layout( column_major shared) uniform mediump uint u})
@@ -106,7 +106,7 @@ ERROR: node is still EOpNull!
 0:44          Convert uint to float ( temp lowp float)
 0:44            direct index ( temp mediump uint)
 0:44              bv: direct index for structure (layout( column_major shared) uniform mediump 4-component vector of uint)
-0:44                'anon@0' (layout( column_major shared) uniform block{layout( column_major shared) uniform mediump 4-component vector of uint bv, layout( column_major shared) uniform mediump 2X2 matrix of float bm2, layout( column_major shared) uniform lowp isampler2D sampler, layout( column_major shared) uniform structure{ global mediump int a} t, layout( column_major shared) uniform structure{ global mediump 4-component vector of float u,  global mediump 4-component vector of uint v,  global lowp isampler3D sampler,  global mediump 3-component vector of float w,  global structure{ global mediump int a} t} fbs})
+0:44                'anon@0' (layout( column_major shared) uniform block{layout( column_major shared) uniform mediump 4-component vector of uint bv, layout( column_major shared) uniform mediump 2X2 matrix of float bm2, layout( column_major shared) uniform lowp isampler2D sampler, layout( column_major shared) uniform structure{ global mediump int a} t, layout( column_major shared) uniform structure{ global mediump 4-component vector of float u,  global mediump 4-component vector of uint v,  global lowp isampler3D sampler,  global mediump 3-component vector of float w, layout( column_major) global structure{ global mediump int a} t} fbs})
 0:44                Constant:
 0:44                  0 (const uint)
 0:44              Constant:
@@ -146,7 +146,7 @@ ERROR: node is still EOpNull!
 0:55        2 (const int)
 0:?   Linker Objects
 0:?     's' ( uniform structure{ global mediump 4-component vector of float u,  global mediump 4-component vector of uint v,  global lowp isampler3D sampler,  global mediump 3-component vector of float w,  global structure{ global mediump int a} t})
-0:?     'anon@0' (layout( column_major shared) uniform block{layout( column_major shared) uniform mediump 4-component vector of uint bv, layout( column_major shared) uniform mediump 2X2 matrix of float bm2, layout( column_major shared) uniform lowp isampler2D sampler, layout( column_major shared) uniform structure{ global mediump int a} t, layout( column_major shared) uniform structure{ global mediump 4-component vector of float u,  global mediump 4-component vector of uint v,  global lowp isampler3D sampler,  global mediump 3-component vector of float w,  global structure{ global mediump int a} t} fbs})
+0:?     'anon@0' (layout( column_major shared) uniform block{layout( column_major shared) uniform mediump 4-component vector of uint bv, layout( column_major shared) uniform mediump 2X2 matrix of float bm2, layout( column_major shared) uniform lowp isampler2D sampler, layout( column_major shared) uniform structure{ global mediump int a} t, layout( column_major shared) uniform structure{ global mediump 4-component vector of float u,  global mediump 4-component vector of uint v,  global lowp isampler3D sampler,  global mediump 3-component vector of float w, layout( column_major) global structure{ global mediump int a} t} fbs})
 0:?     'inst' (layout( column_major shared) uniform block{layout( column_major shared) uniform mediump 4-component vector of uint nbv, layout( column_major shared) uniform mediump int ni})
 0:?     'insts' (layout( column_major shared) uniform 4-element array of block{layout( column_major shared) uniform mediump 4-component vector of uint nbv, layout( column_major shared) uniform mediump int ni})
 0:?     'anon@1' (layout( column_major shared) uniform block{layout( column_major shared) uniform mediump float f, layout( column_major shared) uniform mediump uint u})
index 6d5528b..e74d4ab 100644 (file)
@@ -30,13 +30,13 @@ Shader version: 310
 0:30        's' ( temp structure{ global 10-element array of mediump float buff})
 0:32      Function Call: non_ro_fun(f1[10]; ( global void)
 0:32        buff: direct index for structure (layout( column_major std430 offset=0) buffer 10-element array of mediump float)
-0:32          'non_ro_buffer' (layout( binding=2 column_major std430) buffer block{layout( column_major std430 offset=0) buffer 10-element array of mediump float buff, layout( column_major std430 offset=40) buffer structure{ global 10-element array of mediump float buff} s})
+0:32          'non_ro_buffer' (layout( binding=2 column_major std430) buffer block{layout( column_major std430 offset=0) buffer 10-element array of mediump float buff, layout( column_major std430 offset=40) buffer structure{layout( std430) global 10-element array of mediump float buff} s})
 0:32          Constant:
 0:32            0 (const int)
 0:33      Function Call: non_ro_fun(f1[10]; ( global void)
-0:33        buff: direct index for structure ( global 10-element array of mediump float)
-0:33          s: direct index for structure (layout( column_major std430 offset=40) buffer structure{ global 10-element array of mediump float buff})
-0:33            'non_ro_buffer' (layout( binding=2 column_major std430) buffer block{layout( column_major std430 offset=0) buffer 10-element array of mediump float buff, layout( column_major std430 offset=40) buffer structure{ global 10-element array of mediump float buff} s})
+0:33        buff: direct index for structure (layout( std430) global 10-element array of mediump float)
+0:33          s: direct index for structure (layout( column_major std430 offset=40) buffer structure{layout( std430) global 10-element array of mediump float buff})
+0:33            'non_ro_buffer' (layout( binding=2 column_major std430) buffer block{layout( column_major std430 offset=0) buffer 10-element array of mediump float buff, layout( column_major std430 offset=40) buffer structure{layout( std430) global 10-element array of mediump float buff} s})
 0:33            Constant:
 0:33              1 (const int)
 0:33          Constant:
@@ -44,16 +44,16 @@ Shader version: 310
 0:34      Function Call: non_ro_funf(f1; ( global void)
 0:34        direct index (layout( column_major std430 offset=0) temp mediump float)
 0:34          buff: direct index for structure (layout( column_major std430 offset=0) buffer 10-element array of mediump float)
-0:34            'non_ro_buffer' (layout( binding=2 column_major std430) buffer block{layout( column_major std430 offset=0) buffer 10-element array of mediump float buff, layout( column_major std430 offset=40) buffer structure{ global 10-element array of mediump float buff} s})
+0:34            'non_ro_buffer' (layout( binding=2 column_major std430) buffer block{layout( column_major std430 offset=0) buffer 10-element array of mediump float buff, layout( column_major std430 offset=40) buffer structure{layout( std430) global 10-element array of mediump float buff} s})
 0:34            Constant:
 0:34              0 (const int)
 0:34          Constant:
 0:34            3 (const int)
 0:35      Function Call: non_ro_funf(f1; ( global void)
-0:35        direct index ( temp mediump float)
-0:35          buff: direct index for structure ( global 10-element array of mediump float)
-0:35            s: direct index for structure (layout( column_major std430 offset=40) buffer structure{ global 10-element array of mediump float buff})
-0:35              'non_ro_buffer' (layout( binding=2 column_major std430) buffer block{layout( column_major std430 offset=0) buffer 10-element array of mediump float buff, layout( column_major std430 offset=40) buffer structure{ global 10-element array of mediump float buff} s})
+0:35        direct index (layout( std430) temp mediump float)
+0:35          buff: direct index for structure (layout( std430) global 10-element array of mediump float)
+0:35            s: direct index for structure (layout( column_major std430 offset=40) buffer structure{layout( std430) global 10-element array of mediump float buff})
+0:35              'non_ro_buffer' (layout( binding=2 column_major std430) buffer block{layout( column_major std430 offset=0) buffer 10-element array of mediump float buff, layout( column_major std430 offset=40) buffer structure{layout( std430) global 10-element array of mediump float buff} s})
 0:35              Constant:
 0:35                1 (const int)
 0:35            Constant:
@@ -61,19 +61,19 @@ Shader version: 310
 0:35          Constant:
 0:35            3 (const int)
 0:36      Function Call: non_ro_funS(struct-S-f1[10]1; ( global void)
-0:36        s: direct index for structure (layout( column_major std430 offset=40) buffer structure{ global 10-element array of mediump float buff})
-0:36          'non_ro_buffer' (layout( binding=2 column_major std430) buffer block{layout( column_major std430 offset=0) buffer 10-element array of mediump float buff, layout( column_major std430 offset=40) buffer structure{ global 10-element array of mediump float buff} s})
+0:36        s: direct index for structure (layout( column_major std430 offset=40) buffer structure{layout( std430) global 10-element array of mediump float buff})
+0:36          'non_ro_buffer' (layout( binding=2 column_major std430) buffer block{layout( column_major std430 offset=0) buffer 10-element array of mediump float buff, layout( column_major std430 offset=40) buffer structure{layout( std430) global 10-element array of mediump float buff} s})
 0:36          Constant:
 0:36            1 (const int)
 0:38      Function Call: non_ro_fun(f1[10]; ( global void)
 0:38        buff_ro: direct index for structure (layout( column_major std430 offset=0) readonly buffer 10-element array of mediump float)
-0:38          'ro_buffer' (layout( binding=2 column_major std430) readonly buffer block{layout( column_major std430 offset=0) readonly buffer 10-element array of mediump float buff_ro, layout( column_major std430 offset=40) readonly buffer structure{ global 10-element array of mediump float buff} s_ro})
+0:38          'ro_buffer' (layout( binding=2 column_major std430) readonly buffer block{layout( column_major std430 offset=0) readonly buffer 10-element array of mediump float buff_ro, layout( column_major std430 offset=40) readonly buffer structure{layout( std430) global 10-element array of mediump float buff} s_ro})
 0:38          Constant:
 0:38            0 (const int)
 0:39      Function Call: non_ro_fun(f1[10]; ( global void)
-0:39        buff: direct index for structure ( readonly global 10-element array of mediump float)
-0:39          s_ro: direct index for structure (layout( column_major std430 offset=40) readonly buffer structure{ global 10-element array of mediump float buff})
-0:39            'ro_buffer' (layout( binding=2 column_major std430) readonly buffer block{layout( column_major std430 offset=0) readonly buffer 10-element array of mediump float buff_ro, layout( column_major std430 offset=40) readonly buffer structure{ global 10-element array of mediump float buff} s_ro})
+0:39        buff: direct index for structure (layout( std430) readonly global 10-element array of mediump float)
+0:39          s_ro: direct index for structure (layout( column_major std430 offset=40) readonly buffer structure{layout( std430) global 10-element array of mediump float buff})
+0:39            'ro_buffer' (layout( binding=2 column_major std430) readonly buffer block{layout( column_major std430 offset=0) readonly buffer 10-element array of mediump float buff_ro, layout( column_major std430 offset=40) readonly buffer structure{layout( std430) global 10-element array of mediump float buff} s_ro})
 0:39            Constant:
 0:39              1 (const int)
 0:39          Constant:
@@ -81,16 +81,16 @@ Shader version: 310
 0:40      Function Call: non_ro_funf(f1; ( global void)
 0:40        direct index (layout( column_major std430 offset=0) readonly temp mediump float)
 0:40          buff_ro: direct index for structure (layout( column_major std430 offset=0) readonly buffer 10-element array of mediump float)
-0:40            'ro_buffer' (layout( binding=2 column_major std430) readonly buffer block{layout( column_major std430 offset=0) readonly buffer 10-element array of mediump float buff_ro, layout( column_major std430 offset=40) readonly buffer structure{ global 10-element array of mediump float buff} s_ro})
+0:40            'ro_buffer' (layout( binding=2 column_major std430) readonly buffer block{layout( column_major std430 offset=0) readonly buffer 10-element array of mediump float buff_ro, layout( column_major std430 offset=40) readonly buffer structure{layout( std430) global 10-element array of mediump float buff} s_ro})
 0:40            Constant:
 0:40              0 (const int)
 0:40          Constant:
 0:40            3 (const int)
 0:41      Function Call: non_ro_funf(f1; ( global void)
-0:41        direct index ( readonly temp mediump float)
-0:41          buff: direct index for structure ( readonly global 10-element array of mediump float)
-0:41            s_ro: direct index for structure (layout( column_major std430 offset=40) readonly buffer structure{ global 10-element array of mediump float buff})
-0:41              'ro_buffer' (layout( binding=2 column_major std430) readonly buffer block{layout( column_major std430 offset=0) readonly buffer 10-element array of mediump float buff_ro, layout( column_major std430 offset=40) readonly buffer structure{ global 10-element array of mediump float buff} s_ro})
+0:41        direct index (layout( std430) readonly temp mediump float)
+0:41          buff: direct index for structure (layout( std430) readonly global 10-element array of mediump float)
+0:41            s_ro: direct index for structure (layout( column_major std430 offset=40) readonly buffer structure{layout( std430) global 10-element array of mediump float buff})
+0:41              'ro_buffer' (layout( binding=2 column_major std430) readonly buffer block{layout( column_major std430 offset=0) readonly buffer 10-element array of mediump float buff_ro, layout( column_major std430 offset=40) readonly buffer structure{layout( std430) global 10-element array of mediump float buff} s_ro})
 0:41              Constant:
 0:41                1 (const int)
 0:41            Constant:
@@ -98,13 +98,13 @@ Shader version: 310
 0:41          Constant:
 0:41            3 (const int)
 0:42      Function Call: non_ro_funS(struct-S-f1[10]1; ( global void)
-0:42        s_ro: direct index for structure (layout( column_major std430 offset=40) readonly buffer structure{ global 10-element array of mediump float buff})
-0:42          'ro_buffer' (layout( binding=2 column_major std430) readonly buffer block{layout( column_major std430 offset=0) readonly buffer 10-element array of mediump float buff_ro, layout( column_major std430 offset=40) readonly buffer structure{ global 10-element array of mediump float buff} s_ro})
+0:42        s_ro: direct index for structure (layout( column_major std430 offset=40) readonly buffer structure{layout( std430) global 10-element array of mediump float buff})
+0:42          'ro_buffer' (layout( binding=2 column_major std430) readonly buffer block{layout( column_major std430 offset=0) readonly buffer 10-element array of mediump float buff_ro, layout( column_major std430 offset=40) readonly buffer structure{layout( std430) global 10-element array of mediump float buff} s_ro})
 0:42          Constant:
 0:42            1 (const int)
 0:?   Linker Objects
-0:?     'ro_buffer' (layout( binding=2 column_major std430) readonly buffer block{layout( column_major std430 offset=0) readonly buffer 10-element array of mediump float buff_ro, layout( column_major std430 offset=40) readonly buffer structure{ global 10-element array of mediump float buff} s_ro})
-0:?     'non_ro_buffer' (layout( binding=2 column_major std430) buffer block{layout( column_major std430 offset=0) buffer 10-element array of mediump float buff, layout( column_major std430 offset=40) buffer structure{ global 10-element array of mediump float buff} s})
+0:?     'ro_buffer' (layout( binding=2 column_major std430) readonly buffer block{layout( column_major std430 offset=0) readonly buffer 10-element array of mediump float buff_ro, layout( column_major std430 offset=40) readonly buffer structure{layout( std430) global 10-element array of mediump float buff} s_ro})
+0:?     'non_ro_buffer' (layout( binding=2 column_major std430) buffer block{layout( column_major std430 offset=0) buffer 10-element array of mediump float buff, layout( column_major std430 offset=40) buffer structure{layout( std430) global 10-element array of mediump float buff} s})
 0:?     'fragColor' ( out mediump 4-component vector of float)
 
 
@@ -142,13 +142,13 @@ Shader version: 310
 0:30        's' ( temp structure{ global 10-element array of mediump float buff})
 0:32      Function Call: non_ro_fun(f1[10]; ( global void)
 0:32        buff: direct index for structure (layout( column_major std430 offset=0) buffer 10-element array of mediump float)
-0:32          'non_ro_buffer' (layout( binding=2 column_major std430) buffer block{layout( column_major std430 offset=0) buffer 10-element array of mediump float buff, layout( column_major std430 offset=40) buffer structure{ global 10-element array of mediump float buff} s})
+0:32          'non_ro_buffer' (layout( binding=2 column_major std430) buffer block{layout( column_major std430 offset=0) buffer 10-element array of mediump float buff, layout( column_major std430 offset=40) buffer structure{layout( std430) global 10-element array of mediump float buff} s})
 0:32          Constant:
 0:32            0 (const int)
 0:33      Function Call: non_ro_fun(f1[10]; ( global void)
-0:33        buff: direct index for structure ( global 10-element array of mediump float)
-0:33          s: direct index for structure (layout( column_major std430 offset=40) buffer structure{ global 10-element array of mediump float buff})
-0:33            'non_ro_buffer' (layout( binding=2 column_major std430) buffer block{layout( column_major std430 offset=0) buffer 10-element array of mediump float buff, layout( column_major std430 offset=40) buffer structure{ global 10-element array of mediump float buff} s})
+0:33        buff: direct index for structure (layout( std430) global 10-element array of mediump float)
+0:33          s: direct index for structure (layout( column_major std430 offset=40) buffer structure{layout( std430) global 10-element array of mediump float buff})
+0:33            'non_ro_buffer' (layout( binding=2 column_major std430) buffer block{layout( column_major std430 offset=0) buffer 10-element array of mediump float buff, layout( column_major std430 offset=40) buffer structure{layout( std430) global 10-element array of mediump float buff} s})
 0:33            Constant:
 0:33              1 (const int)
 0:33          Constant:
@@ -156,16 +156,16 @@ Shader version: 310
 0:34      Function Call: non_ro_funf(f1; ( global void)
 0:34        direct index (layout( column_major std430 offset=0) temp mediump float)
 0:34          buff: direct index for structure (layout( column_major std430 offset=0) buffer 10-element array of mediump float)
-0:34            'non_ro_buffer' (layout( binding=2 column_major std430) buffer block{layout( column_major std430 offset=0) buffer 10-element array of mediump float buff, layout( column_major std430 offset=40) buffer structure{ global 10-element array of mediump float buff} s})
+0:34            'non_ro_buffer' (layout( binding=2 column_major std430) buffer block{layout( column_major std430 offset=0) buffer 10-element array of mediump float buff, layout( column_major std430 offset=40) buffer structure{layout( std430) global 10-element array of mediump float buff} s})
 0:34            Constant:
 0:34              0 (const int)
 0:34          Constant:
 0:34            3 (const int)
 0:35      Function Call: non_ro_funf(f1; ( global void)
-0:35        direct index ( temp mediump float)
-0:35          buff: direct index for structure ( global 10-element array of mediump float)
-0:35            s: direct index for structure (layout( column_major std430 offset=40) buffer structure{ global 10-element array of mediump float buff})
-0:35              'non_ro_buffer' (layout( binding=2 column_major std430) buffer block{layout( column_major std430 offset=0) buffer 10-element array of mediump float buff, layout( column_major std430 offset=40) buffer structure{ global 10-element array of mediump float buff} s})
+0:35        direct index (layout( std430) temp mediump float)
+0:35          buff: direct index for structure (layout( std430) global 10-element array of mediump float)
+0:35            s: direct index for structure (layout( column_major std430 offset=40) buffer structure{layout( std430) global 10-element array of mediump float buff})
+0:35              'non_ro_buffer' (layout( binding=2 column_major std430) buffer block{layout( column_major std430 offset=0) buffer 10-element array of mediump float buff, layout( column_major std430 offset=40) buffer structure{layout( std430) global 10-element array of mediump float buff} s})
 0:35              Constant:
 0:35                1 (const int)
 0:35            Constant:
@@ -173,19 +173,19 @@ Shader version: 310
 0:35          Constant:
 0:35            3 (const int)
 0:36      Function Call: non_ro_funS(struct-S-f1[10]1; ( global void)
-0:36        s: direct index for structure (layout( column_major std430 offset=40) buffer structure{ global 10-element array of mediump float buff})
-0:36          'non_ro_buffer' (layout( binding=2 column_major std430) buffer block{layout( column_major std430 offset=0) buffer 10-element array of mediump float buff, layout( column_major std430 offset=40) buffer structure{ global 10-element array of mediump float buff} s})
+0:36        s: direct index for structure (layout( column_major std430 offset=40) buffer structure{layout( std430) global 10-element array of mediump float buff})
+0:36          'non_ro_buffer' (layout( binding=2 column_major std430) buffer block{layout( column_major std430 offset=0) buffer 10-element array of mediump float buff, layout( column_major std430 offset=40) buffer structure{layout( std430) global 10-element array of mediump float buff} s})
 0:36          Constant:
 0:36            1 (const int)
 0:38      Function Call: non_ro_fun(f1[10]; ( global void)
 0:38        buff_ro: direct index for structure (layout( column_major std430 offset=0) readonly buffer 10-element array of mediump float)
-0:38          'ro_buffer' (layout( binding=2 column_major std430) readonly buffer block{layout( column_major std430 offset=0) readonly buffer 10-element array of mediump float buff_ro, layout( column_major std430 offset=40) readonly buffer structure{ global 10-element array of mediump float buff} s_ro})
+0:38          'ro_buffer' (layout( binding=2 column_major std430) readonly buffer block{layout( column_major std430 offset=0) readonly buffer 10-element array of mediump float buff_ro, layout( column_major std430 offset=40) readonly buffer structure{layout( std430) global 10-element array of mediump float buff} s_ro})
 0:38          Constant:
 0:38            0 (const int)
 0:39      Function Call: non_ro_fun(f1[10]; ( global void)
-0:39        buff: direct index for structure ( readonly global 10-element array of mediump float)
-0:39          s_ro: direct index for structure (layout( column_major std430 offset=40) readonly buffer structure{ global 10-element array of mediump float buff})
-0:39            'ro_buffer' (layout( binding=2 column_major std430) readonly buffer block{layout( column_major std430 offset=0) readonly buffer 10-element array of mediump float buff_ro, layout( column_major std430 offset=40) readonly buffer structure{ global 10-element array of mediump float buff} s_ro})
+0:39        buff: direct index for structure (layout( std430) readonly global 10-element array of mediump float)
+0:39          s_ro: direct index for structure (layout( column_major std430 offset=40) readonly buffer structure{layout( std430) global 10-element array of mediump float buff})
+0:39            'ro_buffer' (layout( binding=2 column_major std430) readonly buffer block{layout( column_major std430 offset=0) readonly buffer 10-element array of mediump float buff_ro, layout( column_major std430 offset=40) readonly buffer structure{layout( std430) global 10-element array of mediump float buff} s_ro})
 0:39            Constant:
 0:39              1 (const int)
 0:39          Constant:
@@ -193,16 +193,16 @@ Shader version: 310
 0:40      Function Call: non_ro_funf(f1; ( global void)
 0:40        direct index (layout( column_major std430 offset=0) readonly temp mediump float)
 0:40          buff_ro: direct index for structure (layout( column_major std430 offset=0) readonly buffer 10-element array of mediump float)
-0:40            'ro_buffer' (layout( binding=2 column_major std430) readonly buffer block{layout( column_major std430 offset=0) readonly buffer 10-element array of mediump float buff_ro, layout( column_major std430 offset=40) readonly buffer structure{ global 10-element array of mediump float buff} s_ro})
+0:40            'ro_buffer' (layout( binding=2 column_major std430) readonly buffer block{layout( column_major std430 offset=0) readonly buffer 10-element array of mediump float buff_ro, layout( column_major std430 offset=40) readonly buffer structure{layout( std430) global 10-element array of mediump float buff} s_ro})
 0:40            Constant:
 0:40              0 (const int)
 0:40          Constant:
 0:40            3 (const int)
 0:41      Function Call: non_ro_funf(f1; ( global void)
-0:41        direct index ( readonly temp mediump float)
-0:41          buff: direct index for structure ( readonly global 10-element array of mediump float)
-0:41            s_ro: direct index for structure (layout( column_major std430 offset=40) readonly buffer structure{ global 10-element array of mediump float buff})
-0:41              'ro_buffer' (layout( binding=2 column_major std430) readonly buffer block{layout( column_major std430 offset=0) readonly buffer 10-element array of mediump float buff_ro, layout( column_major std430 offset=40) readonly buffer structure{ global 10-element array of mediump float buff} s_ro})
+0:41        direct index (layout( std430) readonly temp mediump float)
+0:41          buff: direct index for structure (layout( std430) readonly global 10-element array of mediump float)
+0:41            s_ro: direct index for structure (layout( column_major std430 offset=40) readonly buffer structure{layout( std430) global 10-element array of mediump float buff})
+0:41              'ro_buffer' (layout( binding=2 column_major std430) readonly buffer block{layout( column_major std430 offset=0) readonly buffer 10-element array of mediump float buff_ro, layout( column_major std430 offset=40) readonly buffer structure{layout( std430) global 10-element array of mediump float buff} s_ro})
 0:41              Constant:
 0:41                1 (const int)
 0:41            Constant:
@@ -210,12 +210,12 @@ Shader version: 310
 0:41          Constant:
 0:41            3 (const int)
 0:42      Function Call: non_ro_funS(struct-S-f1[10]1; ( global void)
-0:42        s_ro: direct index for structure (layout( column_major std430 offset=40) readonly buffer structure{ global 10-element array of mediump float buff})
-0:42          'ro_buffer' (layout( binding=2 column_major std430) readonly buffer block{layout( column_major std430 offset=0) readonly buffer 10-element array of mediump float buff_ro, layout( column_major std430 offset=40) readonly buffer structure{ global 10-element array of mediump float buff} s_ro})
+0:42        s_ro: direct index for structure (layout( column_major std430 offset=40) readonly buffer structure{layout( std430) global 10-element array of mediump float buff})
+0:42          'ro_buffer' (layout( binding=2 column_major std430) readonly buffer block{layout( column_major std430 offset=0) readonly buffer 10-element array of mediump float buff_ro, layout( column_major std430 offset=40) readonly buffer structure{layout( std430) global 10-element array of mediump float buff} s_ro})
 0:42          Constant:
 0:42            1 (const int)
 0:?   Linker Objects
-0:?     'ro_buffer' (layout( binding=2 column_major std430) readonly buffer block{layout( column_major std430 offset=0) readonly buffer 10-element array of mediump float buff_ro, layout( column_major std430 offset=40) readonly buffer structure{ global 10-element array of mediump float buff} s_ro})
-0:?     'non_ro_buffer' (layout( binding=2 column_major std430) buffer block{layout( column_major std430 offset=0) buffer 10-element array of mediump float buff, layout( column_major std430 offset=40) buffer structure{ global 10-element array of mediump float buff} s})
+0:?     'ro_buffer' (layout( binding=2 column_major std430) readonly buffer block{layout( column_major std430 offset=0) readonly buffer 10-element array of mediump float buff_ro, layout( column_major std430 offset=40) readonly buffer structure{layout( std430) global 10-element array of mediump float buff} s_ro})
+0:?     'non_ro_buffer' (layout( binding=2 column_major std430) buffer block{layout( column_major std430 offset=0) buffer 10-element array of mediump float buff, layout( column_major std430 offset=40) buffer structure{layout( std430) global 10-element array of mediump float buff} s})
 0:?     'fragColor' ( out mediump 4-component vector of float)
 
index 535c7fb..1b3cb51 100644 (file)
@@ -1,5 +1,9 @@
 hlsl.reflection.vert
 Uniform reflection:
+anonDeadMember2: offset 64, type 8b52, size 1, index 0, binding -1, stages 1
+ufDead4: offset 28, type 1406, size 1, index 1, binding -1, stages 1
+anonMember1: offset 0, type 8b51, size 1, index 0, binding -1, stages 1
+uf1: offset 16, type 1406, size 1, index 1, binding -1, stages 1
 anonMember3: offset 80, type 8b52, size 1, index 0, binding -1, stages 1
 s.a: offset 0, type 1404, size 1, index 1, binding -1, stages 1
 m23: offset 16, type 8b67, size 1, index 0, binding -1, stages 1
@@ -54,10 +58,9 @@ deepD[1].d2.d1[2].b: offset 2896, type 8b56, size 1, index 1, binding -1, stages
 deepD[1].d2.d1[3].va: offset 2904, type 8b50, size 3, index 1, binding -1, stages 1, arrayStride 8, topLevelArrayStride 304
 deepD[1].d2.d1[3].b: offset 2928, type 8b56, size 1, index 1, binding -1, stages 1, topLevelArrayStride 304
 deepD[1].v3: offset 2944, type 8b54, size 1, index 1, binding -1, stages 1, topLevelArrayStride 304
+ufDead3: offset 24, type 1406, size 1, index 1, binding -1, stages 1
 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
-anonMember1: offset 0, type 8b51, size 1, index 0, binding -1, stages 1
-uf1: offset 16, type 1406, size 1, index 1, binding -1, stages 1
 
 Uniform block reflection:
 nameless: offset -1, type ffffffff, size 496, index -1, binding -1, stages 1, numMembers 9
index 330733c..612a0b9 100644 (file)
@@ -1,26 +1,33 @@
 reflection.vert
 Uniform reflection:
+named.deadMember1: offset 0, type 8b51, size 1, index 0, binding -1, stages 1
+anonDeadMember2: offset 64, type 8b52, size 1, index 1, binding -1, stages 1
+ufDead4: offset -1, type 1406, size 1, index -1, binding -1, stages 1
+anonMember1: offset 0, type 8b51, size 1, index 1, binding -1, stages 1
+uf1: offset -1, type 1406, size 1, index -1, binding -1, stages 1
+uf2: offset -1, type 1406, size 1, index -1, binding -1, stages 1
+named.member3: offset 32, type 8b52, size 1, index 0, binding -1, stages 1
 image_ui2D: offset -1, type 9063, size 1, index -1, binding -1, stages 1
 sampler_2D: offset -1, type 8b5e, size 1, index -1, binding -1, stages 1
 sampler_2DMSArray: offset -1, type 910b, size 1, index -1, binding -1, stages 1
-anonMember3: offset 80, type 8b52, size 1, index 0, binding -1, stages 1
+anonMember3: offset 80, type 8b52, size 1, index 1, binding -1, stages 1
 s.a: offset -1, type 1404, size 1, index -1, binding -1, stages 1
-named.scalar: offset 12, type 1404, size 1, index 1, binding -1, stages 1
-m23: offset 16, type 8b67, size 1, index 0, binding -1, stages 1
-scalarAfterm23: offset 48, type 1404, size 1, index 0, binding -1, stages 1
+named.scalar: offset 12, type 1404, size 1, index 0, binding -1, stages 1
+m23: offset 16, type 8b67, size 1, index 1, binding -1, stages 1
+scalarAfterm23: offset 48, type 1404, size 1, index 1, binding -1, stages 1
 c_m23: offset 16, type 8b67, size 1, index 2, binding -1, stages 1
 c_scalarAfterm23: offset 64, type 1404, size 1, index 2, binding -1, stages 1
-scalarBeforeArray: offset 96, type 1404, size 1, index 0, binding -1, stages 1
-floatArray: offset 112, type 1406, size 5, index 0, binding -1, stages 1, arrayStride 16, topLevelArrayStride 16
-scalarAfterArray: offset 192, type 1404, size 1, index 0, binding -1, stages 1
-named.memvec2: offset 48, type 8b50, size 1, index 1, binding -1, stages 1
-named.memf1: offset 56, type 1406, size 1, index 1, binding -1, stages 1
-named.memf2: offset 60, type 8b56, size 1, index 1, binding -1, stages 1
-named.memf3: offset 64, type 1404, size 1, index 1, binding -1, stages 1
-named.memvec2a: offset 72, type 8b50, size 1, index 1, binding -1, stages 1
-named.m22: offset 80, type 8b5a, size 7, index 1, binding -1, stages 1, arrayStride 32, topLevelArrayStride 32
+scalarBeforeArray: offset 96, type 1404, size 1, index 1, binding -1, stages 1
+floatArray: offset 112, type 1406, size 5, index 1, binding -1, stages 1, arrayStride 16, topLevelArrayStride 16
+scalarAfterArray: offset 192, type 1404, size 1, index 1, binding -1, stages 1
+named.memvec2: offset 48, type 8b50, size 1, index 0, binding -1, stages 1
+named.memf1: offset 56, type 1406, size 1, index 0, binding -1, stages 1
+named.memf2: offset 60, type 8b56, size 1, index 0, binding -1, stages 1
+named.memf3: offset 64, type 1404, size 1, index 0, binding -1, stages 1
+named.memvec2a: offset 72, type 8b50, size 1, index 0, binding -1, stages 1
+named.m22: offset 80, type 8b5a, size 7, index 0, binding -1, stages 1, arrayStride 32, topLevelArrayStride 32
 dm22: offset -1, type 8b5a, size 4, index -1, binding -1, stages 1, arrayStride 16, topLevelArrayStride 16
-m22: offset 208, type 8b5a, size 3, index 0, binding -1, stages 1, arrayStride 32, topLevelArrayStride 32
+m22: offset 208, type 8b5a, size 3, index 1, binding -1, stages 1, arrayStride 32, topLevelArrayStride 32
 nested.foo.n1.a: offset 0, type 1406, size 1, index 3, binding -1, stages 1
 nested.foo.n2.b: offset 16, type 1406, size 1, index 3, binding -1, stages 1
 nested.foo.n2.c: offset 20, type 1406, size 1, index 3, binding -1, stages 1
@@ -82,6 +89,7 @@ deepA[1].d2.d1[1].b: offset -1, type 8b56, size 1, index -1, binding -1, stages
 deepA[1].d2.d1[2].b: offset -1, type 8b56, size 1, index -1, binding -1, stages 1, topLevelArrayStride 176
 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
 buf1.runtimeArray: offset 4, type 1406, size 4, index 12, binding -1, stages 1, arrayStride 4, topLevelArrayStride 4
@@ -135,14 +143,10 @@ t[4].v[1].position: offset 312, type 1406, size 3, index 17, binding -1, stages
 t[4].v[1].normal: offset 324, type 1406, size 3, index 17, binding -1, stages 1, arrayStride 4, topLevelArrayStride 72
 t[4].v[2].position: offset 336, type 1406, size 3, index 17, binding -1, stages 1, arrayStride 4, topLevelArrayStride 72
 t[4].v[2].normal: offset 348, type 1406, size 3, index 17, binding -1, stages 1, arrayStride 4, topLevelArrayStride 72
-anonMember1: offset 0, type 8b51, size 1, index 0, binding -1, stages 1
-uf1: offset -1, type 1406, size 1, index -1, binding -1, stages 1
-uf2: offset -1, type 1406, size 1, index -1, binding -1, stages 1
-named.member3: offset 32, type 8b52, size 1, index 1, binding -1, stages 1
 
 Uniform block reflection:
-nameless: offset -1, type ffffffff, size 496, index -1, binding -1, stages 1, numMembers 9
 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
index 769f4c4..15bf1e1 100644 (file)
@@ -164,6 +164,7 @@ 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),
     LAST_ELEMENT_MARKER(GLSLANG_REFLECTION_COUNT),
 } glslang_reflection_options_t;
 
index 117c164..b678a36 100644 (file)
@@ -7593,6 +7593,8 @@ void TParseContext::declareBlock(const TSourceLoc& loc, TTypeList& typeList, con
     fixBlockLocations(loc, currentBlockQualifier, typeList, memberWithLocation, memberWithoutLocation);
     fixXfbOffsets(currentBlockQualifier, typeList);
     fixBlockUniformOffsets(currentBlockQualifier, typeList);
+    fixBlockUniformLayoutMatrix(currentBlockQualifier, &typeList, nullptr);
+    fixBlockUniformLayoutPacking(currentBlockQualifier, &typeList, nullptr);
     for (unsigned int member = 0; member < typeList.size(); ++member)
         layoutTypeCheck(typeList[member].loc, *typeList[member].type);
 
@@ -7963,6 +7965,101 @@ void TParseContext::fixBlockUniformOffsets(TQualifier& qualifier, TTypeList& typ
     }
 }
 
+//
+// Spread LayoutMatrix to uniform block member, if a uniform block member is a struct,
+// we need spread LayoutMatrix to this struct member too. and keep this rule for recursive.
+//
+void TParseContext::fixBlockUniformLayoutMatrix(TQualifier& qualifier, TTypeList* originTypeList,
+                                                TTypeList* tmpTypeList)
+{
+    assert(tmpTypeList == nullptr || originTypeList->size() == tmpTypeList->size());
+    for (unsigned int member = 0; member < originTypeList->size(); ++member) {
+        if (qualifier.layoutPacking != ElpNone) {
+            if (tmpTypeList == nullptr) {
+                if (((*originTypeList)[member].type->isMatrix() ||
+                     (*originTypeList)[member].type->getBasicType() == EbtStruct) &&
+                    (*originTypeList)[member].type->getQualifier().layoutMatrix == ElmNone) {
+                    (*originTypeList)[member].type->getQualifier().layoutMatrix = qualifier.layoutMatrix;
+                }
+            } else {
+                if (((*tmpTypeList)[member].type->isMatrix() ||
+                     (*tmpTypeList)[member].type->getBasicType() == EbtStruct) &&
+                    (*tmpTypeList)[member].type->getQualifier().layoutMatrix == ElmNone) {
+                    (*tmpTypeList)[member].type->getQualifier().layoutMatrix = qualifier.layoutMatrix;
+                }
+            }
+        }
+
+        if ((*originTypeList)[member].type->getBasicType() == EbtStruct) {
+            TQualifier* memberQualifier = nullptr;
+            // block member can be declare a matrix style, so it should be update to the member's style
+            if ((*originTypeList)[member].type->getQualifier().layoutMatrix == ElmNone) {
+                memberQualifier = &qualifier;
+            } else {
+                memberQualifier = &((*originTypeList)[member].type->getQualifier());
+            }
+
+            const TType* tmpType = tmpTypeList == nullptr ?
+                (*originTypeList)[member].type->clone() : (*tmpTypeList)[member].type;
+
+            fixBlockUniformLayoutMatrix(*memberQualifier, (*originTypeList)[member].type->getWritableStruct(),
+                                        tmpType->getWritableStruct());
+
+            const TTypeList* structure = recordStructCopy(matrixFixRecord, (*originTypeList)[member].type, tmpType);
+
+            if (tmpTypeList == nullptr) {
+                (*originTypeList)[member].type->setStruct(const_cast<TTypeList*>(structure));
+            }
+            if (tmpTypeList != nullptr) {
+                (*tmpTypeList)[member].type->setStruct(const_cast<TTypeList*>(structure));
+            }
+        }
+    }
+}
+
+//
+// Spread LayoutPacking to block member, if a  block member is a struct, we need spread LayoutPacking to
+// this struct member too. and keep this rule for recursive.
+//
+void TParseContext::fixBlockUniformLayoutPacking(TQualifier& qualifier, TTypeList* originTypeList,
+                                                 TTypeList* tmpTypeList)
+{
+    assert(tmpTypeList == nullptr || originTypeList->size() == tmpTypeList->size());
+    for (unsigned int member = 0; member < originTypeList->size(); ++member) {
+        if (qualifier.layoutPacking != ElpNone) {
+            if (tmpTypeList == nullptr) {
+                if ((*originTypeList)[member].type->getQualifier().layoutPacking == ElpNone) {
+                    (*originTypeList)[member].type->getQualifier().layoutPacking = qualifier.layoutPacking;
+                }
+            } else {
+                if ((*tmpTypeList)[member].type->getQualifier().layoutPacking == ElpNone) {
+                    (*tmpTypeList)[member].type->getQualifier().layoutPacking = qualifier.layoutPacking;
+                }
+            }
+        }
+
+        if ((*originTypeList)[member].type->getBasicType() == EbtStruct) {
+            // Deep copy the type in pool.
+            // Because, struct use in different block may have different layout qualifier.
+            // We have to new a object to distinguish between them.
+            const TType* tmpType = tmpTypeList == nullptr ?
+                (*originTypeList)[member].type->clone() : (*tmpTypeList)[member].type;
+
+            fixBlockUniformLayoutPacking(qualifier, (*originTypeList)[member].type->getWritableStruct(),
+                                         tmpType->getWritableStruct());
+
+            const TTypeList* structure = recordStructCopy(packingFixRecord, (*originTypeList)[member].type, tmpType);
+
+            if (tmpTypeList == nullptr) {
+                (*originTypeList)[member].type->setStruct(const_cast<TTypeList*>(structure));
+            }
+            if (tmpTypeList != nullptr) {
+                (*tmpTypeList)[member].type->setStruct(const_cast<TTypeList*>(structure));
+            }
+        }
+    }
+}
+
 // For an identifier that is already declared, add more qualification to it.
 void TParseContext::addQualifierToExisting(const TSourceLoc& loc, TQualifier qualifier, const TString& identifier)
 {
@@ -8421,5 +8518,43 @@ TIntermNode* TParseContext::addSwitch(const TSourceLoc& loc, TIntermTyped* expre
     return switchNode;
 }
 
+//
+// When a struct used in block, and has it's own layout packing, layout matrix,
+// record the origin structure of a struct to map, and Record the structure copy to the copy table,
+//
+const TTypeList* TParseContext::recordStructCopy(TStructRecord& record, const TType* originType, const TType* tmpType)
+{
+    size_t memberCount = tmpType->getStruct()->size();
+    size_t originHash = 0, tmpHash = 0;
+    std::hash<size_t> hasher;
+    for (uint32_t i = 0; i < memberCount; i++) {
+        size_t originMemberHash = hasher(originType->getStruct()->at(i).type->getQualifier().layoutPacking +
+                                         originType->getStruct()->at(i).type->getQualifier().layoutMatrix);
+        size_t tmpMemberHash = hasher(tmpType->getStruct()->at(i).type->getQualifier().layoutPacking +
+                                      tmpType->getStruct()->at(i).type->getQualifier().layoutMatrix);
+        originHash = hasher((originHash ^ originMemberHash) << 1);
+        tmpHash = hasher((tmpHash ^ tmpMemberHash) << 1);
+    }
+    const TTypeList* originStruct = originType->getStruct();
+    const TTypeList* tmpStruct = tmpType->getStruct();
+    if (originHash != tmpHash) {
+        auto fixRecords = record.find(originStruct);
+        if (fixRecords != record.end()) {
+            auto fixRecord = fixRecords->second.find(tmpHash);
+            if (fixRecord != fixRecords->second.end()) {
+                return fixRecord->second;
+            } else {
+                record[originStruct][tmpHash] = tmpStruct;
+                return tmpStruct;
+            }
+        } else {
+            record[originStruct] = std::map<size_t, const TTypeList*>();
+            record[originStruct][tmpHash] = tmpStruct;
+            return tmpStruct;
+        }
+    }
+    return originStruct;
+}
+
 } // end namespace glslang
 
index 9c5fdc7..8b262c9 100644 (file)
@@ -68,6 +68,7 @@ class TScanContext;
 class TPpContext;
 
 typedef std::set<int> TIdSetType;
+typedef std::map<const TTypeList*, std::map<size_t, const TTypeList*>> TStructRecord;
 
 //
 // Sharable code (as well as what's in TParseVersions) across
@@ -418,12 +419,15 @@ public:
     void fixBlockLocations(const TSourceLoc&, TQualifier&, TTypeList&, bool memberWithLocation, bool memberWithoutLocation);
     void fixXfbOffsets(TQualifier&, TTypeList&);
     void fixBlockUniformOffsets(TQualifier&, TTypeList&);
+    void fixBlockUniformLayoutMatrix(TQualifier&, TTypeList*, TTypeList*);
+    void fixBlockUniformLayoutPacking(TQualifier&, TTypeList*, TTypeList*);
     void addQualifierToExisting(const TSourceLoc&, TQualifier, const TString& identifier);
     void addQualifierToExisting(const TSourceLoc&, TQualifier, TIdentifierList&);
     void invariantCheck(const TSourceLoc&, const TQualifier&);
     void updateStandaloneQualifierDefaults(const TSourceLoc&, const TPublicType&);
     void wrapupSwitchSubsequence(TIntermAggregate* statements, TIntermNode* branchNode);
     TIntermNode* addSwitch(const TSourceLoc&, TIntermTyped* expression, TIntermAggregate* body);
+    const TTypeList* recordStructCopy(TStructRecord&, const TType*, const TType*);
 
 #ifndef GLSLANG_WEB
     TAttributeType attributeFromName(const TString& name) const;
@@ -484,6 +488,8 @@ protected:
     bool anyIndexLimits;
     TIdSetType inductiveLoopIds;
     TVector<TIntermTyped*> needsIndexLimitationChecking;
+    TStructRecord matrixFixRecord;
+    TStructRecord packingFixRecord;
 
     //
     // Geometry shader input arrays:
index 2876933..7694660 100644 (file)
@@ -77,10 +77,10 @@ namespace glslang {
 // This is in the glslang namespace directly so it can be a friend of TReflection.
 //
 
-class TReflectionTraverser : public TLiveTraverser {
+class TReflectionTraverser : public TIntermTraverser {
 public:
     TReflectionTraverser(const TIntermediate& i, TReflection& r) :
-         TLiveTraverser(i), reflection(r) { }
+                            TIntermTraverser(), intermediate(i), reflection(r), updateStageMasks(true) { }
 
     virtual bool visitBinary(TVisit, TIntermBinary* node);
     virtual void visitSymbol(TIntermSymbol* base);
@@ -92,11 +92,37 @@ public:
         if (processedDerefs.find(&base) == processedDerefs.end()) {
             processedDerefs.insert(&base);
 
+            uint32_t blockIndex = -1;
+            uint32_t offset     = -1;
+            TList<TIntermBinary*> derefs;
+            TString baseName = base.getName();
+
+            if (base.getType().getBasicType() == EbtBlock) {
+                offset = 0;
+                bool anonymous = IsAnonymous(baseName);
+                const TString& blockName = base.getType().getTypeName();
+
+                if (!anonymous)
+                    baseName = blockName;
+                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()));
+            }
+
             // Use a degenerate (empty) set of dereferences to immediately put as at the end of
             // the dereference change expected by blowUpActiveAggregate.
-            TList<TIntermBinary*> derefs;
-            blowUpActiveAggregate(base.getType(), base.getName(), derefs, derefs.end(), -1, -1, 0, 0,
-                                  base.getQualifier().storage, true);
+            blowUpActiveAggregate(base.getType(), baseName, derefs, derefs.end(), offset, blockIndex, 0, 0,
+                                  base.getQualifier().storage, updateStageMasks);
         }
     }
 
@@ -155,9 +181,9 @@ public:
     void getOffsets(const TType& type, TVector<int>& offsets)
     {
         const TTypeList& memberList = *type.getStruct();
-
         int memberSize = 0;
         int offset = 0;
+
         for (size_t m = 0; m < offsets.size(); ++m) {
             // if the user supplied an offset, snap to it now
             if (memberList[m].type->getQualifier().hasOffset())
@@ -334,7 +360,8 @@ public:
 
                 for (int i = 0; i < arrayIterateSize; ++i) {
                     TString newBaseName = name;
-                    newBaseName.append(TString("[") + String(i) + "]");
+                    if (terminalType->getBasicType() != EbtBlock)
+                        newBaseName.append(TString("[") + String(i) + "]");
                     TType derefType(*terminalType, 0);
                     if (offset >= 0)
                         offset = baseOffset + stride * i;
@@ -643,13 +670,17 @@ public:
 
             blocks.back().numMembers = countAggregateMembers(type);
 
-            EShLanguageMask& stages = blocks.back().stages;
-            stages = static_cast<EShLanguageMask>(stages | 1 << intermediate.getStage());
+            if (updateStageMasks) {
+                EShLanguageMask& stages = blocks.back().stages;
+                stages = static_cast<EShLanguageMask>(stages | 1 << intermediate.getStage());
+            }
         } else {
             blockIndex = it->second;
 
-            EShLanguageMask& stages = blocks[blockIndex].stages;
-            stages = static_cast<EShLanguageMask>(stages | 1 << intermediate.getStage());
+            if (updateStageMasks) {
+                EShLanguageMask& stages = blocks[blockIndex].stages;
+                stages = static_cast<EShLanguageMask>(stages | 1 << intermediate.getStage());
+            }
         }
 
         return blockIndex;
@@ -995,8 +1026,10 @@ public:
         return type.isArray() ? type.getOuterArraySize() : 1;
     }
 
+    const TIntermediate& intermediate;
     TReflection& reflection;
     std::set<const TIntermNode*> processedDerefs;
+    bool updateStageMasks;
 
 protected:
     TReflectionTraverser(TReflectionTraverser&);
@@ -1029,8 +1062,15 @@ bool TReflectionTraverser::visitBinary(TVisit /* visit */, TIntermBinary* node)
 // To reflect non-dereferenced objects.
 void TReflectionTraverser::visitSymbol(TIntermSymbol* base)
 {
-    if (base->getQualifier().storage == EvqUniform)
-        addUniform(*base);
+    if (base->getQualifier().storage == EvqUniform) {
+        if (base->getBasicType() == EbtBlock) {
+            if (reflection.options & EShReflectionSharedStd140Blocks) {
+                addUniform(*base);
+            }
+        } else {
+            addUniform(*base);
+        }
+    }
 
     if ((intermediate.getStage() == reflection.firstStage && base->getQualifier().isPipeInput()) ||
         (intermediate.getStage() == reflection.lastStage && base->getQualifier().isPipeOutput()))
@@ -1135,15 +1175,39 @@ bool TReflection::addStage(EShLanguage stage, const TIntermediate& intermediate)
 
     TReflectionTraverser it(intermediate, *this);
 
-    // put the entry point on the list of functions to process
-    it.pushFunction(intermediate.getEntryPointMangledName().c_str());
-
-    // process all the functions
-    while (! it.functions.empty()) {
-        TIntermNode* function = it.functions.back();
-        it.functions.pop_back();
-        function->traverse(&it);
+    for (auto& sequnence : intermediate.getTreeRoot()->getAsAggregate()->getSequence()) {
+        if (sequnence->getAsAggregate() != nullptr) {
+            if (sequnence->getAsAggregate()->getOp() == glslang::EOpLinkerObjects) {
+                it.updateStageMasks = false;
+                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) {
+                            // collect std140 and shared uniform block form AST
+                            if (pNode->getQualifier().layoutPacking == ElpStd140 ||
+                                pNode->getQualifier().layoutPacking == ElpShared) {
+                                pNode->traverse(&it);
+                            }
+                        }
+                    }
+                }
+            } else {
+                // This traverser will travers all function in AST.
+                // If we want reflect uncalled function, we need set linke message EShMsgKeepUncalled.
+                // When EShMsgKeepUncalled been set to true, all function will be keep in AST, even it is a uncalled function.
+                // This will keep some uniform variables in reflection, if those uniform variables is used in these uncalled function.
+                //
+                // If we just want reflect only live node, we can use a default link message or set EShMsgKeepUncalled false.
+                // When linke message not been set EShMsgKeepUncalled, linker won't keep uncalled function in AST.
+                // So, travers all function node can equivalent to travers live function.
+                it.updateStageMasks = true;
+                sequnence->getAsAggregate()->traverse(&it);
+            }
+        }
     }
+    it.updateStageMasks = true;
 
     buildCounterIndices(intermediate);
     buildUniformStageMask(intermediate);
old mode 100755 (executable)
new mode 100644 (file)
index ad98494..8ce6541
@@ -264,13 +264,14 @@ enum EShMessages : unsigned {
 // Options for building reflection
 //
 typedef enum {
-    EShReflectionDefault           = 0,        // default is original behaviour before options were added
-    EShReflectionStrictArraySuffix = (1 << 0), // reflection will follow stricter rules for array-of-structs suffixes
-    EShReflectionBasicArraySuffix  = (1 << 1), // arrays of basic types will be appended with [0] as in GL reflection
-    EShReflectionIntermediateIO    = (1 << 2), // reflect inputs and outputs to program, even with no vertex shader
-    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
+    EShReflectionDefault            = 0,        // default is original behaviour before options were added
+    EShReflectionStrictArraySuffix  = (1 << 0), // reflection will follow stricter rules for array-of-structs suffixes
+    EShReflectionBasicArraySuffix   = (1 << 1), // arrays of basic types will be appended with [0] as in GL reflection
+    EShReflectionIntermediateIO     = (1 << 2), // reflect inputs and outputs to program, even with no vertex shader
+    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
     LAST_ELEMENT_MARKER(EShReflectionCount),
 } EShReflectionOptions;