[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); } )"); }