From 27e04a004dea9dd373de1e944551dc67c2eb73a1 Mon Sep 17 00:00:00 2001 From: qining Date: Thu, 14 Apr 2016 16:40:20 -0400 Subject: [PATCH] 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() --- SPIRV/GlslangToSpv.cpp | 73 ++-------------- SPIRV/SpvBuilder.cpp | 29 +++++-- SPIRV/SpvBuilder.h | 2 + .../spv.specConstantComposite.vert.out | 87 +++++++++++-------- .../spv.specConstantOperations.vert.out | 78 ++++++++--------- Test/spv.specConstantComposite.vert | 5 ++ 6 files changed, 127 insertions(+), 147 deletions(-) diff --git a/SPIRV/GlslangToSpv.cpp b/SPIRV/GlslangToSpv.cpp index 39f3b8bc..9d4dc590 100755 --- a/SPIRV/GlslangToSpv.cpp +++ b/SPIRV/GlslangToSpv.cpp @@ -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 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 - // 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) diff --git a/SPIRV/SpvBuilder.cpp b/SPIRV/SpvBuilder.cpp index 7896deb4..5768196c 100644 --- a/SPIRV/SpvBuilder.cpp +++ b/SPIRV/SpvBuilder.cpp @@ -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(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& 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]); diff --git a/SPIRV/SpvBuilder.h b/SPIRV/SpvBuilder.h index 62f6775e..661bb115 100755 --- a/SPIRV/SpvBuilder.h +++ b/SPIRV/SpvBuilder.h @@ -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)); } diff --git a/Test/baseResults/spv.specConstantComposite.vert.out b/Test/baseResults/spv.specConstantComposite.vert.out index 5e2dfa4a..4654c700 100644 --- a/Test/baseResults/spv.specConstantComposite.vert.out +++ b/Test/baseResults/spv.specConstantComposite.vert.out @@ -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 diff --git a/Test/baseResults/spv.specConstantOperations.vert.out b/Test/baseResults/spv.specConstantOperations.vert.out index eedbea5c..39de987d 100644 --- a/Test/baseResults/spv.specConstantOperations.vert.out +++ b/Test/baseResults/spv.specConstantOperations.vert.out @@ -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 diff --git a/Test/spv.specConstantComposite.vert b/Test/spv.specConstantComposite.vert index 4450ddd6..01103302 100644 --- a/Test/spv.specConstantComposite.vert +++ b/Test/spv.specConstantComposite.vert @@ -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 = {