diff --git a/src/writer/hlsl/generator_impl.cc b/src/writer/hlsl/generator_impl.cc index 394017dbae..40f90e1235 100644 --- a/src/writer/hlsl/generator_impl.cc +++ b/src/writer/hlsl/generator_impl.cc @@ -587,8 +587,7 @@ bool GeneratorImpl::EmitCall(std::ostream& pre, return EmitTextureCall(pre, out, expr, intrinsic); } if (intrinsic->Type() == sem::IntrinsicType::kSelect) { - diagnostics_.add_error("select not supported in HLSL backend yet"); - return false; + return EmitSelectCall(pre, out, expr); } else if (intrinsic->Type() == sem::IntrinsicType::kIsNormal) { diagnostics_.add_error("is_normal not supported in HLSL backend yet"); return false; @@ -676,6 +675,32 @@ bool GeneratorImpl::EmitCall(std::ostream& pre, return true; } +bool GeneratorImpl::EmitSelectCall(std::ostream& pre, + std::ostream& out, + ast::CallExpression* expr) { + auto* expr_true = expr->params()[0]; + auto* expr_false = expr->params()[1]; + auto* expr_cond = expr->params()[2]; + ScopedParen paren(out); + if (!EmitExpression(pre, out, expr_cond)) { + return false; + } + + out << " ? "; + + if (!EmitExpression(pre, out, expr_true)) { + return false; + } + + out << " : "; + + if (!EmitExpression(pre, out, expr_false)) { + return false; + } + + return true; +} + bool GeneratorImpl::EmitDataPackingCall(std::ostream& pre, std::ostream& out, ast::CallExpression* expr, diff --git a/src/writer/hlsl/generator_impl.h b/src/writer/hlsl/generator_impl.h index 1b62c769a8..3aa49586b9 100644 --- a/src/writer/hlsl/generator_impl.h +++ b/src/writer/hlsl/generator_impl.h @@ -139,6 +139,16 @@ class GeneratorImpl : public TextGenerator { std::ostream& out, ast::CallExpression* expr, const sem::Intrinsic* intrinsic); + + /// Handles generating a call to the `select()` intrinsic + /// @param pre the preamble of the expression stream + /// @param out the output of the expression stream + /// @param expr the call expression + /// @returns true if the call expression is emitted + bool EmitSelectCall(std::ostream& pre, + std::ostream& out, + ast::CallExpression* expr); + /// Handles generating a call to data packing intrinsic /// @param pre the preamble of the expression stream /// @param out the output of the expression stream diff --git a/src/writer/hlsl/generator_impl_intrinsic_test.cc b/src/writer/hlsl/generator_impl_intrinsic_test.cc index a6d79c63cc..314ead212a 100644 --- a/src/writer/hlsl/generator_impl_intrinsic_test.cc +++ b/src/writer/hlsl/generator_impl_intrinsic_test.cc @@ -272,6 +272,28 @@ TEST_F(HlslGeneratorImplTest_Intrinsic, Intrinsic_Call) { EXPECT_EQ(result(), "dot(param1, param2)"); } +TEST_F(HlslGeneratorImplTest_Intrinsic, Select_Scalar) { + auto* call = Call("select", 1.0f, 2.0f, true); + WrapInFunction(call); + GeneratorImpl& gen = Build(); + + gen.increment_indent(); + ASSERT_TRUE(gen.EmitExpression(pre, out, call)) << gen.error(); + EXPECT_EQ(result(), "(true ? 1.0f : 2.0f)"); +} + +TEST_F(HlslGeneratorImplTest_Intrinsic, Select_Vector) { + auto* call = + Call("select", vec2(1, 2), vec2(3, 4), vec2(true, false)); + WrapInFunction(call); + GeneratorImpl& gen = Build(); + + gen.increment_indent(); + ASSERT_TRUE(gen.EmitExpression(pre, out, call)) << gen.error(); + EXPECT_EQ(result(), + "(vector(true, false) ? int2(1, 2) : int2(3, 4))"); +} + TEST_F(HlslGeneratorImplTest_Intrinsic, Pack4x8Snorm) { auto* call = Call("pack4x8snorm", "p1"); Global("p1", ty.vec4(), ast::StorageClass::kPrivate); diff --git a/test/intrinsics/gen/select/00b848.wgsl.expected.hlsl b/test/intrinsics/gen/select/00b848.wgsl.expected.hlsl index 813c530a7d..7c4709c8c6 100644 --- a/test/intrinsics/gen/select/00b848.wgsl.expected.hlsl +++ b/test/intrinsics/gen/select/00b848.wgsl.expected.hlsl @@ -1,23 +1,25 @@ -SKIP: FAILED +struct tint_symbol { + float4 value : SV_Position; +}; - -fn select_00b848() { - var res : vec2 = select(vec2(), vec2(), vec2()); +void select_00b848() { + int2 res = (vector(false, false) ? int2(0, 0) : int2(0, 0)); } -[[stage(vertex)]] -fn vertex_main() { +tint_symbol vertex_main() { select_00b848(); + const tint_symbol tint_symbol_1 = {float4(0.0f, 0.0f, 0.0f, 0.0f)}; + return tint_symbol_1; } -[[stage(fragment)]] -fn fragment_main() { +void fragment_main() { select_00b848(); + return; } -[[stage(compute)]] -fn compute_main() { +[numthreads(1, 1, 1)] +void compute_main() { select_00b848(); + return; } -Failed to generate: error: select not supported in HLSL backend yet diff --git a/test/intrinsics/gen/select/01e2cd.wgsl.expected.hlsl b/test/intrinsics/gen/select/01e2cd.wgsl.expected.hlsl index a59ac84743..f94a217c3f 100644 --- a/test/intrinsics/gen/select/01e2cd.wgsl.expected.hlsl +++ b/test/intrinsics/gen/select/01e2cd.wgsl.expected.hlsl @@ -1,23 +1,25 @@ -SKIP: FAILED +struct tint_symbol { + float4 value : SV_Position; +}; - -fn select_01e2cd() { - var res : vec3 = select(vec3(), vec3(), vec3()); +void select_01e2cd() { + int3 res = (vector(false, false, false) ? int3(0, 0, 0) : int3(0, 0, 0)); } -[[stage(vertex)]] -fn vertex_main() { +tint_symbol vertex_main() { select_01e2cd(); + const tint_symbol tint_symbol_1 = {float4(0.0f, 0.0f, 0.0f, 0.0f)}; + return tint_symbol_1; } -[[stage(fragment)]] -fn fragment_main() { +void fragment_main() { select_01e2cd(); + return; } -[[stage(compute)]] -fn compute_main() { +[numthreads(1, 1, 1)] +void compute_main() { select_01e2cd(); + return; } -Failed to generate: error: select not supported in HLSL backend yet diff --git a/test/intrinsics/gen/select/1e960b.wgsl.expected.hlsl b/test/intrinsics/gen/select/1e960b.wgsl.expected.hlsl index 2ad2b344de..8a476b888e 100644 --- a/test/intrinsics/gen/select/1e960b.wgsl.expected.hlsl +++ b/test/intrinsics/gen/select/1e960b.wgsl.expected.hlsl @@ -1,23 +1,25 @@ -SKIP: FAILED +struct tint_symbol { + float4 value : SV_Position; +}; - -fn select_1e960b() { - var res : vec2 = select(vec2(), vec2(), vec2()); +void select_1e960b() { + uint2 res = (vector(false, false) ? uint2(0u, 0u) : uint2(0u, 0u)); } -[[stage(vertex)]] -fn vertex_main() { +tint_symbol vertex_main() { select_1e960b(); + const tint_symbol tint_symbol_1 = {float4(0.0f, 0.0f, 0.0f, 0.0f)}; + return tint_symbol_1; } -[[stage(fragment)]] -fn fragment_main() { +void fragment_main() { select_1e960b(); + return; } -[[stage(compute)]] -fn compute_main() { +[numthreads(1, 1, 1)] +void compute_main() { select_1e960b(); + return; } -Failed to generate: error: select not supported in HLSL backend yet diff --git a/test/intrinsics/gen/select/266aff.wgsl.expected.hlsl b/test/intrinsics/gen/select/266aff.wgsl.expected.hlsl index 7fa28bc4f8..430c689e7e 100644 --- a/test/intrinsics/gen/select/266aff.wgsl.expected.hlsl +++ b/test/intrinsics/gen/select/266aff.wgsl.expected.hlsl @@ -1,23 +1,25 @@ -SKIP: FAILED +struct tint_symbol { + float4 value : SV_Position; +}; - -fn select_266aff() { - var res : vec2 = select(vec2(), vec2(), vec2()); +void select_266aff() { + float2 res = (vector(false, false) ? float2(0.0f, 0.0f) : float2(0.0f, 0.0f)); } -[[stage(vertex)]] -fn vertex_main() { +tint_symbol vertex_main() { select_266aff(); + const tint_symbol tint_symbol_1 = {float4(0.0f, 0.0f, 0.0f, 0.0f)}; + return tint_symbol_1; } -[[stage(fragment)]] -fn fragment_main() { +void fragment_main() { select_266aff(); + return; } -[[stage(compute)]] -fn compute_main() { +[numthreads(1, 1, 1)] +void compute_main() { select_266aff(); + return; } -Failed to generate: error: select not supported in HLSL backend yet diff --git a/test/intrinsics/gen/select/28a27e.wgsl.expected.hlsl b/test/intrinsics/gen/select/28a27e.wgsl.expected.hlsl index 51b8dcb1ad..ad1d9923a7 100644 --- a/test/intrinsics/gen/select/28a27e.wgsl.expected.hlsl +++ b/test/intrinsics/gen/select/28a27e.wgsl.expected.hlsl @@ -1,23 +1,25 @@ -SKIP: FAILED +struct tint_symbol { + float4 value : SV_Position; +}; - -fn select_28a27e() { - var res : vec3 = select(vec3(), vec3(), vec3()); +void select_28a27e() { + uint3 res = (vector(false, false, false) ? uint3(0u, 0u, 0u) : uint3(0u, 0u, 0u)); } -[[stage(vertex)]] -fn vertex_main() { +tint_symbol vertex_main() { select_28a27e(); + const tint_symbol tint_symbol_1 = {float4(0.0f, 0.0f, 0.0f, 0.0f)}; + return tint_symbol_1; } -[[stage(fragment)]] -fn fragment_main() { +void fragment_main() { select_28a27e(); + return; } -[[stage(compute)]] -fn compute_main() { +[numthreads(1, 1, 1)] +void compute_main() { select_28a27e(); + return; } -Failed to generate: error: select not supported in HLSL backend yet diff --git a/test/intrinsics/gen/select/416e14.wgsl.expected.hlsl b/test/intrinsics/gen/select/416e14.wgsl.expected.hlsl index f2cabc0d82..afcb7f08e7 100644 --- a/test/intrinsics/gen/select/416e14.wgsl.expected.hlsl +++ b/test/intrinsics/gen/select/416e14.wgsl.expected.hlsl @@ -1,23 +1,25 @@ -SKIP: FAILED +struct tint_symbol { + float4 value : SV_Position; +}; - -fn select_416e14() { - var res : f32 = select(1.0, 1.0, bool()); +void select_416e14() { + float res = (false ? 1.0f : 1.0f); } -[[stage(vertex)]] -fn vertex_main() { +tint_symbol vertex_main() { select_416e14(); + const tint_symbol tint_symbol_1 = {float4(0.0f, 0.0f, 0.0f, 0.0f)}; + return tint_symbol_1; } -[[stage(fragment)]] -fn fragment_main() { +void fragment_main() { select_416e14(); + return; } -[[stage(compute)]] -fn compute_main() { +[numthreads(1, 1, 1)] +void compute_main() { select_416e14(); + return; } -Failed to generate: error: select not supported in HLSL backend yet diff --git a/test/intrinsics/gen/select/80a9a9.wgsl.expected.hlsl b/test/intrinsics/gen/select/80a9a9.wgsl.expected.hlsl index 784f9fdd49..f0700b10e7 100644 --- a/test/intrinsics/gen/select/80a9a9.wgsl.expected.hlsl +++ b/test/intrinsics/gen/select/80a9a9.wgsl.expected.hlsl @@ -1,23 +1,25 @@ -SKIP: FAILED +struct tint_symbol { + float4 value : SV_Position; +}; - -fn select_80a9a9() { - var res : vec3 = select(vec3(), vec3(), vec3()); +void select_80a9a9() { + vector res = (vector(false, false, false) ? vector(false, false, false) : vector(false, false, false)); } -[[stage(vertex)]] -fn vertex_main() { +tint_symbol vertex_main() { select_80a9a9(); + const tint_symbol tint_symbol_1 = {float4(0.0f, 0.0f, 0.0f, 0.0f)}; + return tint_symbol_1; } -[[stage(fragment)]] -fn fragment_main() { +void fragment_main() { select_80a9a9(); + return; } -[[stage(compute)]] -fn compute_main() { +[numthreads(1, 1, 1)] +void compute_main() { select_80a9a9(); + return; } -Failed to generate: error: select not supported in HLSL backend yet diff --git a/test/intrinsics/gen/select/99f883.wgsl.expected.hlsl b/test/intrinsics/gen/select/99f883.wgsl.expected.hlsl index 7c30f9a136..c1874135d4 100644 --- a/test/intrinsics/gen/select/99f883.wgsl.expected.hlsl +++ b/test/intrinsics/gen/select/99f883.wgsl.expected.hlsl @@ -1,23 +1,25 @@ -SKIP: FAILED +struct tint_symbol { + float4 value : SV_Position; +}; - -fn select_99f883() { - var res : u32 = select(1u, 1u, bool()); +void select_99f883() { + uint res = (false ? 1u : 1u); } -[[stage(vertex)]] -fn vertex_main() { +tint_symbol vertex_main() { select_99f883(); + const tint_symbol tint_symbol_1 = {float4(0.0f, 0.0f, 0.0f, 0.0f)}; + return tint_symbol_1; } -[[stage(fragment)]] -fn fragment_main() { +void fragment_main() { select_99f883(); + return; } -[[stage(compute)]] -fn compute_main() { +[numthreads(1, 1, 1)] +void compute_main() { select_99f883(); + return; } -Failed to generate: error: select not supported in HLSL backend yet diff --git a/test/intrinsics/gen/select/a2860e.wgsl.expected.hlsl b/test/intrinsics/gen/select/a2860e.wgsl.expected.hlsl index 06245b94ac..6266236e58 100644 --- a/test/intrinsics/gen/select/a2860e.wgsl.expected.hlsl +++ b/test/intrinsics/gen/select/a2860e.wgsl.expected.hlsl @@ -1,23 +1,25 @@ -SKIP: FAILED +struct tint_symbol { + float4 value : SV_Position; +}; - -fn select_a2860e() { - var res : vec4 = select(vec4(), vec4(), vec4()); +void select_a2860e() { + int4 res = (vector(false, false, false, false) ? int4(0, 0, 0, 0) : int4(0, 0, 0, 0)); } -[[stage(vertex)]] -fn vertex_main() { +tint_symbol vertex_main() { select_a2860e(); + const tint_symbol tint_symbol_1 = {float4(0.0f, 0.0f, 0.0f, 0.0f)}; + return tint_symbol_1; } -[[stage(fragment)]] -fn fragment_main() { +void fragment_main() { select_a2860e(); + return; } -[[stage(compute)]] -fn compute_main() { +[numthreads(1, 1, 1)] +void compute_main() { select_a2860e(); + return; } -Failed to generate: error: select not supported in HLSL backend yet diff --git a/test/intrinsics/gen/select/bb8aae.wgsl.expected.hlsl b/test/intrinsics/gen/select/bb8aae.wgsl.expected.hlsl index b057c7f2cf..55e26b878d 100644 --- a/test/intrinsics/gen/select/bb8aae.wgsl.expected.hlsl +++ b/test/intrinsics/gen/select/bb8aae.wgsl.expected.hlsl @@ -1,23 +1,25 @@ -SKIP: FAILED +struct tint_symbol { + float4 value : SV_Position; +}; - -fn select_bb8aae() { - var res : vec4 = select(vec4(), vec4(), vec4()); +void select_bb8aae() { + float4 res = (vector(false, false, false, false) ? float4(0.0f, 0.0f, 0.0f, 0.0f) : float4(0.0f, 0.0f, 0.0f, 0.0f)); } -[[stage(vertex)]] -fn vertex_main() { +tint_symbol vertex_main() { select_bb8aae(); + const tint_symbol tint_symbol_1 = {float4(0.0f, 0.0f, 0.0f, 0.0f)}; + return tint_symbol_1; } -[[stage(fragment)]] -fn fragment_main() { +void fragment_main() { select_bb8aae(); + return; } -[[stage(compute)]] -fn compute_main() { +[numthreads(1, 1, 1)] +void compute_main() { select_bb8aae(); + return; } -Failed to generate: error: select not supported in HLSL backend yet diff --git a/test/intrinsics/gen/select/c31f9e.wgsl.expected.hlsl b/test/intrinsics/gen/select/c31f9e.wgsl.expected.hlsl index 65ab282a04..7d8695e307 100644 --- a/test/intrinsics/gen/select/c31f9e.wgsl.expected.hlsl +++ b/test/intrinsics/gen/select/c31f9e.wgsl.expected.hlsl @@ -1,23 +1,25 @@ -SKIP: FAILED +struct tint_symbol { + float4 value : SV_Position; +}; - -fn select_c31f9e() { - var res : bool = select(bool(), bool(), bool()); +void select_c31f9e() { + bool res = (false ? false : false); } -[[stage(vertex)]] -fn vertex_main() { +tint_symbol vertex_main() { select_c31f9e(); + const tint_symbol tint_symbol_1 = {float4(0.0f, 0.0f, 0.0f, 0.0f)}; + return tint_symbol_1; } -[[stage(fragment)]] -fn fragment_main() { +void fragment_main() { select_c31f9e(); + return; } -[[stage(compute)]] -fn compute_main() { +[numthreads(1, 1, 1)] +void compute_main() { select_c31f9e(); + return; } -Failed to generate: error: select not supported in HLSL backend yet diff --git a/test/intrinsics/gen/select/c4a4ef.wgsl.expected.hlsl b/test/intrinsics/gen/select/c4a4ef.wgsl.expected.hlsl index 00ad0615ab..b5c3056372 100644 --- a/test/intrinsics/gen/select/c4a4ef.wgsl.expected.hlsl +++ b/test/intrinsics/gen/select/c4a4ef.wgsl.expected.hlsl @@ -1,23 +1,25 @@ -SKIP: FAILED +struct tint_symbol { + float4 value : SV_Position; +}; - -fn select_c4a4ef() { - var res : vec4 = select(vec4(), vec4(), vec4()); +void select_c4a4ef() { + uint4 res = (vector(false, false, false, false) ? uint4(0u, 0u, 0u, 0u) : uint4(0u, 0u, 0u, 0u)); } -[[stage(vertex)]] -fn vertex_main() { +tint_symbol vertex_main() { select_c4a4ef(); + const tint_symbol tint_symbol_1 = {float4(0.0f, 0.0f, 0.0f, 0.0f)}; + return tint_symbol_1; } -[[stage(fragment)]] -fn fragment_main() { +void fragment_main() { select_c4a4ef(); + return; } -[[stage(compute)]] -fn compute_main() { +[numthreads(1, 1, 1)] +void compute_main() { select_c4a4ef(); + return; } -Failed to generate: error: select not supported in HLSL backend yet diff --git a/test/intrinsics/gen/select/cb9301.wgsl.expected.hlsl b/test/intrinsics/gen/select/cb9301.wgsl.expected.hlsl index 3c9013c7de..5041d269ae 100644 --- a/test/intrinsics/gen/select/cb9301.wgsl.expected.hlsl +++ b/test/intrinsics/gen/select/cb9301.wgsl.expected.hlsl @@ -1,23 +1,25 @@ -SKIP: FAILED +struct tint_symbol { + float4 value : SV_Position; +}; - -fn select_cb9301() { - var res : vec2 = select(vec2(), vec2(), vec2()); +void select_cb9301() { + vector res = (vector(false, false) ? vector(false, false) : vector(false, false)); } -[[stage(vertex)]] -fn vertex_main() { +tint_symbol vertex_main() { select_cb9301(); + const tint_symbol tint_symbol_1 = {float4(0.0f, 0.0f, 0.0f, 0.0f)}; + return tint_symbol_1; } -[[stage(fragment)]] -fn fragment_main() { +void fragment_main() { select_cb9301(); + return; } -[[stage(compute)]] -fn compute_main() { +[numthreads(1, 1, 1)] +void compute_main() { select_cb9301(); + return; } -Failed to generate: error: select not supported in HLSL backend yet diff --git a/test/intrinsics/gen/select/e3e028.wgsl.expected.hlsl b/test/intrinsics/gen/select/e3e028.wgsl.expected.hlsl index 31a4f022e5..f65fa64332 100644 --- a/test/intrinsics/gen/select/e3e028.wgsl.expected.hlsl +++ b/test/intrinsics/gen/select/e3e028.wgsl.expected.hlsl @@ -1,23 +1,25 @@ -SKIP: FAILED +struct tint_symbol { + float4 value : SV_Position; +}; - -fn select_e3e028() { - var res : vec4 = select(vec4(), vec4(), vec4()); +void select_e3e028() { + vector res = (vector(false, false, false, false) ? vector(false, false, false, false) : vector(false, false, false, false)); } -[[stage(vertex)]] -fn vertex_main() { +tint_symbol vertex_main() { select_e3e028(); + const tint_symbol tint_symbol_1 = {float4(0.0f, 0.0f, 0.0f, 0.0f)}; + return tint_symbol_1; } -[[stage(fragment)]] -fn fragment_main() { +void fragment_main() { select_e3e028(); + return; } -[[stage(compute)]] -fn compute_main() { +[numthreads(1, 1, 1)] +void compute_main() { select_e3e028(); + return; } -Failed to generate: error: select not supported in HLSL backend yet diff --git a/test/intrinsics/gen/select/ebfea2.wgsl.expected.hlsl b/test/intrinsics/gen/select/ebfea2.wgsl.expected.hlsl index 9889d933f8..7183f0e40c 100644 --- a/test/intrinsics/gen/select/ebfea2.wgsl.expected.hlsl +++ b/test/intrinsics/gen/select/ebfea2.wgsl.expected.hlsl @@ -1,23 +1,25 @@ -SKIP: FAILED +struct tint_symbol { + float4 value : SV_Position; +}; - -fn select_ebfea2() { - var res : vec3 = select(vec3(), vec3(), vec3()); +void select_ebfea2() { + float3 res = (vector(false, false, false) ? float3(0.0f, 0.0f, 0.0f) : float3(0.0f, 0.0f, 0.0f)); } -[[stage(vertex)]] -fn vertex_main() { +tint_symbol vertex_main() { select_ebfea2(); + const tint_symbol tint_symbol_1 = {float4(0.0f, 0.0f, 0.0f, 0.0f)}; + return tint_symbol_1; } -[[stage(fragment)]] -fn fragment_main() { +void fragment_main() { select_ebfea2(); + return; } -[[stage(compute)]] -fn compute_main() { +[numthreads(1, 1, 1)] +void compute_main() { select_ebfea2(); + return; } -Failed to generate: error: select not supported in HLSL backend yet diff --git a/test/intrinsics/gen/select/ed8a15.wgsl.expected.hlsl b/test/intrinsics/gen/select/ed8a15.wgsl.expected.hlsl index 4211acad11..48f9b9296b 100644 --- a/test/intrinsics/gen/select/ed8a15.wgsl.expected.hlsl +++ b/test/intrinsics/gen/select/ed8a15.wgsl.expected.hlsl @@ -1,23 +1,25 @@ -SKIP: FAILED +struct tint_symbol { + float4 value : SV_Position; +}; - -fn select_ed8a15() { - var res : i32 = select(1, 1, bool()); +void select_ed8a15() { + int res = (false ? 1 : 1); } -[[stage(vertex)]] -fn vertex_main() { +tint_symbol vertex_main() { select_ed8a15(); + const tint_symbol tint_symbol_1 = {float4(0.0f, 0.0f, 0.0f, 0.0f)}; + return tint_symbol_1; } -[[stage(fragment)]] -fn fragment_main() { +void fragment_main() { select_ed8a15(); + return; } -[[stage(compute)]] -fn compute_main() { +[numthreads(1, 1, 1)] +void compute_main() { select_ed8a15(); + return; } -Failed to generate: error: select not supported in HLSL backend yet