summaryrefslogtreecommitdiffstats
path: root/source
diff options
context:
space:
mode:
Diffstat (limited to 'source')
-rw-r--r--source/slang/emit.cpp73
1 files changed, 55 insertions, 18 deletions
diff --git a/source/slang/emit.cpp b/source/slang/emit.cpp
index 426c4b9f3..0c1896c0c 100644
--- a/source/slang/emit.cpp
+++ b/source/slang/emit.cpp
@@ -1469,6 +1469,7 @@ struct EmitVisitor
EOpInfo leftSide(EOpInfo const& outerPrec, EOpInfo const& prec)
{
EOpInfo result;
+ result.op = nullptr;
result.leftPrecedence = outerPrec.leftPrecedence;
result.rightPrecedence = prec.leftPrecedence;
return result;
@@ -1477,6 +1478,7 @@ struct EmitVisitor
EOpInfo rightSide(EOpInfo const& prec, EOpInfo const& outerPrec)
{
EOpInfo result;
+ result.op = nullptr;
result.leftPrecedence = prec.rightPrecedence;
result.rightPrecedence = outerPrec.rightPrecedence;
return result;
@@ -3599,34 +3601,69 @@ struct EmitVisitor
}
}
- void emitComparison(EmitContext* ctx, IRInst* inst, IREmitMode mode, EOpInfo& inOutOuterPrec, const EOpInfo& opPrec, bool* needCloseOut)
+ void _maybeEmitGLSLCast(EmitContext* ctx, IRType* castType, IRInst* inst, IREmitMode mode)
{
- *needCloseOut = maybeEmitParens(inOutOuterPrec, opPrec);
-
- if (getTarget(ctx) == CodeGenTarget::GLSL
- && as<IRVectorType>(inst->getOperand(0)->getDataType())
- && as<IRVectorType>(inst->getOperand(1)->getDataType()))
+ // Wrap in cast if a cast type is specified
+ if (castType)
{
- const char* funcName = getGLSLVectorCompareFunctionName(inst->op);
- SLANG_ASSERT(funcName);
-
- emit(funcName);
+ emitIRType(ctx, castType);
emit("(");
- emitIROperand(ctx, inst->getOperand(0), mode, leftSide(inOutOuterPrec, opPrec));
- emit(",");
- emitIROperand(ctx, inst->getOperand(1), mode, rightSide(inOutOuterPrec, opPrec));
+
+ // Emit the operand
+ emitIROperand(ctx, inst, mode, kEOp_General);
+
emit(")");
}
else
{
- emitIROperand(ctx, inst->getOperand(0), mode, leftSide(inOutOuterPrec, opPrec));
- emit(" ");
- emit(opPrec.op);
- emit(" ");
- emitIROperand(ctx, inst->getOperand(1), mode, rightSide(inOutOuterPrec, opPrec));
+ // Emit the operand
+ emitIROperand(ctx, inst, mode, kEOp_General);
}
}
+ void emitComparison(EmitContext* ctx, IRInst* inst, IREmitMode mode, EOpInfo& ioOuterPrec, const EOpInfo& opPrec, bool* needCloseOut)
+ {
+ if (getTarget(ctx) == CodeGenTarget::GLSL)
+ {
+ IRInst* left = inst->getOperand(0);
+ IRInst* right = inst->getOperand(1);
+
+ auto leftVectorType = as<IRVectorType>(left->getDataType());
+ auto rightVectorType = as<IRVectorType>(right->getDataType());
+
+ // If either side is a vector handle as a vector
+ if (leftVectorType || rightVectorType)
+ {
+ const char* funcName = getGLSLVectorCompareFunctionName(inst->op);
+ SLANG_ASSERT(funcName);
+
+ // Determine the vector type
+ const auto vecType = leftVectorType ? leftVectorType : rightVectorType;
+
+ // Handle as a function call
+ auto prec = kEOp_Postfix;
+ *needCloseOut = maybeEmitParens(ioOuterPrec, prec);
+
+ emit(funcName);
+ emit("(");
+ _maybeEmitGLSLCast(ctx, (leftVectorType ? nullptr : vecType), left, mode);
+ emit(",");
+ _maybeEmitGLSLCast(ctx, (rightVectorType ? nullptr : vecType), right, mode);
+ emit(")");
+
+ return;
+ }
+ }
+
+ *needCloseOut = maybeEmitParens(ioOuterPrec, opPrec);
+
+ emitIROperand(ctx, inst->getOperand(0), mode, leftSide(ioOuterPrec, opPrec));
+ emit(" ");
+ emit(opPrec.op);
+ emit(" ");
+ emitIROperand(ctx, inst->getOperand(1), mode, rightSide(ioOuterPrec, opPrec));
+ }
+
void emitIRInstExpr(
EmitContext* ctx,
IRInst* inst,