Vectorize scalars in SPIR-V using ConstructorSplat.

This avoids redundant code, and has a small side benefit of
deduplicating constant vectors which appear more than once in the code,
since `writeConstructorSplat` already supports this.

Change-Id: I2972ee922ac92adeb40bc765da3b490a59b957b3
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/408360
Auto-Submit: John Stiles <johnstiles@google.com>
Reviewed-by: Brian Osman <brianosman@google.com>
Commit-Queue: John Stiles <johnstiles@google.com>
diff --git a/src/sksl/codegen/SkSLSPIRVCodeGenerator.cpp b/src/sksl/codegen/SkSLSPIRVCodeGenerator.cpp
index 466f611..f851f0f 100644
--- a/src/sksl/codegen/SkSLSPIRVCodeGenerator.cpp
+++ b/src/sksl/codegen/SkSLSPIRVCodeGenerator.cpp
@@ -855,18 +855,13 @@
     result.reserve(args.size());
     for (const auto& arg : args) {
         const Type& argType = arg->type();
-        SpvId raw = this->writeExpression(*arg, out);
         if (vectorSize && argType.isScalar()) {
-            SpvId vector = this->nextId(&arg->type());
-            this->writeOpCode(SpvOpCompositeConstruct, 3 + vectorSize, out);
-            this->writeWord(this->getType(argType.toCompound(fContext, vectorSize, 1)), out);
-            this->writeWord(vector, out);
-            for (int i = 0; i < vectorSize; i++) {
-                this->writeWord(raw, out);
-            }
-            result.push_back(vector);
+            ConstructorSplat splat{/*offset=*/-1,
+                                   argType.toCompound(fContext, vectorSize, /*rows=*/1),
+                                   arg->clone()};
+            result.push_back(this->writeConstructorSplat(splat, out));
         } else {
-            result.push_back(raw);
+            result.push_back(this->writeExpression(*arg, out));
         }
     }
     return result;