diff options
| author | Yong He <yonghe@outlook.com> | 2019-03-10 15:31:38 -0700 |
|---|---|---|
| committer | Yong He <yonghe@outlook.com> | 2019-03-10 15:35:44 -0700 |
| commit | fbba2775eb381caba23dac1c36869b6ce11c6357 (patch) | |
| tree | 9f44be5afceb2dfe216645e2719680867d2cc6bc | |
| parent | d5492155d6d8b16f262c09f72d8653e3e675b616 (diff) | |
Fix GLSL emit logic for select expr
| -rw-r--r-- | source/slang/emit.cpp | 31 | ||||
| -rw-r--r-- | tests/cross-compile/vector-comparison.slang | 24 | ||||
| -rw-r--r-- | tests/cross-compile/vector-comparison.slang.glsl | 26 |
3 files changed, 73 insertions, 8 deletions
diff --git a/source/slang/emit.cpp b/source/slang/emit.cpp index dcc99fc0d..9b1ebc91b 100644 --- a/source/slang/emit.cpp +++ b/source/slang/emit.cpp @@ -3959,14 +3959,29 @@ struct EmitVisitor case kIROp_Select: { - auto prec = kEOp_Conditional; - needClose = maybeEmitParens(outerPrec, prec); - - emitIROperand(ctx, inst->getOperand(0), mode, leftSide(outerPrec, prec)); - emit(" ? "); - emitIROperand(ctx, inst->getOperand(1), mode, prec); - emit(" : "); - emitIROperand(ctx, inst->getOperand(2), mode, rightSide(prec, outerPrec)); + if (getTarget(ctx) == CodeGenTarget::GLSL && + inst->getOperand(0)->getDataType()->op != kIROp_BoolType) + { + // For GLSL, emit a call to `mix` if condition is a vector + emit("mix("); + emitIROperand(ctx, inst->getOperand(2), mode, leftSide(kEOp_General, kEOp_General)); + emit(", "); + emitIROperand(ctx, inst->getOperand(1), mode, leftSide(kEOp_General, kEOp_General)); + emit(", "); + emitIROperand(ctx, inst->getOperand(0), mode, leftSide(kEOp_General, kEOp_General)); + emit(")"); + } + else + { + auto prec = kEOp_Conditional; + needClose = maybeEmitParens(outerPrec, prec); + + emitIROperand(ctx, inst->getOperand(0), mode, leftSide(outerPrec, prec)); + emit(" ? "); + emitIROperand(ctx, inst->getOperand(1), mode, prec); + emit(" : "); + emitIROperand(ctx, inst->getOperand(2), mode, rightSide(prec, outerPrec)); + } } break; diff --git a/tests/cross-compile/vector-comparison.slang b/tests/cross-compile/vector-comparison.slang new file mode 100644 index 000000000..d1fdcfd4a --- /dev/null +++ b/tests/cross-compile/vector-comparison.slang @@ -0,0 +1,24 @@ +// vector-comparison.slang + +//TEST:CROSS_COMPILE:-target spirv-assembly -entry main -stage fragment + +// This test ensures that we cross-compile vector comparison operators +// correctly to GLSL + +struct Param +{ + float4 a, b; +}; +ParameterBlock<Param> params; +float4 main() : SV_Target +{ + float4 v0 = params.a; + float4 v1 = params.b; + float4 result = v0 == v1 ? float4(2.0f) : float4(3.0f); + result += v0 < v1 ? float4(2.0f) : float4(3.0f); + result += v0 > v1 ? float4(2.0f) : float4(3.0f); + result += v0 <= v1 ? float4(2.0f) : float4(3.0f); + result += v0 >= v1 ? float4(2.0f) : float4(3.0f); + result += v0 != v1 ? float4(2.0f) : float4(3.0f); + return result; +}
\ No newline at end of file diff --git a/tests/cross-compile/vector-comparison.slang.glsl b/tests/cross-compile/vector-comparison.slang.glsl new file mode 100644 index 000000000..77578a368 --- /dev/null +++ b/tests/cross-compile/vector-comparison.slang.glsl @@ -0,0 +1,26 @@ +//TEST_IGNORE_FILE +#version 450 +layout(row_major) uniform; +layout(row_major) buffer; + +struct Param_0 +{ + vec4 a_0; + vec4 b_0; +}; + +layout(binding = 0) +layout(std140) uniform _S1 +{ + Param_0 _data; +} params_0; +layout(location = 0) +out vec4 _S2; + +void main() +{ + vec4 v0_0 = params_0._data.a_0; + vec4 v1_0 = params_0._data.b_0; + _S2 = mix(vec4(3.00000000000000000000), vec4(2.00000000000000000000), equal(v0_0,v1_0)) + mix(vec4(3.00000000000000000000), vec4(2.00000000000000000000), lessThan(v0_0,v1_0)) + mix(vec4(3.00000000000000000000), vec4(2.00000000000000000000), greaterThan(v0_0,v1_0)) + mix(vec4(3.00000000000000000000), vec4(2.00000000000000000000), lessThanEqual(v0_0,v1_0)) + mix(vec4(3.00000000000000000000), vec4(2.00000000000000000000), greaterThanEqual(v0_0,v1_0)) + mix(vec4(3.00000000000000000000), vec4(2.00000000000000000000), notEqual(v0_0,v1_0)); + return; +} |
