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
6090df0f
Commit
6090df0f
authored
Jun 30, 2016
by
John Kessenich
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
SPV: Non-functional: break up big function into three smaller ones.
Also, improve variable names. This grew to be overly hard to understand.
parent
266b1d3e
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
156 additions
and
129 deletions
+156
-129
GlslangToSpv.cpp
SPIRV/GlslangToSpv.cpp
+156
-129
No files found.
SPIRV/GlslangToSpv.cpp
View file @
6090df0f
...
@@ -115,6 +115,10 @@ protected:
...
@@ -115,6 +115,10 @@ protected:
spv
::
Id
getSampledType
(
const
glslang
::
TSampler
&
);
spv
::
Id
getSampledType
(
const
glslang
::
TSampler
&
);
spv
::
Id
convertGlslangToSpvType
(
const
glslang
::
TType
&
type
);
spv
::
Id
convertGlslangToSpvType
(
const
glslang
::
TType
&
type
);
spv
::
Id
convertGlslangToSpvType
(
const
glslang
::
TType
&
type
,
glslang
::
TLayoutPacking
,
const
glslang
::
TQualifier
&
);
spv
::
Id
convertGlslangToSpvType
(
const
glslang
::
TType
&
type
,
glslang
::
TLayoutPacking
,
const
glslang
::
TQualifier
&
);
spv
::
Id
convertGlslangStructToSpvType
(
const
glslang
::
TType
&
,
const
glslang
::
TTypeList
*
glslangStruct
,
glslang
::
TLayoutPacking
,
const
glslang
::
TQualifier
&
);
void
decorateStructType
(
const
glslang
::
TType
&
,
const
glslang
::
TTypeList
*
glslangStruct
,
glslang
::
TLayoutPacking
,
const
glslang
::
TQualifier
&
,
spv
::
Id
);
spv
::
Id
makeArraySizeId
(
const
glslang
::
TArraySizes
&
,
int
dim
);
spv
::
Id
makeArraySizeId
(
const
glslang
::
TArraySizes
&
,
int
dim
);
spv
::
Id
accessChainLoad
(
const
glslang
::
TType
&
type
);
spv
::
Id
accessChainLoad
(
const
glslang
::
TType
&
type
);
void
accessChainStore
(
const
glslang
::
TType
&
type
,
spv
::
Id
rvalue
);
void
accessChainStore
(
const
glslang
::
TType
&
type
,
spv
::
Id
rvalue
);
...
@@ -1789,6 +1793,7 @@ spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& ty
...
@@ -1789,6 +1793,7 @@ spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& ty
// Do full recursive conversion of an arbitrary glslang type to a SPIR-V Id.
// Do full recursive conversion of an arbitrary glslang type to a SPIR-V Id.
// explicitLayout can be kept the same throughout the hierarchical recursive walk.
// explicitLayout can be kept the same throughout the hierarchical recursive walk.
// Mutually recursive with convertGlslangStructToSpvType().
spv
::
Id
TGlslangToSpvTraverser
::
convertGlslangToSpvType
(
const
glslang
::
TType
&
type
,
glslang
::
TLayoutPacking
explicitLayout
,
const
glslang
::
TQualifier
&
qualifier
)
spv
::
Id
TGlslangToSpvTraverser
::
convertGlslangToSpvType
(
const
glslang
::
TType
&
type
,
glslang
::
TLayoutPacking
explicitLayout
,
const
glslang
::
TQualifier
&
qualifier
)
{
{
spv
::
Id
spvType
=
spv
::
NoResult
;
spv
::
Id
spvType
=
spv
::
NoResult
;
...
@@ -1851,144 +1856,19 @@ spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& ty
...
@@ -1851,144 +1856,19 @@ spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& ty
case
glslang
:
:
EbtBlock
:
case
glslang
:
:
EbtBlock
:
{
{
// If we've seen this struct type, return it
// If we've seen this struct type, return it
const
glslang
::
TTypeList
*
glslangStruct
=
type
.
getStruct
();
const
glslang
::
TTypeList
*
glslangMembers
=
type
.
getStruct
();
std
::
vector
<
spv
::
Id
>
structFields
;
// Try to share structs for different layouts, but not yet for other
// Try to share structs for different layouts, but not yet for other
// kinds of qualification (primarily not yet including interpolant qualification).
// kinds of qualification (primarily not yet including interpolant qualification).
if
(
!
HasNonLayoutQualifiers
(
qualifier
))
if
(
!
HasNonLayoutQualifiers
(
qualifier
))
spvType
=
structMap
[
explicitLayout
][
qualifier
.
layoutMatrix
][
glslang
Struct
];
spvType
=
structMap
[
explicitLayout
][
qualifier
.
layoutMatrix
][
glslang
Members
];
if
(
spvType
!=
spv
::
NoResult
)
if
(
spvType
!=
spv
::
NoResult
)
break
;
break
;
// else, we haven't seen it...
// else, we haven't seen it...
// Create a vector of struct types for SPIR-V to consume
int
memberDelta
=
0
;
// how much the member's index changes from glslang to SPIR-V, normally 0, except sometimes for blocks
if
(
type
.
getBasicType
()
==
glslang
::
EbtBlock
)
if
(
type
.
getBasicType
()
==
glslang
::
EbtBlock
)
memberRemapper
[
glslangStruct
].
resize
(
glslangStruct
->
size
());
memberRemapper
[
glslangMembers
].
resize
(
glslangMembers
->
size
());
int
locationOffset
=
0
;
// for use across struct members, when they are called recursively
spvType
=
convertGlslangStructToSpvType
(
type
,
glslangMembers
,
explicitLayout
,
qualifier
);
for
(
int
i
=
0
;
i
<
(
int
)
glslangStruct
->
size
();
i
++
)
{
glslang
::
TType
&
glslangType
=
*
(
*
glslangStruct
)[
i
].
type
;
if
(
glslangType
.
hiddenMember
())
{
++
memberDelta
;
if
(
type
.
getBasicType
()
==
glslang
::
EbtBlock
)
memberRemapper
[
glslangStruct
][
i
]
=
-
1
;
}
else
{
if
(
type
.
getBasicType
()
==
glslang
::
EbtBlock
)
memberRemapper
[
glslangStruct
][
i
]
=
i
-
memberDelta
;
// modify just this child's view of the qualifier
glslang
::
TQualifier
subQualifier
=
glslangType
.
getQualifier
();
InheritQualifiers
(
subQualifier
,
qualifier
);
// manually inherit location; it's more complex
if
(
!
subQualifier
.
hasLocation
()
&&
qualifier
.
hasLocation
())
subQualifier
.
layoutLocation
=
qualifier
.
layoutLocation
+
locationOffset
;
if
(
qualifier
.
hasLocation
())
locationOffset
+=
glslangIntermediate
->
computeTypeLocationSize
(
glslangType
);
// recurse
structFields
.
push_back
(
convertGlslangToSpvType
(
glslangType
,
explicitLayout
,
subQualifier
));
}
}
// Make the SPIR-V type
spvType
=
builder
.
makeStructType
(
structFields
,
type
.
getTypeName
().
c_str
());
if
(
!
HasNonLayoutQualifiers
(
qualifier
))
structMap
[
explicitLayout
][
qualifier
.
layoutMatrix
][
glslangStruct
]
=
spvType
;
// Name and decorate the non-hidden members
int
offset
=
-
1
;
locationOffset
=
0
;
// for use within the members of this struct, right now
for
(
int
i
=
0
;
i
<
(
int
)
glslangStruct
->
size
();
i
++
)
{
glslang
::
TType
&
glslangType
=
*
(
*
glslangStruct
)[
i
].
type
;
int
member
=
i
;
if
(
type
.
getBasicType
()
==
glslang
::
EbtBlock
)
member
=
memberRemapper
[
glslangStruct
][
i
];
// modify just this child's view of the qualifier
glslang
::
TQualifier
subQualifier
=
glslangType
.
getQualifier
();
InheritQualifiers
(
subQualifier
,
qualifier
);
// using -1 above to indicate a hidden member
if
(
member
>=
0
)
{
builder
.
addMemberName
(
spvType
,
member
,
glslangType
.
getFieldName
().
c_str
());
addMemberDecoration
(
spvType
,
member
,
TranslateLayoutDecoration
(
glslangType
,
subQualifier
.
layoutMatrix
));
addMemberDecoration
(
spvType
,
member
,
TranslatePrecisionDecoration
(
glslangType
));
// Add interpolation and auxiliary storage decorations only to top-level members of Input and Output storage classes
if
(
type
.
getQualifier
().
storage
==
glslang
::
EvqVaryingIn
||
type
.
getQualifier
().
storage
==
glslang
::
EvqVaryingOut
)
{
if
(
type
.
getBasicType
()
==
glslang
::
EbtBlock
)
{
addMemberDecoration
(
spvType
,
member
,
TranslateInterpolationDecoration
(
subQualifier
));
addMemberDecoration
(
spvType
,
member
,
TranslateAuxiliaryStorageDecoration
(
subQualifier
));
}
}
addMemberDecoration
(
spvType
,
member
,
TranslateInvariantDecoration
(
subQualifier
));
if
(
qualifier
.
storage
==
glslang
::
EvqBuffer
)
{
std
::
vector
<
spv
::
Decoration
>
memory
;
TranslateMemoryDecoration
(
subQualifier
,
memory
);
for
(
unsigned
int
i
=
0
;
i
<
memory
.
size
();
++
i
)
addMemberDecoration
(
spvType
,
member
,
memory
[
i
]);
}
// compute location decoration; tricky based on whether inheritance is at play
// TODO: This algorithm (and it's cousin above doing almost the same thing) should
// probably move to the linker stage of the front end proper, and just have the
// answer sitting already distributed throughout the individual member locations.
int
location
=
-
1
;
// will only decorate if present or inherited
if
(
subQualifier
.
hasLocation
())
{
// no inheritance, or override of inheritance
// struct members should not have explicit locations
assert
(
type
.
getBasicType
()
!=
glslang
::
EbtStruct
);
location
=
subQualifier
.
layoutLocation
;
}
else
if
(
type
.
getBasicType
()
!=
glslang
::
EbtBlock
)
{
// If it is a not a Block, (...) Its members are assigned consecutive locations (...)
// The members, and their nested types, must not themselves have Location decorations.
}
else
if
(
qualifier
.
hasLocation
())
// inheritance
location
=
qualifier
.
layoutLocation
+
locationOffset
;
if
(
qualifier
.
hasLocation
())
// track for upcoming inheritance
locationOffset
+=
glslangIntermediate
->
computeTypeLocationSize
(
glslangType
);
if
(
location
>=
0
)
builder
.
addMemberDecoration
(
spvType
,
member
,
spv
::
DecorationLocation
,
location
);
// component, XFB, others
if
(
glslangType
.
getQualifier
().
hasComponent
())
builder
.
addMemberDecoration
(
spvType
,
member
,
spv
::
DecorationComponent
,
glslangType
.
getQualifier
().
layoutComponent
);
if
(
glslangType
.
getQualifier
().
hasXfbOffset
())
builder
.
addMemberDecoration
(
spvType
,
member
,
spv
::
DecorationOffset
,
glslangType
.
getQualifier
().
layoutXfbOffset
);
else
if
(
explicitLayout
!=
glslang
::
ElpNone
)
{
// figure out what to do with offset, which is accumulating
int
nextOffset
;
updateMemberOffset
(
type
,
glslangType
,
offset
,
nextOffset
,
explicitLayout
,
subQualifier
.
layoutMatrix
);
if
(
offset
>=
0
)
builder
.
addMemberDecoration
(
spvType
,
member
,
spv
::
DecorationOffset
,
offset
);
offset
=
nextOffset
;
}
if
(
glslangType
.
isMatrix
()
&&
explicitLayout
!=
glslang
::
ElpNone
)
builder
.
addMemberDecoration
(
spvType
,
member
,
spv
::
DecorationMatrixStride
,
getMatrixStride
(
glslangType
,
explicitLayout
,
subQualifier
.
layoutMatrix
));
// built-in variable decorations
spv
::
BuiltIn
builtIn
=
TranslateBuiltInDecoration
(
glslangType
.
getQualifier
().
builtIn
,
true
);
if
(
builtIn
!=
spv
::
BadValue
)
addMemberDecoration
(
spvType
,
member
,
spv
::
DecorationBuiltIn
,
(
int
)
builtIn
);
}
}
// Decorate the structure
addDecoration
(
spvType
,
TranslateLayoutDecoration
(
type
,
qualifier
.
layoutMatrix
));
addDecoration
(
spvType
,
TranslateBlockDecoration
(
type
));
if
(
type
.
getQualifier
().
hasStream
()
&&
glslangIntermediate
->
isMultiStream
())
{
builder
.
addCapability
(
spv
::
CapabilityGeometryStreams
);
builder
.
addDecoration
(
spvType
,
spv
::
DecorationStream
,
type
.
getQualifier
().
layoutStream
);
}
if
(
glslangIntermediate
->
getXfbMode
())
{
builder
.
addCapability
(
spv
::
CapabilityTransformFeedback
);
if
(
type
.
getQualifier
().
hasXfbStride
())
builder
.
addDecoration
(
spvType
,
spv
::
DecorationXfbStride
,
type
.
getQualifier
().
layoutXfbStride
);
if
(
type
.
getQualifier
().
hasXfbBuffer
())
builder
.
addDecoration
(
spvType
,
spv
::
DecorationXfbBuffer
,
type
.
getQualifier
().
layoutXfbBuffer
);
}
}
}
break
;
break
;
default
:
default
:
...
@@ -2051,6 +1931,153 @@ spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& ty
...
@@ -2051,6 +1931,153 @@ spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& ty
return
spvType
;
return
spvType
;
}
}
// Do full recursive conversion of a glslang structure (or block) type to a SPIR-V Id.
// explicitLayout can be kept the same throughout the hierarchical recursive walk.
// Mutually recursive with convertGlslangToSpvType().
spv
::
Id
TGlslangToSpvTraverser
::
convertGlslangStructToSpvType
(
const
glslang
::
TType
&
type
,
const
glslang
::
TTypeList
*
glslangMembers
,
glslang
::
TLayoutPacking
explicitLayout
,
const
glslang
::
TQualifier
&
qualifier
)
{
// Create a vector of struct types for SPIR-V to consume
std
::
vector
<
spv
::
Id
>
spvMembers
;
int
memberDelta
=
0
;
// how much the member's index changes from glslang to SPIR-V, normally 0, except sometimes for blocks
int
locationOffset
=
0
;
// for use across struct members, when they are called recursively
for
(
int
i
=
0
;
i
<
(
int
)
glslangMembers
->
size
();
i
++
)
{
glslang
::
TType
&
glslangMember
=
*
(
*
glslangMembers
)[
i
].
type
;
if
(
glslangMember
.
hiddenMember
())
{
++
memberDelta
;
if
(
type
.
getBasicType
()
==
glslang
::
EbtBlock
)
memberRemapper
[
glslangMembers
][
i
]
=
-
1
;
}
else
{
if
(
type
.
getBasicType
()
==
glslang
::
EbtBlock
)
memberRemapper
[
glslangMembers
][
i
]
=
i
-
memberDelta
;
// modify just this child's view of the qualifier
glslang
::
TQualifier
memberQualifier
=
glslangMember
.
getQualifier
();
InheritQualifiers
(
memberQualifier
,
qualifier
);
// manually inherit location; it's more complex
if
(
!
memberQualifier
.
hasLocation
()
&&
qualifier
.
hasLocation
())
memberQualifier
.
layoutLocation
=
qualifier
.
layoutLocation
+
locationOffset
;
if
(
qualifier
.
hasLocation
())
locationOffset
+=
glslangIntermediate
->
computeTypeLocationSize
(
glslangMember
);
// recurse
spvMembers
.
push_back
(
convertGlslangToSpvType
(
glslangMember
,
explicitLayout
,
memberQualifier
));
}
}
// Make the SPIR-V type
spv
::
Id
spvType
=
builder
.
makeStructType
(
spvMembers
,
type
.
getTypeName
().
c_str
());
if
(
!
HasNonLayoutQualifiers
(
qualifier
))
structMap
[
explicitLayout
][
qualifier
.
layoutMatrix
][
glslangMembers
]
=
spvType
;
// Decorate it
decorateStructType
(
type
,
glslangMembers
,
explicitLayout
,
qualifier
,
spvType
);
return
spvType
;
}
void
TGlslangToSpvTraverser
::
decorateStructType
(
const
glslang
::
TType
&
type
,
const
glslang
::
TTypeList
*
glslangMembers
,
glslang
::
TLayoutPacking
explicitLayout
,
const
glslang
::
TQualifier
&
qualifier
,
spv
::
Id
spvType
)
{
// Name and decorate the non-hidden members
int
offset
=
-
1
;
int
locationOffset
=
0
;
// for use within the members of this struct
for
(
int
i
=
0
;
i
<
(
int
)
glslangMembers
->
size
();
i
++
)
{
glslang
::
TType
&
glslangMember
=
*
(
*
glslangMembers
)[
i
].
type
;
int
member
=
i
;
if
(
type
.
getBasicType
()
==
glslang
::
EbtBlock
)
member
=
memberRemapper
[
glslangMembers
][
i
];
// modify just this child's view of the qualifier
glslang
::
TQualifier
memberQualifier
=
glslangMember
.
getQualifier
();
InheritQualifiers
(
memberQualifier
,
qualifier
);
// using -1 above to indicate a hidden member
if
(
member
>=
0
)
{
builder
.
addMemberName
(
spvType
,
member
,
glslangMember
.
getFieldName
().
c_str
());
addMemberDecoration
(
spvType
,
member
,
TranslateLayoutDecoration
(
glslangMember
,
memberQualifier
.
layoutMatrix
));
addMemberDecoration
(
spvType
,
member
,
TranslatePrecisionDecoration
(
glslangMember
));
// Add interpolation and auxiliary storage decorations only to top-level members of Input and Output storage classes
if
(
type
.
getQualifier
().
storage
==
glslang
::
EvqVaryingIn
||
type
.
getQualifier
().
storage
==
glslang
::
EvqVaryingOut
)
{
if
(
type
.
getBasicType
()
==
glslang
::
EbtBlock
)
{
addMemberDecoration
(
spvType
,
member
,
TranslateInterpolationDecoration
(
memberQualifier
));
addMemberDecoration
(
spvType
,
member
,
TranslateAuxiliaryStorageDecoration
(
memberQualifier
));
}
}
addMemberDecoration
(
spvType
,
member
,
TranslateInvariantDecoration
(
memberQualifier
));
if
(
qualifier
.
storage
==
glslang
::
EvqBuffer
)
{
std
::
vector
<
spv
::
Decoration
>
memory
;
TranslateMemoryDecoration
(
memberQualifier
,
memory
);
for
(
unsigned
int
i
=
0
;
i
<
memory
.
size
();
++
i
)
addMemberDecoration
(
spvType
,
member
,
memory
[
i
]);
}
// compute location decoration; tricky based on whether inheritance is at play
// TODO: This algorithm (and it's cousin above doing almost the same thing) should
// probably move to the linker stage of the front end proper, and just have the
// answer sitting already distributed throughout the individual member locations.
int
location
=
-
1
;
// will only decorate if present or inherited
if
(
memberQualifier
.
hasLocation
())
{
// no inheritance, or override of inheritance
// struct members should not have explicit locations
assert
(
type
.
getBasicType
()
!=
glslang
::
EbtStruct
);
location
=
memberQualifier
.
layoutLocation
;
}
else
if
(
type
.
getBasicType
()
!=
glslang
::
EbtBlock
)
{
// If it is a not a Block, (...) Its members are assigned consecutive locations (...)
// The members, and their nested types, must not themselves have Location decorations.
}
else
if
(
qualifier
.
hasLocation
())
// inheritance
location
=
qualifier
.
layoutLocation
+
locationOffset
;
if
(
qualifier
.
hasLocation
())
// track for upcoming inheritance
locationOffset
+=
glslangIntermediate
->
computeTypeLocationSize
(
glslangMember
);
if
(
location
>=
0
)
builder
.
addMemberDecoration
(
spvType
,
member
,
spv
::
DecorationLocation
,
location
);
// component, XFB, others
if
(
glslangMember
.
getQualifier
().
hasComponent
())
builder
.
addMemberDecoration
(
spvType
,
member
,
spv
::
DecorationComponent
,
glslangMember
.
getQualifier
().
layoutComponent
);
if
(
glslangMember
.
getQualifier
().
hasXfbOffset
())
builder
.
addMemberDecoration
(
spvType
,
member
,
spv
::
DecorationOffset
,
glslangMember
.
getQualifier
().
layoutXfbOffset
);
else
if
(
explicitLayout
!=
glslang
::
ElpNone
)
{
// figure out what to do with offset, which is accumulating
int
nextOffset
;
updateMemberOffset
(
type
,
glslangMember
,
offset
,
nextOffset
,
explicitLayout
,
memberQualifier
.
layoutMatrix
);
if
(
offset
>=
0
)
builder
.
addMemberDecoration
(
spvType
,
member
,
spv
::
DecorationOffset
,
offset
);
offset
=
nextOffset
;
}
if
(
glslangMember
.
isMatrix
()
&&
explicitLayout
!=
glslang
::
ElpNone
)
builder
.
addMemberDecoration
(
spvType
,
member
,
spv
::
DecorationMatrixStride
,
getMatrixStride
(
glslangMember
,
explicitLayout
,
memberQualifier
.
layoutMatrix
));
// built-in variable decorations
spv
::
BuiltIn
builtIn
=
TranslateBuiltInDecoration
(
glslangMember
.
getQualifier
().
builtIn
,
true
);
if
(
builtIn
!=
spv
::
BadValue
)
addMemberDecoration
(
spvType
,
member
,
spv
::
DecorationBuiltIn
,
(
int
)
builtIn
);
}
}
// Decorate the structure
addDecoration
(
spvType
,
TranslateLayoutDecoration
(
type
,
qualifier
.
layoutMatrix
));
addDecoration
(
spvType
,
TranslateBlockDecoration
(
type
));
if
(
type
.
getQualifier
().
hasStream
()
&&
glslangIntermediate
->
isMultiStream
())
{
builder
.
addCapability
(
spv
::
CapabilityGeometryStreams
);
builder
.
addDecoration
(
spvType
,
spv
::
DecorationStream
,
type
.
getQualifier
().
layoutStream
);
}
if
(
glslangIntermediate
->
getXfbMode
())
{
builder
.
addCapability
(
spv
::
CapabilityTransformFeedback
);
if
(
type
.
getQualifier
().
hasXfbStride
())
builder
.
addDecoration
(
spvType
,
spv
::
DecorationXfbStride
,
type
.
getQualifier
().
layoutXfbStride
);
if
(
type
.
getQualifier
().
hasXfbBuffer
())
builder
.
addDecoration
(
spvType
,
spv
::
DecorationXfbBuffer
,
type
.
getQualifier
().
layoutXfbBuffer
);
}
}
// Turn the expression forming the array size into an id.
// Turn the expression forming the array size into an id.
// This is not quite trivial, because of specialization constants.
// This is not quite trivial, because of specialization constants.
// Sometimes, a raw constant is turned into an Id, and sometimes
// Sometimes, a raw constant is turned into an Id, and sometimes
...
...
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