Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
G
glslang
Project
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Chen Yisong
glslang
Commits
c3869fee
Commit
c3869fee
authored
Mar 25, 2016
by
John Kessenich
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #211 from Qining/spec-constants-composite
SPV: Support specialization composite constants.
parents
28001b1c
0840838d
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
362 additions
and
19 deletions
+362
-19
GlslangToSpv.cpp
SPIRV/GlslangToSpv.cpp
+75
-12
spv.specConstantComposite.vert.out
Test/baseResults/spv.specConstantComposite.vert.out
+172
-0
spv.specConstantComposite.vert
Test/spv.specConstantComposite.vert
+93
-0
test-spirv-list
Test/test-spirv-list
+1
-0
Types.h
glslang/Include/Types.h
+1
-0
ParseHelper.cpp
glslang/MachineIndependent/ParseHelper.cpp
+20
-7
No files found.
SPIRV/GlslangToSpv.cpp
View file @
c3869fee
...
...
@@ -128,8 +128,9 @@ protected:
void
addDecoration
(
spv
::
Id
id
,
spv
::
Decoration
dec
,
unsigned
value
);
void
addMemberDecoration
(
spv
::
Id
id
,
int
member
,
spv
::
Decoration
dec
);
void
addMemberDecoration
(
spv
::
Id
id
,
int
member
,
spv
::
Decoration
dec
,
unsigned
value
);
spv
::
Id
createSpvSpecConstant
(
const
glslang
::
TIntermTyped
&
);
spv
::
Id
createSpvConstant
(
const
glslang
::
TType
&
type
,
const
glslang
::
TConstUnionArray
&
,
int
&
nextConst
,
bool
specConstant
);
spv
::
Id
createSpvConstant
(
const
glslang
::
TIntermTyped
&
);
spv
::
Id
createSpvConstantFromConstUnionArray
(
const
glslang
::
TType
&
type
,
const
glslang
::
TConstUnionArray
&
,
int
&
nextConst
,
bool
specConstant
);
spv
::
Id
createSpvConstantFromConstSubTree
(
const
glslang
::
TIntermTyped
*
subTree
);
bool
isTrivialLeaf
(
const
glslang
::
TIntermTyped
*
node
);
bool
isTrivial
(
const
glslang
::
TIntermTyped
*
node
);
spv
::
Id
createShortCircuit
(
glslang
::
TOperator
,
glslang
::
TIntermTyped
&
left
,
glslang
::
TIntermTyped
&
right
);
...
...
@@ -1520,7 +1521,7 @@ bool TGlslangToSpvTraverser::visitSwitch(glslang::TVisit /* visit */, glslang::T
void
TGlslangToSpvTraverser
::
visitConstantUnion
(
glslang
::
TIntermConstantUnion
*
node
)
{
int
nextConst
=
0
;
spv
::
Id
constant
=
createSpvConstant
(
node
->
getType
(),
node
->
getConstArray
(),
nextConst
,
false
);
spv
::
Id
constant
=
createSpvConstant
FromConstUnionArray
(
node
->
getType
(),
node
->
getConstArray
(),
nextConst
,
false
);
builder
.
clearAccessChain
();
builder
.
setAccessChainRValue
(
constant
);
...
...
@@ -1630,7 +1631,7 @@ spv::Id TGlslangToSpvTraverser::createSpvVariable(const glslang::TIntermSymbol*
// can still have a mapping to a SPIR-V Id.
// This includes specialization constants.
if
(
node
->
getQualifier
().
isConstant
())
{
return
createSpv
Spec
Constant
(
*
node
);
return
createSpvConstant
(
*
node
);
}
// Now, handle actual variables
...
...
@@ -3730,7 +3731,7 @@ void TGlslangToSpvTraverser::addMemberDecoration(spv::Id id, int member, spv::De
// recursively walks. So, this function walks the "top" of the tree:
// - emit specialization constant-building instructions for specConstant
// - when running into a non-spec-constant, switch to createSpvConstant()
spv
::
Id
TGlslangToSpvTraverser
::
createSpv
Spec
Constant
(
const
glslang
::
TIntermTyped
&
node
)
spv
::
Id
TGlslangToSpvTraverser
::
createSpvConstant
(
const
glslang
::
TIntermTyped
&
node
)
{
assert
(
node
.
getQualifier
().
isConstant
());
...
...
@@ -3738,7 +3739,7 @@ spv::Id TGlslangToSpvTraverser::createSpvSpecConstant(const glslang::TIntermType
// hand off to the non-spec-constant path
assert
(
node
.
getAsConstantUnion
()
!=
nullptr
||
node
.
getAsSymbolNode
()
!=
nullptr
);
int
nextConst
=
0
;
return
createSpvConstant
(
node
.
getType
(),
node
.
getAsConstantUnion
()
?
node
.
getAsConstantUnion
()
->
getConstArray
()
:
node
.
getAsSymbolNode
()
->
getConstArray
(),
return
createSpvConstant
FromConstUnionArray
(
node
.
getType
(),
node
.
getAsConstantUnion
()
?
node
.
getAsConstantUnion
()
->
getConstArray
()
:
node
.
getAsSymbolNode
()
->
getConstArray
(),
nextConst
,
false
);
}
...
...
@@ -3747,7 +3748,7 @@ spv::Id TGlslangToSpvTraverser::createSpvSpecConstant(const glslang::TIntermType
if
(
node
.
getAsSymbolNode
()
&&
node
.
getQualifier
().
hasSpecConstantId
())
{
// this is a direct literal assigned to a layout(constant_id=) declaration
int
nextConst
=
0
;
return
createSpvConstant
(
node
.
getType
(),
node
.
getAsConstantUnion
()
?
node
.
getAsConstantUnion
()
->
getConstArray
()
:
node
.
getAsSymbolNode
()
->
getConstArray
(),
return
createSpvConstant
FromConstUnionArray
(
node
.
getType
(),
node
.
getAsConstantUnion
()
?
node
.
getAsConstantUnion
()
->
getConstArray
()
:
node
.
getAsSymbolNode
()
->
getConstArray
(),
nextConst
,
true
);
}
else
{
// gl_WorkgroupSize is a special case until the front-end handles hierarchical specialization constants,
...
...
@@ -3761,8 +3762,10 @@ spv::Id TGlslangToSpvTraverser::createSpvSpecConstant(const glslang::TIntermType
addDecoration
(
dimConstId
.
back
(),
spv
::
DecorationSpecId
,
glslangIntermediate
->
getLocalSizeSpecId
(
dim
));
}
return
builder
.
makeCompositeConstant
(
builder
.
makeVectorType
(
builder
.
makeUintType
(
32
),
3
),
dimConstId
,
true
);
}
else
if
(
auto
*
sn
=
node
.
getAsSymbolNode
()){
return
createSpvConstantFromConstSubTree
(
sn
->
getConstSubtree
());
}
else
{
spv
::
MissingFunctionality
(
"
specialization-constant expression trees
"
);
spv
::
MissingFunctionality
(
"
Neither a front-end constant nor a spec constant.
"
);
exit
(
1
);
return
spv
::
NoResult
;
}
...
...
@@ -3775,7 +3778,7 @@ spv::Id TGlslangToSpvTraverser::createSpvSpecConstant(const glslang::TIntermType
// If there are not enough elements present in 'consts', 0 will be substituted;
// an empty 'consts' can be used to create a fully zeroed SPIR-V constant.
//
spv
::
Id
TGlslangToSpvTraverser
::
createSpvConstant
(
const
glslang
::
TType
&
glslangType
,
const
glslang
::
TConstUnionArray
&
consts
,
int
&
nextConst
,
bool
specConstant
)
spv
::
Id
TGlslangToSpvTraverser
::
createSpvConstant
FromConstUnionArray
(
const
glslang
::
TType
&
glslangType
,
const
glslang
::
TConstUnionArray
&
consts
,
int
&
nextConst
,
bool
specConstant
)
{
// vector of constants for SPIR-V
std
::
vector
<
spv
::
Id
>
spvConsts
;
...
...
@@ -3786,15 +3789,15 @@ spv::Id TGlslangToSpvTraverser::createSpvConstant(const glslang::TType& glslangT
if
(
glslangType
.
isArray
())
{
glslang
::
TType
elementType
(
glslangType
,
0
);
for
(
int
i
=
0
;
i
<
glslangType
.
getOuterArraySize
();
++
i
)
spvConsts
.
push_back
(
createSpvConstant
(
elementType
,
consts
,
nextConst
,
false
));
spvConsts
.
push_back
(
createSpvConstant
FromConstUnionArray
(
elementType
,
consts
,
nextConst
,
false
));
}
else
if
(
glslangType
.
isMatrix
())
{
glslang
::
TType
vectorType
(
glslangType
,
0
);
for
(
int
col
=
0
;
col
<
glslangType
.
getMatrixCols
();
++
col
)
spvConsts
.
push_back
(
createSpvConstant
(
vectorType
,
consts
,
nextConst
,
false
));
spvConsts
.
push_back
(
createSpvConstant
FromConstUnionArray
(
vectorType
,
consts
,
nextConst
,
false
));
}
else
if
(
glslangType
.
getStruct
())
{
glslang
::
TVector
<
glslang
::
TTypeLoc
>::
const_iterator
iter
;
for
(
iter
=
glslangType
.
getStruct
()
->
begin
();
iter
!=
glslangType
.
getStruct
()
->
end
();
++
iter
)
spvConsts
.
push_back
(
createSpvConstant
(
*
iter
->
type
,
consts
,
nextConst
,
false
));
spvConsts
.
push_back
(
createSpvConstant
FromConstUnionArray
(
*
iter
->
type
,
consts
,
nextConst
,
false
));
}
else
if
(
glslangType
.
isVector
())
{
for
(
unsigned
int
i
=
0
;
i
<
(
unsigned
int
)
glslangType
.
getVectorSize
();
++
i
)
{
bool
zero
=
nextConst
>=
consts
.
size
();
...
...
@@ -3851,6 +3854,66 @@ spv::Id TGlslangToSpvTraverser::createSpvConstant(const glslang::TType& glslangT
return
builder
.
makeCompositeConstant
(
typeId
,
spvConsts
);
}
// Create constant ID from const initializer sub tree.
spv
::
Id
TGlslangToSpvTraverser
::
createSpvConstantFromConstSubTree
(
const
glslang
::
TIntermTyped
*
subTree
)
{
const
glslang
::
TType
&
glslangType
=
subTree
->
getType
();
spv
::
Id
typeId
=
convertGlslangToSpvType
(
glslangType
);
bool
is_spec_const
=
subTree
->
getType
().
getQualifier
().
isSpecConstant
();
if
(
const
glslang
::
TIntermAggregate
*
an
=
subTree
->
getAsAggregate
())
{
// Aggregate node, we should generate OpConstantComposite or
// OpSpecConstantComposite instruction.
std
::
vector
<
spv
::
Id
>
const_constituents
;
for
(
auto
NI
=
an
->
getSequence
().
begin
();
NI
!=
an
->
getSequence
().
end
();
NI
++
)
{
const_constituents
.
push_back
(
createSpvConstantFromConstSubTree
((
*
NI
)
->
getAsTyped
()));
}
// Note that constructors are aggregate nodes, so expressions like:
// float x = float(y) will become an aggregate node. If 'x' is declared
// as a constant, the aggregate node representing 'float(y)' will be
// processed here.
if
(
builder
.
isVectorType
(
typeId
)
||
builder
.
isMatrixType
(
typeId
)
||
builder
.
isAggregateType
(
typeId
))
{
return
builder
.
makeCompositeConstant
(
typeId
,
const_constituents
,
is_spec_const
);
}
else
{
assert
(
builder
.
isScalarType
(
typeId
)
&&
const_constituents
.
size
()
==
1
);
return
const_constituents
.
front
();
}
}
else
if
(
const
glslang
::
TIntermBinary
*
bn
=
subTree
->
getAsBinaryNode
())
{
// Binary operation node, we should generate OpSpecConstantOp <binary op>
// This case should only happen when Specialization Constants are involved.
spv
::
MissingFunctionality
(
"OpSpecConstantOp <binary op> not implemented"
);
return
spv
::
NoResult
;
}
else
if
(
const
glslang
::
TIntermUnary
*
un
=
subTree
->
getAsUnaryNode
())
{
// Unary operation node, similar to binary operation node, should only
// happen when specialization constants are involved.
spv
::
MissingFunctionality
(
"OpSpecConstantOp <unary op> not implemented"
);
return
spv
::
NoResult
;
}
else
if
(
const
glslang
::
TIntermConstantUnion
*
cn
=
subTree
->
getAsConstantUnion
())
{
// ConstantUnion node, should redirect to
// createSpvConstantFromConstUnionArray
int
nextConst
=
0
;
return
createSpvConstantFromConstUnionArray
(
glslangType
,
cn
->
getConstArray
(),
nextConst
,
is_spec_const
);
}
else
if
(
const
glslang
::
TIntermSymbol
*
sn
=
subTree
->
getAsSymbolNode
())
{
// Symbol node. Call getSymbolId(). This should cover both cases 1) the
// symbol has already been assigned an ID, 2) need a new ID for this
// symbol.
return
getSymbolId
(
sn
);
}
else
{
spv
::
MissingFunctionality
(
"createSpvConstantFromConstSubTree() not covered TIntermTyped* const "
"initializer subtree."
);
return
spv
::
NoResult
;
}
}
// Return true if the node is a constant or symbol whose reading has no
// non-trivial observable cost or effect.
bool
TGlslangToSpvTraverser
::
isTrivialLeaf
(
const
glslang
::
TIntermTyped
*
node
)
...
...
Test/baseResults/spv.specConstantComposite.vert.out
0 → 100644
View file @
c3869fee
spv.specConstantComposite.vert
Warning, version 450 is not yet complete; most version-specific features are present, but some are missing.
Linked vertex stage:
// Module Version 10000
// Generated by (magic number): 80001
// Id's are bound by 106
Capability Shader
Capability Float64
1: ExtInstImport "GLSL.std.450"
MemoryModel Logical GLSL450
EntryPoint Vertex 4 "main" 27 105
Source GLSL 450
Name 4 "main"
Name 6 "refer_primary_spec_const("
Name 8 "refer_composite_spec_const("
Name 10 "refer_copmosite_dot_dereference("
Name 12 "refer_composite_bracket_dereference("
Name 16 "refer_spec_const_array_length("
Name 18 "declare_spec_const_in_func("
Name 27 "color"
Name 41 "flat_struct"
MemberName 41(flat_struct) 0 "i"
MemberName 41(flat_struct) 1 "f"
MemberName 41(flat_struct) 2 "d"
MemberName 41(flat_struct) 3 "b"
Name 42 "nesting_struct"
MemberName 42(nesting_struct) 0 "nested"
MemberName 42(nesting_struct) 1 "v"
MemberName 42(nesting_struct) 2 "i"
Name 72 "indexable"
Name 76 "indexable"
Name 83 "len"
Name 105 "global_vec4_array_with_spec_length"
Decorate 21 SpecId 203
Decorate 28 SpecId 200
Decorate 32 SpecId 201
Decorate 43 SpecId 202
2: TypeVoid
3: TypeFunction 2
14: TypeInt 32 1
15: TypeFunction 14(int)
20: TypeBool
21: 20(bool) SpecConstantTrue
24: TypeFloat 32
25: TypeVector 24(float) 4
26: TypePointer Output 25(fvec4)
27(color): 26(ptr) Variable Output
28: 14(int) SpecConstant 3
32: 24(float) SpecConstant 1078523331
33: 25(fvec4) SpecConstantComposite 32 32 32 32
36: 24(float) Constant 1133908460
37: 25(fvec4) SpecConstantComposite 32 32 36 36
40: TypeFloat 64
41(flat_struct): TypeStruct 14(int) 24(float) 40(float) 20(bool)
42(nesting_struct): TypeStruct 41(flat_struct) 25(fvec4) 14(int)
43: 40(float) SpecConstant 1413754136 1074340347
44:41(flat_struct) SpecConstantComposite 28 32 43 21
45:42(nesting_struct) SpecConstantComposite 44 33 28
46: 14(int) Constant 2
51: TypeInt 32 0
52: 51(int) Constant 0
57: 51(int) Constant 5
58: TypeArray 24(float) 57
59: 24(float) Constant 1065353216
60: 24(float) Constant 1073741824
61: 24(float) Constant 1077936128
62: 58 SpecConstantComposite 32 32 59 60 61
63: 14(int) Constant 1
68: TypeArray 14(int) 57
69: 14(int) Constant 30
70: 68 SpecConstantComposite 28 28 63 46 69
71: TypePointer Function 68
73: TypePointer Function 14(int)
87: 24(float) Constant 1106321080
88:41(flat_struct) SpecConstantComposite 69 87 43 21
89: 14(int) Constant 10
90:42(nesting_struct) SpecConstantComposite 88 37 89
96: 20(bool) ConstantFalse
97:41(flat_struct) SpecConstantComposite 28 32 43 96
98: 24(float) Constant 1036831949
99: 25(fvec4) ConstantComposite 98 98 98 98
100:42(nesting_struct) SpecConstantComposite 97 99 28
101: 14(int) Constant 3000
102:42(nesting_struct) SpecConstantComposite 88 37 101
103: TypeArray 25(fvec4) 28
104: TypePointer Input 103
105(global_vec4_array_with_spec_length): 104(ptr) Variable Input
4(main): 2 Function None 3
5: Label
Return
FunctionEnd
6(refer_primary_spec_const(): 2 Function None 3
7: Label
SelectionMerge 23 None
BranchConditional 21 22 23
22: Label
29: 24(float) ConvertSToF 28
30: 25(fvec4) Load 27(color)
31: 25(fvec4) VectorTimesScalar 30 29
Store 27(color) 31
Branch 23
23: Label
Return
FunctionEnd
8(refer_composite_spec_const(): 2 Function None 3
9: Label
34: 25(fvec4) Load 27(color)
35: 25(fvec4) FAdd 34 33
Store 27(color) 35
38: 25(fvec4) Load 27(color)
39: 25(fvec4) FSub 38 37
Store 27(color) 39
Return
FunctionEnd
10(refer_copmosite_dot_dereference(): 2 Function None 3
11: Label
47: 14(int) CompositeExtract 45 2
48: 24(float) ConvertSToF 47
49: 25(fvec4) Load 27(color)
50: 25(fvec4) VectorTimesScalar 49 48
Store 27(color) 50
53: 24(float) CompositeExtract 33 0
54: 25(fvec4) Load 27(color)
55: 25(fvec4) CompositeConstruct 53 53 53 53
56: 25(fvec4) FAdd 54 55
Store 27(color) 56
Return
FunctionEnd
12(refer_composite_bracket_dereference(): 2 Function None 3
13: Label
72(indexable): 71(ptr) Variable Function
76(indexable): 71(ptr) Variable Function
64: 24(float) CompositeExtract 62 1
65: 25(fvec4) Load 27(color)
66: 25(fvec4) CompositeConstruct 64 64 64 64
67: 25(fvec4) FSub 65 66
Store 27(color) 67
Store 72(indexable) 70
74: 73(ptr) AccessChain 72(indexable) 28
75: 14(int) Load 74
Store 76(indexable) 70
77: 73(ptr) AccessChain 76(indexable) 75
78: 14(int) Load 77
79: 24(float) ConvertSToF 78
80: 25(fvec4) Load 27(color)
81: 25(fvec4) CompositeConstruct 79 79 79 79
82: 25(fvec4) FDiv 80 81
Store 27(color) 82
Return
FunctionEnd
16(refer_spec_const_array_length(): 14(int) Function None 15
17: Label
83(len): 73(ptr) Variable Function
Store 83(len) 28
84: 14(int) Load 83(len)
ReturnValue 84
FunctionEnd
18(declare_spec_const_in_func(): 2 Function None 3
19: Label
91: 14(int) CompositeExtract 90 2
92: 24(float) ConvertSToF 91
93: 25(fvec4) Load 27(color)
94: 25(fvec4) CompositeConstruct 92 92 92 92
95: 25(fvec4) FDiv 93 94
Store 27(color) 95
Return
FunctionEnd
Test/spv.specConstantComposite.vert
0 → 100644
View file @
c3869fee
#version 450
// constant_id specified scalar spec constants
layout
(
constant_id
=
200
)
const
int
spec_int
=
3
;
layout
(
constant_id
=
201
)
const
float
spec_float
=
3
.
14
;
layout
(
constant_id
=
202
)
const
double
spec_double
=
3
.
1415926535897932384626433832795
;
layout
(
constant_id
=
203
)
const
bool
spec_bool
=
true
;
const
float
cast_spec_float
=
float
(
spec_float
);
// Flat struct
struct
flat_struct
{
int
i
;
float
f
;
double
d
;
bool
b
;
};
// Nesting struct
struct
nesting_struct
{
flat_struct
nested
;
vec4
v
;
int
i
;
};
// Expect OpSpecConstantComposite
// Flat struct initializer
const
flat_struct
spec_flat_struct_all_spec
=
{
spec_int
,
spec_float
,
spec_double
,
spec_bool
};
const
flat_struct
spec_flat_struct_partial_spec
=
{
30
,
30
.
14
,
spec_double
,
spec_bool
};
// Nesting struct initializer
const
nesting_struct
nesting_struct_ctor
=
{
{
spec_int
,
spec_float
,
spec_double
,
false
},
vec4
(
0
.
1
,
0
.
1
,
0
.
1
,
0
.
1
),
spec_int
};
// Vector constructor
const
vec4
spec_vec4_all_spec
=
vec4
(
spec_float
,
spec_float
,
spec_float
,
spec_float
);
const
vec4
spec_vec4_partial_spec
=
vec4
(
spec_float
,
spec_float
,
300
.
14
,
300
.
14
);
// Struct nesting constructor
const
nesting_struct
spec_nesting_struct_all_spec
=
{
spec_flat_struct_all_spec
,
spec_vec4_all_spec
,
spec_int
};
const
nesting_struct
spec_nesting_struct_partial_spec
=
{
spec_flat_struct_partial_spec
,
spec_vec4_partial_spec
,
3000
};
const
float
spec_float_array
[
5
]
=
{
spec_float
,
spec_float
,
1
.
0
,
2
.
0
,
3
.
0
};
const
int
spec_int_array
[
5
]
=
{
spec_int
,
spec_int
,
1
,
2
,
30
};
// global_vec4_array_with_spec_length is not a spec constant, but its array
// size is. When calling global_vec4_array_with_spec_length.length(), A
// TIntermSymbol Node shoule be returned, instead of a TIntermConstantUnion
// node which represents a known constant value.
in
vec4
global_vec4_array_with_spec_length
[
spec_int
];
out
vec4
color
;
void
refer_primary_spec_const
()
{
if
(
spec_bool
)
color
*=
spec_int
;
}
void
refer_composite_spec_const
()
{
color
+=
spec_vec4_all_spec
;
color
-=
spec_vec4_partial_spec
;
}
void
refer_copmosite_dot_dereference
()
{
color
*=
spec_nesting_struct_all_spec
.
i
;
color
+=
spec_vec4_all_spec
.
x
;
}
void
refer_composite_bracket_dereference
()
{
color
-=
spec_float_array
[
1
];
color
/=
spec_int_array
[
spec_int_array
[
spec_int
]];
}
int
refer_spec_const_array_length
()
{
int
len
=
global_vec4_array_with_spec_length
.
length
();
return
len
;
}
void
declare_spec_const_in_func
()
{
const
nesting_struct
spec_const_declared_in_func
=
{
spec_flat_struct_partial_spec
,
spec_vec4_partial_spec
,
10
};
color
/=
spec_const_declared_in_func
.
i
;
}
void
main
()
{}
Test/test-spirv-list
View file @
c3869fee
...
...
@@ -102,6 +102,7 @@ spv.pushConstant.vert
spv.subpass.frag
spv.specConstant.vert
spv.specConstant.comp
spv.specConstantComposite.vert
# GLSL-level semantics
vulkan.frag
vulkan.vert
...
...
glslang/Include/Types.h
View file @
c3869fee
...
...
@@ -1223,6 +1223,7 @@ public:
virtual
int
getMatrixCols
()
const
{
return
matrixCols
;
}
virtual
int
getMatrixRows
()
const
{
return
matrixRows
;
}
virtual
int
getOuterArraySize
()
const
{
return
arraySizes
->
getOuterSize
();
}
virtual
TIntermTyped
*
getOuterArrayNode
()
const
{
return
arraySizes
->
getOuterNode
();
}
virtual
int
getCumulativeArraySize
()
const
{
return
arraySizes
->
getCumulativeSize
();
}
virtual
bool
isArrayOfArrays
()
const
{
return
arraySizes
!=
nullptr
&&
arraySizes
->
getNumDims
()
>
1
;
}
virtual
int
getImplicitArraySize
()
const
{
return
arraySizes
->
getImplicitSize
();
}
...
...
glslang/MachineIndependent/ParseHelper.cpp
View file @
c3869fee
...
...
@@ -484,7 +484,7 @@ TIntermTyped* TParseContext::handleBracketDereference(const TSourceLoc& loc, TIn
TIntermTyped
*
result
=
nullptr
;
int
indexValue
=
0
;
if
(
index
->
getQualifier
().
isConstant
())
{
if
(
index
->
getQualifier
().
is
FrontEnd
Constant
())
{
indexValue
=
index
->
getAsConstantUnion
()
->
getConstArray
()[
0
].
getIConst
();
checkIndex
(
loc
,
base
->
getType
(),
indexValue
);
}
...
...
@@ -503,7 +503,7 @@ TIntermTyped* TParseContext::handleBracketDereference(const TSourceLoc& loc, TIn
if
(
base
->
getAsSymbolNode
()
&&
isIoResizeArray
(
base
->
getType
()))
handleIoResizeArrayAccess
(
loc
,
base
);
if
(
index
->
getQualifier
().
isConstant
())
{
if
(
index
->
getQualifier
().
is
FrontEnd
Constant
())
{
if
(
base
->
getType
().
isImplicitlySizedArray
())
updateImplicitArraySize
(
loc
,
base
,
indexValue
);
result
=
intermediate
.
addIndex
(
EOpIndexDirect
,
base
,
index
,
loc
);
...
...
@@ -541,10 +541,15 @@ TIntermTyped* TParseContext::handleBracketDereference(const TSourceLoc& loc, TIn
}
else
{
// Insert valid dereferenced result
TType
newType
(
base
->
getType
(),
0
);
// dereferenced type
if
(
base
->
getType
().
getQualifier
().
is
FrontEndConstant
()
&&
index
->
getQualifier
().
isFrontEndConstant
())
if
(
base
->
getType
().
getQualifier
().
is
Constant
()
&&
index
->
getQualifier
().
isConstant
())
{
newType
.
getQualifier
().
storage
=
EvqConst
;
else
// If base or index is a specialization constant, the result should also be a specialization constant.
if
(
base
->
getType
().
getQualifier
().
isSpecConstant
()
||
index
->
getQualifier
().
isSpecConstant
())
{
newType
.
getQualifier
().
makeSpecConstant
();
}
}
else
{
newType
.
getQualifier
().
makePartialTemporary
();
}
result
->
setType
(
newType
);
if
(
anyIndexLimits
)
...
...
@@ -1226,6 +1231,11 @@ TIntermTyped* TParseContext::handleLengthMethod(const TSourceLoc& loc, TFunction
else
error
(
loc
,
""
,
function
->
getName
().
c_str
(),
"array must be declared with a size before using this method"
);
}
}
else
if
(
type
.
getOuterArrayNode
())
{
// If the array's outer size is specified by an intermediate node, it means the array's length
// was specified by a specialization constant. In such a case, we should return the node of the
// specialization constants to represent the length.
return
type
.
getOuterArrayNode
();
}
else
length
=
type
.
getOuterArraySize
();
}
else
if
(
type
.
isMatrix
())
...
...
@@ -5110,7 +5120,8 @@ TIntermTyped* TParseContext::addConstructor(const TSourceLoc& loc, TIntermNode*
// We don't know "top down" whether type is a specialization constant,
// but a const becomes a specialization constant if any of its children are.
bool
specConst
=
false
;
bool
hasSpecConst
=
false
;
bool
isConstConstrutor
=
true
;
for
(
TIntermSequence
::
iterator
p
=
sequenceVector
.
begin
();
p
!=
sequenceVector
.
end
();
p
++
,
paramCount
++
)
{
...
...
@@ -5123,14 +5134,16 @@ TIntermTyped* TParseContext::addConstructor(const TSourceLoc& loc, TIntermNode*
if
(
newNode
)
{
*
p
=
newNode
;
if
(
!
newNode
->
getType
().
getQualifier
().
isConstant
())
isConstConstrutor
=
false
;
if
(
newNode
->
getType
().
getQualifier
().
isSpecConstant
())
s
pecConst
=
true
;
hasS
pecConst
=
true
;
}
else
return
nullptr
;
}
TIntermTyped
*
constructor
=
intermediate
.
setAggregateOperator
(
aggrNode
,
op
,
type
,
loc
);
if
(
constructor
->
getType
().
getQualifier
().
isConstant
()
&&
s
pecConst
)
if
(
isConstConstrutor
&&
hasS
pecConst
)
constructor
->
getWritableType
().
getQualifier
().
makeSpecConstant
();
return
constructor
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment