if(left->totalRegisterCount() > 1)
{
sw::Shader::SourceParameter relativeRegister;
- argument(relativeRegister, right);
+ source(relativeRegister, right);
mov->src[0].rel.type = relativeRegister.type;
mov->src[0].rel.index = relativeRegister.index;
if(dst)
{
- instruction->dst.type = registerType(dst);
- instruction->dst.index = registerIndex(dst) + dstIndex;
- instruction->dst.mask = writeMask(dst);
+ destination(instruction->dst, dst, dstIndex);
}
if(src0)
instruction->dst.partialPrecision = src && (src->getPrecision() <= EbpLow);
}
- argument(instruction->src[0], src0, index0);
- argument(instruction->src[1], src1, index1);
- argument(instruction->src[2], src2, index2);
- argument(instruction->src[3], src3, index3);
- argument(instruction->src[4], src4, index4);
+ source(instruction->src[0], src0, index0);
+ source(instruction->src[1], src1, index1);
+ source(instruction->src[2], src2, index2);
+ source(instruction->src[3], src3, index3);
+ source(instruction->src[4], src4, index4);
shader->append(instruction);
return argumentInfo;
}
- void OutputASM::argument(sw::Shader::SourceParameter ¶meter, TIntermNode *argument, int index)
+ void OutputASM::source(sw::Shader::SourceParameter ¶meter, TIntermNode *argument, int index)
{
if(argument)
{
}
}
+ void OutputASM::destination(sw::Shader::DestinationParameter ¶meter, 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)
{
for(int index = 0; index < dst->totalRegisterCount(); index++)
insert->src[0].type = insert->dst.type;
insert->src[0].index = insert->dst.index;
insert->src[0].rel = insert->dst.rel;
- argument(insert->src[1], src);
- argument(insert->src[2], binary->getRight());
+ source(insert->src[1], src);
+ source(insert->src[2], binary->getRight());
shader->append(insert);
}
Temporary address(this);
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);
shader->append(mov1);
mov->dst.index += offset;
mov->dst.mask = writeMask(dst, offset);
- argument(mov->src[0], src, offset);
+ source(mov->src[0], src, offset);
shader->append(mov);
}
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;
TIntermBinary *binary = node->getAsBinaryNode();
TIntermSymbol *symbol = node->getAsSymbolNode();
TIntermTyped *left = binary->getLeft();
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())
{
if(left->isRegister())
{
- int leftMask = dst.mask;
+ int leftMask = mask;
- dst.mask = 1;
- while((leftMask & dst.mask) == 0)
+ mask = 1;
+ while((leftMask & mask) == 0)
{
- dst.mask = dst.mask << 1;
+ mask = mask << 1;
}
int element = swizzleElement(leftSwizzle, rightIndex);
- dst.mask = 1 << element;
+ mask = 1 << element;
return element;
}
else if(left->isArray() || left->isMatrix())
{
- dst.index += rightIndex * result->totalRegisterCount();
+ offset += rightIndex * result->totalRegisterCount();
return 0xE4;
}
else UNREACHABLE(0);
{
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)
{
sw::Shader::SourceParameter relativeRegister;
- argument(relativeRegister, right);
+ source(relativeRegister, right);
- dst.rel.index = relativeRegister.index;
- dst.rel.type = relativeRegister.type;
- dst.rel.scale = scale;
- dst.rel.deterministic = !(vertexShader && left->getQualifier() == EvqUniform);
+ rel.index = relativeRegister.index;
+ rel.type = relativeRegister.type;
+ rel.scale = scale;
+ 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)
{
- Constant oldScale((int)dst.rel.scale);
+ Constant oldScale((int)rel.scale);
Instruction *mad = emit(sw::Shader::OPCODE_IMAD, &address, &address, &oldScale, right);
- mad->src[0].index = dst.rel.index;
- mad->src[0].type = dst.rel.type;
+ mad->src[0].index = rel.index;
+ mad->src[0].type = rel.type;
}
else
{
- Constant oldScale((int)dst.rel.scale);
+ Constant oldScale((int)rel.scale);
Instruction *mul = emit(sw::Shader::OPCODE_IMUL, &address, &address, &oldScale);
- mul->src[0].index = dst.rel.index;
- mul->src[0].type = dst.rel.type;
+ mul->src[0].index = rel.index;
+ mul->src[0].type = rel.type;
Constant newScale(scale);
emit(sw::Shader::OPCODE_IMAD, &address, right, &newScale, &address);
}
- dst.rel.type = sw::Shader::PARAMETER_TEMP;
- dst.rel.index = registerIndex(&address);
- dst.rel.scale = 1;
+ rel.type = sw::Shader::PARAMETER_TEMP;
+ rel.index = registerIndex(&address);
+ rel.scale = 1;
}
else // Just add the new index to the address register
{
fieldOffset += fields[i]->type()->totalRegisterCount();
}
- dst.type = registerType(left);
- dst.index += fieldOffset;
- dst.mask = writeMask(result);
+ offset += fieldOffset;
+ mask = writeMask(result);
return 0xE4;
}
{
ASSERT(left->isRegister());
- int leftMask = dst.mask;
+ int leftMask = mask;
int swizzle = 0;
int rightMask = 0;
swizzle = swizzle | swizzleElement(leftSwizzle, i) << (element * 2);
}
- dst.mask = leftMask & rightMask;
+ mask = leftMask & rightMask;
return swizzle;
}
}
else if(symbol)
{
- dst.type = registerType(symbol);
- dst.index = registerIndex(symbol);
- dst.mask = writeMask(symbol);
+ root = symbol;
+ offset = 0;
+ mask = writeMask(symbol);
+
+ return 0xE4;
+ }
+ else
+ {
+ node->traverse(this);
+
+ root = node;
+ offset = 0;
+ mask = writeMask(node);
+
return 0xE4;
}
}
const TQualifier qualifier = operand->getQualifier();
- if((EvqFragColor == qualifier) || (EvqFragData == qualifier))
+ if((qualifier == EvqFragColor) || (qualifier == EvqFragData))
{
- if(((EvqFragData == qualifier) && (EvqFragColor == outputQualifier)) ||
- ((EvqFragColor == qualifier) && (EvqFragData == outputQualifier)))
+ if(((qualifier == EvqFragData) && (outputQualifier == EvqFragColor)) ||
+ ((qualifier == EvqFragColor) && (outputQualifier == EvqFragData)))
{
mContext.error(operand->getLine(), "static assignment to both gl_FragData and gl_FragColor", "");
}
void emitShader(Scope scope);
// Visit AST nodes and output their code to the body stream
- virtual void visitSymbol(TIntermSymbol*);
- virtual bool visitBinary(Visit visit, TIntermBinary*);
- virtual bool visitUnary(Visit visit, TIntermUnary*);
- virtual bool visitSelection(Visit visit, TIntermSelection*);
- virtual bool visitAggregate(Visit visit, TIntermAggregate*);
- virtual bool visitLoop(Visit visit, TIntermLoop*);
- virtual bool visitBranch(Visit visit, TIntermBranch*);
- virtual bool visitSwitch(Visit, TIntermSwitch*);
+ void visitSymbol(TIntermSymbol*) override;
+ bool visitBinary(Visit visit, TIntermBinary*) override;
+ bool visitUnary(Visit visit, TIntermUnary*) override;
+ bool visitSelection(Visit visit, TIntermSelection*) override;
+ bool visitAggregate(Visit visit, TIntermAggregate*) override;
+ bool visitLoop(Visit visit, TIntermLoop*) override;
+ bool visitBranch(Visit visit, TIntermBranch*) override;
+ bool visitSwitch(Visit, TIntermSwitch*) override;
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);
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 emitDeterminant(TIntermTyped *result, TIntermTyped *arg, int size, int col = -1, int row = -1, int outCol = 0, int outRow = 0);
- void argument(sw::Shader::SourceParameter ¶meter, TIntermNode *argument, int index = 0);
+ void source(sw::Shader::SourceParameter ¶meter, TIntermNode *argument, int index = 0);
+ void destination(sw::Shader::DestinationParameter ¶meter, TIntermTyped *argument, int index = 0);
void copy(TIntermTyped *dst, TIntermNode *src, int offset = 0);
void assignLvalue(TIntermTyped *dst, TIntermTyped *src);
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);
bool hasFlatQualifier(TIntermTyped *operand);
unsigned int registerIndex(TIntermTyped *operand);