compiler: Fix const non-square matrix component mult.

It seems like there weren't any dEQP tests for constant folding of
nonsquare matrices component-wise multiplication. There were a couple
bugs in our implementation which could lead to undefined behaviour.

Fixes the code and cleans up a few style issues.

Also includes a regression test.

Bug: chromium:912505
Bug: chromium:912508
Change-Id: I7fb85d1404a32950fa9fe4c3bbba9edc9f38ddd1
Reviewed-on: https://chromium-review.googlesource.com/c/1387065
Commit-Queue: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Yuly Novikov <ynovikov@chromium.org>
This commit is contained in:
Jamie Madill 2018-12-20 12:43:37 -05:00 коммит произвёл Commit Bot
Родитель bcb7890895
Коммит 2b35654dcf
3 изменённых файлов: 61 добавлений и 17 удалений

Просмотреть файл

@ -27,21 +27,21 @@ template <typename T>
class Matrix
{
public:
Matrix(const std::vector<T> &elements, const unsigned int &numRows, const unsigned int &numCols)
Matrix(const std::vector<T> &elements, const unsigned int numRows, const unsigned int numCols)
: mElements(elements), mRows(numRows), mCols(numCols)
{
ASSERT(rows() >= 1 && rows() <= 4);
ASSERT(columns() >= 1 && columns() <= 4);
}
Matrix(const std::vector<T> &elements, const unsigned int &size)
Matrix(const std::vector<T> &elements, const unsigned int size)
: mElements(elements), mRows(size), mCols(size)
{
ASSERT(rows() >= 1 && rows() <= 4);
ASSERT(columns() >= 1 && columns() <= 4);
}
Matrix(const T *elements, const unsigned int &size) : mRows(size), mCols(size)
Matrix(const T *elements, const unsigned int size) : mRows(size), mCols(size)
{
ASSERT(rows() >= 1 && rows() <= 4);
ASSERT(columns() >= 1 && columns() <= 4);
@ -49,18 +49,24 @@ class Matrix
mElements.push_back(elements[i]);
}
const T &operator()(const unsigned int &rowIndex, const unsigned int &columnIndex) const
const T &operator()(const unsigned int rowIndex, const unsigned int columnIndex) const
{
ASSERT(rowIndex < mRows);
ASSERT(columnIndex < mCols);
return mElements[rowIndex * columns() + columnIndex];
}
T &operator()(const unsigned int &rowIndex, const unsigned int &columnIndex)
T &operator()(const unsigned int rowIndex, const unsigned int columnIndex)
{
ASSERT(rowIndex < mRows);
ASSERT(columnIndex < mCols);
return mElements[rowIndex * columns() + columnIndex];
}
const T &at(const unsigned int &rowIndex, const unsigned int &columnIndex) const
const T &at(const unsigned int rowIndex, const unsigned int columnIndex) const
{
ASSERT(rowIndex < mRows);
ASSERT(columnIndex < mCols);
return operator()(rowIndex, columnIndex);
}
@ -131,10 +137,16 @@ class Matrix
Matrix<T> compMult(const Matrix<T> &mat1) const
{
Matrix result(std::vector<T>(mElements.size()), size());
for (unsigned int i = 0; i < columns(); i++)
for (unsigned int j = 0; j < rows(); j++)
result(i, j) = at(i, j) * mat1(i, j);
Matrix result(std::vector<T>(mElements.size()), rows(), columns());
for (unsigned int i = 0; i < rows(); i++)
{
for (unsigned int j = 0; j < columns(); j++)
{
T lhs = at(i, j);
T rhs = mat1(i, j);
result(i, j) = rhs * lhs;
}
}
return result;
}

Просмотреть файл

@ -107,8 +107,8 @@ TIntermTyped *CreateFoldedNode(const TConstantUnion *constArray, const TIntermTy
}
angle::Matrix<float> GetMatrix(const TConstantUnion *paramArray,
const unsigned int &rows,
const unsigned int &cols)
const unsigned int rows,
const unsigned int cols)
{
std::vector<float> elements;
for (size_t i = 0; i < rows * cols; i++)
@ -119,7 +119,7 @@ angle::Matrix<float> GetMatrix(const TConstantUnion *paramArray,
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)
{
std::vector<float> elements;
for (size_t i = 0; i < size * size; i++)
@ -3435,10 +3435,12 @@ TConstantUnion *TIntermConstantUnion::FoldAggregateBuiltIn(TIntermAggregate *agg
ASSERT(basicType == EbtFloat && (*arguments)[0]->getAsTyped()->isMatrix() &&
(*arguments)[1]->getAsTyped()->isMatrix());
// Perform component-wise matrix multiplication.
resultArray = new TConstantUnion[maxObjectSize];
int size = (*arguments)[0]->getAsTyped()->getNominalSize();
angle::Matrix<float> result =
GetMatrix(unionArrays[0], size).compMult(GetMatrix(unionArrays[1], size));
resultArray = new TConstantUnion[maxObjectSize];
int rows = (*arguments)[0]->getAsTyped()->getRows();
int cols = (*arguments)[0]->getAsTyped()->getCols();
angle::Matrix<float> lhs = GetMatrix(unionArrays[0], rows, cols);
angle::Matrix<float> rhs = GetMatrix(unionArrays[1], rows, cols);
angle::Matrix<float> result = lhs.compMult(rhs);
SetUnionArrayFromMatrix(result, resultArray);
break;
}

Просмотреть файл

@ -5059,6 +5059,36 @@ foo
ANGLE_GL_PROGRAM(program, kVS, kFS);
}
// Tests constant folding of non-square 'matrixCompMult'.
TEST_P(GLSLTest_ES3, NonSquareMatrixCompMult)
{
constexpr char kFS[] = R"(#version 300 es
precision mediump float;
const mat4x2 matA = mat4x2(2.0, 4.0, 8.0, 16.0, 32.0, 64.0, 128.0, 256.0);
const mat4x2 matB = mat4x2(1.0/2.0, 1.0/4.0, 1.0/8.0, 1.0/16.0, 1.0/32.0, 1.0/64.0, 1.0/128.0, 1.0/256.0);
out vec4 color;
void main()
{
mat4x2 result = matrixCompMult(matA, matB);
vec2 vresult = result * vec4(1.0, 1.0, 1.0, 1.0);
if (vresult == vec2(4.0, 4.0))
{
color = vec4(0.0, 1.0, 0.0, 1.0);
}
else
{
color = vec4(1.0, 0.0, 0.0, 1.0);
}
})";
ANGLE_GL_PROGRAM(program, essl3_shaders::vs::Simple(), kFS);
drawQuad(program, essl3_shaders::PositionAttrib(), 0.5f, 1.0f, true);
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
}
// Use this to select which configurations (e.g. which renderer, which GLES major version) these
// tests should be run against.
ANGLE_INSTANTIATE_TEST(GLSLTest,