From 1f2820a3d3f510b1d1aeb80526c68505390192db Mon Sep 17 00:00:00 2001 From: qining Date: Thu, 14 Apr 2016 18:34:27 -0400 Subject: [PATCH] fix the problem that spec constant composite instruction being used when only front-end constants are used in the constructor --- SPIRV/SpvBuilder.cpp | 23 ++++++++++++++++--- .../spv.specConstantComposite.vert.out | 2 +- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/SPIRV/SpvBuilder.cpp b/SPIRV/SpvBuilder.cpp index 5768196c..bbb30c35 100644 --- a/SPIRV/SpvBuilder.cpp +++ b/SPIRV/SpvBuilder.cpp @@ -47,6 +47,7 @@ #include #include +#include #include "SpvBuilder.h" @@ -1360,8 +1361,14 @@ Id Builder::smearScalar(Decoration precision, Id scalar, Id vectorType) Instruction* smear = nullptr; if (generatingOpCodeForSpecConst) { auto members = std::vector(numComponents, scalar); - // "generatingOpCodeForSpecConst == true" does not mean the generated vector - // is a spec constant vector. It depends on the scalar. + // Sometime even in spec-constant-op mode, the temporary vector created by + // promoting a scalar might not be a spec constant. This should depend on + // the scalar. + // e.g.: + // const vec2 spec_const_result = a_spec_const_vec2 + a_front_end_const_scalar; + // In such cases, the temporary vector created from a_front_end_const_scalar + // is not a spec constant vector, even though the binary operation node is marked + // as 'specConstant' and we are in spec-constant-op mode. auto result_id = makeCompositeConstant(vectorType, members, isSpecConstant(scalar)); smear = module.getInstruction(result_id); } else { @@ -1726,7 +1733,17 @@ 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); + // Sometime, even in spec-constant-op mode, the constant composite to be + // constructed may not be a specialization constant. + // e.g.: + // const mat2 m2 = mat2(a_spec_const, a_front_end_const, another_front_end_const, third_front_end_const); + // The first column vector should be a spec constant one, as a_spec_const is a spec constant. + // The second column vector should NOT be spec constant, as it does not contain any spec constants. + // To handle such cases, we check the constituents of the constant vector to determine whether this + // vector should be created as a spec constant. + return makeCompositeConstant(typeId, constituents, + std::any_of(constituents.begin(), constituents.end(), + [&](spv::Id id) { return isSpecConstant(id); })); } Instruction* op = new Instruction(getUniqueId(), typeId, OpCompositeConstruct); diff --git a/Test/baseResults/spv.specConstantComposite.vert.out b/Test/baseResults/spv.specConstantComposite.vert.out index 4654c700..ac101f28 100644 --- a/Test/baseResults/spv.specConstantComposite.vert.out +++ b/Test/baseResults/spv.specConstantComposite.vert.out @@ -93,7 +93,7 @@ Linked vertex stage: 106: TypeMatrix 105(fvec3) 2 107: 24(float) Constant 0 108: 105(fvec3) SpecConstantComposite 32 32 32 - 109: 105(fvec3) SpecConstantComposite 102 103 104 + 109: 105(fvec3) ConstantComposite 102 103 104 110: 106 SpecConstantComposite 108 109 111: 105(fvec3) SpecConstantComposite 32 107 107 112: 105(fvec3) SpecConstantComposite 107 32 107