From fbba2775eb381caba23dac1c36869b6ce11c6357 Mon Sep 17 00:00:00 2001 From: Yong He Date: Sun, 10 Mar 2019 15:31:38 -0700 Subject: Fix GLSL emit logic for select expr --- source/slang/emit.cpp | 31 ++++++++++++++++++------ tests/cross-compile/vector-comparison.slang | 24 ++++++++++++++++++ tests/cross-compile/vector-comparison.slang.glsl | 26 ++++++++++++++++++++ 3 files changed, 73 insertions(+), 8 deletions(-) create mode 100644 tests/cross-compile/vector-comparison.slang create mode 100644 tests/cross-compile/vector-comparison.slang.glsl 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 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; +} -- cgit v1.2.3