Commit 40d9edf1 by Olli Etuaho

Fix structure comparison constant folding

objectSize() will return the size of all data in the structure, and simply iterating over the data will work for determining whether two structures are equal. The earlier complex and broken approach where the structure was traversed recursively is not needed. BUG=angleproject:1211 TEST=angle_unittests Change-Id: I0e5c5ccbb767d44ef6acb0f1f25f27dfc42866e1 Reviewed-on: https://chromium-review.googlesource.com/312490 Tryjob-Request: Olli Etuaho <oetuaho@nvidia.com> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarCorentin Wallez <cwallez@chromium.org> Tested-by: 's avatarOlli Etuaho <oetuaho@nvidia.com>
parent 5c0e023c
...@@ -66,73 +66,6 @@ bool ValidateMultiplication(TOperator op, const TType &left, const TType &right) ...@@ -66,73 +66,6 @@ bool ValidateMultiplication(TOperator op, const TType &left, const TType &right)
} }
} }
bool CompareStructure(const TType& leftNodeType,
const TConstantUnion *rightUnionArray,
const TConstantUnion *leftUnionArray);
bool CompareStruct(const TType &leftNodeType,
const TConstantUnion *rightUnionArray,
const TConstantUnion *leftUnionArray)
{
const TFieldList &fields = leftNodeType.getStruct()->fields();
size_t structSize = fields.size();
size_t index = 0;
for (size_t j = 0; j < structSize; j++)
{
size_t size = fields[j]->type()->getObjectSize();
for (size_t i = 0; i < size; i++)
{
if (fields[j]->type()->getBasicType() == EbtStruct)
{
if (!CompareStructure(*fields[j]->type(),
&rightUnionArray[index],
&leftUnionArray[index]))
{
return false;
}
}
else
{
if (leftUnionArray[index] != rightUnionArray[index])
return false;
index++;
}
}
}
return true;
}
bool CompareStructure(const TType &leftNodeType,
const TConstantUnion *rightUnionArray,
const TConstantUnion *leftUnionArray)
{
if (leftNodeType.isArray())
{
TType typeWithoutArrayness = leftNodeType;
typeWithoutArrayness.clearArrayness();
size_t arraySize = leftNodeType.getArraySize();
for (size_t i = 0; i < arraySize; ++i)
{
size_t offset = typeWithoutArrayness.getObjectSize() * i;
if (!CompareStruct(typeWithoutArrayness,
&rightUnionArray[offset],
&leftUnionArray[offset]))
{
return false;
}
}
}
else
{
return CompareStruct(leftNodeType, rightUnionArray, leftUnionArray);
}
return true;
}
TConstantUnion *Vectorize(const TConstantUnion &constant, size_t size) TConstantUnion *Vectorize(const TConstantUnion &constant, size_t size)
{ {
TConstantUnion *constUnion = new TConstantUnion[size]; TConstantUnion *constUnion = new TConstantUnion[size];
...@@ -1269,19 +1202,12 @@ TConstantUnion *TIntermConstantUnion::foldBinary(TOperator op, TIntermConstantUn ...@@ -1269,19 +1202,12 @@ TConstantUnion *TIntermConstantUnion::foldBinary(TOperator op, TIntermConstantUn
{ {
resultArray = new TConstantUnion[1]; resultArray = new TConstantUnion[1];
bool equal = true; bool equal = true;
if (getType().getBasicType() == EbtStruct) for (size_t i = 0; i < objectSize; i++)
{
equal = CompareStructure(getType(), rightArray, leftArray);
}
else
{ {
for (size_t i = 0; i < objectSize; i++) if (leftArray[i] != rightArray[i])
{ {
if (leftArray[i] != rightArray[i]) equal = false;
{ break; // break out of for loop
equal = false;
break; // break out of for loop
}
} }
} }
if (op == EOpEqual) if (op == EOpEqual)
......
...@@ -697,3 +697,50 @@ TEST_F(ConstantFoldingTest, FoldMat2ConstructorTakingVec4) ...@@ -697,3 +697,50 @@ TEST_F(ConstantFoldingTest, FoldMat2ConstructorTakingVec4)
std::vector<float> result(outputElements, outputElements + 4); std::vector<float> result(outputElements, outputElements + 4);
ASSERT_TRUE(constantVectorFoundInAST(result)); ASSERT_TRUE(constantVectorFoundInAST(result));
} }
// Test that equality comparison of two different structs with a nested struct inside returns false.
TEST_F(ConstantFoldingTest, FoldNestedDifferentStructEqualityComparison)
{
const std::string &shaderString =
"precision mediump float;\n"
"struct nested {\n"
" float f\n;"
"};\n"
"struct S {\n"
" nested a;\n"
" float f;\n"
"};\n"
"uniform vec4 mult;\n"
"void main()\n"
"{\n"
" const S s1 = S(nested(0.0), 2.0);\n"
" const S s2 = S(nested(0.0), 3.0);\n"
" gl_FragColor = (s1 == s2 ? 1.0 : 0.5) * mult;\n"
"}\n";
compile(shaderString);
ASSERT_TRUE(constantFoundInAST(0.5f));
}
// Test that equality comparison of two identical structs with a nested struct inside returns true.
TEST_F(ConstantFoldingTest, FoldNestedIdenticalStructEqualityComparison)
{
const std::string &shaderString =
"precision mediump float;\n"
"struct nested {\n"
" float f\n;"
"};\n"
"struct S {\n"
" nested a;\n"
" float f;\n"
" int i;\n"
"};\n"
"uniform vec4 mult;\n"
"void main()\n"
"{\n"
" const S s1 = S(nested(0.0), 2.0, 3);\n"
" const S s2 = S(nested(0.0), 2.0, 3);\n"
" gl_FragColor = (s1 == s2 ? 1.0 : 0.5) * mult;\n"
"}\n";
compile(shaderString);
ASSERT_TRUE(constantFoundInAST(1.0f));
}
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