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 ...@@ -1337,17 +1337,20 @@ namespace glsl
if(visit == PostVisit) if(visit == PostVisit)
{ {
int component = 0; int component = 0;
int arrayMaxIndex = result->isArray() ? result->getArraySize() - 1 : 0;
int arrayComponents = result->getType().getElementSize();
for(size_t i = 0; i < argumentCount; i++) for(size_t i = 0; i < argumentCount; i++)
{ {
TIntermTyped *argi = arg[i]->getAsTyped(); TIntermTyped *argi = arg[i]->getAsTyped();
int size = argi->getNominalSize(); int size = argi->getNominalSize();
int arrayIndex = std::min(component / arrayComponents, arrayMaxIndex);
int swizzle = component - (arrayIndex * arrayComponents);
if(!argi->isMatrix()) if(!argi->isMatrix())
{ {
Instruction *mov = emitCast(result, argi); Instruction *mov = emitCast(result, arrayIndex, argi, 0);
mov->dst.mask = (0xF << component) & 0xF; mov->dst.mask = (0xF << swizzle) & 0xF;
mov->src[0].swizzle = readSwizzle(argi, size) << (component * 2); mov->src[0].swizzle = readSwizzle(argi, size) << (swizzle * 2);
component += size; component += size;
} }
...@@ -1357,9 +1360,9 @@ namespace glsl ...@@ -1357,9 +1360,9 @@ namespace glsl
while(component < resultType.getNominalSize()) while(component < resultType.getNominalSize())
{ {
Instruction *mov = emitCast(result, 0, argi, column); Instruction *mov = emitCast(result, arrayIndex, argi, column);
mov->dst.mask = (0xF << component) & 0xF; mov->dst.mask = (0xF << swizzle) & 0xF;
mov->src[0].swizzle = readSwizzle(argi, size) << (component * 2); mov->src[0].swizzle = readSwizzle(argi, size) << (swizzle * 2);
column++; column++;
component += size; component += size;
...@@ -1395,8 +1398,13 @@ namespace glsl ...@@ -1395,8 +1398,13 @@ namespace glsl
} }
else if(arg0->isMatrix()) else if(arg0->isMatrix())
{ {
const int inCols = arg0->getNominalSize(); int arraySize = result->isArray() ? result->getArraySize() : 1;
const int inRows = arg0->getSecondarySize();
for(int n = 0; n < arraySize; n++)
{
TIntermTyped *argi = arg[n]->getAsTyped();
const int inCols = argi->getNominalSize();
const int inRows = argi->getSecondarySize();
for(int i = 0; i < outCols; i++) for(int i = 0; i < outCols; i++)
{ {
...@@ -1404,16 +1412,17 @@ namespace glsl ...@@ -1404,16 +1412,17 @@ namespace glsl
{ {
// Initialize to identity matrix // 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)); 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); emitCast(result, i + n * outCols, &col, 0);
} }
if(i < inCols) if(i < inCols)
{ {
Instruction *mov = emitCast(result, i, arg0, i); Instruction *mov = emitCast(result, i + n * outCols, argi, i);
mov->dst.mask = 0xF >> (4 - inRows); mov->dst.mask = 0xF >> (4 - inRows);
} }
} }
} }
}
else else
{ {
int column = 0; int column = 0;
......
...@@ -2076,7 +2076,23 @@ TIntermTyped* TParseContext::addConstructor(TIntermNode* arguments, const TType* ...@@ -2076,7 +2076,23 @@ TIntermTyped* TParseContext::addConstructor(TIntermNode* arguments, const TType*
aggregateArguments->getSequence().push_back(arguments); 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(); const TFieldList &fields = type->getStruct()->fields();
TIntermSequence &args = aggregateArguments->getSequence(); 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