Updated glslang.

This commit is contained in:
Бранимир Караџић
2019-08-09 20:14:59 -07:00
parent 52e1fb9d9f
commit 4386b7770e
22 changed files with 1421 additions and 546 deletions

View File

@@ -88,10 +88,14 @@ if(${CMAKE_CXX_COMPILER_ID} MATCHES "GNU")
add_compile_options(-Wall -Wmaybe-uninitialized -Wuninitialized -Wunused -Wunused-local-typedefs
-Wunused-parameter -Wunused-value -Wunused-variable -Wunused-but-set-parameter -Wunused-but-set-variable -fno-exceptions)
add_compile_options(-Wno-reorder) # disable this from -Wall, since it happens all over.
add_compile_options(-fno-rtti)
elseif(${CMAKE_CXX_COMPILER_ID} MATCHES "Clang")
add_compile_options(-Wall -Wuninitialized -Wunused -Wunused-local-typedefs
-Wunused-parameter -Wunused-value -Wunused-variable)
add_compile_options(-Wno-reorder) # disable this from -Wall, since it happens all over.
add_compile_options(-fno-rtti)
elseif(${CMAKE_CXX_COMPILER_ID} MATCHES "MSVC")
add_compile_options(/GR-) # Disable RTTI
endif()
# Request C++11
@@ -105,8 +109,6 @@ else()
set(CMAKE_CXX_EXTENSIONS OFF)
endif()
add_compile_options(-fno-rtti)
function(glslang_set_link_args TARGET)
# For MinGW compiles, statically link against the GCC and C++ runtimes.
# This avoids the need to ship those runtimes as DLLs.

0
3rdparty/glslang/LICENSE.txt vendored Executable file → Normal file
View File

View File

@@ -210,6 +210,7 @@ protected:
}
std::pair<spv::Id, spv::Id> getForcedType(spv::BuiltIn, const glslang::TType&);
spv::Id translateForcedType(spv::Id object);
spv::Id createCompositeConstruct(spv::Id typeId, std::vector<spv::Id> constituents);
glslang::SpvOptions& options;
spv::Function* shaderEntry;
@@ -2172,6 +2173,39 @@ bool TGlslangToSpvTraverser::visitUnary(glslang::TVisit /* visit */, glslang::TI
}
}
// Construct a composite object, recursively copying members if their types don't match
spv::Id TGlslangToSpvTraverser::createCompositeConstruct(spv::Id resultTypeId, std::vector<spv::Id> constituents)
{
for (int c = 0; c < (int)constituents.size(); ++c) {
spv::Id& constituent = constituents[c];
spv::Id lType = builder.getContainedTypeId(resultTypeId, c);
spv::Id rType = builder.getTypeId(constituent);
if (lType != rType) {
if (glslangIntermediate->getSpv().spv >= glslang::EShTargetSpv_1_4) {
constituent = builder.createUnaryOp(spv::OpCopyLogical, lType, constituent);
} else if (builder.isStructType(rType)) {
std::vector<spv::Id> rTypeConstituents;
int numrTypeConstituents = builder.getNumTypeConstituents(rType);
for (int i = 0; i < numrTypeConstituents; ++i) {
rTypeConstituents.push_back(builder.createCompositeExtract(constituent, builder.getContainedTypeId(rType, i), i));
}
constituents[c] = createCompositeConstruct(lType, rTypeConstituents);
} else {
assert(builder.isArrayType(rType));
std::vector<spv::Id> rTypeConstituents;
int numrTypeConstituents = builder.getNumTypeConstituents(rType);
spv::Id elementRType = builder.getContainedTypeId(rType);
for (int i = 0; i < numrTypeConstituents; ++i) {
rTypeConstituents.push_back(builder.createCompositeExtract(constituent, elementRType, i));
}
constituents[c] = createCompositeConstruct(lType, rTypeConstituents);
}
}
}
return builder.createCompositeConstruct(resultTypeId, constituents);
}
bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TIntermAggregate* node)
{
SpecConstantOpModeGuard spec_constant_op_mode_setter(&builder);
@@ -2413,7 +2447,7 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
std::vector<spv::Id> constituents;
for (int c = 0; c < (int)arguments.size(); ++c)
constituents.push_back(arguments[c]);
constructed = builder.createCompositeConstruct(resultType(), constituents);
constructed = createCompositeConstruct(resultType(), constituents);
} else if (isMatrix)
constructed = builder.createMatrixConstructor(precision, arguments, resultType());
else

View File

@@ -412,7 +412,6 @@ const char* BuiltInString(int builtIn)
case 5264: return "FullyCoveredEXT";
#ifdef NV_EXTENSIONS
case BuiltInTaskCountNV: return "TaskCountNV";
case BuiltInPrimitiveCountNV: return "PrimitiveCountNV";

View File

