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:
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user