diff options
| author | jsmall-nvidia <jsmall@nvidia.com> | 2019-03-14 16:21:03 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2019-03-14 16:21:03 -0400 |
| commit | c8e36bd128a29654b2ec145038da9e132330581b (patch) | |
| tree | 950ce7c3bb1cc235f97ceb982643e99245c87e16 | |
| parent | 04416431993b1d5efa8eac759a16832d40c2a159 (diff) | |
Hotfix/bool fix (#907)
* * Handle ! for bool vector in glsl
* Handle operators that have a boolean return value
* || or && take bool
* * Add comment in bool-op.slang test about doing || or && on vector types not supported for GLSL targets
| -rw-r--r-- | source/slang/core.meta.slang | 11 | ||||
| -rw-r--r-- | source/slang/core.meta.slang.h | 13 | ||||
| -rw-r--r-- | source/slang/emit.cpp | 33 | ||||
| -rw-r--r-- | source/slang/slang-stdlib.cpp | 20 | ||||
| -rw-r--r-- | tests/bugs/bool-op.slang | 77 | ||||
| -rw-r--r-- | tests/bugs/bool-op.slang.expected.txt | 16 |
6 files changed, 146 insertions, 24 deletions
diff --git a/source/slang/core.meta.slang b/source/slang/core.meta.slang index f3e57b90b..e42669822 100644 --- a/source/slang/core.meta.slang +++ b/source/slang/core.meta.slang @@ -1103,22 +1103,25 @@ for (auto op : unaryOps) if ((type.flags & op.flags) == 0) continue; + char const* resultType = type.name; + if (op.flags & BOOL_RESULT) resultType = "bool"; + char const* fixity = (op.flags & POSTFIX) != 0 ? "__postfix " : "__prefix "; char const* qual = (op.flags & ASSIGNMENT) != 0 ? "in out " : ""; // scalar version sb << fixity; - sb << "__intrinsic_op(" << int(op.opCode) << ") " << type.name << " operator" << op.opName << "(" << qual << type.name << " value);\n"; + sb << "__intrinsic_op(" << int(op.opCode) << ") " << resultType << " operator" << op.opName << "(" << qual << type.name << " value);\n"; // vector version sb << "__generic<let N : int> "; sb << fixity; - sb << "__intrinsic_op(" << int(op.opCode) << ") vector<" << type.name << ",N> operator" << op.opName << "(" << qual << "vector<" << type.name << ",N> value);\n"; + sb << "__intrinsic_op(" << int(op.opCode) << ") vector<" << resultType << ",N> operator" << op.opName << "(" << qual << "vector<" << type.name << ",N> value);\n"; // matrix version sb << "__generic<let N : int, let M : int> "; sb << fixity; - sb << "__intrinsic_op(" << int(op.opCode) << ") matrix<" << type.name << ",N,M> operator" << op.opName << "(" << qual << "matrix<" << type.name << ",N,M> value);\n"; + sb << "__intrinsic_op(" << int(op.opCode) << ") matrix<" << resultType << ",N,M> operator" << op.opName << "(" << qual << "matrix<" << type.name << ",N,M> value);\n"; } } @@ -1133,7 +1136,7 @@ for (auto op : binaryOps) char const* rightType = leftType; char const* resultType = leftType; - if (op.flags & COMPARISON) resultType = "bool"; + if (op.flags & BOOL_RESULT) resultType = "bool"; char const* leftQual = ""; if(op.flags & ASSIGNMENT) leftQual = "in out "; diff --git a/source/slang/core.meta.slang.h b/source/slang/core.meta.slang.h index 2ae45a01c..6dc84df43 100644 --- a/source/slang/core.meta.slang.h +++ b/source/slang/core.meta.slang.h @@ -1121,22 +1121,25 @@ for (auto op : unaryOps) if ((type.flags & op.flags) == 0) continue; + char const* resultType = type.name; + if (op.flags & BOOL_RESULT) resultType = "bool"; + char const* fixity = (op.flags & POSTFIX) != 0 ? "__postfix " : "__prefix "; char const* qual = (op.flags & ASSIGNMENT) != 0 ? "in out " : ""; // scalar version sb << fixity; - sb << "__intrinsic_op(" << int(op.opCode) << ") " << type.name << " operator" << op.opName << "(" << qual << type.name << " value);\n"; + sb << "__intrinsic_op(" << int(op.opCode) << ") " << resultType << " operator" << op.opName << "(" << qual << type.name << " value);\n"; // vector version sb << "__generic<let N : int> "; sb << fixity; - sb << "__intrinsic_op(" << int(op.opCode) << ") vector<" << type.name << ",N> operator" << op.opName << "(" << qual << "vector<" << type.name << ",N> value);\n"; + sb << "__intrinsic_op(" << int(op.opCode) << ") vector<" << resultType << ",N> operator" << op.opName << "(" << qual << "vector<" << type.name << ",N> value);\n"; // matrix version sb << "__generic<let N : int, let M : int> "; sb << fixity; - sb << "__intrinsic_op(" << int(op.opCode) << ") matrix<" << type.name << ",N,M> operator" << op.opName << "(" << qual << "matrix<" << type.name << ",N,M> value);\n"; + sb << "__intrinsic_op(" << int(op.opCode) << ") matrix<" << resultType << ",N,M> operator" << op.opName << "(" << qual << "matrix<" << type.name << ",N,M> value);\n"; } } @@ -1151,7 +1154,7 @@ for (auto op : binaryOps) char const* rightType = leftType; char const* resultType = leftType; - if (op.flags & COMPARISON) resultType = "bool"; + if (op.flags & BOOL_RESULT) resultType = "bool"; char const* leftQual = ""; if(op.flags & ASSIGNMENT) leftQual = "in out "; @@ -1202,7 +1205,7 @@ for (auto op : binaryOps) sb << "__intrinsic_op(" << int(op.opCode) << ") matrix<" << resultType << ",N,M> operator" << op.opName << "(" << leftQual << "matrix<" << leftType << ",N,M> left, " << rightType << " right);\n"; } } -SLANG_RAW("#line 1187 \"core.meta.slang\"") +SLANG_RAW("#line 1190 \"core.meta.slang\"") SLANG_RAW("\n") SLANG_RAW("\n") SLANG_RAW("// Operators to apply to `enum` types\n") diff --git a/source/slang/emit.cpp b/source/slang/emit.cpp index 0c1896c0c..d2de479b4 100644 --- a/source/slang/emit.cpp +++ b/source/slang/emit.cpp @@ -3621,6 +3621,33 @@ struct EmitVisitor } } + void emitNot(EmitContext* ctx, IRInst* inst, IREmitMode mode, EOpInfo& ioOuterPrec, bool* outNeedClose) + { + IRInst* operand = inst->getOperand(0); + + if (getTarget(ctx) == CodeGenTarget::GLSL) + { + if (auto vectorType = as<IRVectorType>(operand->getDataType())) + { + // Handle as a function call + auto prec = kEOp_Postfix; + *outNeedClose = maybeEmitParens(ioOuterPrec, prec); + + emit("not("); + emitIROperand(ctx, operand, mode, kEOp_General); + emit(")"); + return; + } + } + + auto prec = kEOp_Prefix; + *outNeedClose = maybeEmitParens(ioOuterPrec, prec); + + emit("!"); + emitIROperand(ctx, operand, mode, rightSide(prec, ioOuterPrec)); + } + + void emitComparison(EmitContext* ctx, IRInst* inst, IREmitMode mode, EOpInfo& ioOuterPrec, const EOpInfo& opPrec, bool* needCloseOut) { if (getTarget(ctx) == CodeGenTarget::GLSL) @@ -3839,11 +3866,7 @@ struct EmitVisitor case kIROp_Not: { - auto prec = kEOp_Prefix; - needClose = maybeEmitParens(outerPrec, prec); - - emit("!"); - emitIROperand(ctx, inst->getOperand(0), mode, rightSide(prec, outerPrec)); + emitNot(ctx, inst, mode, outerPrec, &needClose); } break; diff --git a/source/slang/slang-stdlib.cpp b/source/slang/slang-stdlib.cpp index 936c92fdd..183bed9ba 100644 --- a/source/slang/slang-stdlib.cpp +++ b/source/slang/slang-stdlib.cpp @@ -46,7 +46,7 @@ namespace Slang { SINT_MASK = 1 << 0, FLOAT_MASK = 1 << 1, - COMPARISON = 1 << 2, + BOOL_RESULT = 1 << 2, BOOL_MASK = 1 << 3, UINT_MASK = 1 << 4, ASSIGNMENT = 1 << 5, @@ -203,7 +203,7 @@ namespace Slang static const OpInfo unaryOps[] = { { kIRPseudoOp_Pos, "+", ARITHMETIC_MASK }, { kIROp_Neg, "-", ARITHMETIC_MASK }, - { kIROp_Not, "!", ANY_MASK }, + { kIROp_Not, "!", BOOL_MASK | BOOL_RESULT }, { kIROp_BitNot, "~", INT_MASK }, { kIRPseudoOp_PreInc, "++", ARITHMETIC_MASK | ASSIGNMENT }, { kIRPseudoOp_PreDec, "--", ARITHMETIC_MASK | ASSIGNMENT }, @@ -217,19 +217,19 @@ namespace Slang { kIROp_Mul, "*", ARITHMETIC_MASK }, { kIROp_Div, "/", ARITHMETIC_MASK }, { kIROp_Mod, "%", INT_MASK }, - { kIROp_And, "&&", LOGICAL_MASK }, - { kIROp_Or, "||", LOGICAL_MASK }, + { kIROp_And, "&&", BOOL_MASK | BOOL_RESULT}, + { kIROp_Or, "||", BOOL_MASK | BOOL_RESULT }, { kIROp_BitAnd, "&", LOGICAL_MASK }, { kIROp_BitOr, "|", LOGICAL_MASK }, { kIROp_BitXor, "^", LOGICAL_MASK }, { kIROp_Lsh, "<<", INT_MASK }, { kIROp_Rsh, ">>", INT_MASK }, - { kIROp_Eql, "==", ANY_MASK | COMPARISON }, - { kIROp_Neq, "!=", ANY_MASK | COMPARISON }, - { kIROp_Greater, ">", ARITHMETIC_MASK | COMPARISON }, - { kIROp_Less, "<", ARITHMETIC_MASK | COMPARISON }, - { kIROp_Geq, ">=", ARITHMETIC_MASK | COMPARISON }, - { kIROp_Leq, "<=", ARITHMETIC_MASK | COMPARISON }, + { kIROp_Eql, "==", ANY_MASK | BOOL_RESULT }, + { kIROp_Neq, "!=", ANY_MASK | BOOL_RESULT }, + { kIROp_Greater, ">", ARITHMETIC_MASK | BOOL_RESULT }, + { kIROp_Less, "<", ARITHMETIC_MASK | BOOL_RESULT }, + { kIROp_Geq, ">=", ARITHMETIC_MASK | BOOL_RESULT }, + { kIROp_Leq, "<=", ARITHMETIC_MASK | BOOL_RESULT }, { kIRPseudoOp_AddAssign, "+=", ASSIGNMENT | ARITHMETIC_MASK }, { kIRPseudoOp_SubAssign, "-=", ASSIGNMENT | ARITHMETIC_MASK }, { kIRPseudoOp_MulAssign, "*=", ASSIGNMENT | ARITHMETIC_MASK }, diff --git a/tests/bugs/bool-op.slang b/tests/bugs/bool-op.slang new file mode 100644 index 000000000..1388ef8f1 --- /dev/null +++ b/tests/bugs/bool-op.slang @@ -0,0 +1,77 @@ +// enum.slang +//TEST(compute):COMPARE_COMPUTE_EX:-slang -compute +//TEST(compute, vulkan):COMPARE_COMPUTE_EX:-vk -compute + +// Confirm operations that produce bools - such as comparisons, or && ||, ! work correctly + +//TEST_INPUT:ubuffer(data=[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0], stride=4):dxbinding(0),glbinding(0),out +RWStructuredBuffer<int> outputBuffer; + +[numthreads(16, 1, 1)] +void computeMain(uint3 dispatchThreadID : SV_DispatchThreadID) +{ + uint tid = dispatchThreadID.x;; + + uint uv = tid; + int iv = int(tid); + + bool2 bv2 = { tid & 1, tid > 10 }; + + float2 f2 = { float(tid), float(tid + 1) }; + + bool bv = tid > 6; + let not_bv2 = !bv2; + + int r = 0; + if (bv) + { + r |= 0x0001; + } + if (!bv) + { + r |= 0x0002; + } + + if (iv) + { + r|= 0x0004; + } + if (!iv) + { + r|= 0x0008; + } + + if (uv) + { + r |= 0x0010; + } + if (!uv) + { + r |= 0x0020; + } + + if (all(bv2)) + { + r |= 0x0040; + } + if (all(not_bv2)) + { + r |= 0x0080; + } + + if (any(!f2)) + { + r |= 0x0100; + } + + // TODO(JS): Support on GLSL targets + // This doesn't currently work on GLSL targets, and because there + // do not appear to be any vector bitwise operations. Could be achieved + // by deconstructing, and reconstructing the vec result + /* if (all(f2 || bv2)) + { + r |= 0x0200; + } */ + + outputBuffer[tid] = r; +}
\ No newline at end of file diff --git a/tests/bugs/bool-op.slang.expected.txt b/tests/bugs/bool-op.slang.expected.txt new file mode 100644 index 000000000..08b720347 --- /dev/null +++ b/tests/bugs/bool-op.slang.expected.txt @@ -0,0 +1,16 @@ +1AA +16 +96 +16 +96 +16 +96 +15 +95 +15 +95 +55 +15 +55 +15 +55 |
