[glsl][ir] Emit vector types.
Add vector type emission to the GLSL IR backend.
Bug: 42251044
Change-Id: Iea6eacc4d871545e44ecd4aeb9a81c241ae8ef96
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/204254
Reviewed-by: James Price <jrprice@google.com>
Commit-Queue: dan sinclair <dsinclair@chromium.org>
diff --git a/src/tint/lang/glsl/writer/printer/printer.cc b/src/tint/lang/glsl/writer/printer/printer.cc
index 3c59959..958ca60 100644
--- a/src/tint/lang/glsl/writer/printer/printer.cc
+++ b/src/tint/lang/glsl/writer/printer/printer.cc
@@ -30,6 +30,7 @@
#include <string>
#include <utility>
+#include "src/tint/lang/core/constant/splat.h"
#include "src/tint/lang/core/ir/access.h"
#include "src/tint/lang/core/ir/bitcast.h"
#include "src/tint/lang/core/ir/construct.h"
@@ -55,6 +56,7 @@
#include "src/tint/lang/core/type/i32.h"
#include "src/tint/lang/core/type/pointer.h"
#include "src/tint/lang/core/type/u32.h"
+#include "src/tint/lang/core/type/vector.h"
#include "src/tint/lang/core/type/void.h"
#include "src/tint/lang/glsl/writer/common/printer_support.h"
#include "src/tint/lang/glsl/writer/common/version.h"
@@ -302,11 +304,28 @@
[&](const core::type::Pointer* p) {
EmitType(out, p->StoreType(), name, name_printed);
},
+ [&](const core::type::Vector* v) { EmitVectorType(out, v); },
// TODO(dsinclair): Handle remaining types
TINT_ICE_ON_NO_MATCH);
}
+ void EmitVectorType(StringStream& out, const core::type::Vector* v) {
+ tint::Switch(
+ v->Type(), //
+ [&](const core::type::F32*) {}, //
+ [&](const core::type::F16*) {
+ EmitExtension(kAMDGpuShaderHalfFloat);
+ out << "f16";
+ },
+ [&](const core::type::I32*) { out << "i"; },
+ [&](const core::type::U32*) { out << "u"; },
+ [&](const core::type::Bool*) { out << "b"; }, //
+ TINT_ICE_ON_NO_MATCH);
+
+ out << "vec" << v->Width();
+ }
+
void EmitArrayType(StringStream& out,
const core::type::Array* ary,
const std::string& name,
@@ -416,11 +435,32 @@
[&](const core::type::U32*) { out << c->ValueAs<AInt>() << "u"; },
[&](const core::type::F32*) { PrintF32(out, c->ValueAs<f32>()); },
[&](const core::type::F16*) { PrintF16(out, c->ValueAs<f16>()); },
+ [&](const core::type::Vector* v) { EmitConstantVector(out, v, c); },
// TODO(dsinclair): Emit remaining constant types
TINT_ICE_ON_NO_MATCH);
}
+ void EmitConstantVector(StringStream& out,
+ const core::type::Vector* v,
+ const core::constant::Value* c) {
+ EmitType(out, v);
+
+ ScopedParen sp(out);
+
+ if (auto* splat = c->As<core::constant::Splat>()) {
+ EmitConstant(out, splat->el);
+ return;
+ }
+
+ for (size_t i = 0; i < v->Width(); ++i) {
+ if (i > 0) {
+ out << ", ";
+ }
+ EmitConstant(out, c->Index(i));
+ }
+ }
+
void EmitConstantArray(StringStream& out,
const core::type::Array* ary,
const core::constant::Value* c) {
diff --git a/src/tint/lang/glsl/writer/type_test.cc b/src/tint/lang/glsl/writer/type_test.cc
index 2a179be..ae4f717 100644
--- a/src/tint/lang/glsl/writer/type_test.cc
+++ b/src/tint/lang/glsl/writer/type_test.cc
@@ -250,8 +250,7 @@
)");
}
-// TODO(dsinclair): Add vector support
-TEST_F(GlslWriterTest, DISABLED_EmitType_Vector_F32) {
+TEST_F(GlslWriterTest, EmitType_Vector_F32) {
auto* func = b.Function("foo", ty.void_(), core::ir::Function::PipelineStage::kCompute);
func->SetWorkgroupSize(1, 1, 1);
b.Append(func->Block(), [&] {
@@ -263,13 +262,12 @@
EXPECT_EQ(output_.glsl, GlslHeader() + R"(
layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
void foo() {
- vec3 a = 0.0f;
+ vec3 a = vec3(0.0f);
}
)");
}
-// TODO(dsinclair): Add vector support
-TEST_F(GlslWriterTest, DISABLED_EmitType_Vector_F16) {
+TEST_F(GlslWriterTest, EmitType_Vector_F16) {
auto* func = b.Function("foo", ty.void_(), core::ir::Function::PipelineStage::kCompute);
func->SetWorkgroupSize(1, 1, 1);
b.Append(func->Block(), [&] {
@@ -278,10 +276,62 @@
});
ASSERT_TRUE(Generate()) << err_ << output_.glsl;
+ EXPECT_EQ(output_.glsl, GlslHeader() + R"(#extension GL_AMD_gpu_shader_half_float: require
+
+layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
+void foo() {
+ f16vec3 a = f16vec3(0.0hf);
+}
+)");
+}
+
+TEST_F(GlslWriterTest, EmitType_Vector_I32) {
+ auto* func = b.Function("foo", ty.void_(), core::ir::Function::PipelineStage::kCompute);
+ func->SetWorkgroupSize(1, 1, 1);
+ b.Append(func->Block(), [&] {
+ b.Var("a", ty.ptr(core::AddressSpace::kPrivate, ty.vec2<i32>()));
+ b.Return(func);
+ });
+
+ ASSERT_TRUE(Generate()) << err_ << output_.glsl;
EXPECT_EQ(output_.glsl, GlslHeader() + R"(
layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
void foo() {
- f16vec3 a = 0.0h;
+ ivec2 a = ivec2(0);
+}
+)");
+}
+
+TEST_F(GlslWriterTest, EmitType_Vector_U32) {
+ auto* func = b.Function("foo", ty.void_(), core::ir::Function::PipelineStage::kCompute);
+ func->SetWorkgroupSize(1, 1, 1);
+ b.Append(func->Block(), [&] {
+ b.Var("a", ty.ptr(core::AddressSpace::kPrivate, ty.vec4<u32>()));
+ b.Return(func);
+ });
+
+ ASSERT_TRUE(Generate()) << err_ << output_.glsl;
+ EXPECT_EQ(output_.glsl, GlslHeader() + R"(
+layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
+void foo() {
+ uvec4 a = uvec4(0u);
+}
+)");
+}
+
+TEST_F(GlslWriterTest, EmitType_Vector_bool) {
+ auto* func = b.Function("foo", ty.void_(), core::ir::Function::PipelineStage::kCompute);
+ func->SetWorkgroupSize(1, 1, 1);
+ b.Append(func->Block(), [&] {
+ b.Var("a", ty.ptr(core::AddressSpace::kPrivate, ty.vec3<bool>()));
+ b.Return(func);
+ });
+
+ ASSERT_TRUE(Generate()) << err_ << output_.glsl;
+ EXPECT_EQ(output_.glsl, GlslHeader() + R"(
+layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
+void foo() {
+ bvec3 a = bvec3(false);
}
)");
}