Handle SPIR-V type mismatch when constructing a composite

This commit is contained in:
Jeff Bolz 2019-06-25 13:31:10 -05:00
parent 4e6b9ea329
commit 531344905f
6 changed files with 213 additions and 1 deletions

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

@ -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

@ -295,6 +295,7 @@ INSTANTIATE_TEST_CASE_P(
"spv.bufferhandle_Error.frag",
"spv.builtInXFB.vert",
"spv.conditionalDiscard.frag",
"spv.constructComposite.comp",
"spv.constStruct.vert",
"spv.constConstruct.vert",
"spv.controlFlowAttributes.frag",
@ -482,6 +483,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
);