tint/writer/glsl: Fix vector select

mix of ivec is not core until later GLSL versions.
Just polyfill in the writer with ternary ops.

Change-Id: Ia0c35bf95842e03ef8447019f3264d01c11fd384
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/123240
Commit-Queue: Ben Clayton <bclayton@google.com>
Reviewed-by: Stephen White <senorblanco@chromium.org>
Kokoro: Ben Clayton <bclayton@google.com>
This commit is contained in:
Ben Clayton
2023-03-08 22:29:38 +00:00
committed by Dawn LUCI CQ
parent da353b4b39
commit 2657b923c9
119 changed files with 1869 additions and 635 deletions

View File

@@ -780,7 +780,7 @@ bool GeneratorImpl::EmitBuiltinCall(utils::StringStream& out,
return EmitCountOneBitsCall(out, expr);
}
if (builtin->Type() == sem::BuiltinType::kSelect) {
return EmitSelectCall(out, expr);
return EmitSelectCall(out, expr, builtin);
}
if (builtin->Type() == sem::BuiltinType::kDot) {
return EmitDotCall(out, expr, builtin);
@@ -1100,28 +1100,39 @@ bool GeneratorImpl::EmitCountOneBitsCall(utils::StringStream& out,
return true;
}
bool GeneratorImpl::EmitSelectCall(utils::StringStream& out, const ast::CallExpression* expr) {
bool GeneratorImpl::EmitSelectCall(utils::StringStream& out,
const ast::CallExpression* expr,
const sem::Builtin* builtin) {
// GLSL does not support ternary expressions with a bool vector conditional,
// so polyfill with a helper.
if (auto* vec = builtin->Parameters()[2]->Type()->As<type::Vector>()) {
return CallBuiltinHelper(
out, expr, builtin, [&](TextBuffer* b, const std::vector<std::string>& params) {
auto l = line(b);
l << " return ";
if (!EmitType(l, builtin->ReturnType(), builtin::AddressSpace::kUndefined,
builtin::Access::kUndefined, "")) {
return false;
}
{
ScopedParen sp(l);
for (uint32_t i = 0; i < vec->Width(); i++) {
if (i > 0) {
l << ", ";
}
l << params[2] << "[" << i << "] ? " << params[1] << "[" << i
<< "] : " << params[0] << "[" << i << "]";
}
}
l << ";";
return true;
});
}
auto* expr_false = expr->args[0];
auto* expr_true = expr->args[1];
auto* expr_cond = expr->args[2];
// GLSL does not support ternary expressions with a bool vector conditional,
// but it does support mix() with same.
if (TypeOf(expr_cond)->UnwrapRef()->is_bool_vector()) {
out << "mix(";
if (!EmitExpression(out, expr_false)) {
return false;
}
out << ", ";
if (!EmitExpression(out, expr_true)) {
return false;
}
out << ", ";
if (!EmitExpression(out, expr_cond)) {
return false;
}
out << ")";
return true;
}
ScopedParen paren(out);
if (!EmitExpression(out, expr_cond)) {
return false;

View File

@@ -234,8 +234,11 @@ class GeneratorImpl : public TextGenerator {
/// Handles generating a call to the `countOneBits()` builtin
/// @param out the output of the expression stream
/// @param expr the call expression
/// @param builtin the semantic information for the builtin
/// @returns true if the call expression is emitted
bool EmitSelectCall(utils::StringStream& out, const ast::CallExpression* expr);
bool EmitSelectCall(utils::StringStream& out,
const ast::CallExpression* expr,
const sem::Builtin* builtin);
/// Handles generating a call to the `dot()` builtin
/// @param out the output of the expression stream
/// @param expr the call expression

View File

@@ -379,7 +379,7 @@ TEST_F(GlslGeneratorImplTest_Builtin, Select_Vector) {
gen.increment_indent();
utils::StringStream out;
ASSERT_TRUE(gen.EmitExpression(out, call)) << gen.error();
EXPECT_EQ(out.str(), "mix(a, b, bvec2(true, false))");
EXPECT_EQ(out.str(), "tint_select(a, b, bvec2(true, false))");
}
TEST_F(GlslGeneratorImplTest_Builtin, FMA_f32) {