MCPcopy Create free account
hub / github.com/KhronosGroup/glslang / addShapeConversion

Method addShapeConversion

glslang/MachineIndependent/Intermediate.cpp:1181–1272  ·  view source on GitHub ↗

Convert the node's shape of type for the given type, as allowed by the operation involved: 'op'. Generally, the AST represents allowed GLSL shapes, so this isn't needed for GLSL. Bad shapes are caught in conversion or promotion. Return 'node' if no conversion was done. Promotion handles final shape checking.

Source from the content-addressed store, hash-verified

1179// checking.
1180//
1181TIntermTyped* TIntermediate::addShapeConversion(const TType& type, TIntermTyped* node)
1182{
1183 // no conversion needed
1184 if (node->getType() == type)
1185 return node;
1186
1187 // structures and arrays don't change shape, either to or from
1188 if (node->getType().isStruct() || node->getType().isArray() ||
1189 type.isStruct() || type.isArray())
1190 return node;
1191
1192 // The new node that handles the conversion
1193 TOperator constructorOp = mapTypeToConstructorOp(type);
1194
1195 if (getSource() == EShSourceHlsl) {
1196 // HLSL rules for scalar, vector and matrix conversions:
1197 // 1) scalar can become anything, initializing every component with its value
1198 // 2) vector and matrix can become scalar, first element is used (warning: truncation)
1199 // 3) matrix can become matrix with less rows and/or columns (warning: truncation)
1200 // 4) vector can become vector with less rows size (warning: truncation)
1201 // 5a) vector 4 can become 2x2 matrix (special case) (same packing layout, its a reinterpret)
1202 // 5b) 2x2 matrix can become vector 4 (special case) (same packing layout, its a reinterpret)
1203
1204 const TType &sourceType = node->getType();
1205
1206 // rule 1 for scalar to matrix is special
1207 if (sourceType.isScalarOrVec1() && type.isMatrix()) {
1208
1209 // HLSL semantics: the scalar (or vec1) is replicated to every component of the matrix. Left to its
1210 // own devices, the constructor from a scalar would populate the diagonal. This forces replication
1211 // to every matrix element.
1212
1213 // Note that if the node is complex (e.g, a function call), we don't want to duplicate it here
1214 // repeatedly, so we copy it to a temp, then use the temp.
1215 const int matSize = type.computeNumComponents();
1216 TIntermAggregate* rhsAggregate = new TIntermAggregate();
1217
1218 const bool isSimple = (node->getAsSymbolNode() != nullptr) || (node->getAsConstantUnion() != nullptr);
1219
1220 if (!isSimple) {
1221 assert(0); // TODO: use node replicator service when available.
1222 }
1223
1224 for (int x = 0; x < matSize; ++x)
1225 rhsAggregate->getSequence().push_back(node);
1226
1227 return setAggregateOperator(rhsAggregate, constructorOp, type, node->getLoc());
1228 }
1229
1230 // rule 1 and 2
1231 if ((sourceType.isScalar() && !type.isScalar()) || (!sourceType.isScalar() && type.isScalar()))
1232 return setAggregateOperator(makeAggregate(node), constructorOp, type, node->getLoc());
1233
1234 // rule 3 and 5b
1235 if (sourceType.isMatrix()) {
1236 // rule 3
1237 if (type.isMatrix()) {
1238 if ((sourceType.getMatrixCols() != type.getMatrixCols() || sourceType.getMatrixRows() != type.getMatrixRows()) &&

Callers 1

addConstructorMethod · 0.80

Calls 14

getTypeMethod · 0.80
isScalarOrVec1Method · 0.80
computeNumComponentsMethod · 0.80
isStructMethod · 0.45
isArrayMethod · 0.45
isMatrixMethod · 0.45
getAsSymbolNodeMethod · 0.45
getAsConstantUnionMethod · 0.45
push_backMethod · 0.45
isScalarMethod · 0.45
getMatrixColsMethod · 0.45
getMatrixRowsMethod · 0.45

Tested by

no test coverage detected