[tint][ir] Serialize Swizzle instruction
Change-Id: I24066ea619a3f0fb9c72e6b6046ae34dc81b9c5d
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/164880
Auto-Submit: Ben Clayton <bclayton@google.com>
Commit-Queue: James Price <jrprice@google.com>
Kokoro: Kokoro <noreply+kokoro@google.com>
Reviewed-by: James Price <jrprice@google.com>
diff --git a/src/tint/lang/core/ir/binary/decode.cc b/src/tint/lang/core/ir/binary/decode.cc
index 8ffd626..6d235882 100644
--- a/src/tint/lang/core/ir/binary/decode.cc
+++ b/src/tint/lang/core/ir/binary/decode.cc
@@ -196,6 +196,9 @@
case pb::Instruction::KindCase::kStoreVectorElement:
inst_out = CreateInstructionStoreVectorElement(inst_in.store_vector_element());
break;
+ case pb::Instruction::KindCase::kSwizzle:
+ inst_out = CreateInstructionSwizzle(inst_in.swizzle());
+ break;
case pb::Instruction::KindCase::kUnary:
inst_out = CreateInstructionUnary(inst_in.unary());
break;
@@ -270,6 +273,16 @@
return mod_out_.instructions.Create<ir::StoreVectorElement>();
}
+ ir::Swizzle* CreateInstructionSwizzle(const pb::InstructionSwizzle& swizzle_in) {
+ auto* swizzle_out = mod_out_.instructions.Create<ir::Swizzle>();
+ Vector<uint32_t, 4> indices;
+ for (auto idx : swizzle_in.indices()) {
+ indices.Push(idx);
+ }
+ swizzle_out->SetIndices(indices);
+ return swizzle_out;
+ }
+
ir::Unary* CreateInstructionUnary(const pb::InstructionUnary& unary_in) {
auto* unary_out = mod_out_.instructions.Create<ir::Unary>();
unary_out->SetOp(UnaryOp(unary_in.op()));
diff --git a/src/tint/lang/core/ir/binary/encode.cc b/src/tint/lang/core/ir/binary/encode.cc
index c2b175f..7846a4a 100644
--- a/src/tint/lang/core/ir/binary/encode.cc
+++ b/src/tint/lang/core/ir/binary/encode.cc
@@ -44,6 +44,7 @@
#include "src/tint/lang/core/ir/return.h"
#include "src/tint/lang/core/ir/store.h"
#include "src/tint/lang/core/ir/store_vector_element.h"
+#include "src/tint/lang/core/ir/swizzle.h"
#include "src/tint/lang/core/ir/unary.h"
#include "src/tint/lang/core/ir/user_call.h"
#include "src/tint/lang/core/ir/var.h"
@@ -162,6 +163,7 @@
[&](const ir::StoreVectorElement* i) {
InstructionStoreVectorElement(*inst_out.mutable_store_vector_element(), i);
},
+ [&](const ir::Swizzle* i) { InstructionSwizzle(*inst_out.mutable_swizzle(), i); },
[&](const ir::Unary* i) { InstructionUnary(*inst_out.mutable_unary(), i); },
[&](const ir::UserCall* i) { InstructionUserCall(*inst_out.mutable_user_call(), i); },
[&](const ir::Var* i) { InstructionVar(*inst_out.mutable_var(), i); },
@@ -198,6 +200,12 @@
void InstructionStoreVectorElement(pb::InstructionStoreVectorElement&,
const ir::StoreVectorElement*) {}
+ void InstructionSwizzle(pb::InstructionSwizzle& swizzle_out, const ir::Swizzle* swizzle_in) {
+ for (auto idx : swizzle_in->Indices()) {
+ swizzle_out.add_indices(idx);
+ }
+ }
+
void InstructionUnary(pb::InstructionUnary& unary_out, const ir::Unary* unary_in) {
unary_out.set_op(UnaryOp(unary_in->Op()));
}
diff --git a/src/tint/lang/core/ir/binary/ir.proto b/src/tint/lang/core/ir/binary/ir.proto
index 67d6caa..3db27a5 100644
--- a/src/tint/lang/core/ir/binary/ir.proto
+++ b/src/tint/lang/core/ir/binary/ir.proto
@@ -194,6 +194,7 @@
InstructionStore store = 15;
InstructionLoadVectorElement load_vector_element = 16;
InstructionStoreVectorElement store_vector_element = 17;
+ InstructionSwizzle swizzle = 18;
}
}
@@ -233,6 +234,10 @@
message InstructionStoreVectorElement {}
+message InstructionSwizzle {
+ repeated uint32 indices = 1;
+}
+
message BindingPoint {
uint32 group = 1;
uint32 binding = 2;
diff --git a/src/tint/lang/core/ir/binary/roundtrip_test.cc b/src/tint/lang/core/ir/binary/roundtrip_test.cc
index 42f199c..57ade4e 100644
--- a/src/tint/lang/core/ir/binary/roundtrip_test.cc
+++ b/src/tint/lang/core/ir/binary/roundtrip_test.cc
@@ -304,5 +304,15 @@
RUN_TEST();
}
+TEST_F(IRBinaryRoundtripTest, Swizzle) {
+ auto x = b.FunctionParam<vec4<f32>>("x");
+ auto* fn = b.Function("Function", ty.vec3<f32>());
+ fn->SetParams({x});
+ b.Append(fn->Block(), [&] {
+ b.Return(fn, b.Swizzle<vec3<f32>>(x, Vector<uint32_t, 3>{1, 0, 2}));
+ });
+ RUN_TEST();
+}
+
} // namespace
} // namespace tint::core::ir::binary
diff --git a/src/tint/lang/core/ir/builder.h b/src/tint/lang/core/ir/builder.h
index 8a9644d..bdbd507 100644
--- a/src/tint/lang/core/ir/builder.h
+++ b/src/tint/lang/core/ir/builder.h
@@ -1315,6 +1315,17 @@
}
/// Creates a new `Swizzle`
+ /// @tparam TYPE the return type
+ /// @param object the object being swizzled
+ /// @param indices the swizzle indices
+ /// @returns the instruction
+ template <typename TYPE, typename OBJ>
+ ir::Swizzle* Swizzle(OBJ&& object, VectorRef<uint32_t> indices) {
+ auto* type = ir.Types().Get<TYPE>();
+ return Swizzle(type, std::forward<OBJ>(object), std::move(indices));
+ }
+
+ /// Creates a new `Swizzle`
/// @param type the return type
/// @param object the object being swizzled
/// @param indices the swizzle indices
diff --git a/src/tint/lang/core/ir/swizzle.cc b/src/tint/lang/core/ir/swizzle.cc
index 1a1e6dc..184ddf6 100644
--- a/src/tint/lang/core/ir/swizzle.cc
+++ b/src/tint/lang/core/ir/swizzle.cc
@@ -37,6 +37,8 @@
namespace tint::core::ir {
+Swizzle::Swizzle() = default;
+
Swizzle::Swizzle(InstructionResult* result, Value* object, VectorRef<uint32_t> indices)
: indices_(std::move(indices)) {
TINT_ASSERT(!indices.IsEmpty());
diff --git a/src/tint/lang/core/ir/swizzle.h b/src/tint/lang/core/ir/swizzle.h
index 1e5b0fc..88740d0 100644
--- a/src/tint/lang/core/ir/swizzle.h
+++ b/src/tint/lang/core/ir/swizzle.h
@@ -29,6 +29,7 @@
#define SRC_TINT_LANG_CORE_IR_SWIZZLE_H_
#include <string>
+#include <utility>
#include "src/tint/lang/core/ir/operand_instruction.h"
#include "src/tint/utils/rtti/castable.h"
@@ -41,6 +42,9 @@
/// The offset in Operands() for the object being swizzled
static constexpr size_t kObjectOperandOffset = 0;
+ /// Constructor (no results, no operands)
+ Swizzle();
+
/// Constructor
/// @param result the result value
/// @param object the object being swizzled
@@ -60,6 +64,9 @@
/// @returns the swizzle indices
VectorRef<uint32_t> Indices() const { return indices_; }
+ /// @param indices the new swizzle indices
+ void SetIndices(VectorRef<uint32_t> indices) { indices_ = std::move(indices); }
+
/// @returns the friendly name for the instruction
std::string FriendlyName() const override { return "swizzle"; }