Fix spec const construtor for matrix and vector
Fix issue: #237 1. The code generated for matrix constructor should 1) build column vectors first, 2) build matrix with the vectors. 2. When there is only one scalar type constituent in vector's constructor, we should populate the constituent to fill all the slots in the vector. As for matrix, the single constituent should be populated to the diagonal positions (top-left to bottom-right diagonal). remove createSpvConstantFromConstSubTree()
This commit is contained in:
parent
e1cd410d9c
commit
27e04a004d
@ -151,7 +151,6 @@ protected:
|
||||
void addMemberDecoration(spv::Id id, int member, spv::Decoration dec, unsigned value);
|
||||
spv::Id createSpvConstant(const glslang::TIntermTyped&);
|
||||
spv::Id createSpvConstantFromConstUnionArray(const glslang::TType& type, const glslang::TConstUnionArray&, int& nextConst, bool specConstant);
|
||||
spv::Id createSpvConstantFromConstSubTree(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);
|
||||
@ -1113,6 +1112,10 @@ bool TGlslangToSpvTraverser::visitUnary(glslang::TVisit /* visit */, glslang::TI
|
||||
|
||||
bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TIntermAggregate* node)
|
||||
{
|
||||
SpecConstantOpModeGuard spec_constant_op_mode_setter(&builder);
|
||||
if (node->getType().getQualifier().isSpecConstant())
|
||||
spec_constant_op_mode_setter.turnOnSpecConstantOpMode();
|
||||
|
||||
spv::Id result = spv::NoResult;
|
||||
|
||||
// try texturing
|
||||
@ -3814,7 +3817,11 @@ spv::Id TGlslangToSpvTraverser::createSpvConstant(const glslang::TIntermTyped& n
|
||||
// Its initializer should either be a sub tree with constant nodes, or a constant union array.
|
||||
if (auto* sn = node.getAsSymbolNode()) {
|
||||
if (auto* sub_tree = sn->getConstSubtree()) {
|
||||
return createSpvConstantFromConstSubTree(sub_tree);
|
||||
// Traverse the constant constructor sub tree like generating normal run-time instructions.
|
||||
// During the AST traversal, if the node is marked as 'specConstant', SpecConstantOpModeGuard
|
||||
// will set the builder into spec constant op instruction generating mode.
|
||||
sub_tree->traverse(this);
|
||||
return accessChainLoad(sub_tree->getType());
|
||||
} else if (auto* const_union_array = &sn->getConstArray()){
|
||||
int nextConst = 0;
|
||||
return createSpvConstantFromConstUnionArray(sn->getType(), *const_union_array, nextConst, true);
|
||||
@ -3910,68 +3917,6 @@ spv::Id TGlslangToSpvTraverser::createSpvConstantFromConstUnionArray(const glsla
|
||||
return builder.makeCompositeConstant(typeId, spvConsts);
|
||||
}
|
||||
|
||||
// Create constant ID from const initializer sub tree.
|
||||
spv::Id TGlslangToSpvTraverser::createSpvConstantFromConstSubTree(
|
||||
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 (glslang::TIntermBinary* bn = subTree->getAsBinaryNode()) {
|
||||
// Binary operation node, we should generate OpSpecConstantOp <binary op>
|
||||
// This case should only happen when Specialization Constants are involved.
|
||||
bn->traverse(this);
|
||||
return accessChainLoad(bn->getType());
|
||||
|
||||
} else if (glslang::TIntermUnary* un = subTree->getAsUnaryNode()) {
|
||||
// Unary operation node, similar to binary operation node, should only
|
||||
// happen when specialization constants are involved.
|
||||
un->traverse(this);
|
||||
return accessChainLoad(un->getType());
|
||||
|
||||
} 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)
|
||||
|
||||
@ -645,6 +645,21 @@ bool Builder::isConstantOpCode(Op opcode) const
|
||||
}
|
||||
}
|
||||
|
||||
// Return true if consuming 'opcode' means consuming a specialization constant.
|
||||
bool Builder::isSpecConstantOpCode(Op opcode) const
|
||||
{
|
||||
switch (opcode) {
|
||||
case OpSpecConstantTrue:
|
||||
case OpSpecConstantFalse:
|
||||
case OpSpecConstant:
|
||||
case OpSpecConstantComposite:
|
||||
case OpSpecConstantOp:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Id Builder::makeBoolConstant(bool b, bool specConstant)
|
||||
{
|
||||
Id typeId = makeBoolType();
|
||||
@ -1345,13 +1360,9 @@ Id Builder::smearScalar(Decoration precision, Id scalar, Id vectorType)
|
||||
Instruction* smear = nullptr;
|
||||
if (generatingOpCodeForSpecConst) {
|
||||
auto members = std::vector<spv::Id>(numComponents, scalar);
|
||||
// 'scalar' can not be spec constant here. All spec constant involved
|
||||
// promotion is done in createSpvConstantFromConstUnionArray(). This
|
||||
// 'if' branch is only accessed when 'scalar' is used in the def-chain
|
||||
// of other vector type spec constants. In such cases, all the
|
||||
// instructions needed to promote 'scalar' to a vector type constants
|
||||
// should be added at module level.
|
||||
auto result_id = makeCompositeConstant(vectorType, members, false);
|
||||
// "generatingOpCodeForSpecConst == true" does not mean the generated vector
|
||||
// is a spec constant vector. It depends on the scalar.
|
||||
auto result_id = makeCompositeConstant(vectorType, members, isSpecConstant(scalar));
|
||||
smear = module.getInstruction(result_id);
|
||||
} else {
|
||||
smear = new Instruction(getUniqueId(), vectorType, OpCompositeConstruct);
|
||||
@ -1714,6 +1725,10 @@ Id Builder::createCompositeConstruct(Id typeId, std::vector<Id>& constituents)
|
||||
{
|
||||
assert(isAggregateType(typeId) || (getNumTypeConstituents(typeId) > 1 && getNumTypeConstituents(typeId) == (int)constituents.size()));
|
||||
|
||||
if (generatingOpCodeForSpecConst) {
|
||||
return makeCompositeConstant(typeId, constituents, true);
|
||||
}
|
||||
|
||||
Instruction* op = new Instruction(getUniqueId(), typeId, OpCompositeConstruct);
|
||||
for (int c = 0; c < (int)constituents.size(); ++c)
|
||||
op->addIdOperand(constituents[c]);
|
||||
|
||||
@ -147,8 +147,10 @@ public:
|
||||
bool isSampledImageType(Id typeId) const { return getTypeClass(typeId) == OpTypeSampledImage; }
|
||||
|
||||
bool isConstantOpCode(Op opcode) const;
|
||||
bool isSpecConstantOpCode(Op opcode) const;
|
||||
bool isConstant(Id resultId) const { return isConstantOpCode(getOpCode(resultId)); }
|
||||
bool isConstantScalar(Id resultId) const { return getOpCode(resultId) == OpConstant; }
|
||||
bool isSpecConstant(Id resultId) const { return isSpecConstantOpCode(getOpCode(resultId)); }
|
||||
unsigned int getConstantScalar(Id resultId) const { return module.getInstruction(resultId)->getImmediateOperand(0); }
|
||||
StorageClass getStorageClass(Id resultId) const { return getTypeStorageClass(getTypeId(resultId)); }
|
||||
|
||||
|
||||
@ -7,13 +7,13 @@ Linked vertex stage:
|
||||
|
||||
// Module Version 10000
|
||||
// Generated by (magic number): 80001
|
||||
// Id's are bound by 106
|
||||
// Id's are bound by 119
|
||||
|
||||
Capability Shader
|
||||
Capability Float64
|
||||
1: ExtInstImport "GLSL.std.450"
|
||||
MemoryModel Logical GLSL450
|
||||
EntryPoint Vertex 4 "main" 27 105
|
||||
EntryPoint Vertex 4 "main" 27 118
|
||||
Source GLSL 450
|
||||
Name 4 "main"
|
||||
Name 6 "refer_primary_spec_const("
|
||||
@ -23,23 +23,23 @@ Linked vertex stage:
|
||||
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 42 "flat_struct"
|
||||
MemberName 42(flat_struct) 0 "i"
|
||||
MemberName 42(flat_struct) 1 "f"
|
||||
MemberName 42(flat_struct) 2 "d"
|
||||
MemberName 42(flat_struct) 3 "b"
|
||||
Name 44 "nesting_struct"
|
||||
MemberName 44(nesting_struct) 0 "nested"
|
||||
MemberName 44(nesting_struct) 1 "v"
|
||||
MemberName 44(nesting_struct) 2 "i"
|
||||
Name 72 "indexable"
|
||||
Name 76 "indexable"
|
||||
Name 83 "len"
|
||||
Name 105 "global_vec4_array_with_spec_length"
|
||||
Name 118 "global_vec4_array_with_spec_length"
|
||||
Decorate 21 SpecId 203
|
||||
Decorate 28 SpecId 200
|
||||
Decorate 32 SpecId 201
|
||||
Decorate 43 SpecId 202
|
||||
Decorate 41 SpecId 202
|
||||
2: TypeVoid
|
||||
3: TypeFunction 2
|
||||
14: TypeInt 32 1
|
||||
@ -56,40 +56,53 @@ Linked vertex stage:
|
||||
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
|
||||
41: 40(float) SpecConstant 1413754136 1074340347
|
||||
42(flat_struct): TypeStruct 14(int) 24(float) 40(float) 20(bool)
|
||||
43:42(flat_struct) SpecConstantComposite 28 32 41 21
|
||||
44(nesting_struct): TypeStruct 42(flat_struct) 25(fvec4) 14(int)
|
||||
45:44(nesting_struct) SpecConstantComposite 43 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
|
||||
57: 24(float) Constant 1065353216
|
||||
58: 24(float) Constant 1073741824
|
||||
59: 24(float) Constant 1077936128
|
||||
60: 51(int) Constant 5
|
||||
61: TypeArray 24(float) 60
|
||||
62: 61 SpecConstantComposite 32 32 57 58 59
|
||||
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
|
||||
68: 14(int) Constant 30
|
||||
69: TypeArray 14(int) 60
|
||||
70: 69 SpecConstantComposite 28 28 63 46 68
|
||||
71: TypePointer Function 69
|
||||
73: TypePointer Function 14(int)
|
||||
87: 24(float) Constant 1106321080
|
||||
88:41(flat_struct) SpecConstantComposite 69 87 43 21
|
||||
88:42(flat_struct) SpecConstantComposite 68 87 41 21
|
||||
89: 14(int) Constant 10
|
||||
90:42(nesting_struct) SpecConstantComposite 88 37 89
|
||||
90:44(nesting_struct) SpecConstantComposite 88 37 89
|
||||
96: 20(bool) ConstantFalse
|
||||
97:41(flat_struct) SpecConstantComposite 28 32 43 96
|
||||
97:42(flat_struct) SpecConstantComposite 28 32 41 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
|
||||
100:44(nesting_struct) SpecConstantComposite 97 99 28
|
||||
101: 25(fvec4) SpecConstantComposite 32 32 32 32
|
||||
102: 24(float) Constant 1066192077
|
||||
103: 24(float) Constant 1074580685
|
||||
104: 24(float) Constant 1079194419
|
||||
105: TypeVector 24(float) 3
|
||||
106: TypeMatrix 105(fvec3) 2
|
||||
107: 24(float) Constant 0
|
||||
108: 105(fvec3) SpecConstantComposite 32 32 32
|
||||
109: 105(fvec3) SpecConstantComposite 102 103 104
|
||||
110: 106 SpecConstantComposite 108 109
|
||||
111: 105(fvec3) SpecConstantComposite 32 107 107
|
||||
112: 105(fvec3) SpecConstantComposite 107 32 107
|
||||
113: 106 SpecConstantComposite 111 112
|
||||
114: 14(int) Constant 3000
|
||||
115:44(nesting_struct) SpecConstantComposite 88 37 114
|
||||
116: TypeArray 25(fvec4) 28
|
||||
117: TypePointer Input 116
|
||||
118(global_vec4_array_with_spec_length): 117(ptr) Variable Input
|
||||
4(main): 2 Function None 3
|
||||
5: Label
|
||||
Return
|
||||
|
||||
@ -84,55 +84,55 @@ Linked vertex stage:
|
||||
82: 22(bool) SpecConstantOp 177 19 43
|
||||
83: 22(bool) SpecConstantOp 170 42 42
|
||||
84: 22(bool) SpecConstantOp 173 19 43
|
||||
85: TypeVector 6(int) 4
|
||||
86: 6(int) Constant 30
|
||||
87: 85(ivec4) SpecConstantComposite 74 86 19 19
|
||||
88: TypeVector 41(int) 4
|
||||
89: 41(int) Constant 4294967295
|
||||
90: 41(int) Constant 4294967294
|
||||
91: 88(ivec4) SpecConstantComposite 42 42 89 90
|
||||
92: TypeVector 39(float) 4
|
||||
93: 39(float) Constant 1067450368
|
||||
94: 92(fvec4) SpecConstantComposite 40 93 40 93
|
||||
85: 6(int) Constant 30
|
||||
86: TypeVector 6(int) 4
|
||||
87: 86(ivec4) SpecConstantComposite 74 85 19 19
|
||||
88: 41(int) Constant 4294967295
|
||||
89: 41(int) Constant 4294967294
|
||||
90: TypeVector 41(int) 4
|
||||
91: 90(ivec4) SpecConstantComposite 42 42 88 89
|
||||
92: 39(float) Constant 1067450368
|
||||
93: TypeVector 39(float) 4
|
||||
94: 93(fvec4) SpecConstantComposite 40 92 40 92
|
||||
95: TypeVector 22(bool) 4
|
||||
96: 88(ivec4) ConstantComposite 44 44 44 44
|
||||
96: 90(ivec4) ConstantComposite 44 44 44 44
|
||||
97: 95(bvec4) SpecConstantOp 171 87 96
|
||||
98: 95(bvec4) SpecConstantOp 171 91 96
|
||||
99: 85(ivec4) ConstantComposite 12 12 12 12
|
||||
100: 85(ivec4) ConstantComposite 32 32 32 32
|
||||
101: 85(ivec4) SpecConstantOp 169 97 100 99
|
||||
102: 88(ivec4) ConstantComposite 48 48 48 48
|
||||
103: 88(ivec4) SpecConstantOp 169 97 102 96
|
||||
104: 88(ivec4) SpecConstantOp 128 87 96
|
||||
105: 85(ivec4) SpecConstantOp 128 91 96
|
||||
106: 85(ivec4) SpecConstantOp 200 87
|
||||
107: 85(ivec4) SpecConstantOp 126 87
|
||||
108: 85(ivec4) ConstantComposite 20 20 20 20
|
||||
109: 85(ivec4) SpecConstantOp 128 87 108
|
||||
110: 85(ivec4) SpecConstantOp 128 87 108
|
||||
111: 85(ivec4) ConstantComposite 56 56 56 56
|
||||
112: 85(ivec4) SpecConstantOp 130 110 111
|
||||
113: 85(ivec4) ConstantComposite 58 58 58 58
|
||||
114: 85(ivec4) SpecConstantOp 130 112 113
|
||||
115: 85(ivec4) SpecConstantOp 132 87 108
|
||||
116: 85(ivec4) ConstantComposite 63 63 63 63
|
||||
117: 85(ivec4) SpecConstantOp 135 115 116
|
||||
118: 85(ivec4) SpecConstantOp 139 87 113
|
||||
119: 85(ivec4) ConstantComposite 72 72 72 72
|
||||
120: 85(ivec4) SpecConstantOp 195 87 119
|
||||
121: 85(ivec4) SpecConstantOp 196 87 108
|
||||
99: 86(ivec4) ConstantComposite 12 12 12 12
|
||||
100: 86(ivec4) ConstantComposite 32 32 32 32
|
||||
101: 86(ivec4) SpecConstantOp 169 97 100 99
|
||||
102: 90(ivec4) ConstantComposite 48 48 48 48
|
||||
103: 90(ivec4) SpecConstantOp 169 97 102 96
|
||||
104: 90(ivec4) SpecConstantOp 128 87 96
|
||||
105: 86(ivec4) SpecConstantOp 128 91 96
|
||||
106: 86(ivec4) SpecConstantOp 200 87
|
||||
107: 86(ivec4) SpecConstantOp 126 87
|
||||
108: 86(ivec4) ConstantComposite 20 20 20 20
|
||||
109: 86(ivec4) SpecConstantOp 128 87 108
|
||||
110: 86(ivec4) SpecConstantOp 128 87 108
|
||||
111: 86(ivec4) ConstantComposite 56 56 56 56
|
||||
112: 86(ivec4) SpecConstantOp 130 110 111
|
||||
113: 86(ivec4) ConstantComposite 58 58 58 58
|
||||
114: 86(ivec4) SpecConstantOp 130 112 113
|
||||
115: 86(ivec4) SpecConstantOp 132 87 108
|
||||
116: 86(ivec4) ConstantComposite 63 63 63 63
|
||||
117: 86(ivec4) SpecConstantOp 135 115 116
|
||||
118: 86(ivec4) SpecConstantOp 139 87 113
|
||||
119: 86(ivec4) ConstantComposite 72 72 72 72
|
||||
120: 86(ivec4) SpecConstantOp 195 87 119
|
||||
121: 86(ivec4) SpecConstantOp 196 87 108
|
||||
122: 6(int) Constant 1024
|
||||
123: 85(ivec4) ConstantComposite 122 122 122 122
|
||||
124: 85(ivec4) SpecConstantOp 197 87 123
|
||||
123: 86(ivec4) ConstantComposite 122 122 122 122
|
||||
124: 86(ivec4) SpecConstantOp 197 87 123
|
||||
125: 41(int) Constant 2048
|
||||
126: 88(ivec4) ConstantComposite 125 125 125 125
|
||||
127: 88(ivec4) SpecConstantOp 198 91 126
|
||||
126: 90(ivec4) ConstantComposite 125 125 125 125
|
||||
127: 90(ivec4) SpecConstantOp 198 91 126
|
||||
128: 6(int) SpecConstantOp 81 87 0
|
||||
129: TypeVector 6(int) 2
|
||||
130: 129(ivec2) SpecConstantOp 79 87 87 1(GLSL.std.450) 0
|
||||
131: TypeVector 6(int) 3
|
||||
132: 131(ivec3) SpecConstantOp 79 87 87 2 1(GLSL.std.450) 0
|
||||
133: 85(ivec4) SpecConstantOp 79 87 87 1(GLSL.std.450) 2 0 3
|
||||
133: 86(ivec4) SpecConstantOp 79 87 87 1(GLSL.std.450) 2 0 3
|
||||
4(main): 2 Function None 3
|
||||
5: Label
|
||||
Return
|
||||
|
||||
@ -42,6 +42,11 @@ 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);
|
||||
const vec4 spec_vec4_from_one_scalar = vec4(spec_float);
|
||||
|
||||
// Matrix constructor
|
||||
const mat2x3 spec_mat2x3 = mat2x3(spec_float, spec_float, spec_float, 1.1, 2.2, 3.3);
|
||||
const mat2x3 spec_mat2x3_from_one_scalar = mat2x3(spec_float);
|
||||
|
||||
// Struct nesting constructor
|
||||
const nesting_struct spec_nesting_struct_all_spec = {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user