From 04416431993b1d5efa8eac759a16832d40c2a159 Mon Sep 17 00:00:00 2001 From: jsmall-nvidia Date: Wed, 13 Mar 2019 16:31:29 -0400 Subject: Add support for vector/scalar compares for GLSL (#903) * * leftSide and rightSide set op to nullptr, before was just uninitialized * Added support for GLSL for vector/scalar comparisons * Added test * * Remove unneeded precedence code. * Simplify function to _maybeEmitGLSLCast * * Take into account precedence & closing of brackets in same way as function call, if function call used for vector comparison (as on GLSL) --- source/slang/emit.cpp | 73 ++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 55 insertions(+), 18 deletions(-) (limited to 'source') 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(inst->getOperand(0)->getDataType()) - && as(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(left->getDataType()); + auto rightVectorType = as(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, -- cgit v1.2.3