SPV: Nested layouts: Recursively send around the top-level std140 or std430 packing.
This also distinguishes between the same struct included in multiple parent packings.
This commit is contained in:
@@ -91,11 +91,11 @@ protected:
|
|||||||
spv::Id createSpvVariable(const glslang::TIntermSymbol*);
|
spv::Id createSpvVariable(const glslang::TIntermSymbol*);
|
||||||
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, bool explicitLayout);
|
spv::Id convertGlslangToSpvType(const glslang::TType& type, glslang::TLayoutPacking);
|
||||||
bool requiresExplicitLayout(const glslang::TType& type) const;
|
glslang::TLayoutPacking getExplicitLayout(const glslang::TType& type) const;
|
||||||
int getArrayStride(const glslang::TType& arrayType);
|
int getArrayStride(const glslang::TType& arrayType, glslang::TLayoutPacking);
|
||||||
int getMatrixStride(const glslang::TType& matrixType);
|
int getMatrixStride(const glslang::TType& matrixType, glslang::TLayoutPacking);
|
||||||
void updateMemberOffset(const glslang::TType& structType, const glslang::TType& memberType, int& currentOffset, int& nextOffset);
|
void updateMemberOffset(const glslang::TType& structType, const glslang::TType& memberType, int& currentOffset, int& nextOffset, glslang::TLayoutPacking);
|
||||||
|
|
||||||
bool isShaderEntrypoint(const glslang::TIntermAggregate* node);
|
bool isShaderEntrypoint(const glslang::TIntermAggregate* node);
|
||||||
void makeFunctions(const glslang::TIntermSequence&);
|
void makeFunctions(const glslang::TIntermSequence&);
|
||||||
@@ -140,7 +140,7 @@ protected:
|
|||||||
std::unordered_map<int, spv::Id> symbolValues;
|
std::unordered_map<int, spv::Id> symbolValues;
|
||||||
std::unordered_set<int> constReadOnlyParameters; // set of formal function parameters that have glslang qualifier constReadOnly, so we know they are not local function "const" that are write-once
|
std::unordered_set<int> constReadOnlyParameters; // set of formal function parameters that have glslang qualifier constReadOnly, so we know they are not local function "const" that are write-once
|
||||||
std::unordered_map<std::string, spv::Function*> functionMap;
|
std::unordered_map<std::string, spv::Function*> functionMap;
|
||||||
std::unordered_map<const glslang::TTypeList*, spv::Id> structMap;
|
std::unordered_map<const glslang::TTypeList*, spv::Id> structMap[glslang::ElpStd430 + 1];
|
||||||
std::unordered_map<const glslang::TTypeList*, std::vector<int> > memberRemapper; // for mapping glslang block indices to spv indices (e.g., due to hidden members)
|
std::unordered_map<const glslang::TTypeList*, std::vector<int> > memberRemapper; // for mapping glslang block indices to spv indices (e.g., due to hidden members)
|
||||||
std::stack<bool> breakForLoop; // false means break for switch
|
std::stack<bool> breakForLoop; // false means break for switch
|
||||||
std::stack<glslang::TIntermTyped*> loopTerminal; // code from the last part of a for loop: for(...; ...; terminal), needed for e.g., continue };
|
std::stack<glslang::TIntermTyped*> loopTerminal; // code from the last part of a for loop: for(...; ...; terminal), needed for e.g., continue };
|
||||||
@@ -1455,12 +1455,12 @@ spv::Id TGlslangToSpvTraverser::getSampledType(const glslang::TSampler& sampler)
|
|||||||
// recursive version of this function.
|
// recursive version of this function.
|
||||||
spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& type)
|
spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& type)
|
||||||
{
|
{
|
||||||
return convertGlslangToSpvType(type, requiresExplicitLayout(type));
|
return convertGlslangToSpvType(type, getExplicitLayout(type));
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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 heirarchical recursive walk.
|
// explicitLayout can be kept the same throughout the heirarchical recursive walk.
|
||||||
spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& type, bool explicitLayout)
|
spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& type, glslang::TLayoutPacking explicitLayout)
|
||||||
{
|
{
|
||||||
spv::Id spvType = 0;
|
spv::Id spvType = 0;
|
||||||
|
|
||||||
@@ -1505,7 +1505,7 @@ spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& ty
|
|||||||
// 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* glslangStruct = type.getStruct();
|
||||||
std::vector<spv::Id> structFields;
|
std::vector<spv::Id> structFields;
|
||||||
spvType = structMap[glslangStruct];
|
spvType = structMap[explicitLayout][glslangStruct];
|
||||||
if (spvType)
|
if (spvType)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -1530,7 +1530,7 @@ spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& ty
|
|||||||
|
|
||||||
// Make the SPIR-V type
|
// Make the SPIR-V type
|
||||||
spvType = builder.makeStructType(structFields, type.getTypeName().c_str());
|
spvType = builder.makeStructType(structFields, type.getTypeName().c_str());
|
||||||
structMap[glslangStruct] = spvType;
|
structMap[explicitLayout][glslangStruct] = spvType;
|
||||||
|
|
||||||
// Name and decorate the non-hidden members
|
// Name and decorate the non-hidden members
|
||||||
int offset = -1;
|
int offset = -1;
|
||||||
@@ -1552,18 +1552,17 @@ spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& ty
|
|||||||
builder.addMemberDecoration(spvType, member, spv::DecorationComponent, glslangType.getQualifier().layoutComponent);
|
builder.addMemberDecoration(spvType, member, spv::DecorationComponent, glslangType.getQualifier().layoutComponent);
|
||||||
if (glslangType.getQualifier().hasXfbOffset())
|
if (glslangType.getQualifier().hasXfbOffset())
|
||||||
builder.addMemberDecoration(spvType, member, spv::DecorationOffset, glslangType.getQualifier().layoutXfbOffset);
|
builder.addMemberDecoration(spvType, member, spv::DecorationOffset, glslangType.getQualifier().layoutXfbOffset);
|
||||||
else if (explicitLayout) {
|
else if (explicitLayout != glslang::ElpNone) {
|
||||||
// figure out what to do with offset, which is accumulating
|
// figure out what to do with offset, which is accumulating
|
||||||
int nextOffset;
|
int nextOffset;
|
||||||
updateMemberOffset(type, glslangType, offset, nextOffset);
|
updateMemberOffset(type, glslangType, offset, nextOffset, explicitLayout);
|
||||||
if (offset >= 0)
|
if (offset >= 0)
|
||||||
builder.addMemberDecoration(spvType, member, spv::DecorationOffset, offset);
|
builder.addMemberDecoration(spvType, member, spv::DecorationOffset, offset);
|
||||||
offset = nextOffset;
|
offset = nextOffset;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (glslangType.isMatrix() && explicitLayout) {
|
if (glslangType.isMatrix() && explicitLayout != glslang::ElpNone)
|
||||||
builder.addMemberDecoration(spvType, member, spv::DecorationMatrixStride, getMatrixStride(glslangType));
|
builder.addMemberDecoration(spvType, member, spv::DecorationMatrixStride, getMatrixStride(glslangType, explicitLayout));
|
||||||
}
|
|
||||||
|
|
||||||
// built-in variable decorations
|
// built-in variable decorations
|
||||||
spv::BuiltIn builtIn = TranslateBuiltInDecoration(glslangType.getQualifier().builtIn);
|
spv::BuiltIn builtIn = TranslateBuiltInDecoration(glslangType.getQualifier().builtIn);
|
||||||
@@ -1621,26 +1620,41 @@ spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& ty
|
|||||||
// except for the very top if it is an array of blocks; that array is
|
// except for the very top if it is an array of blocks; that array is
|
||||||
// not laid out in memory in a way needing a stride.
|
// not laid out in memory in a way needing a stride.
|
||||||
if (explicitLayout && type.getBasicType() != glslang::EbtBlock)
|
if (explicitLayout && type.getBasicType() != glslang::EbtBlock)
|
||||||
builder.addDecoration(spvType, spv::DecorationArrayStride, getArrayStride(type));
|
builder.addDecoration(spvType, spv::DecorationArrayStride, getArrayStride(type, explicitLayout));
|
||||||
}
|
}
|
||||||
|
|
||||||
return spvType;
|
return spvType;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TGlslangToSpvTraverser::requiresExplicitLayout(const glslang::TType& type) const
|
// Decide whether or not this type should be
|
||||||
|
// decorated with offsets and strides, and if so
|
||||||
|
// whether std140 or std430 rules should be applied.
|
||||||
|
glslang::TLayoutPacking TGlslangToSpvTraverser::getExplicitLayout(const glslang::TType& type) const
|
||||||
{
|
{
|
||||||
return type.getBasicType() == glslang::EbtBlock &&
|
// has to be a block
|
||||||
type.getQualifier().layoutPacking != glslang::ElpShared &&
|
if (type.getBasicType() != glslang::EbtBlock)
|
||||||
type.getQualifier().layoutPacking != glslang::ElpPacked &&
|
return glslang::ElpNone;
|
||||||
(type.getQualifier().storage == glslang::EvqUniform ||
|
|
||||||
type.getQualifier().storage == glslang::EvqBuffer);
|
// has to be a uniform or buffer block
|
||||||
|
if (type.getQualifier().storage != glslang::EvqUniform &&
|
||||||
|
type.getQualifier().storage != glslang::EvqBuffer)
|
||||||
|
return glslang::ElpNone;
|
||||||
|
|
||||||
|
// return the layout to use
|
||||||
|
switch (type.getQualifier().layoutPacking) {
|
||||||
|
case glslang::ElpStd140:
|
||||||
|
case glslang::ElpStd430:
|
||||||
|
return type.getQualifier().layoutPacking;
|
||||||
|
default:
|
||||||
|
return glslang::ElpNone;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Given an array type, returns the integer stride required for that array
|
// Given an array type, returns the integer stride required for that array
|
||||||
int TGlslangToSpvTraverser::getArrayStride(const glslang::TType& arrayType)
|
int TGlslangToSpvTraverser::getArrayStride(const glslang::TType& arrayType, glslang::TLayoutPacking explicitLayout)
|
||||||
{
|
{
|
||||||
int size;
|
int size;
|
||||||
int stride = glslangIntermediate->getBaseAlignment(arrayType, size, arrayType.getQualifier().layoutPacking == glslang::ElpStd140);
|
int stride = glslangIntermediate->getBaseAlignment(arrayType, size, explicitLayout == glslang::ElpStd140);
|
||||||
if (arrayType.isMatrix()) {
|
if (arrayType.isMatrix()) {
|
||||||
// GLSL strides are set to alignments of the matrix flattened to individual rows/cols,
|
// GLSL strides are set to alignments of the matrix flattened to individual rows/cols,
|
||||||
// but SPV needs an array stride for the whole matrix, not the rows/cols
|
// but SPV needs an array stride for the whole matrix, not the rows/cols
|
||||||
@@ -1655,10 +1669,10 @@ int TGlslangToSpvTraverser::getArrayStride(const glslang::TType& arrayType)
|
|||||||
|
|
||||||
// Given a matrix type, returns the integer stride required for that matrix
|
// Given a matrix type, returns the integer stride required for that matrix
|
||||||
// when used as a member of an interface block
|
// when used as a member of an interface block
|
||||||
int TGlslangToSpvTraverser::getMatrixStride(const glslang::TType& matrixType)
|
int TGlslangToSpvTraverser::getMatrixStride(const glslang::TType& matrixType, glslang::TLayoutPacking explicitLayout)
|
||||||
{
|
{
|
||||||
int size;
|
int size;
|
||||||
return glslangIntermediate->getBaseAlignment(matrixType, size, matrixType.getQualifier().layoutPacking == glslang::ElpStd140);
|
return glslangIntermediate->getBaseAlignment(matrixType, size, explicitLayout == glslang::ElpStd140);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Given a member type of a struct, realign the current offset for it, and compute
|
// Given a member type of a struct, realign the current offset for it, and compute
|
||||||
@@ -1667,14 +1681,12 @@ int TGlslangToSpvTraverser::getMatrixStride(const glslang::TType& matrixType)
|
|||||||
// 'currentOffset' should be passed in already initialized, ready to modify, and reflecting
|
// 'currentOffset' should be passed in already initialized, ready to modify, and reflecting
|
||||||
// the migration of data from nextOffset -> currentOffset. It should be -1 on the first call.
|
// the migration of data from nextOffset -> currentOffset. It should be -1 on the first call.
|
||||||
// -1 means a non-forced member offset (no decoration needed).
|
// -1 means a non-forced member offset (no decoration needed).
|
||||||
void TGlslangToSpvTraverser::updateMemberOffset(const glslang::TType& structType, const glslang::TType& memberType, int& currentOffset, int& nextOffset)
|
void TGlslangToSpvTraverser::updateMemberOffset(const glslang::TType& structType, const glslang::TType& memberType, int& currentOffset, int& nextOffset,
|
||||||
|
glslang::TLayoutPacking explicitLayout)
|
||||||
{
|
{
|
||||||
// this will get a positive value when deemed necessary
|
// this will get a positive value when deemed necessary
|
||||||
nextOffset = -1;
|
nextOffset = -1;
|
||||||
|
|
||||||
bool forceOffset = structType.getQualifier().layoutPacking == glslang::ElpStd140 ||
|
|
||||||
structType.getQualifier().layoutPacking == glslang::ElpStd430;
|
|
||||||
|
|
||||||
// override anything in currentOffset with user-set offset
|
// override anything in currentOffset with user-set offset
|
||||||
if (memberType.getQualifier().hasOffset())
|
if (memberType.getQualifier().hasOffset())
|
||||||
currentOffset = memberType.getQualifier().layoutOffset;
|
currentOffset = memberType.getQualifier().layoutOffset;
|
||||||
@@ -1684,14 +1696,14 @@ void TGlslangToSpvTraverser::updateMemberOffset(const glslang::TType& structType
|
|||||||
// once cross-compilation unit GLSL validation is done, as the original user
|
// once cross-compilation unit GLSL validation is done, as the original user
|
||||||
// settings are needed in layoutOffset, and then the following will come into play.
|
// settings are needed in layoutOffset, and then the following will come into play.
|
||||||
|
|
||||||
if (! forceOffset) {
|
if (explicitLayout == glslang::ElpNone) {
|
||||||
if (! memberType.getQualifier().hasOffset())
|
if (! memberType.getQualifier().hasOffset())
|
||||||
currentOffset = -1;
|
currentOffset = -1;
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Getting this far means we are forcing offsets
|
// Getting this far means we need explicit offsets
|
||||||
if (currentOffset < 0)
|
if (currentOffset < 0)
|
||||||
currentOffset = 0;
|
currentOffset = 0;
|
||||||
|
|
||||||
@@ -1699,7 +1711,7 @@ void TGlslangToSpvTraverser::updateMemberOffset(const glslang::TType& structType
|
|||||||
// but possibly not yet correctly aligned.
|
// but possibly not yet correctly aligned.
|
||||||
|
|
||||||
int memberSize;
|
int memberSize;
|
||||||
int memberAlignment = glslangIntermediate->getBaseAlignment(memberType, memberSize, memberType.getQualifier().layoutPacking == glslang::ElpStd140);
|
int memberAlignment = glslangIntermediate->getBaseAlignment(memberType, memberSize, explicitLayout == glslang::ElpStd140);
|
||||||
glslang::RoundToPow2(currentOffset, memberAlignment);
|
glslang::RoundToPow2(currentOffset, memberAlignment);
|
||||||
nextOffset = currentOffset + memberSize;
|
nextOffset = currentOffset + memberSize;
|
||||||
}
|
}
|
||||||
|
|||||||
138
Test/baseResults/spv.layoutNested.vert.out
Normal file
138
Test/baseResults/spv.layoutNested.vert.out
Normal file
@@ -0,0 +1,138 @@
|
|||||||
|
spv.layoutNested.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 54
|
||||||
|
|
||||||
|
Capability Shader
|
||||||
|
1: ExtInstImport "GLSL.std.450"
|
||||||
|
MemoryModel Logical GLSL450
|
||||||
|
EntryPoint Vertex 4 "main" 38 52 53
|
||||||
|
Source GLSL 450
|
||||||
|
Name 4 "main"
|
||||||
|
Name 13 "S"
|
||||||
|
MemberName 13(S) 0 "a"
|
||||||
|
MemberName 13(S) 1 "b"
|
||||||
|
MemberName 13(S) 2 "c"
|
||||||
|
Name 15 "s"
|
||||||
|
Name 18 "S"
|
||||||
|
MemberName 18(S) 0 "a"
|
||||||
|
MemberName 18(S) 1 "b"
|
||||||
|
MemberName 18(S) 2 "c"
|
||||||
|
Name 23 "Block140"
|
||||||
|
MemberName 23(Block140) 0 "u"
|
||||||
|
MemberName 23(Block140) 1 "s"
|
||||||
|
MemberName 23(Block140) 2 "v"
|
||||||
|
Name 25 "inst140"
|
||||||
|
Name 36 "gl_PerVertex"
|
||||||
|
MemberName 36(gl_PerVertex) 0 "gl_Position"
|
||||||
|
MemberName 36(gl_PerVertex) 1 "gl_PointSize"
|
||||||
|
MemberName 36(gl_PerVertex) 2 "gl_ClipDistance"
|
||||||
|
MemberName 36(gl_PerVertex) 3 "gl_CullDistance"
|
||||||
|
Name 38 ""
|
||||||
|
Name 45 "S"
|
||||||
|
MemberName 45(S) 0 "a"
|
||||||
|
MemberName 45(S) 1 "b"
|
||||||
|
MemberName 45(S) 2 "c"
|
||||||
|
Name 48 "Block430"
|
||||||
|
MemberName 48(Block430) 0 "u"
|
||||||
|
MemberName 48(Block430) 1 "s"
|
||||||
|
MemberName 48(Block430) 2 "v"
|
||||||
|
Name 50 "inst430"
|
||||||
|
Name 52 "gl_VertexID"
|
||||||
|
Name 53 "gl_InstanceID"
|
||||||
|
MemberDecorate 13(S) 1 ColMajor
|
||||||
|
Decorate 12 ArrayStride 32
|
||||||
|
MemberDecorate 18(S) 0 Offset 0
|
||||||
|
MemberDecorate 18(S) 1 ColMajor
|
||||||
|
MemberDecorate 18(S) 1 Offset 16
|
||||||
|
MemberDecorate 18(S) 1 MatrixStride 16
|
||||||
|
MemberDecorate 18(S) 2 Offset 144
|
||||||
|
Decorate 22 ArrayStride 16
|
||||||
|
MemberDecorate 23(Block140) 0 Offset 0
|
||||||
|
MemberDecorate 23(Block140) 1 Offset 16
|
||||||
|
MemberDecorate 23(Block140) 2 Offset 976
|
||||||
|
Decorate 23(Block140) Block
|
||||||
|
Decorate 25(inst140) DescriptorSet 0
|
||||||
|
Decorate 25(inst140) Binding 0
|
||||||
|
MemberDecorate 36(gl_PerVertex) 0 BuiltIn Position
|
||||||
|
MemberDecorate 36(gl_PerVertex) 1 BuiltIn PointSize
|
||||||
|
MemberDecorate 36(gl_PerVertex) 2 BuiltIn ClipDistance
|
||||||
|
MemberDecorate 36(gl_PerVertex) 3 BuiltIn CullDistance
|
||||||
|
Decorate 36(gl_PerVertex) Block
|
||||||
|
Decorate 12 ArrayStride 16
|
||||||
|
MemberDecorate 45(S) 0 Offset 0
|
||||||
|
MemberDecorate 45(S) 1 ColMajor
|
||||||
|
MemberDecorate 45(S) 1 Offset 16
|
||||||
|
MemberDecorate 45(S) 1 MatrixStride 8
|
||||||
|
MemberDecorate 45(S) 2 Offset 80
|
||||||
|
Decorate 47 ArrayStride 16
|
||||||
|
MemberDecorate 48(Block430) 0 Offset 0
|
||||||
|
MemberDecorate 48(Block430) 1 Offset 16
|
||||||
|
MemberDecorate 48(Block430) 2 Offset 592
|
||||||
|
Decorate 48(Block430) BufferBlock
|
||||||
|
Decorate 50(inst430) DescriptorSet 0
|
||||||
|
Decorate 50(inst430) Binding 1
|
||||||
|
Decorate 52(gl_VertexID) BuiltIn VertexId
|
||||||
|
Decorate 53(gl_InstanceID) BuiltIn InstanceId
|
||||||
|
2: TypeVoid
|
||||||
|
3: TypeFunction 2
|
||||||
|
6: TypeInt 32 0
|
||||||
|
7: TypeVector 6(int) 3
|
||||||
|
8: TypeFloat 32
|
||||||
|
9: TypeVector 8(float) 2
|
||||||
|
10: TypeMatrix 9(fvec2) 2
|
||||||
|
11: 6(int) Constant 4
|
||||||
|
12: TypeArray 10 11
|
||||||
|
13(S): TypeStruct 7(ivec3) 12 6(int)
|
||||||
|
14: TypePointer Private 13(S)
|
||||||
|
15(s): 14(ptr) Variable Private
|
||||||
|
16: TypeInt 32 1
|
||||||
|
17: 16(int) Constant 2
|
||||||
|
18(S): TypeStruct 7(ivec3) 12 6(int)
|
||||||
|
19: 6(int) Constant 3
|
||||||
|
20: TypeArray 18(S) 19
|
||||||
|
21: 6(int) Constant 2
|
||||||
|
22: TypeArray 20 21
|
||||||
|
23(Block140): TypeStruct 16(int) 22 9(fvec2)
|
||||||
|
24: TypePointer Uniform 23(Block140)
|
||||||
|
25(inst140): 24(ptr) Variable Uniform
|
||||||
|
26: 16(int) Constant 0
|
||||||
|
27: TypePointer Uniform 16(int)
|
||||||
|
31: TypePointer Private 6(int)
|
||||||
|
33: TypeVector 8(float) 4
|
||||||
|
34: 6(int) Constant 1
|
||||||
|
35: TypeArray 8(float) 34
|
||||||
|
36(gl_PerVertex): TypeStruct 33(fvec4) 8(float) 35 35
|
||||||
|
37: TypePointer Output 36(gl_PerVertex)
|
||||||
|
38: 37(ptr) Variable Output
|
||||||
|
43: TypePointer Output 33(fvec4)
|
||||||
|
45(S): TypeStruct 7(ivec3) 12 6(int)
|
||||||
|
46: TypeArray 45(S) 19
|
||||||
|
47: TypeArray 46 21
|
||||||
|
48(Block430): TypeStruct 16(int) 47 9(fvec2)
|
||||||
|
49: TypePointer Uniform 48(Block430)
|
||||||
|
50(inst430): 49(ptr) Variable Uniform
|
||||||
|
51: TypePointer Input 16(int)
|
||||||
|
52(gl_VertexID): 51(ptr) Variable Input
|
||||||
|
53(gl_InstanceID): 51(ptr) Variable Input
|
||||||
|
4(main): 2 Function None 3
|
||||||
|
5: Label
|
||||||
|
28: 27(ptr) AccessChain 25(inst140) 26
|
||||||
|
29: 16(int) Load 28
|
||||||
|
30: 6(int) Bitcast 29
|
||||||
|
32: 31(ptr) AccessChain 15(s) 17
|
||||||
|
Store 32 30
|
||||||
|
39: 31(ptr) AccessChain 15(s) 17
|
||||||
|
40: 6(int) Load 39
|
||||||
|
41: 8(float) ConvertUToF 40
|
||||||
|
42: 33(fvec4) CompositeConstruct 41 41 41 41
|
||||||
|
44: 43(ptr) AccessChain 38 26
|
||||||
|
Store 44 42
|
||||||
|
Return
|
||||||
|
FunctionEnd
|
||||||
31
Test/spv.layoutNested.vert
Normal file
31
Test/spv.layoutNested.vert
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
#version 450
|
||||||
|
|
||||||
|
// should get 3 SPV types: no layout, 140, and 430
|
||||||
|
struct S
|
||||||
|
{
|
||||||
|
highp uvec3 a;
|
||||||
|
mediump mat2 b[4];
|
||||||
|
lowp uint c;
|
||||||
|
};
|
||||||
|
|
||||||
|
layout(set = 0, binding = 0, std140) uniform Block140
|
||||||
|
{
|
||||||
|
mediump int u;
|
||||||
|
S s[2][3];
|
||||||
|
mediump vec2 v;
|
||||||
|
} inst140;
|
||||||
|
|
||||||
|
layout(set = 0, binding = 1, std430) buffer Block430
|
||||||
|
{
|
||||||
|
mediump int u;
|
||||||
|
S s[2][3];
|
||||||
|
mediump vec2 v;
|
||||||
|
} inst430;
|
||||||
|
|
||||||
|
S s;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
s.c = inst140.u;
|
||||||
|
gl_Position = vec4(s.c);
|
||||||
|
}
|
||||||
@@ -48,6 +48,7 @@ spv.forwardFun.frag
|
|||||||
spv.functionCall.frag
|
spv.functionCall.frag
|
||||||
spv.functionSemantics.frag
|
spv.functionSemantics.frag
|
||||||
spv.interpOps.frag
|
spv.interpOps.frag
|
||||||
|
spv.layoutNested.vert
|
||||||
spv.length.frag
|
spv.length.frag
|
||||||
spv.localAggregates.frag
|
spv.localAggregates.frag
|
||||||
spv.loops.frag
|
spv.loops.frag
|
||||||
|
|||||||
@@ -2,5 +2,5 @@
|
|||||||
// For the version, it uses the latest git tag followed by the number of commits.
|
// For the version, it uses the latest git tag followed by the number of commits.
|
||||||
// For the date, it uses the current date (when then script is run).
|
// For the date, it uses the current date (when then script is run).
|
||||||
|
|
||||||
#define GLSLANG_REVISION "SPIRV99.851"
|
#define GLSLANG_REVISION "SPIRV99.860"
|
||||||
#define GLSLANG_DATE "19-Dec-2015"
|
#define GLSLANG_DATE "19-Dec-2015"
|
||||||
|
|||||||
Reference in New Issue
Block a user