fix the problem that spec constant composite instruction being used when only front-end constants are used in the constructor

This commit is contained in:
qining 2016-04-14 18:34:27 -04:00
parent 27e04a004d
commit 1f2820a3d3
2 changed files with 21 additions and 4 deletions

View File

@ -47,6 +47,7 @@
#include <stdlib.h>
#include <unordered_set>
#include <algorithm>
#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<spv::Id>(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<Id>& 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);

View File

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