diff options
| author | jsmall-nvidia <jsmall@nvidia.com> | 2019-03-13 16:31:29 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2019-03-13 16:31:29 -0400 |
| commit | 04416431993b1d5efa8eac759a16832d40c2a159 (patch) | |
| tree | e5059ff16c9ada8fd3386c39ace805118603e545 /source | |
| parent | 3b33c1be0ad4c1256878d8669773ef1f8fc9b58d (diff) | |
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)
Diffstat (limited to 'source')
| -rw-r--r-- | source/slang/emit.cpp | 73 |
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, |