@@ -269,7 +269,7 @@ ERROR: node is still EOpNull!
0:117 'gl_InstanceID' ( gl_InstanceId highp int InstanceId)
0:118 move second child to first child ( temp highp 4-component vector of float)
0:118 gl_Position: direct index for structure ( gl_Position highp 4-component vector of float Position)
0:118 'anon@1' ( out block{ gl_Position highp 4-component vector of float Position gl_Position, })
0:118 'anon@1' ( out block{ gl_Position highp 4-component vector of float Position gl_Position})
0:118 Constant:
0:118 0 (const uint)
0:118 Constant:
@@ -278,7 +278,7 @@ ERROR: node is still EOpNull!
0:118 1.000000
0:118 1.000000
0:119 gl_PointSize: direct index for structure ( gl_PointSize highp void PointSize)
0:119 'anon@1' ( out block{ gl_Position highp 4-component vector of float Position gl_Position, })
0:119 'anon@1' ( out block{ gl_Position highp 4-component vector of float Position gl_Position})
0:119 Constant:
0:119 1 (const uint)
0:153 Function Definition: pfooBad( ( global void)
@@ -940,7 +940,7 @@ ERROR: node is still EOpNull!
0:? 'anon@0' ( out block{layout( location=12) out highp int aAnon, layout( location=13) out highp 4-component vector of float vAnon})
0:? 'aliased' (layout( location=12) smooth out highp int)
0:? 'inbinst' ( in block{ in highp int a})
0:? 'anon@1' ( out block{ gl_Position highp 4-component vector of float Position gl_Position, })
0:? 'anon@1' ( out block{ gl_Position highp 4-component vector of float Position gl_Position})
0:? 'smon' ( smooth out block{ out highp int i})
0:? 'fmon' ( flat out block{ out highp int i})
0:? 'cmon' ( centroid out block{ out highp int i})
@@ -1184,7 +1184,7 @@ ERROR: node is still EOpNull!
0:? 'anon@0' ( out block{layout( location=12) out highp int aAnon, layout( location=13) out highp 4-component vector of float vAnon})
0:? 'aliased' (layout( location=12) smooth out highp int)
0:? 'inbinst' ( in block{ in highp int a})
0:? 'anon@1' ( out block{ gl_Position highp 4-component vector of float Position gl_Position, })
0:? 'anon@1' ( out block{ gl_Position highp 4-component vector of float Position gl_Position})
0:? 'smon' ( smooth out block{ out highp int i})
0:? 'fmon' ( flat out block{ out highp int i})
0:? 'cmon' ( centroid out block{ out highp int i})

View File

@@ -49,7 +49,7 @@ ERROR: node is still EOpNull!
0:26 'gl_InstanceID' ( gl_InstanceId highp int InstanceId)
0:27 move second child to first child ( temp highp 4-component vector of float)
0:27 gl_Position: direct index for structure ( gl_Position highp 4-component vector of float Position)
0:27 'anon@1' ( out block{ gl_Position highp 4-component vector of float Position gl_Position, })
0:27 'anon@1' ( out block{ gl_Position highp 4-component vector of float Position gl_Position})
0:27 Constant:
0:27 0 (const uint)
0:27 Constant:
@@ -58,7 +58,7 @@ ERROR: node is still EOpNull!
0:27 1.000000
0:27 1.000000
0:28 gl_PointSize: direct index for structure ( gl_PointSize highp void PointSize)
0:28 'anon@1' ( out block{ gl_Position highp 4-component vector of float Position gl_Position, })
0:28 'anon@1' ( out block{ gl_Position highp 4-component vector of float Position gl_Position})
0:28 Constant:
0:28 1 (const uint)
0:62 Function Definition: pfoo( ( global void)
@@ -623,7 +623,7 @@ ERROR: node is still EOpNull!
0:? 'anon@0' ( out block{layout( location=12) out highp int aAnon, layout( location=13) out highp 4-component vector of float vAnon})
0:? 'aliased' (layout( location=12) smooth out highp int)
0:? 'inbinst' ( in block{ in highp int a})
0:? 'anon@1' ( out block{ gl_Position highp 4-component vector of float Position gl_Position, })
0:? 'anon@1' ( out block{ gl_Position highp 4-component vector of float Position gl_Position})
0:? 'smon' ( smooth out block{ out highp int i})
0:? 'fmon' ( flat out block{ out highp int i})
0:? 'cmon' ( centroid out block{ out highp int i})
@@ -709,7 +709,7 @@ ERROR: node is still EOpNull!
0:26 'gl_InstanceID' ( gl_InstanceId highp int InstanceId)
0:27 move second child to first child ( temp highp 4-component vector of float)
0:27 gl_Position: direct index for structure ( gl_Position highp 4-component vector of float Position)
0:27 'anon@1' ( out block{ gl_Position highp 4-component vector of float Position gl_Position, })
0:27 'anon@1' ( out block{ gl_Position highp 4-component vector of float Position gl_Position})
0:27 Constant:
0:27 0 (const uint)
0:27 Constant:
@@ -718,7 +718,7 @@ ERROR: node is still EOpNull!
0:27 1.000000
0:27 1.000000
0:28 gl_PointSize: direct index for structure ( gl_PointSize highp void PointSize)
0:28 'anon@1' ( out block{ gl_Position highp 4-component vector of float Position gl_Position, })
0:28 'anon@1' ( out block{ gl_Position highp 4-component vector of float Position gl_Position})
0:28 Constant:
0:28 1 (const uint)
0:? Linker Objects
@@ -726,7 +726,7 @@ ERROR: node is still EOpNull!
0:? 'anon@0' ( out block{layout( location=12) out highp int aAnon, layout( location=13) out highp 4-component vector of float vAnon})
0:? 'aliased' (layout( location=12) smooth out highp int)
0:? 'inbinst' ( in block{ in highp int a})
0:? 'anon@1' ( out block{ gl_Position highp 4-component vector of float Position gl_Position, })
0:? 'anon@1' ( out block{ gl_Position highp 4-component vector of float Position gl_Position})
0:? 'smon' ( smooth out block{ out highp int i})
0:? 'fmon' ( flat out block{ out highp int i})
0:? 'cmon' ( centroid out block{ out highp int i})

View File

@@ -71,7 +71,7 @@ ERROR: node is still EOpNull!
0:23 move second child to first child ( temp 4-component vector of float)
0:23 'c' ( temp 4-component vector of float)
0:23 gl_Color: direct index for structure ( in 4-component vector of float Color)
0:23 'anon@0' ( in block{ in 4-component vector of float Color gl_Color, })
0:23 'anon@0' ( in block{ in 4-component vector of float Color gl_Color})
0:23 Constant:
0:23 2 (const uint)
0:24 move second child to first child ( temp 4-component vector of float)
@@ -93,7 +93,7 @@ ERROR: node is still EOpNull!
0:? 'inVar' ( smooth in 4-component vector of float)
0:? 'outVar' (layout( location=0 index=0) out 4-component vector of float)
0:? 'varyingVar' ( smooth in 4-component vector of float)
0:? 'anon@0' ( in block{ in 4-component vector of float Color gl_Color, })
0:? 'anon@0' ( in block{ in 4-component vector of float Color gl_Color})
0:? 'gl_name' ( in block{ in int gl_i})
0:? 'start' ( const int)
0:? 6 (const int)
@@ -158,7 +158,7 @@ ERROR: node is still EOpNull!
0:? 'inVar' ( smooth in 4-component vector of float)
0:? 'outVar' (layout( location=0 index=0) out 4-component vector of float)
0:? 'varyingVar' ( smooth in 4-component vector of float)
0:? 'anon@0' ( in block{ in 4-component vector of float Color gl_Color, })
0:? 'anon@0' ( in block{ in 4-component vector of float Color gl_Color})
0:? 'gl_name' ( in block{ in int gl_i})
0:? 'start' ( const int)
0:? 6 (const int)

View File

@@ -38,12 +38,12 @@ ERROR: node is still EOpNull!
0:30 0 (const int)
0:31 move second child to first child ( temp float)
0:31 gl_PointSize: direct index for structure (layout( stream=0) gl_PointSize float PointSize)
0:31 'anon@0' (layout( stream=0) out block{layout( stream=0) gl_PointSize float PointSize gl_PointSize, })
0:31 'anon@0' (layout( stream=0) out block{layout( stream=0) gl_PointSize float PointSize gl_PointSize})
0:31 Constant:
0:31 1 (const uint)
0:31 'p' ( temp float)
0:33 gl_Position: direct index for structure (layout( stream=0) gl_Position void Position)
0:33 'anon@0' (layout( stream=0) out block{layout( stream=0) gl_PointSize float PointSize gl_PointSize, })
0:33 'anon@0' (layout( stream=0) out block{layout( stream=0) gl_PointSize float PointSize gl_PointSize})
0:33 Constant:
0:33 0 (const uint)
0:36 Function Definition: foo5( ( global float)
@@ -54,7 +54,7 @@ ERROR: node is still EOpNull!
0:38 4.000000
0:? Linker Objects
0:? 'gl_in' ( in unsized 2-element array of block{ in float PointSize gl_PointSize})
0:? 'anon@0' (layout( stream=0) out block{layout( stream=0) gl_PointSize float PointSize gl_PointSize, })
0:? 'anon@0' (layout( stream=0) out block{layout( stream=0) gl_PointSize float PointSize gl_PointSize})
Linked geometry stage:
@@ -78,5 +78,5 @@ ERROR: node is still EOpNull!
0:5 7 (const int)
0:? Linker Objects
0:? 'gl_in' ( in 2-element array of block{ in float PointSize gl_PointSize})
0:? 'anon@0' (layout( stream=0) out block{layout( stream=0) gl_PointSize float PointSize gl_PointSize, })
0:? 'anon@0' (layout( stream=0) out block{layout( stream=0) gl_PointSize float PointSize gl_PointSize})

View File

@@ -281,7 +281,7 @@ ERROR: node is still EOpNull!
0:? 'sampb3' (layout( binding=80) uniform sampler2D)
0:? 'sampb4' (layout( binding=31) uniform sampler2D)
0:? 'sampb5' (layout( binding=79) uniform 2-element array of sampler2D)
0:? 'anon@3' ( out block{ out 4-element array of float ClipDistance gl_ClipDistance, })
0:? 'anon@3' ( out block{ out 4-element array of float ClipDistance gl_ClipDistance})
0:? 'patchIn' ( patch in 4-component vector of float)
0:? 'patchOut' ( smooth patch out 4-component vector of float)
0:? 'comma0' ( temp int)
@@ -363,7 +363,7 @@ ERROR: node is still EOpNull!
0:? 'sampb3' (layout( binding=80) uniform sampler2D)
0:? 'sampb4' (layout( binding=31) uniform sampler2D)
0:? 'sampb5' (layout( binding=79) uniform 2-element array of sampler2D)
0:? 'anon@3' ( out block{ out 4-element array of float ClipDistance gl_ClipDistance, })
0:? 'anon@3' ( out block{ out 4-element array of float ClipDistance gl_ClipDistance})
0:? 'patchIn' ( patch in 4-component vector of float)
0:? 'patchOut' ( smooth patch out 4-component vector of float)
0:? 'comma0' ( temp int)

View File

@@ -78,7 +78,7 @@ ERROR: node is still EOpNull!
0:16 move second child to first child ( temp float)
0:16 direct index ( temp float ClipDistance)
0:16 gl_ClipDistance: direct index for structure ( out 17-element array of float ClipDistance)
0:16 'anon@0' ( out block{ out 17-element array of float ClipDistance gl_ClipDistance, })
0:16 'anon@0' ( out block{ out 17-element array of float ClipDistance gl_ClipDistance})
0:16 Constant:
0:16 2 (const uint)
0:16 Constant:
@@ -206,7 +206,7 @@ ERROR: node is still EOpNull!
0:? 'uv4' (layout( location=4) uniform 4-component vector of float)
0:? 'b1' (layout( location=2) in block{ in 4-component vector of float v})
0:? 'b2' (layout( location=2) out block{ out 4-component vector of float v})
0:? 'anon@0' ( out block{ out 17-element array of float ClipDistance gl_ClipDistance, })
0:? 'anon@0' ( out block{ out 17-element array of float ClipDistance gl_ClipDistance})
0:? 'cs' (layout( location=10) smooth out 2-element array of structure{ global 7-element array of 3X2 matrix of float m, global float f})
0:? 'cf' (layout( location=54) smooth out float)
0:? 'cg' (layout( location=53) smooth out float)
@@ -281,7 +281,7 @@ ERROR: node is still EOpNull!
0:? 'uv4' (layout( location=4) uniform 4-component vector of float)
0:? 'b1' (layout( location=2) in block{ in 4-component vector of float v})
0:? 'b2' (layout( location=2) out block{ out 4-component vector of float v})
0:? 'anon@0' ( out block{ out 17-element array of float ClipDistance gl_ClipDistance, })
0:? 'anon@0' ( out block{ out 17-element array of float ClipDistance gl_ClipDistance})
0:? 'cs' (layout( location=10) smooth out 2-element array of structure{ global 7-element array of 3X2 matrix of float m, global float f})
0:? 'cf' (layout( location=54) smooth out float)
0:? 'cg' (layout( location=53) smooth out float)

View File

@@ -156,7 +156,7 @@ ERROR: node is still EOpNull!
0:? 'bbinst9' ( out block{layout( xfb_buffer=4 xfb_offset=1) out bool b, layout( xfb_buffer=4 xfb_offset=12) out structure{ global bool b, global structure{ global int i, global double d, global float f} s, global 2-component vector of float v2} t, layout( xfb_buffer=4 xfb_offset=52) out 3X3 matrix of float m3, layout( xfb_buffer=4 xfb_offset=90) out int i, layout( xfb_buffer=4 xfb_offset=98) out double d, layout( xfb_buffer=4 xfb_offset=108) out structure{ global int a} s})
0:? 'bm' (layout( xfb_buffer=5 xfb_offset=0) smooth out float)
0:? 'bbinst10' ( out block{layout( xfb_buffer=7 xfb_offset=0) out 4X4 matrix of double m1, layout( xfb_buffer=7 xfb_offset=128) out 4X4 matrix of double m2, layout( xfb_buffer=7 xfb_offset=256) out float f})
0:? 'anon@0' ( out block{layout( xfb_buffer=3 xfb_offset=36) gl_Position 4-component vector of float Position gl_Position, layout( xfb_buffer=3 xfb_offset=32) gl_PointSize float PointSize gl_PointSize, })
0:? 'anon@0' ( out block{layout( xfb_buffer=3 xfb_offset=36) gl_Position 4-component vector of float Position gl_Position, layout( xfb_buffer=3 xfb_offset=32) gl_PointSize float PointSize gl_PointSize})
0:? 'gl_VertexID' ( gl_VertexId int VertexId)
0:? 'gl_InstanceID' ( gl_InstanceId int InstanceId)
@@ -241,7 +241,7 @@ ERROR: node is still EOpNull!
0:? 'bbinst9' ( out block{layout( xfb_buffer=4 xfb_offset=1) out bool b, layout( xfb_buffer=4 xfb_offset=12) out structure{ global bool b, global structure{ global int i, global double d, global float f} s, global 2-component vector of float v2} t, layout( xfb_buffer=4 xfb_offset=52) out 3X3 matrix of float m3, layout( xfb_buffer=4 xfb_offset=90) out int i, layout( xfb_buffer=4 xfb_offset=98) out double d, layout( xfb_buffer=4 xfb_offset=108) out structure{ global int a} s})
0:? 'bm' (layout( xfb_buffer=5 xfb_offset=0) smooth out float)
0:? 'bbinst10' ( out block{layout( xfb_buffer=7 xfb_offset=0) out 4X4 matrix of double m1, layout( xfb_buffer=7 xfb_offset=128) out 4X4 matrix of double m2, layout( xfb_buffer=7 xfb_offset=256) out float f})
0:? 'anon@0' ( out block{layout( xfb_buffer=3 xfb_offset=36) gl_Position 4-component vector of float Position gl_Position, layout( xfb_buffer=3 xfb_offset=32) gl_PointSize float PointSize gl_PointSize, })
0:? 'anon@0' ( out block{layout( xfb_buffer=3 xfb_offset=36) gl_Position 4-component vector of float Position gl_Position, layout( xfb_buffer=3 xfb_offset=32) gl_PointSize float PointSize gl_PointSize})
0:? 'gl_VertexID' ( gl_VertexId int VertexId)
0:? 'gl_InstanceID' ( gl_InstanceId int InstanceId)

View File

@@ -0,0 +1,62 @@
spv.1.4.constructComposite.comp
// Module Version 10400
// Generated by (magic number): 80007
// Id's are bound by 27
Capability Shader
1: ExtInstImport "GLSL.std.450"
MemoryModel Logical GLSL450
EntryPoint GLCompute 4 "main" 10 15
ExecutionMode 4 LocalSize 64 1 1
Source GLSL 460
Name 4 "main"
Name 7 "sA"
MemberName 7(sA) 0 "x"
MemberName 7(sA) 1 "y"
Name 8 "sC"
MemberName 8(sC) 0 "state"
Name 10 "c"
Name 11 "sA"
MemberName 11(sA) 0 "x"
MemberName 11(sA) 1 "y"
Name 12 "sB"
MemberName 12(sB) 0 "a"
Name 13 "ubo"
MemberName 13(ubo) 0 "b"
Name 15 ""
MemberDecorate 11(sA) 0 Offset 0
MemberDecorate 11(sA) 1 Offset 4
MemberDecorate 12(sB) 0 Offset 0
MemberDecorate 13(ubo) 0 Offset 0
Decorate 13(ubo) Block
Decorate 15 DescriptorSet 0
Decorate 15 Binding 0
Decorate 26 BuiltIn WorkgroupSize
2: TypeVoid
3: TypeFunction 2
6: TypeInt 32 1
7(sA): TypeStruct 6(int) 6(int)
8(sC): TypeStruct 7(sA)
9: TypePointer Private 8(sC)
10(c): 9(ptr) Variable Private
11(sA): TypeStruct 6(int) 6(int)
12(sB): TypeStruct 11(sA)
13(ubo): TypeStruct 12(sB)
14: TypePointer Uniform 13(ubo)
15: 14(ptr) Variable Uniform
16: 6(int) Constant 0
17: TypePointer Uniform 11(sA)
22: TypeInt 32 0
23: TypeVector 22(int) 3
24: 22(int) Constant 64
25: 22(int) Constant 1
26: 23(ivec3) ConstantComposite 24 25 25
4(main): 2 Function None 3
5: Label
18: 17(ptr) AccessChain 15 16 16
19: 11(sA) Load 18
20: 7(sA) CopyLogical 19
21: 8(sC) CompositeConstruct 20
Store 10(c) 21
Return
FunctionEnd

View File

@@ -0,0 +1,64 @@
spv.constructComposite.comp
// Module Version 10000
// Generated by (magic number): 80007
// Id's are bound by 29
Capability Shader
1: ExtInstImport "GLSL.std.450"
MemoryModel Logical GLSL450
EntryPoint GLCompute 4 "main"
ExecutionMode 4 LocalSize 64 1 1
Source GLSL 460
Name 4 "main"
Name 7 "sA"
MemberName 7(sA) 0 "x"
MemberName 7(sA) 1 "y"
Name 8 "sC"
MemberName 8(sC) 0 "state"
Name 10 "c"
Name 11 "sA"
MemberName 11(sA) 0 "x"
MemberName 11(sA) 1 "y"
Name 12 "sB"
MemberName 12(sB) 0 "a"
Name 13 "ubo"
MemberName 13(ubo) 0 "b"
Name 15 ""
MemberDecorate 11(sA) 0 Offset 0
MemberDecorate 11(sA) 1 Offset 4
MemberDecorate 12(sB) 0 Offset 0
MemberDecorate 13(ubo) 0 Offset 0
Decorate 13(ubo) Block
Decorate 15 DescriptorSet 0
Decorate 15 Binding 0
Decorate 28 BuiltIn WorkgroupSize
2: TypeVoid
3: TypeFunction 2
6: TypeInt 32 1
7(sA): TypeStruct 6(int) 6(int)
8(sC): TypeStruct 7(sA)
9: TypePointer Private 8(sC)
10(c): 9(ptr) Variable Private
11(sA): TypeStruct 6(int) 6(int)
12(sB): TypeStruct 11(sA)
13(ubo): TypeStruct 12(sB)
14: TypePointer Uniform 13(ubo)
15: 14(ptr) Variable Uniform
16: 6(int) Constant 0
17: TypePointer Uniform 11(sA)
24: TypeInt 32 0
25: TypeVector 24(int) 3
26: 24(int) Constant 64
27: 24(int) Constant 1
28: 25(ivec3) ConstantComposite 26 27 27
4(main): 2 Function None 3
5: Label
18: 17(ptr) AccessChain 15 16 16
19: 11(sA) Load 18
20: 6(int) CompositeExtract 19 0
21: 6(int) CompositeExtract 19 1
22: 7(sA) CompositeConstruct 20 21
23: 8(sC) CompositeConstruct 22
Store 10(c) 23
Return
FunctionEnd

View File

@@ -0,0 +1,25 @@
#version 460 core
layout(local_size_x=64) in;
struct sA {
int x, y;
};
struct sB {
sA a;
};
layout(binding=0,set=0) uniform ubo {
sB b;
};
struct sC {
sA state;
} c = {
b.a,
};
void main()
{
}

View File

@@ -0,0 +1,25 @@
#version 460 core
layout(local_size_x=64) in;
struct sA {
int x, y;
};
struct sB {
sA a;
};
layout(binding=0,set=0) uniform ubo {
sB b;
};
struct sC {
sA state;
} c = {
b.a,
};
void main()
{
}

View File

@@ -2050,13 +2050,15 @@ public:
// Add struct/block members
if (isStruct() && structure) {
appendStr("{");
bool hasHiddenMember = true;
for (size_t i = 0; i < structure->size(); ++i) {
if (! (*structure)[i].type->hiddenMember()) {
if (!hasHiddenMember)
appendStr(", ");
typeString.append((*structure)[i].type->getCompleteString());
typeString.append(" ");
typeString.append((*structure)[i].type->getFieldName());
if (i < structure->size() - 1)
appendStr(", ");
hasHiddenMember = false;
}
}
appendStr("}");

View File

@@ -1,3 +1,3 @@
// This header is generated by the make-revision script.
#define GLSLANG_PATCH_LEVEL 3321
#define GLSLANG_PATCH_LEVEL 3345

View File

@@ -1852,7 +1852,7 @@ const char* TShader::getInfoDebugLog()
return infoSink->debug.c_str();
}
TProgram::TProgram() : reflection(0), ioMapper(nullptr), linked(false)
TProgram::TProgram() : reflection(0), linked(false)
{
pool = new TPoolAllocator;
infoSink = new TInfoSink;
@@ -1864,7 +1864,6 @@ TProgram::TProgram() : reflection(0), ioMapper(nullptr), linked(false)
TProgram::~TProgram()
{
delete ioMapper;
delete infoSink;
delete reflection;
@@ -2035,21 +2034,24 @@ void TProgram::dumpReflection() { if (reflection != nullptr) reflection->dump();
//
// I/O mapping implementation.
//
bool TProgram::mapIO(TIoMapResolver* resolver)
bool TProgram::mapIO(TIoMapResolver* pResolver, TIoMapper* pIoMapper)
{
if (! linked || ioMapper)
if (! linked)
return false;
ioMapper = new TIoMapper;
TIoMapper* ioMapper = nullptr;
TIoMapper defaultIOMapper;
if (pIoMapper == nullptr)
ioMapper = &defaultIOMapper;
else
ioMapper = pIoMapper;
for (int s = 0; s < EShLangCount; ++s) {
if (intermediate[s]) {
if (! ioMapper->addStage((EShLanguage)s, *intermediate[s], *infoSink, resolver))
if (! ioMapper->addStage((EShLanguage)s, *intermediate[s], *infoSink, pResolver))
return false;
}
}
return true;
return ioMapper->doMap(pResolver, *infoSink);
}
} // end namespace glslang

File diff suppressed because it is too large Load Diff

View File

@@ -36,8 +36,10 @@
#ifndef _IOMAPPER_INCLUDED
#define _IOMAPPER_INCLUDED
#include "../Public/ShaderLang.h"
#include <cstdint>
#include "LiveTraverser.h"
#include <unordered_map>
#include <unordered_set>
//
// A reflection database and its interface, consistent with the OpenGL API reflection queries.
//
@@ -47,15 +49,245 @@ class TInfoSink;
namespace glslang {
class TIntermediate;
struct TVarEntryInfo {
int id;
TIntermSymbol* symbol;
bool live;
int newBinding;
int newSet;
int newLocation;
int newComponent;
int newIndex;
EShLanguage stage;
struct TOrderById {
inline bool operator()(const TVarEntryInfo& l, const TVarEntryInfo& r) { return l.id < r.id; }
};
struct TOrderByPriority {
// ordering:
// 1) has both binding and set
// 2) has binding but no set
// 3) has no binding but set
// 4) has no binding and no set
inline bool operator()(const TVarEntryInfo& l, const TVarEntryInfo& r) {
const TQualifier& lq = l.symbol->getQualifier();
const TQualifier& rq = r.symbol->getQualifier();
// simple rules:
// has binding gives 2 points
// has set gives 1 point
// who has the most points is more important.
int lPoints = (lq.hasBinding() ? 2 : 0) + (lq.hasSet() ? 1 : 0);
int rPoints = (rq.hasBinding() ? 2 : 0) + (rq.hasSet() ? 1 : 0);
if (lPoints == rPoints)
return l.id < r.id;
return lPoints > rPoints;
}
};
};
// Base class for shared TIoMapResolver services, used by several derivations.
struct TDefaultIoResolverBase : public glslang::TIoMapResolver {
public:
TDefaultIoResolverBase(const TIntermediate& intermediate);
typedef std::vector<int> TSlotSet;
typedef std::unordered_map<int, TSlotSet> TSlotSetMap;
// grow the reflection stage by stage
void notifyBinding(EShLanguage, TVarEntryInfo& /*ent*/) override {}
void notifyInOut(EShLanguage, TVarEntryInfo& /*ent*/) override {}
void beginNotifications(EShLanguage) override {}
void endNotifications(EShLanguage) override {}
void beginResolve(EShLanguage) override {}
void endResolve(EShLanguage) override {}
void beginCollect(EShLanguage) override {}
void endCollect(EShLanguage) override {}
void reserverResourceSlot(TVarEntryInfo& /*ent*/, TInfoSink& /*infoSink*/) override {}
void reserverStorageSlot(TVarEntryInfo& /*ent*/, TInfoSink& /*infoSink*/) override {}
int getBaseBinding(TResourceType res, unsigned int set) const;
const std::vector<std::string>& getResourceSetBinding() const;
virtual TResourceType getResourceType(const glslang::TType& type) = 0;
bool doAutoBindingMapping() const;
bool doAutoLocationMapping() const;
TSlotSet::iterator findSlot(int set, int slot);
bool checkEmpty(int set, int slot);
bool validateInOut(EShLanguage /*stage*/, TVarEntryInfo& /*ent*/) override { return true; };
int reserveSlot(int set, int slot, int size = 1);
int getFreeSlot(int set, int base, int size = 1);
int resolveSet(EShLanguage /*stage*/, TVarEntryInfo& ent) override;
int resolveUniformLocation(EShLanguage /*stage*/, TVarEntryInfo& ent) override;
int resolveInOutLocation(EShLanguage stage, TVarEntryInfo& ent) override;
int resolveInOutComponent(EShLanguage /*stage*/, TVarEntryInfo& ent) override;
int resolveInOutIndex(EShLanguage /*stage*/, TVarEntryInfo& ent) override;
void addStage(EShLanguage stage) override {
if (stage < EShLangCount)
stageMask[stage] = true;
};
uint32_t computeTypeLocationSize(const TType& type, EShLanguage stage);
TSlotSetMap slots;
protected:
TDefaultIoResolverBase(TDefaultIoResolverBase&);
TDefaultIoResolverBase& operator=(TDefaultIoResolverBase&);
const TIntermediate& intermediate;
int nextUniformLocation;
int nextInputLocation;
int nextOutputLocation;
bool stageMask[EShLangCount + 1];
// Return descriptor set specific base if there is one, and the generic base otherwise.
int selectBaseBinding(int base, int descriptorSetBase) const {
return descriptorSetBase != -1 ? descriptorSetBase : base;
}
static int getLayoutSet(const glslang::TType& type) {
if (type.getQualifier().hasSet())
return type.getQualifier().layoutSet;
else
return 0;
}
static bool isSamplerType(const glslang::TType& type) {
return type.getBasicType() == glslang::EbtSampler && type.getSampler().isPureSampler();
}
static bool isTextureType(const glslang::TType& type) {
return (type.getBasicType() == glslang::EbtSampler &&
(type.getSampler().isTexture() || type.getSampler().isSubpass()));
}
static bool isUboType(const glslang::TType& type) {
return type.getQualifier().storage == EvqUniform;
}
static bool isImageType(const glslang::TType& type) {
return type.getBasicType() == glslang::EbtSampler && type.getSampler().isImage();
}
static bool isSsboType(const glslang::TType& type) {
return type.getQualifier().storage == EvqBuffer;
}
// Return true if this is a SRV (shader resource view) type:
static bool isSrvType(const glslang::TType& type) {
return isTextureType(type) || type.getQualifier().storage == EvqBuffer;
}
// Return true if this is a UAV (unordered access view) type:
static bool isUavType(const glslang::TType& type) {
if (type.getQualifier().readonly)
return false;
return (type.getBasicType() == glslang::EbtSampler && type.getSampler().isImage()) ||
(type.getQualifier().storage == EvqBuffer);
}
};
// Defaulf I/O resolver for OpenGL
struct TDefaultGlslIoResolver : public TDefaultIoResolverBase {
public:
typedef std::map<TString, int> TVarSlotMap; // <resourceName, location/binding>
typedef std::map<int, TVarSlotMap> TSlotMap; // <resourceKey, TVarSlotMap>
TDefaultGlslIoResolver(const TIntermediate& intermediate);
bool validateBinding(EShLanguage /*stage*/, TVarEntryInfo& /*ent*/) override { return true; };
TResourceType getResourceType(const glslang::TType& type) override;
int resolveInOutLocation(EShLanguage stage, TVarEntryInfo& ent) override;
int resolveUniformLocation(EShLanguage /*stage*/, TVarEntryInfo& ent) override;
int resolveBinding(EShLanguage /*stage*/, TVarEntryInfo& ent) override;
void beginResolve(EShLanguage /*stage*/) override;
void endResolve(EShLanguage stage) override;
void beginCollect(EShLanguage) override;
void endCollect(EShLanguage) override;
void reserverStorageSlot(TVarEntryInfo& ent, TInfoSink& infoSink) override;
void reserverResourceSlot(TVarEntryInfo& ent, TInfoSink& infoSink) override;
// in/out symbol and uniform symbol are stored in the same resourceSlotMap, the storage key is used to identify each type of symbol.
// We use stage and storage qualifier to construct a storage key. it can help us identify the same storage resource used in different stage.
// if a resource is a program resource and we don't need know it usage stage, we can use same stage to build storage key.
// Note: both stage and type must less then 0xffff.
int buildStorageKey(EShLanguage stage, TStorageQualifier type) {
assert(static_cast<uint32_t>(stage) <= 0x0000ffff && static_cast<uint32_t>(type) <= 0x0000ffff);
return (stage << 16) | type;
};
protected:
// Use for mark pre stage, to get more interface symbol information.
EShLanguage preStage;
// Use for mark current shader stage for resolver
EShLanguage currentStage;
// Slot map for storage resource(location of uniform and interface symbol) It's a program share slot
TSlotMap resourceSlotMap;
// Slot map for other resource(image, ubo, ssbo), It's a program share slot.
TSlotMap storageSlotMap;
};
typedef std::map<TString, TVarEntryInfo> TVarLiveMap;
// override function "operator=", if a vector<const _Kty, _Ty> being sort,
// when use vc++, the sort function will call :
// pair& operator=(const pair<_Other1, _Other2>& _Right)
// {
// first = _Right.first;
// second = _Right.second;
// return (*this);
// }
// that will make a const type handing on left.
// override this function can avoid a compiler error.
// In the future, if the vc++ compiler can handle such a situation,
// this part of the code will be removed.
struct TVarLivePair : std::pair<const TString, TVarEntryInfo> {
TVarLivePair(std::pair<const TString, TVarEntryInfo>& _Right) : pair(_Right.first, _Right.second) {}
TVarLivePair& operator=(const TVarLivePair& _Right) {
const_cast<TString&>(first) = _Right.first;
second = _Right.second;
return (*this);
};
};
typedef std::vector<TVarLivePair> TVarLiveVector;
// I/O mapper
class TIoMapper {
public:
TIoMapper() {}
virtual ~TIoMapper() {}
// grow the reflection stage by stage
bool addStage(EShLanguage, TIntermediate&, TInfoSink&, TIoMapResolver*);
bool virtual addStage(EShLanguage, TIntermediate&, TInfoSink&, TIoMapResolver*);
bool virtual doMap(TIoMapResolver*, TInfoSink&) { return true; };
};
// I/O mapper for OpenGL
class TGlslIoMapper : public TIoMapper {
public:
TGlslIoMapper() {
memset(inVarMaps, 0, sizeof(TVarLiveMap*) * (EShLangCount + 1));
memset(outVarMaps, 0, sizeof(TVarLiveMap*) * (EShLangCount + 1));
memset(uniformVarMap, 0, sizeof(TVarLiveMap*) * (EShLangCount + 1));
memset(intermediates, 0, sizeof(TIntermediate*) * (EShLangCount + 1));
}
virtual ~TGlslIoMapper() {
for (size_t stage = 0; stage < EShLangCount; stage++) {
if (inVarMaps[stage] != nullptr) {
delete inVarMaps[stage];
inVarMaps[stage] = nullptr;
}
if (outVarMaps[stage] != nullptr) {
delete outVarMaps[stage];
outVarMaps[stage] = nullptr;
}
if (uniformVarMap[stage] != nullptr) {
delete uniformVarMap[stage];
uniformVarMap[stage] = nullptr;
}
if (intermediates[stage] != nullptr)
intermediates[stage] = nullptr;
}
}
// grow the reflection stage by stage
bool addStage(EShLanguage, TIntermediate&, TInfoSink&, TIoMapResolver*) override;
bool doMap(TIoMapResolver*, TInfoSink&) override;
TVarLiveMap *inVarMaps[EShLangCount], *outVarMaps[EShLangCount],
*uniformVarMap[EShLangCount];
TIntermediate* intermediates[EShLangCount];
bool hadError = false;
};
} // end namespace glslang

View File

@@ -646,8 +646,9 @@ protected:
const TType* type;
};
class TReflection;
class TIoMapper;
class TReflection;
class TIoMapper;
struct TVarEntryInfo;
// Allows to customize the binding layout after linking.
// All used uniform variables will invoke at least validateBinding.
@@ -668,51 +669,61 @@ class TIoMapper;
// notifiy callbacks, this phase ends with a call to endNotifications.
// Phase two starts directly after the call to endNotifications
// and calls all other callbacks to validate and to get the
// bindings, sets, locations, component and color indices.
// bindings, sets, locations, component and color indices.
//
// NOTE: that still limit checks are applied to bindings and sets
// and may result in an error.
class TIoMapResolver
{
public:
virtual ~TIoMapResolver() {}
virtual ~TIoMapResolver() {}
// Should return true if the resulting/current binding would be okay.
// Basic idea is to do aliasing binding checks with this.
virtual bool validateBinding(EShLanguage stage, const char* name, const TType& type, bool is_live) = 0;
// Should return a value >= 0 if the current binding should be overridden.
// Return -1 if the current binding (including no binding) should be kept.
virtual int resolveBinding(EShLanguage stage, const char* name, const TType& type, bool is_live) = 0;
// Should return a value >= 0 if the current set should be overridden.
// Return -1 if the current set (including no set) should be kept.
virtual int resolveSet(EShLanguage stage, const char* name, const TType& type, bool is_live) = 0;
// Should return a value >= 0 if the current location should be overridden.
// Return -1 if the current location (including no location) should be kept.
virtual int resolveUniformLocation(EShLanguage stage, const char* name, const TType& type, bool is_live) = 0;
// Should return true if the resulting/current setup would be okay.
// Basic idea is to do aliasing checks and reject invalid semantic names.
virtual bool validateInOut(EShLanguage stage, const char* name, const TType& type, bool is_live) = 0;
// Should return a value >= 0 if the current location should be overridden.
// Return -1 if the current location (including no location) should be kept.
virtual int resolveInOutLocation(EShLanguage stage, const char* name, const TType& type, bool is_live) = 0;
// Should return a value >= 0 if the current component index should be overridden.
// Return -1 if the current component index (including no index) should be kept.
virtual int resolveInOutComponent(EShLanguage stage, const char* name, const TType& type, bool is_live) = 0;
// Should return a value >= 0 if the current color index should be overridden.
// Return -1 if the current color index (including no index) should be kept.
virtual int resolveInOutIndex(EShLanguage stage, const char* name, const TType& type, bool is_live) = 0;
// Notification of a uniform variable
virtual void notifyBinding(EShLanguage stage, const char* name, const TType& type, bool is_live) = 0;
// Notification of a in or out variable
virtual void notifyInOut(EShLanguage stage, const char* name, const TType& type, bool is_live) = 0;
// Called by mapIO when it has finished the notify pass
virtual void endNotifications(EShLanguage stage) = 0;
// Called by mapIO when it starts its notify pass for the given stage
virtual void beginNotifications(EShLanguage stage) = 0;
// Called by mipIO when it starts its resolve pass for the given stage
virtual void beginResolve(EShLanguage stage) = 0;
// Called by mapIO when it has finished the resolve pass
virtual void endResolve(EShLanguage stage) = 0;
// Should return true if the resulting/current binding would be okay.
// Basic idea is to do aliasing binding checks with this.
virtual bool validateBinding(EShLanguage stage, TVarEntryInfo& ent) = 0;
// Should return a value >= 0 if the current binding should be overridden.
// Return -1 if the current binding (including no binding) should be kept.
virtual int resolveBinding(EShLanguage stage, TVarEntryInfo& ent) = 0;
// Should return a value >= 0 if the current set should be overridden.
// Return -1 if the current set (including no set) should be kept.
virtual int resolveSet(EShLanguage stage, TVarEntryInfo& ent) = 0;
// Should return a value >= 0 if the current location should be overridden.
// Return -1 if the current location (including no location) should be kept.
virtual int resolveUniformLocation(EShLanguage stage, TVarEntryInfo& ent) = 0;
// Should return true if the resulting/current setup would be okay.
// Basic idea is to do aliasing checks and reject invalid semantic names.
virtual bool validateInOut(EShLanguage stage, TVarEntryInfo& ent) = 0;
// Should return a value >= 0 if the current location should be overridden.
// Return -1 if the current location (including no location) should be kept.
virtual int resolveInOutLocation(EShLanguage stage, TVarEntryInfo& ent) = 0;
// Should return a value >= 0 if the current component index should be overridden.
// Return -1 if the current component index (including no index) should be kept.
virtual int resolveInOutComponent(EShLanguage stage, TVarEntryInfo& ent) = 0;
// Should return a value >= 0 if the current color index should be overridden.
// Return -1 if the current color index (including no index) should be kept.
virtual int resolveInOutIndex(EShLanguage stage, TVarEntryInfo& ent) = 0;
// Notification of a uniform variable
virtual void notifyBinding(EShLanguage stage, TVarEntryInfo& ent) = 0;
// Notification of a in or out variable
virtual void notifyInOut(EShLanguage stage, TVarEntryInfo& ent) = 0;
// Called by mapIO when it starts its notify pass for the given stage
virtual void beginNotifications(EShLanguage stage) = 0;
// Called by mapIO when it has finished the notify pass
virtual void endNotifications(EShLanguage stage) = 0;
// Called by mipIO when it starts its resolve pass for the given stage
virtual void beginResolve(EShLanguage stage) = 0;
// Called by mapIO when it has finished the resolve pass
virtual void endResolve(EShLanguage stage) = 0;
// Called by mapIO when it starts its symbol collect for teh given stage
virtual void beginCollect(EShLanguage stage) = 0;
// Called by mapIO when it has finished the symbol collect
virtual void endCollect(EShLanguage stage) = 0;
// Called by TSlotCollector to resolve storage locations or bindings
virtual void reserverStorageSlot(TVarEntryInfo& ent, TInfoSink& infoSink) = 0;
// Called by TSlotCollector to resolve resource locations or bindings
virtual void reserverResourceSlot(TVarEntryInfo& ent, TInfoSink& infoSink) = 0;
// Called by mapIO.addStage to set shader stage mask to mark a stage be added to this pipeline
virtual void addStage(EShLanguage stage) = 0;
};
// Make one TProgram per set of shaders that will get linked together. Add all
@@ -824,7 +835,7 @@ public:
// I/O mapping: apply base offsets and map live unbound variables
// If resolver is not provided it uses the previous approach
// and respects auto assignment and offsets.
bool mapIO(TIoMapResolver* resolver = NULL);
bool mapIO(TIoMapResolver* pResolver = nullptr, TIoMapper* pIoMapper = nullptr);
protected:
bool linkStage(EShLanguage, EShMessages);
@@ -835,7 +846,6 @@ protected:
bool newedIntermediate[EShLangCount]; // track which intermediate were "new" versus reusing a singleton unit in a stage
TInfoSink* infoSink;
TReflection* reflection;
TIoMapper* ioMapper;
bool linked;
private:

View File

@@ -296,6 +296,7 @@ INSTANTIATE_TEST_CASE_P(
"spv.builtInXFB.vert",
"spv.conditionalDemote.frag",
"spv.conditionalDiscard.frag",
"spv.constructComposite.comp",
"spv.constStruct.vert",
"spv.constConstruct.vert",
"spv.controlFlowAttributes.frag",
@@ -484,6 +485,7 @@ INSTANTIATE_TEST_CASE_P(
"spv.1.4.image.frag",
"spv.1.4.sparseTexture.frag",
"spv.1.4.texture.frag",
"spv.1.4.constructComposite.comp",
})),
FileNameAsCustomTestSuffix
);