Commit d5da505d by Olli Etuaho Committed by Commit Bot

Fix constant folding non-square outerProduct

Use all the vector elements correctly when constant folding non-square outerProduct. Previously the code used to discard some elements of the smaller outerProduct operand. Also clear up confusion about matrix rows/columns in matrix constant folding code in general. BUG=angleproject:1482 TEST=angle_unittests Change-Id: I7cba8f97a92b875de01e57255d54258cdfd92a47 Reviewed-on: https://chromium-review.googlesource.com/377298Reviewed-by: 's avatarCorentin Wallez <cwallez@chromium.org> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Commit-Queue: Olli Etuaho <oetuaho@nvidia.com>
parent 2ac58792
...@@ -113,8 +113,9 @@ angle::Matrix<float> GetMatrix(const TConstantUnion *paramArray, ...@@ -113,8 +113,9 @@ angle::Matrix<float> GetMatrix(const TConstantUnion *paramArray,
for (size_t i = 0; i < rows * cols; i++) for (size_t i = 0; i < rows * cols; i++)
elements.push_back(paramArray[i].getFConst()); elements.push_back(paramArray[i].getFConst());
// Transpose is used since the Matrix constructor expects arguments in row-major order, // Transpose is used since the Matrix constructor expects arguments in row-major order,
// whereas the paramArray is in column-major order. // whereas the paramArray is in column-major order. Rows/cols parameters are also flipped below
return angle::Matrix<float>(elements, rows, cols).transpose(); // so that the created matrix will have the expected dimensions after the transpose.
return angle::Matrix<float>(elements, cols, rows).transpose();
} }
angle::Matrix<float> GetMatrix(const TConstantUnion *paramArray, const unsigned int &size) angle::Matrix<float> GetMatrix(const TConstantUnion *paramArray, const unsigned int &size)
...@@ -1225,7 +1226,7 @@ TConstantUnion *TIntermConstantUnion::foldUnaryWithDifferentReturnType(TOperator ...@@ -1225,7 +1226,7 @@ TConstantUnion *TIntermConstantUnion::foldUnaryWithDifferentReturnType(TOperator
{ {
resultArray = new TConstantUnion[objectSize]; resultArray = new TConstantUnion[objectSize];
angle::Matrix<float> result = angle::Matrix<float> result =
GetMatrix(operandArray, getType().getNominalSize(), getType().getSecondarySize()).transpose(); GetMatrix(operandArray, getType().getRows(), getType().getCols()).transpose();
SetUnionArrayFromMatrix(result, resultArray); SetUnionArrayFromMatrix(result, resultArray);
break; break;
} }
...@@ -1943,7 +1944,7 @@ TConstantUnion *TIntermConstantUnion::FoldAggregateBuiltIn(TIntermAggregate *agg ...@@ -1943,7 +1944,7 @@ TConstantUnion *TIntermConstantUnion::FoldAggregateBuiltIn(TIntermAggregate *agg
maxObjectSize = objectSizes[i]; maxObjectSize = objectSizes[i];
} }
if (!(*sequence)[0]->getAsTyped()->isMatrix()) if (!(*sequence)[0]->getAsTyped()->isMatrix() && aggregate->getOp() != EOpOuterProduct)
{ {
for (unsigned int i = 0; i < paramsCount; i++) for (unsigned int i = 0; i < paramsCount; i++)
if (objectSizes[i] != maxObjectSize) if (objectSizes[i] != maxObjectSize)
...@@ -2318,8 +2319,8 @@ TConstantUnion *TIntermConstantUnion::FoldAggregateBuiltIn(TIntermAggregate *agg ...@@ -2318,8 +2319,8 @@ TConstantUnion *TIntermConstantUnion::FoldAggregateBuiltIn(TIntermAggregate *agg
size_t numCols = (*sequence)[1]->getAsTyped()->getType().getObjectSize(); size_t numCols = (*sequence)[1]->getAsTyped()->getType().getObjectSize();
resultArray = new TConstantUnion[numRows * numCols]; resultArray = new TConstantUnion[numRows * numCols];
angle::Matrix<float> result = angle::Matrix<float> result =
GetMatrix(unionArrays[0], 1, static_cast<int>(numCols)) GetMatrix(unionArrays[0], static_cast<int>(numRows), 1)
.outerProduct(GetMatrix(unionArrays[1], static_cast<int>(numRows), 1)); .outerProduct(GetMatrix(unionArrays[1], 1, static_cast<int>(numCols)));
SetUnionArrayFromMatrix(result, resultArray); SetUnionArrayFromMatrix(result, resultArray);
} }
else else
......
...@@ -149,6 +149,12 @@ class ConstantFoldingTest : public testing::Test ...@@ -149,6 +149,12 @@ class ConstantFoldingTest : public testing::Test
} }
template <typename T> template <typename T>
bool constantColumnMajorMatrixFoundInAST(const std::vector<T> &constantMatrix)
{
return constantVectorFoundInAST(constantMatrix);
}
template <typename T>
bool constantVectorNearFoundInAST(const std::vector<T> &constantVector, const T &faultTolerance) bool constantVectorNearFoundInAST(const std::vector<T> &constantVector, const T &faultTolerance)
{ {
ConstantFinder<T> finder(constantVector, faultTolerance); ConstantFinder<T> finder(constantVector, faultTolerance);
...@@ -293,14 +299,14 @@ TEST_F(ConstantFoldingTest, Fold2x2MatrixInverse) ...@@ -293,14 +299,14 @@ TEST_F(ConstantFoldingTest, Fold2x2MatrixInverse)
5.0f, 7.0f 5.0f, 7.0f
}; };
std::vector<float> input(inputElements, inputElements + 4); std::vector<float> input(inputElements, inputElements + 4);
ASSERT_FALSE(constantVectorFoundInAST(input)); ASSERT_FALSE(constantColumnMajorMatrixFoundInAST(input));
float outputElements[] = float outputElements[] =
{ {
-7.0f, 3.0f, -7.0f, 3.0f,
5.0f, -2.0f 5.0f, -2.0f
}; };
std::vector<float> result(outputElements, outputElements + 4); std::vector<float> result(outputElements, outputElements + 4);
ASSERT_TRUE(constantVectorFoundInAST(result)); ASSERT_TRUE(constantColumnMajorMatrixFoundInAST(result));
} }
// Check if the matrix 'inverse' operation on 3x3 matrix is constant folded. // Check if the matrix 'inverse' operation on 3x3 matrix is constant folded.
...@@ -398,7 +404,7 @@ TEST_F(ConstantFoldingTest, Fold2x2MatrixDeterminant) ...@@ -398,7 +404,7 @@ TEST_F(ConstantFoldingTest, Fold2x2MatrixDeterminant)
5.0f, 7.0f 5.0f, 7.0f
}; };
std::vector<float> input(inputElements, inputElements + 4); std::vector<float> input(inputElements, inputElements + 4);
ASSERT_FALSE(constantVectorFoundInAST(input)); ASSERT_FALSE(constantColumnMajorMatrixFoundInAST(input));
ASSERT_TRUE(constantFoundInAST(-1.0f)); ASSERT_TRUE(constantFoundInAST(-1.0f));
} }
...@@ -423,7 +429,7 @@ TEST_F(ConstantFoldingTest, Fold3x3MatrixDeterminant) ...@@ -423,7 +429,7 @@ TEST_F(ConstantFoldingTest, Fold3x3MatrixDeterminant)
37.0f, 41.0f, 43.0f 37.0f, 41.0f, 43.0f
}; };
std::vector<float> input(inputElements, inputElements + 9); std::vector<float> input(inputElements, inputElements + 9);
ASSERT_FALSE(constantVectorFoundInAST(input)); ASSERT_FALSE(constantColumnMajorMatrixFoundInAST(input));
ASSERT_TRUE(constantFoundInAST(-680.0f)); ASSERT_TRUE(constantFoundInAST(-680.0f));
} }
...@@ -450,7 +456,7 @@ TEST_F(ConstantFoldingTest, Fold4x4MatrixDeterminant) ...@@ -450,7 +456,7 @@ TEST_F(ConstantFoldingTest, Fold4x4MatrixDeterminant)
79.0f, 83.0f, 89.0f, 97.0f 79.0f, 83.0f, 89.0f, 97.0f
}; };
std::vector<float> input(inputElements, inputElements + 16); std::vector<float> input(inputElements, inputElements + 16);
ASSERT_FALSE(constantVectorFoundInAST(input)); ASSERT_FALSE(constantColumnMajorMatrixFoundInAST(input));
ASSERT_TRUE(constantFoundInAST(-2520.0f)); ASSERT_TRUE(constantFoundInAST(-2520.0f));
} }
...@@ -478,7 +484,7 @@ TEST_F(ConstantFoldingTest, Fold3x3MatrixTranspose) ...@@ -478,7 +484,7 @@ TEST_F(ConstantFoldingTest, Fold3x3MatrixTranspose)
37.0f, 41.0f, 43.0f 37.0f, 41.0f, 43.0f
}; };
std::vector<float> input(inputElements, inputElements + 9); std::vector<float> input(inputElements, inputElements + 9);
ASSERT_FALSE(constantVectorFoundInAST(input)); ASSERT_FALSE(constantColumnMajorMatrixFoundInAST(input));
float outputElements[] = float outputElements[] =
{ {
11.0f, 23.0f, 37.0f, 11.0f, 23.0f, 37.0f,
...@@ -486,7 +492,7 @@ TEST_F(ConstantFoldingTest, Fold3x3MatrixTranspose) ...@@ -486,7 +492,7 @@ TEST_F(ConstantFoldingTest, Fold3x3MatrixTranspose)
19.0f, 31.0f, 43.0f 19.0f, 31.0f, 43.0f
}; };
std::vector<float> result(outputElements, outputElements + 9); std::vector<float> result(outputElements, outputElements + 9);
ASSERT_TRUE(constantVectorFoundInAST(result)); ASSERT_TRUE(constantColumnMajorMatrixFoundInAST(result));
} }
// Test that 0xFFFFFFFF wraps to -1 when parsed as integer. // Test that 0xFFFFFFFF wraps to -1 when parsed as integer.
...@@ -583,7 +589,7 @@ TEST_F(ConstantFoldingTest, FoldMat2ConstructorTakingMat2) ...@@ -583,7 +589,7 @@ TEST_F(ConstantFoldingTest, FoldMat2ConstructorTakingMat2)
2.0f, 3.0f 2.0f, 3.0f
}; };
std::vector<float> result(outputElements, outputElements + 4); std::vector<float> result(outputElements, outputElements + 4);
ASSERT_TRUE(constantVectorFoundInAST(result)); ASSERT_TRUE(constantColumnMajorMatrixFoundInAST(result));
} }
// Test that constant mat2 initialization with an int parameter works correctly. // Test that constant mat2 initialization with an int parameter works correctly.
...@@ -604,7 +610,7 @@ TEST_F(ConstantFoldingTest, FoldMat2ConstructorTakingScalar) ...@@ -604,7 +610,7 @@ TEST_F(ConstantFoldingTest, FoldMat2ConstructorTakingScalar)
0.0f, 3.0f 0.0f, 3.0f
}; };
std::vector<float> result(outputElements, outputElements + 4); std::vector<float> result(outputElements, outputElements + 4);
ASSERT_TRUE(constantVectorFoundInAST(result)); ASSERT_TRUE(constantColumnMajorMatrixFoundInAST(result));
} }
// Test that constant mat2 initialization with a mix of parameters works correctly. // Test that constant mat2 initialization with a mix of parameters works correctly.
...@@ -625,7 +631,7 @@ TEST_F(ConstantFoldingTest, FoldMat2ConstructorTakingMix) ...@@ -625,7 +631,7 @@ TEST_F(ConstantFoldingTest, FoldMat2ConstructorTakingMix)
1.0f, 2.0f 1.0f, 2.0f
}; };
std::vector<float> result(outputElements, outputElements + 4); std::vector<float> result(outputElements, outputElements + 4);
ASSERT_TRUE(constantVectorFoundInAST(result)); ASSERT_TRUE(constantColumnMajorMatrixFoundInAST(result));
} }
// Test that constant mat2 initialization with a mat3 parameter works correctly. // Test that constant mat2 initialization with a mat3 parameter works correctly.
...@@ -646,7 +652,7 @@ TEST_F(ConstantFoldingTest, FoldMat2ConstructorTakingMat3) ...@@ -646,7 +652,7 @@ TEST_F(ConstantFoldingTest, FoldMat2ConstructorTakingMat3)
3.0f, 4.0f 3.0f, 4.0f
}; };
std::vector<float> result(outputElements, outputElements + 4); std::vector<float> result(outputElements, outputElements + 4);
ASSERT_TRUE(constantVectorFoundInAST(result)); ASSERT_TRUE(constantColumnMajorMatrixFoundInAST(result));
} }
// Test that constant mat4x3 initialization with a mat3x2 parameter works correctly. // Test that constant mat4x3 initialization with a mat3x2 parameter works correctly.
...@@ -673,7 +679,7 @@ TEST_F(ConstantFoldingTest, FoldMat4x3ConstructorTakingMat3x2) ...@@ -673,7 +679,7 @@ TEST_F(ConstantFoldingTest, FoldMat4x3ConstructorTakingMat3x2)
0.0f, 0.0f, 0.0f 0.0f, 0.0f, 0.0f
}; };
std::vector<float> result(outputElements, outputElements + 12); std::vector<float> result(outputElements, outputElements + 12);
ASSERT_TRUE(constantVectorFoundInAST(result)); ASSERT_TRUE(constantColumnMajorMatrixFoundInAST(result));
} }
...@@ -695,7 +701,7 @@ TEST_F(ConstantFoldingTest, FoldMat2ConstructorTakingVec4) ...@@ -695,7 +701,7 @@ TEST_F(ConstantFoldingTest, FoldMat2ConstructorTakingVec4)
2.0f, 3.0f 2.0f, 3.0f
}; };
std::vector<float> result(outputElements, outputElements + 4); std::vector<float> result(outputElements, outputElements + 4);
ASSERT_TRUE(constantVectorFoundInAST(result)); ASSERT_TRUE(constantColumnMajorMatrixFoundInAST(result));
} }
// Test that equality comparison of two different structs with a nested struct inside returns false. // Test that equality comparison of two different structs with a nested struct inside returns false.
...@@ -761,3 +767,28 @@ TEST_F(ConstantFoldingTest, FoldNonSquareMatrixIndexing) ...@@ -761,3 +767,28 @@ TEST_F(ConstantFoldingTest, FoldNonSquareMatrixIndexing)
std::vector<float> result(outputElements, outputElements + 4); std::vector<float> result(outputElements, outputElements + 4);
ASSERT_TRUE(constantVectorFoundInAST(result)); ASSERT_TRUE(constantVectorFoundInAST(result));
} }
// Test that folding outer product of vectors with non-matching lengths works.
TEST_F(ConstantFoldingTest, FoldNonSquareOuterProduct)
{
const std::string &shaderString =
"#version 300 es\n"
"precision mediump float;\n"
"out vec4 my_FragColor;\n"
"void main()\n"
"{\n"
" mat3x2 prod = outerProduct(vec2(2.0, 3.0), vec3(5.0, 7.0, 11.0));\n"
" my_FragColor = vec4(prod[0].x);\n"
"}\n";
compile(shaderString);
// clang-format off
float outputElements[] =
{
10.0f, 15.0f,
14.0f, 21.0f,
22.0f, 33.0f
};
// clang-format on
std::vector<float> result(outputElements, outputElements + 6);
ASSERT_TRUE(constantColumnMajorMatrixFoundInAST(result));
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment