mirror of
https://github.com/RPCS3/glslang.git
synced 2024-11-23 19:29:44 +00:00
SPV arrays: Add support for runtime-sized array types and arrays of arrays.
This includes run-time block.member.length() (OpArrayLength).
This commit is contained in:
parent
9312269d09
commit
c9a808319a
@ -680,6 +680,24 @@ bool TGlslangToSpvTraverser::visitUnary(glslang::TVisit /* visit */, glslang::TI
|
||||
}
|
||||
|
||||
// Non-texturing.
|
||||
|
||||
if (node->getOp() == glslang::EOpArrayLength) {
|
||||
// Quite special; won't want to evaluate the operand.
|
||||
|
||||
// Normal .length() would have been constant folded by the front-end.
|
||||
// So, this has to be block.lastMember.length().
|
||||
// SPV wants "block" as the operand, go get it.
|
||||
assert(node->getOperand()->getType().isRuntimeSizedArray());
|
||||
glslang::TIntermTyped* block = node->getOperand()->getAsBinaryNode()->getLeft();
|
||||
block->traverse(this);
|
||||
spv::Id length = builder.createUnaryOp(spv::OpArrayLength, builder.makeIntType(32), builder.accessChainGetLValue());
|
||||
|
||||
builder.clearAccessChain();
|
||||
builder.setAccessChainRValue(length);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Start by evaluating the operand
|
||||
|
||||
builder.clearAccessChain();
|
||||
@ -967,17 +985,6 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
|
||||
// which can be emitted by the one in createBinaryOperation()
|
||||
binOp = glslang::EOpMod;
|
||||
break;
|
||||
case glslang::EOpArrayLength:
|
||||
{
|
||||
glslang::TIntermTyped* typedNode = node->getSequence()[0]->getAsTyped();
|
||||
assert(typedNode);
|
||||
spv::Id length = builder.makeIntConstant(typedNode->getType().getOuterArraySize());
|
||||
|
||||
builder.clearAccessChain();
|
||||
builder.setAccessChainRValue(length);
|
||||
|
||||
return false;
|
||||
}
|
||||
case glslang::EOpEmitVertex:
|
||||
case glslang::EOpEndPrimitive:
|
||||
case glslang::EOpBarrier:
|
||||
@ -1468,14 +1475,23 @@ spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& ty
|
||||
}
|
||||
|
||||
if (type.isArray()) {
|
||||
unsigned arraySize;
|
||||
if (! type.isExplicitlySizedArray()) {
|
||||
spv::MissingFunctionality("Unsized array");
|
||||
arraySize = 8;
|
||||
} else
|
||||
arraySize = type.getOuterArraySize();
|
||||
spvType = builder.makeArrayType(spvType, arraySize);
|
||||
// Do all but the outer dimension
|
||||
for (int dim = type.getArraySizes()->getNumDims() - 1; dim > 0; --dim) {
|
||||
assert(type.getArraySizes()->getDimSize(dim) > 0);
|
||||
spvType = builder.makeArrayType(spvType, type.getArraySizes()->getDimSize(dim));
|
||||
}
|
||||
|
||||
// Do the outer dimension, which might not be known for a runtime-sized array
|
||||
if (type.isRuntimeSizedArray()) {
|
||||
spvType = builder.makeRuntimeArray(spvType);
|
||||
} else {
|
||||
assert(type.getOuterArraySize() > 0);
|
||||
spvType = builder.makeArrayType(spvType, type.getOuterArraySize());
|
||||
}
|
||||
|
||||
// TODO: layout still needs to be done hierarchically for arrays of arrays, which
|
||||
// may still require additional "link time" support from the front-end
|
||||
// for arrays of arrays
|
||||
if (explicitLayout)
|
||||
builder.addDecoration(spvType, spv::DecorationArrayStride, getArrayStride(type));
|
||||
}
|
||||
|
@ -264,6 +264,16 @@ Id Builder::makeArrayType(Id element, unsigned size)
|
||||
return type->getResultId();
|
||||
}
|
||||
|
||||
Id Builder::makeRuntimeArray(Id element)
|
||||
{
|
||||
Instruction* type = new Instruction(getUniqueId(), NoType, OpTypeRuntimeArray);
|
||||
type->addIdOperand(element);
|
||||
constantsTypesGlobals.push_back(type);
|
||||
module.mapInstruction(type);
|
||||
|
||||
return type->getResultId();
|
||||
}
|
||||
|
||||
Id Builder::makeFunctionType(Id returnType, std::vector<Id>& paramTypes)
|
||||
{
|
||||
// try to find it
|
||||
@ -280,7 +290,7 @@ Id Builder::makeFunctionType(Id returnType, std::vector<Id>& paramTypes)
|
||||
}
|
||||
}
|
||||
if (! mismatch)
|
||||
return type->getResultId();
|
||||
return type->getResultId();
|
||||
}
|
||||
|
||||
// not found, make it
|
||||
|
@ -102,6 +102,7 @@ public:
|
||||
Id makeVectorType(Id component, int size);
|
||||
Id makeMatrixType(Id component, int cols, int rows);
|
||||
Id makeArrayType(Id element, unsigned size);
|
||||
Id makeRuntimeArray(Id element);
|
||||
Id makeFunctionType(Id returnType, std::vector<Id>& paramTypes);
|
||||
Id makeImageType(Id sampledType, Dim, bool depth, bool arrayed, bool ms, unsigned sampled, ImageFormat format);
|
||||
Id makeSampledImageType(Id imageType);
|
||||
|
@ -5,4 +5,121 @@ Warning, version 310 is not yet complete; most version-specific features are pre
|
||||
Linked compute stage:
|
||||
|
||||
|
||||
Missing functionality: Unsized array
|
||||
// Module Version 99
|
||||
// Generated by (magic number): 51a00bb
|
||||
// Id's are bound by 72
|
||||
|
||||
Source ESSL 310
|
||||
Capability Shader
|
||||
1: ExtInstImport "GLSL.std.450"
|
||||
MemoryModel Logical GLSL450
|
||||
EntryPoint GLCompute 4 "main"
|
||||
Name 4 "main"
|
||||
Name 14 "outb"
|
||||
MemberName 14(outb) 0 "f"
|
||||
MemberName 14(outb) 1 "g"
|
||||
MemberName 14(outb) 2 "h"
|
||||
MemberName 14(outb) 3 "uns"
|
||||
Name 16 "outbname"
|
||||
Name 20 "s"
|
||||
Name 25 "outbna"
|
||||
MemberName 25(outbna) 0 "k"
|
||||
MemberName 25(outbna) 1 "na"
|
||||
Name 27 "outbnamena"
|
||||
Name 47 "i"
|
||||
Name 53 "outs"
|
||||
MemberName 53(outs) 0 "s"
|
||||
MemberName 53(outs) 1 "va"
|
||||
Name 55 "outnames"
|
||||
Name 59 "gl_LocalInvocationID"
|
||||
Decorate 14(outb) GLSLShared
|
||||
Decorate 14(outb) BufferBlock
|
||||
Decorate 25(outbna) GLSLShared
|
||||
Decorate 25(outbna) BufferBlock
|
||||
Decorate 53(outs) GLSLShared
|
||||
Decorate 53(outs) BufferBlock
|
||||
Decorate 59(gl_LocalInvocationID) BuiltIn LocalInvocationId
|
||||
Decorate 71 BuiltIn WorkgroupSize
|
||||
Decorate 71 NoStaticUse
|
||||
2: TypeVoid
|
||||
3: TypeFunction 2
|
||||
7: TypeInt 32 0
|
||||
8: 7(int) Constant 1
|
||||
9: 7(int) Constant 1023
|
||||
10: 7(int) Constant 0
|
||||
11: TypeFloat 32
|
||||
12: TypeVector 11(float) 3
|
||||
13: TypeRuntimeArray 12(fvec3)
|
||||
14(outb): TypeStruct 11(float) 11(float) 11(float) 13
|
||||
15: TypePointer Uniform 14(outb)
|
||||
16(outbname): 15(ptr) Variable Uniform
|
||||
17: TypeInt 32 1
|
||||
18: 17(int) Constant 0
|
||||
19: TypePointer WorkgroupLocal 11(float)
|
||||
20(s): 19(ptr) Variable WorkgroupLocal
|
||||
22: TypePointer Uniform 11(float)
|
||||
24: TypeVector 11(float) 4
|
||||
25(outbna): TypeStruct 17(int) 24(fvec4)
|
||||
26: TypePointer Uniform 25(outbna)
|
||||
27(outbnamena): 26(ptr) Variable Uniform
|
||||
28: 17(int) Constant 1
|
||||
31: TypePointer Uniform 24(fvec4)
|
||||
33: TypeRuntimeArray 12(fvec3)
|
||||
34: 17(int) Constant 3
|
||||
35: 17(int) Constant 18
|
||||
36: TypePointer Uniform 12(fvec3)
|
||||
40: TypeRuntimeArray 12(fvec3)
|
||||
41: 17(int) Constant 17
|
||||
42: 11(float) Constant 1077936128
|
||||
43: 12(fvec3) ConstantComposite 42 42 42
|
||||
45: TypeRuntimeArray 12(fvec3)
|
||||
46: TypePointer WorkgroupLocal 17(int)
|
||||
47(i): 46(ptr) Variable WorkgroupLocal
|
||||
52: TypeRuntimeArray 24(fvec4)
|
||||
53(outs): TypeStruct 17(int) 52
|
||||
54: TypePointer Uniform 53(outs)
|
||||
55(outnames): 54(ptr) Variable Uniform
|
||||
56: TypeRuntimeArray 24(fvec4)
|
||||
57: TypeVector 7(int) 3
|
||||
58: TypePointer Input 57(ivec3)
|
||||
59(gl_LocalInvocationID): 58(ptr) Variable Input
|
||||
66: TypePointer Uniform 17(int)
|
||||
68: 7(int) Constant 16
|
||||
69: 7(int) Constant 32
|
||||
70: 7(int) Constant 4
|
||||
71: 57(ivec3) ConstantComposite 68 69 70
|
||||
4(main): 2 Function None 3
|
||||
5: Label
|
||||
MemoryBarrier 8 9
|
||||
ControlBarrier 8 8 10
|
||||
21: 11(float) Load 20(s)
|
||||
23: 22(ptr) AccessChain 16(outbname) 18
|
||||
Store 23 21
|
||||
29: 11(float) Load 20(s)
|
||||
30: 24(fvec4) CompositeConstruct 29 29 29 29
|
||||
32: 31(ptr) AccessChain 27(outbnamena) 28
|
||||
Store 32 30
|
||||
37: 36(ptr) AccessChain 16(outbname) 34 35
|
||||
38: 12(fvec3) Load 37
|
||||
39: 11(float) CompositeExtract 38 0
|
||||
Store 20(s) 39
|
||||
44: 36(ptr) AccessChain 16(outbname) 34 41
|
||||
Store 44 43
|
||||
48: 17(int) Load 47(i)
|
||||
49: 11(float) Load 20(s)
|
||||
50: 12(fvec3) CompositeConstruct 49 49 49
|
||||
51: 36(ptr) AccessChain 16(outbname) 34 48
|
||||
Store 51 50
|
||||
60: 57(ivec3) Load 59(gl_LocalInvocationID)
|
||||
61: 7(int) CompositeExtract 60 0
|
||||
62: 11(float) Load 20(s)
|
||||
63: 24(fvec4) CompositeConstruct 62 62 62 62
|
||||
64: 31(ptr) AccessChain 55(outnames) 28 61
|
||||
Store 64 63
|
||||
65: 17(int) ArrayLength 16(outbname)
|
||||
67: 66(ptr) AccessChain 55(outnames) 18
|
||||
Store 67 65
|
||||
Branch 6
|
||||
6: Label
|
||||
Return
|
||||
FunctionEnd
|
||||
|
154
Test/baseResults/spv.AofA.frag.out
Normal file
154
Test/baseResults/spv.AofA.frag.out
Normal file
@ -0,0 +1,154 @@
|
||||
spv.AofA.frag
|
||||
Warning, version 430 is not yet complete; most version-specific features are present, but some are missing.
|
||||
|
||||
|
||||
Linked fragment stage:
|
||||
|
||||
|
||||
// Module Version 99
|
||||
// Generated by (magic number): 51a00bb
|
||||
// Id's are bound by 104
|
||||
|
||||
Source GLSL 430
|
||||
Capability Shader
|
||||
1: ExtInstImport "GLSL.std.450"
|
||||
MemoryModel Logical GLSL450
|
||||
EntryPoint Fragment 4 "main"
|
||||
ExecutionMode 4 OriginLowerLeft
|
||||
Name 4 "main"
|
||||
Name 18 "foo(f1[5][7];"
|
||||
Name 17 "a"
|
||||
Name 21 "r"
|
||||
Name 39 "outfloat"
|
||||
Name 42 "g4"
|
||||
Name 44 "g5"
|
||||
Name 45 "param"
|
||||
Name 48 "u"
|
||||
Name 52 "param"
|
||||
Name 66 "many"
|
||||
Name 68 "i"
|
||||
Name 70 "j"
|
||||
Name 72 "k"
|
||||
Name 78 "infloat"
|
||||
Name 94 "uAofA"
|
||||
MemberName 94(uAofA) 0 "f"
|
||||
Name 98 "nameAofA"
|
||||
Decorate 44(g5) Smooth
|
||||
Decorate 78(infloat) Smooth
|
||||
Decorate 94(uAofA) GLSLShared
|
||||
Decorate 94(uAofA) Block
|
||||
2: TypeVoid
|
||||
3: TypeFunction 2
|
||||
7: TypeFloat 32
|
||||
8: TypeInt 32 0
|
||||
9: 8(int) Constant 7
|
||||
10: TypeArray 7(float) 9
|
||||
11: 8(int) Constant 5
|
||||
12: TypeArray 10 11
|
||||
13: TypePointer Function 12
|
||||
14: 8(int) Constant 4
|
||||
15: TypeArray 10 14
|
||||
16: TypeFunction 15 13(ptr)
|
||||
20: TypePointer Function 10
|
||||
22: TypeInt 32 1
|
||||
23: 22(int) Constant 2
|
||||
26: 22(int) Constant 0
|
||||
29: 22(int) Constant 1
|
||||
33: 22(int) Constant 3
|
||||
38: TypePointer Output 7(float)
|
||||
39(outfloat): 38(ptr) Variable Output
|
||||
40: 7(float) Constant 0
|
||||
41: TypePointer PrivateGlobal 15
|
||||
42(g4): 41(ptr) Variable PrivateGlobal
|
||||
43: TypePointer Input 12
|
||||
44(g5): 43(ptr) Variable Input
|
||||
49: 7(float) Constant 1077936128
|
||||
50: TypePointer Function 7(float)
|
||||
55: 8(int) Constant 6
|
||||
56: TypeArray 7(float) 55
|
||||
57: TypeArray 56 11
|
||||
58: TypeArray 57 14
|
||||
59: 8(int) Constant 3
|
||||
60: TypeArray 58 59
|
||||
61: 8(int) Constant 2
|
||||
62: TypeArray 60 61
|
||||
63: 8(int) Constant 1
|
||||
64: TypeArray 62 63
|
||||
65: TypePointer PrivateGlobal 64
|
||||
66(many): 65(ptr) Variable PrivateGlobal
|
||||
67: TypePointer UniformConstant 22(int)
|
||||
68(i): 67(ptr) Variable UniformConstant
|
||||
70(j): 67(ptr) Variable UniformConstant
|
||||
72(k): 67(ptr) Variable UniformConstant
|
||||
77: TypePointer Input 7(float)
|
||||
78(infloat): 77(ptr) Variable Input
|
||||
80: TypePointer PrivateGlobal 7(float)
|
||||
92: TypeArray 7(float) 14
|
||||
93: TypeArray 92 61
|
||||
94(uAofA): TypeStruct 93
|
||||
95: TypeArray 94(uAofA) 11
|
||||
96: TypeArray 95 59
|
||||
97: TypePointer Uniform 96
|
||||
98(nameAofA): 97(ptr) Variable Uniform
|
||||
99: TypePointer Uniform 7(float)
|
||||
4(main): 2 Function None 3
|
||||
5: Label
|
||||
45(param): 13(ptr) Variable Function
|
||||
48(u): 13(ptr) Variable Function
|
||||
52(param): 13(ptr) Variable Function
|
||||
Store 39(outfloat) 40
|
||||
46: 12 Load 44(g5)
|
||||
Store 45(param) 46
|
||||
47: 15 FunctionCall 18(foo(f1[5][7];) 45(param)
|
||||
Store 42(g4) 47
|
||||
51: 50(ptr) AccessChain 48(u) 23 23
|
||||
Store 51 49
|
||||
53: 12 Load 48(u)
|
||||
Store 52(param) 53
|
||||
54: 15 FunctionCall 18(foo(f1[5][7];) 52(param)
|
||||
69: 22(int) Load 68(i)
|
||||
71: 22(int) Load 70(j)
|
||||
73: 22(int) Load 72(k)
|
||||
74: 22(int) Load 68(i)
|
||||
75: 22(int) Load 70(j)
|
||||
76: 22(int) Load 72(k)
|
||||
79: 7(float) Load 78(infloat)
|
||||
81: 80(ptr) AccessChain 66(many) 69 71 73 74 75 76
|
||||
Store 81 79
|
||||
82: 22(int) Load 70(j)
|
||||
83: 22(int) Load 70(j)
|
||||
84: 22(int) Load 70(j)
|
||||
85: 22(int) Load 70(j)
|
||||
86: 22(int) Load 70(j)
|
||||
87: 22(int) Load 70(j)
|
||||
88: 80(ptr) AccessChain 66(many) 82 83 84 85 86 87
|
||||
89: 7(float) Load 88
|
||||
90: 7(float) Load 39(outfloat)
|
||||
91: 7(float) FAdd 90 89
|
||||
Store 39(outfloat) 91
|
||||
100: 99(ptr) AccessChain 98(nameAofA) 29 23 26 26 33
|
||||
101: 7(float) Load 100
|
||||
102: 7(float) Load 39(outfloat)
|
||||
103: 7(float) FAdd 102 101
|
||||
Store 39(outfloat) 103
|
||||
Branch 6
|
||||
6: Label
|
||||
Return
|
||||
FunctionEnd
|
||||
18(foo(f1[5][7];): 15 Function None 16
|
||||
17(a): 13(ptr) FunctionParameter
|
||||
19: Label
|
||||
21(r): 20(ptr) Variable Function
|
||||
24: 20(ptr) AccessChain 17(a) 23
|
||||
25: 10 Load 24
|
||||
Store 21(r) 25
|
||||
27: 20(ptr) AccessChain 17(a) 26
|
||||
28: 10 Load 27
|
||||
30: 20(ptr) AccessChain 17(a) 29
|
||||
31: 10 Load 30
|
||||
32: 10 Load 21(r)
|
||||
34: 20(ptr) AccessChain 17(a) 33
|
||||
35: 10 Load 34
|
||||
36: 15 CompositeConstruct 28 31 32 35
|
||||
ReturnValue 36
|
||||
FunctionEnd
|
@ -11,9 +11,7 @@ buffer outb {
|
||||
float f;
|
||||
float g;
|
||||
float h;
|
||||
vec3 uns[]; // this makes it look like the "second" set of 3 floats in a struct, which LLVM
|
||||
// takes advantage of when optimizing, giving confusing results, like thinking
|
||||
// &outbname.uns[18].x == &outbname[9].uns.x
|
||||
vec3 uns[];
|
||||
} outbname;
|
||||
|
||||
buffer outbna {
|
||||
@ -22,6 +20,7 @@ buffer outbna {
|
||||
} outbnamena;
|
||||
|
||||
buffer outs {
|
||||
int s;
|
||||
vec4 va[];
|
||||
} outnames;
|
||||
|
||||
@ -30,8 +29,9 @@ void main()
|
||||
barrier();
|
||||
outbname.f = s;
|
||||
outbnamena.na = vec4(s);
|
||||
s = outbname.uns[18].x; // TODO: see note above
|
||||
//outbname.uns[17] = vec3(3.0); // TODO: see note above, this one bitcasts, which isn't handled
|
||||
s = outbname.uns[18].x;
|
||||
outbname.uns[17] = vec3(3.0);
|
||||
outbname.uns[i] = vec3(s);
|
||||
outnames.va[gl_LocalInvocationID.x] = vec4(s);
|
||||
outnames.s = outbname.uns.length();
|
||||
}
|
||||
|
43
Test/spv.AofA.frag
Normal file
43
Test/spv.AofA.frag
Normal file
@ -0,0 +1,43 @@
|
||||
#version 430
|
||||
|
||||
in float infloat;
|
||||
out float outfloat;
|
||||
|
||||
uniform uAofA {
|
||||
float f[2][4];
|
||||
} nameAofA[3][5];
|
||||
|
||||
float[4][5][6] many[1][2][3];
|
||||
|
||||
float g4[4][7];
|
||||
in float g5[5][7];
|
||||
|
||||
uniform int i, j, k;
|
||||
|
||||
float[4][7] foo(float a[5][7])
|
||||
{
|
||||
float r[7];
|
||||
r = a[2];
|
||||
|
||||
return float[4][7](a[0], a[1], r, a[3]);
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
outfloat = 0.0;
|
||||
|
||||
g4 = foo(g5);
|
||||
|
||||
// if (foo(g5) == g4)
|
||||
// ++outfloat;
|
||||
|
||||
float u[][7];
|
||||
u[2][2] = 3.0;
|
||||
float u[5][7];
|
||||
|
||||
foo(u);
|
||||
|
||||
many[i][j][k][i][j][k] = infloat;
|
||||
outfloat += many[j][j][j][j][j][j];
|
||||
outfloat += nameAofA[1][2].f[0][3];
|
||||
}
|
@ -79,3 +79,4 @@ spv.varyingArrayIndirect.frag
|
||||
spv.voidFunction.frag
|
||||
spv.whileLoop.frag
|
||||
spv.atomic.comp
|
||||
spv.AofA.frag
|
||||
|
@ -2,5 +2,5 @@
|
||||
// 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).
|
||||
|
||||
#define GLSLANG_REVISION "3.0.748"
|
||||
#define GLSLANG_DATE "11-Sep-2015"
|
||||
#define GLSLANG_REVISION "3.0.750"
|
||||
#define GLSLANG_DATE "13-Sep-2015"
|
||||
|
Loading…
Reference in New Issue
Block a user