[tint][ir][ToProgram] Implement swizzles
Change-Id: I9bccd2178febb0748207eef38a2639d02a378693
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/140989
Kokoro: Kokoro <noreply+kokoro@google.com>
Commit-Queue: Ben Clayton <bclayton@google.com>
Auto-Submit: Ben Clayton <bclayton@google.com>
Reviewed-by: James Price <jrprice@google.com>
Reviewed-by: Dan Sinclair <dsinclair@chromium.org>
diff --git a/src/tint/ir/to_program.cc b/src/tint/ir/to_program.cc
index 72050ac..58c7449 100644
--- a/src/tint/ir/to_program.cc
+++ b/src/tint/ir/to_program.cc
@@ -47,6 +47,7 @@
#include "src/tint/ir/store.h"
#include "src/tint/ir/store_vector_element.h"
#include "src/tint/ir/switch.h"
+#include "src/tint/ir/swizzle.h"
#include "src/tint/ir/unary.h"
#include "src/tint/ir/unreachable.h"
#include "src/tint/ir/user_call.h"
@@ -304,7 +305,8 @@
[&](ir::Store* i) { Store(i); }, //
[&](ir::StoreVectorElement* i) { StoreVectorElement(i); }, //
[&](ir::Switch* i) { Switch(i); }, //
- [&](ir::Unary* u) { Unary(u); }, //
+ [&](ir::Swizzle* i) { Swizzle(i); }, //
+ [&](ir::Unary* i) { Unary(i); }, //
[&](ir::Unreachable*) {}, //
[&](ir::Var* i) { Var(i); }, //
[&](Default) { UNHANDLED_CASE(inst); });
@@ -652,6 +654,21 @@
Bind(a->Result(), expr);
}
+ void Swizzle(ir::Swizzle* s) {
+ auto* vec = Expr(s->Object());
+ utils::Vector<char, 4> components;
+ for (uint32_t i : s->Indices()) {
+ if (TINT_UNLIKELY(i >= 4)) {
+ TINT_ICE(IR, b.Diagnostics()) << "invalid swizzle index: " << i;
+ return;
+ }
+ components.Push("xyzw"[i]);
+ }
+ auto* swizzle =
+ b.MemberAccessor(vec, std::string_view(components.begin(), components.Length()));
+ Bind(s->Result(), swizzle);
+ }
+
void Binary(ir::Binary* e) {
if (e->Kind() == ir::Binary::Kind::kEqual) {
auto* rhs = e->RHS()->As<ir::Constant>();
diff --git a/src/tint/ir/to_program_roundtrip_test.cc b/src/tint/ir/to_program_roundtrip_test.cc
index fe8eb02..6282218 100644
--- a/src/tint/ir/to_program_roundtrip_test.cc
+++ b/src/tint/ir/to_program_roundtrip_test.cc
@@ -783,6 +783,73 @@
}
////////////////////////////////////////////////////////////////////////////////
+// Swizzle
+////////////////////////////////////////////////////////////////////////////////
+TEST_F(IRToProgramRoundtripTest, Access_Vec3_Value_xy) {
+ Test(R"(
+fn f(v : vec3<f32>) -> vec2<f32> {
+ return v.xy;
+}
+)");
+}
+
+TEST_F(IRToProgramRoundtripTest, Access_Vec3_Value_yz) {
+ Test(R"(
+fn f(v : vec3<f32>) -> vec2<f32> {
+ return v.yz;
+}
+)");
+}
+
+TEST_F(IRToProgramRoundtripTest, Access_Vec3_Value_yzx) {
+ Test(R"(
+fn f(v : vec3<f32>) -> vec3<f32> {
+ return v.yzx;
+}
+)");
+}
+
+TEST_F(IRToProgramRoundtripTest, Access_Vec3_Value_yzxy) {
+ Test(R"(
+fn f(v : vec3<f32>) -> vec4<f32> {
+ return v.yzxy;
+}
+)");
+}
+
+TEST_F(IRToProgramRoundtripTest, Access_Vec3_Pointer_xy) {
+ Test(R"(
+fn f(v : ptr<function, vec3<f32>>) -> vec2<f32> {
+ return (*(v)).xy;
+}
+)");
+}
+
+TEST_F(IRToProgramRoundtripTest, Access_Vec3_Pointer_yz) {
+ Test(R"(
+fn f(v : ptr<function, vec3<f32>>) -> vec2<f32> {
+ return (*(v)).yz;
+}
+)");
+}
+
+TEST_F(IRToProgramRoundtripTest, Access_Vec3_Pointer_yzx) {
+ Test(R"(
+fn f(v : ptr<function, vec3<f32>>) -> vec3<f32> {
+ return (*(v)).yzx;
+}
+)");
+}
+
+TEST_F(IRToProgramRoundtripTest, Access_Vec3_Pointer_yzxy) {
+ Test(R"(
+fn f(v : ptr<function, vec3<f32>>) -> vec4<f32> {
+ return (*(v)).yzxy;
+}
+)");
+}
+
+////////////////////////////////////////////////////////////////////////////////
// Unary ops
////////////////////////////////////////////////////////////////////////////////
TEST_F(IRToProgramRoundtripTest, UnaryOp_Negate) {