Commit 2a19855f by Alexis Hetu Committed by Alexis Hétu

Fixed array constructors

Fixed first class array constructors by allowing basic type arrays and structure arrays to be handled properly for the EOpConstruct* operations. This fixes all dEQP.functional.shaders.arrays.* tests. Change-Id: I4fe99ec5256abf6483d3595890ba9c426abc97f8 Reviewed-on: https://swiftshader-review.googlesource.com/7351Tested-by: 's avatarAlexis Hétu <sugoi@google.com> Reviewed-by: 's avatarNicolas Capens <capn@google.com>
parent 853e48de
......@@ -1337,17 +1337,20 @@ namespace glsl
if(visit == PostVisit)
{
int component = 0;
int arrayMaxIndex = result->isArray() ? result->getArraySize() - 1 : 0;
int arrayComponents = result->getType().getElementSize();
for(size_t i = 0; i < argumentCount; i++)
{
TIntermTyped *argi = arg[i]->getAsTyped();
int size = argi->getNominalSize();
int arrayIndex = std::min(component / arrayComponents, arrayMaxIndex);
int swizzle = component - (arrayIndex * arrayComponents);
if(!argi->isMatrix())
{
Instruction *mov = emitCast(result, argi);
mov->dst.mask = (0xF << component) & 0xF;
mov->src[0].swizzle = readSwizzle(argi, size) << (component * 2);
Instruction *mov = emitCast(result, arrayIndex, argi, 0);
mov->dst.mask = (0xF << swizzle) & 0xF;
mov->src[0].swizzle = readSwizzle(argi, size) << (swizzle * 2);
component += size;
}
......@@ -1357,9 +1360,9 @@ namespace glsl
while(component < resultType.getNominalSize())
{
Instruction *mov = emitCast(result, 0, argi, column);
mov->dst.mask = (0xF << component) & 0xF;
mov->src[0].swizzle = readSwizzle(argi, size) << (component * 2);
Instruction *mov = emitCast(result, arrayIndex, argi, column);
mov->dst.mask = (0xF << swizzle) & 0xF;
mov->src[0].swizzle = readSwizzle(argi, size) << (swizzle * 2);
column++;
component += size;
......@@ -1395,22 +1398,28 @@ namespace glsl
}
else if(arg0->isMatrix())
{
const int inCols = arg0->getNominalSize();
const int inRows = arg0->getSecondarySize();
int arraySize = result->isArray() ? result->getArraySize() : 1;
for(int i = 0; i < outCols; i++)
for(int n = 0; n < arraySize; n++)
{
if(i >= inCols || outRows > inRows)
{
// Initialize to identity matrix
Constant col((i == 0 ? 1.0f : 0.0f), (i == 1 ? 1.0f : 0.0f), (i == 2 ? 1.0f : 0.0f), (i == 3 ? 1.0f : 0.0f));
emitCast(result, i, &col, 0);
}
TIntermTyped *argi = arg[n]->getAsTyped();
const int inCols = argi->getNominalSize();
const int inRows = argi->getSecondarySize();
if(i < inCols)
for(int i = 0; i < outCols; i++)
{
Instruction *mov = emitCast(result, i, arg0, i);
mov->dst.mask = 0xF >> (4 - inRows);
if(i >= inCols || outRows > inRows)
{
// Initialize to identity matrix
Constant col((i == 0 ? 1.0f : 0.0f), (i == 1 ? 1.0f : 0.0f), (i == 2 ? 1.0f : 0.0f), (i == 3 ? 1.0f : 0.0f));
emitCast(result, i + n * outCols, &col, 0);
}
if(i < inCols)
{
Instruction *mov = emitCast(result, i + n * outCols, argi, i);
mov->dst.mask = 0xF >> (4 - inRows);
}
}
}
}
......
......@@ -2076,7 +2076,23 @@ TIntermTyped* TParseContext::addConstructor(TIntermNode* arguments, const TType*
aggregateArguments->getSequence().push_back(arguments);
}
if(op == EOpConstructStruct)
if(type->isArray())
{
// GLSL ES 3.00 section 5.4.4: Each argument must be the same type as the element type of
// the array.
for(TIntermNode *&argNode : aggregateArguments->getSequence())
{
const TType &argType = argNode->getAsTyped()->getType();
// It has already been checked that the argument is not an array.
ASSERT(!argType.isArray());
if(!argType.sameElementType(*type))
{
error(line, "Array constructor argument has an incorrect type", "Error");
return false;
}
}
}
else if(op == EOpConstructStruct)
{
const TFieldList &fields = type->getStruct()->fields();
TIntermSequence &args = aggregateArguments->getSequence();
......
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