Commit 0530b456 by Nicolas Capens Committed by Nicolas Capens

Refactor lvalue() to return the root node.

This will enable reusing it to determine the root node of rvalues as well. The only functional change is that struct indexing no longer overrides the register type. This is of no effect here since lvalue intermediates already inherited their type from the root node, but for rvalues the intermediates are considered temporary registers, while instead the root's type should be used. Change-Id: I2dbd1b0f8886c3f111a2ed3ef7fe4e9a5b480085 Reviewed-on: https://swiftshader-review.googlesource.com/13930Tested-by: 's avatarNicolas Capens <nicolascapens@google.com> Reviewed-by: 's avatarAlexis Hétu <sugoi@google.com> Reviewed-by: 's avatarNicolas Capens <nicolascapens@google.com>
parent 84249fde
...@@ -614,7 +614,7 @@ namespace glsl ...@@ -614,7 +614,7 @@ namespace glsl
if(left->totalRegisterCount() > 1) if(left->totalRegisterCount() > 1)
{ {
sw::Shader::SourceParameter relativeRegister; sw::Shader::SourceParameter relativeRegister;
argument(relativeRegister, right); source(relativeRegister, right);
mov->src[0].rel.type = relativeRegister.type; mov->src[0].rel.type = relativeRegister.type;
mov->src[0].rel.index = relativeRegister.index; mov->src[0].rel.index = relativeRegister.index;
...@@ -1887,9 +1887,7 @@ namespace glsl ...@@ -1887,9 +1887,7 @@ namespace glsl
if(dst) if(dst)
{ {
instruction->dst.type = registerType(dst); destination(instruction->dst, dst, dstIndex);
instruction->dst.index = registerIndex(dst) + dstIndex;
instruction->dst.mask = writeMask(dst);
} }
if(src0) if(src0)
...@@ -1898,11 +1896,11 @@ namespace glsl ...@@ -1898,11 +1896,11 @@ namespace glsl
instruction->dst.partialPrecision = src && (src->getPrecision() <= EbpLow); instruction->dst.partialPrecision = src && (src->getPrecision() <= EbpLow);
} }
argument(instruction->src[0], src0, index0); source(instruction->src[0], src0, index0);
argument(instruction->src[1], src1, index1); source(instruction->src[1], src1, index1);
argument(instruction->src[2], src2, index2); source(instruction->src[2], src2, index2);
argument(instruction->src[3], src3, index3); source(instruction->src[3], src3, index3);
argument(instruction->src[4], src4, index4); source(instruction->src[4], src4, index4);
shader->append(instruction); shader->append(instruction);
...@@ -2176,7 +2174,7 @@ namespace glsl ...@@ -2176,7 +2174,7 @@ namespace glsl
return argumentInfo; return argumentInfo;
} }
void OutputASM::argument(sw::Shader::SourceParameter &parameter, TIntermNode *argument, int index) void OutputASM::source(sw::Shader::SourceParameter &parameter, TIntermNode *argument, int index)
{ {
if(argument) if(argument)
{ {
...@@ -2286,6 +2284,13 @@ namespace glsl ...@@ -2286,6 +2284,13 @@ namespace glsl
} }
} }
void OutputASM::destination(sw::Shader::DestinationParameter &parameter, TIntermTyped *arg, int index)
{
parameter.type = registerType(arg);
parameter.index = registerIndex(arg) + index;
parameter.mask = writeMask(arg);
}
void OutputASM::copy(TIntermTyped *dst, TIntermNode *src, int offset) void OutputASM::copy(TIntermTyped *dst, TIntermNode *src, int offset)
{ {
for(int index = 0; index < dst->totalRegisterCount(); index++) for(int index = 0; index < dst->totalRegisterCount(); index++)
...@@ -2328,8 +2333,8 @@ namespace glsl ...@@ -2328,8 +2333,8 @@ namespace glsl
insert->src[0].type = insert->dst.type; insert->src[0].type = insert->dst.type;
insert->src[0].index = insert->dst.index; insert->src[0].index = insert->dst.index;
insert->src[0].rel = insert->dst.rel; insert->src[0].rel = insert->dst.rel;
argument(insert->src[1], src); source(insert->src[1], src);
argument(insert->src[2], binary->getRight()); source(insert->src[2], binary->getRight());
shader->append(insert); shader->append(insert);
} }
...@@ -2340,7 +2345,7 @@ namespace glsl ...@@ -2340,7 +2345,7 @@ namespace glsl
Temporary address(this); Temporary address(this);
int swizzle = lvalue(mov1->dst, address, dst); int swizzle = lvalue(mov1->dst, address, dst);
argument(mov1->src[0], src); source(mov1->src[0], src);
mov1->src[0].swizzle = swizzleSwizzle(mov1->src[0].swizzle, swizzle); mov1->src[0].swizzle = swizzleSwizzle(mov1->src[0].swizzle, swizzle);
shader->append(mov1); shader->append(mov1);
...@@ -2353,7 +2358,7 @@ namespace glsl ...@@ -2353,7 +2358,7 @@ namespace glsl
mov->dst.index += offset; mov->dst.index += offset;
mov->dst.mask = writeMask(dst, offset); mov->dst.mask = writeMask(dst, offset);
argument(mov->src[0], src, offset); source(mov->src[0], src, offset);
shader->append(mov); shader->append(mov);
} }
...@@ -2362,6 +2367,20 @@ namespace glsl ...@@ -2362,6 +2367,20 @@ namespace glsl
int OutputASM::lvalue(sw::Shader::DestinationParameter &dst, Temporary &address, TIntermTyped *node) int OutputASM::lvalue(sw::Shader::DestinationParameter &dst, Temporary &address, TIntermTyped *node)
{ {
TIntermTyped *root = nullptr;
unsigned int offset = 0;
unsigned char mask = 0xF;
int swizzle = lvalue(root, offset, dst.rel, mask, address, node);
dst.type = registerType(root);
dst.index = registerIndex(root) + offset;
dst.mask = mask;
return swizzle;
}
int OutputASM::lvalue(TIntermTyped *&root, unsigned int &offset, sw::Shader::Relative &rel, unsigned char &mask, Temporary &address, TIntermTyped *node)
{
TIntermTyped *result = node; TIntermTyped *result = node;
TIntermBinary *binary = node->getAsBinaryNode(); TIntermBinary *binary = node->getAsBinaryNode();
TIntermSymbol *symbol = node->getAsSymbolNode(); TIntermSymbol *symbol = node->getAsSymbolNode();
...@@ -2371,7 +2390,7 @@ namespace glsl ...@@ -2371,7 +2390,7 @@ namespace glsl
TIntermTyped *left = binary->getLeft(); TIntermTyped *left = binary->getLeft();
TIntermTyped *right = binary->getRight(); TIntermTyped *right = binary->getRight();
int leftSwizzle = lvalue(dst, address, left); // Resolve the l-value of the left side int leftSwizzle = lvalue(root, offset, rel, mask, address, left); // Resolve the l-value of the left side
switch(binary->getOp()) switch(binary->getOp())
{ {
...@@ -2381,22 +2400,22 @@ namespace glsl ...@@ -2381,22 +2400,22 @@ namespace glsl
if(left->isRegister()) if(left->isRegister())
{ {
int leftMask = dst.mask; int leftMask = mask;
dst.mask = 1; mask = 1;
while((leftMask & dst.mask) == 0) while((leftMask & mask) == 0)
{ {
dst.mask = dst.mask << 1; mask = mask << 1;
} }
int element = swizzleElement(leftSwizzle, rightIndex); int element = swizzleElement(leftSwizzle, rightIndex);
dst.mask = 1 << element; mask = 1 << element;
return element; return element;
} }
else if(left->isArray() || left->isMatrix()) else if(left->isArray() || left->isMatrix())
{ {
dst.index += rightIndex * result->totalRegisterCount(); offset += rightIndex * result->totalRegisterCount();
return 0xE4; return 0xE4;
} }
else UNREACHABLE(0); else UNREACHABLE(0);
...@@ -2414,42 +2433,42 @@ namespace glsl ...@@ -2414,42 +2433,42 @@ namespace glsl
{ {
int scale = result->totalRegisterCount(); int scale = result->totalRegisterCount();
if(dst.rel.type == sw::Shader::PARAMETER_VOID) // Use the index register as the relative address directly if(rel.type == sw::Shader::PARAMETER_VOID) // Use the index register as the relative address directly
{ {
if(left->totalRegisterCount() > 1) if(left->totalRegisterCount() > 1)
{ {
sw::Shader::SourceParameter relativeRegister; sw::Shader::SourceParameter relativeRegister;
argument(relativeRegister, right); source(relativeRegister, right);
dst.rel.index = relativeRegister.index; rel.index = relativeRegister.index;
dst.rel.type = relativeRegister.type; rel.type = relativeRegister.type;
dst.rel.scale = scale; rel.scale = scale;
dst.rel.deterministic = !(vertexShader && left->getQualifier() == EvqUniform); rel.deterministic = !(vertexShader && left->getQualifier() == EvqUniform);
} }
} }
else if(dst.rel.index != registerIndex(&address)) // Move the previous index register to the address register else if(rel.index != registerIndex(&address)) // Move the previous index register to the address register
{ {
if(scale == 1) if(scale == 1)
{ {
Constant oldScale((int)dst.rel.scale); Constant oldScale((int)rel.scale);
Instruction *mad = emit(sw::Shader::OPCODE_IMAD, &address, &address, &oldScale, right); Instruction *mad = emit(sw::Shader::OPCODE_IMAD, &address, &address, &oldScale, right);
mad->src[0].index = dst.rel.index; mad->src[0].index = rel.index;
mad->src[0].type = dst.rel.type; mad->src[0].type = rel.type;
} }
else else
{ {
Constant oldScale((int)dst.rel.scale); Constant oldScale((int)rel.scale);
Instruction *mul = emit(sw::Shader::OPCODE_IMUL, &address, &address, &oldScale); Instruction *mul = emit(sw::Shader::OPCODE_IMUL, &address, &address, &oldScale);
mul->src[0].index = dst.rel.index; mul->src[0].index = rel.index;
mul->src[0].type = dst.rel.type; mul->src[0].type = rel.type;
Constant newScale(scale); Constant newScale(scale);
emit(sw::Shader::OPCODE_IMAD, &address, right, &newScale, &address); emit(sw::Shader::OPCODE_IMAD, &address, right, &newScale, &address);
} }
dst.rel.type = sw::Shader::PARAMETER_TEMP; rel.type = sw::Shader::PARAMETER_TEMP;
dst.rel.index = registerIndex(&address); rel.index = registerIndex(&address);
dst.rel.scale = 1; rel.scale = 1;
} }
else // Just add the new index to the address register else // Just add the new index to the address register
{ {
...@@ -2481,9 +2500,8 @@ namespace glsl ...@@ -2481,9 +2500,8 @@ namespace glsl
fieldOffset += fields[i]->type()->totalRegisterCount(); fieldOffset += fields[i]->type()->totalRegisterCount();
} }
dst.type = registerType(left); offset += fieldOffset;
dst.index += fieldOffset; mask = writeMask(result);
dst.mask = writeMask(result);
return 0xE4; return 0xE4;
} }
...@@ -2492,7 +2510,7 @@ namespace glsl ...@@ -2492,7 +2510,7 @@ namespace glsl
{ {
ASSERT(left->isRegister()); ASSERT(left->isRegister());
int leftMask = dst.mask; int leftMask = mask;
int swizzle = 0; int swizzle = 0;
int rightMask = 0; int rightMask = 0;
...@@ -2508,7 +2526,7 @@ namespace glsl ...@@ -2508,7 +2526,7 @@ namespace glsl
swizzle = swizzle | swizzleElement(leftSwizzle, i) << (element * 2); swizzle = swizzle | swizzleElement(leftSwizzle, i) << (element * 2);
} }
dst.mask = leftMask & rightMask; mask = leftMask & rightMask;
return swizzle; return swizzle;
} }
...@@ -2520,9 +2538,20 @@ namespace glsl ...@@ -2520,9 +2538,20 @@ namespace glsl
} }
else if(symbol) else if(symbol)
{ {
dst.type = registerType(symbol); root = symbol;
dst.index = registerIndex(symbol); offset = 0;
dst.mask = writeMask(symbol); mask = writeMask(symbol);
return 0xE4;
}
else
{
node->traverse(this);
root = node;
offset = 0;
mask = writeMask(node);
return 0xE4; return 0xE4;
} }
...@@ -2537,10 +2566,10 @@ namespace glsl ...@@ -2537,10 +2566,10 @@ namespace glsl
} }
const TQualifier qualifier = operand->getQualifier(); const TQualifier qualifier = operand->getQualifier();
if((EvqFragColor == qualifier) || (EvqFragData == qualifier)) if((qualifier == EvqFragColor) || (qualifier == EvqFragData))
{ {
if(((EvqFragData == qualifier) && (EvqFragColor == outputQualifier)) || if(((qualifier == EvqFragData) && (outputQualifier == EvqFragColor)) ||
((EvqFragColor == qualifier) && (EvqFragData == outputQualifier))) ((qualifier == EvqFragColor) && (outputQualifier == EvqFragData)))
{ {
mContext.error(operand->getLine(), "static assignment to both gl_FragData and gl_FragColor", ""); mContext.error(operand->getLine(), "static assignment to both gl_FragData and gl_FragColor", "");
} }
......
...@@ -251,14 +251,14 @@ namespace glsl ...@@ -251,14 +251,14 @@ namespace glsl
void emitShader(Scope scope); void emitShader(Scope scope);
// Visit AST nodes and output their code to the body stream // Visit AST nodes and output their code to the body stream
virtual void visitSymbol(TIntermSymbol*); void visitSymbol(TIntermSymbol*) override;
virtual bool visitBinary(Visit visit, TIntermBinary*); bool visitBinary(Visit visit, TIntermBinary*) override;
virtual bool visitUnary(Visit visit, TIntermUnary*); bool visitUnary(Visit visit, TIntermUnary*) override;
virtual bool visitSelection(Visit visit, TIntermSelection*); bool visitSelection(Visit visit, TIntermSelection*) override;
virtual bool visitAggregate(Visit visit, TIntermAggregate*); bool visitAggregate(Visit visit, TIntermAggregate*) override;
virtual bool visitLoop(Visit visit, TIntermLoop*); bool visitLoop(Visit visit, TIntermLoop*) override;
virtual bool visitBranch(Visit visit, TIntermBranch*); bool visitBranch(Visit visit, TIntermBranch*) override;
virtual bool visitSwitch(Visit, TIntermSwitch*); bool visitSwitch(Visit, TIntermSwitch*) override;
sw::Shader::Opcode getOpcode(sw::Shader::Opcode op, TIntermTyped *in) const; sw::Shader::Opcode getOpcode(sw::Shader::Opcode op, TIntermTyped *in) const;
Instruction *emit(sw::Shader::Opcode op, TIntermTyped *dst = 0, TIntermNode *src0 = 0, TIntermNode *src1 = 0, TIntermNode *src2 = 0, TIntermNode *src3 = 0, TIntermNode *src4 = 0); Instruction *emit(sw::Shader::Opcode op, TIntermTyped *dst = 0, TIntermNode *src0 = 0, TIntermNode *src1 = 0, TIntermNode *src2 = 0, TIntermNode *src3 = 0, TIntermNode *src4 = 0);
...@@ -270,10 +270,12 @@ namespace glsl ...@@ -270,10 +270,12 @@ namespace glsl
void emitAssign(sw::Shader::Opcode op, TIntermTyped *result, TIntermTyped *lhs, TIntermTyped *src0, TIntermTyped *src1 = 0); void emitAssign(sw::Shader::Opcode op, TIntermTyped *result, TIntermTyped *lhs, TIntermTyped *src0, TIntermTyped *src1 = 0);
void emitCmp(sw::Shader::Control cmpOp, TIntermTyped *dst, TIntermNode *left, TIntermNode *right, int index = 0); void emitCmp(sw::Shader::Control cmpOp, TIntermTyped *dst, TIntermNode *left, TIntermNode *right, int index = 0);
void emitDeterminant(TIntermTyped *result, TIntermTyped *arg, int size, int col = -1, int row = -1, int outCol = 0, int outRow = 0); void emitDeterminant(TIntermTyped *result, TIntermTyped *arg, int size, int col = -1, int row = -1, int outCol = 0, int outRow = 0);
void argument(sw::Shader::SourceParameter &parameter, TIntermNode *argument, int index = 0); void source(sw::Shader::SourceParameter &parameter, TIntermNode *argument, int index = 0);
void destination(sw::Shader::DestinationParameter &parameter, TIntermTyped *argument, int index = 0);
void copy(TIntermTyped *dst, TIntermNode *src, int offset = 0); void copy(TIntermTyped *dst, TIntermNode *src, int offset = 0);
void assignLvalue(TIntermTyped *dst, TIntermTyped *src); void assignLvalue(TIntermTyped *dst, TIntermTyped *src);
int lvalue(sw::Shader::DestinationParameter &dst, Temporary &address, TIntermTyped *node); int lvalue(sw::Shader::DestinationParameter &dst, Temporary &address, TIntermTyped *node);
int lvalue(TIntermTyped *&root, unsigned int &offset, sw::Shader::Relative &rel, unsigned char &mask, Temporary &address, TIntermTyped *node);
sw::Shader::ParameterType registerType(TIntermTyped *operand); sw::Shader::ParameterType registerType(TIntermTyped *operand);
bool hasFlatQualifier(TIntermTyped *operand); bool hasFlatQualifier(TIntermTyped *operand);
unsigned int registerIndex(TIntermTyped *operand); unsigned int registerIndex(TIntermTyped *operand);
......
...@@ -396,6 +396,15 @@ namespace sw ...@@ -396,6 +396,15 @@ namespace sw
ANALYSIS_LEAVE = 0x00000008, ANALYSIS_LEAVE = 0x00000008,
}; };
struct Relative
{
ParameterType type : 8;
unsigned int index;
unsigned int swizzle : 8;
unsigned int scale;
bool deterministic; // Equal accross shader instances run in lockstep (e.g. unrollable loop couters)
};
struct Parameter struct Parameter
{ {
union union
...@@ -404,14 +413,7 @@ namespace sw ...@@ -404,14 +413,7 @@ namespace sw
{ {
unsigned int index; // For registers types unsigned int index; // For registers types
struct Relative rel;
{
ParameterType type : 8;
unsigned int index;
unsigned int swizzle : 8;
unsigned int scale;
bool deterministic; // Equal accross shader instances run in lockstep (e.g. unrollable loop couters)
} rel;
}; };
float value[4]; // For float constants float value[4]; // For float constants
......
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