Expose non-square matrix types when fEnforceES2Restrictions is off.

This will allow us to write tests that verify the behavior of non-square
matrix ops.

Change-Id: I1490c4675778cbdc8428ac7a6c9de16083179fc8
Bug: skia:11985
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/408645
Commit-Queue: John Stiles <johnstiles@google.com>
Commit-Queue: Brian Osman <brianosman@google.com>
Auto-Submit: John Stiles <johnstiles@google.com>
Reviewed-by: Brian Osman <brianosman@google.com>
diff --git a/src/sksl/SkSLIRGenerator.cpp b/src/sksl/SkSLIRGenerator.cpp
index 4cf5f08..4c421aa 100644
--- a/src/sksl/SkSLIRGenerator.cpp
+++ b/src/sksl/SkSLIRGenerator.cpp
@@ -1920,11 +1920,41 @@
     }
 
     if (externalFunctions) {
-        // Add any external values to the new symbol table, so they're only visible to this Program
-        for (const auto& ef : *externalFunctions) {
+        // Add any external values to the new symbol table, so they're only visible to this Program.
+        for (const std::unique_ptr<ExternalFunction>& ef : *externalFunctions) {
             fSymbolTable->addWithoutOwnership(ef.get());
         }
     }
+
+    if (!fContext.fConfig->fSettings.fEnforceES2Restrictions &&
+        (this->programKind() == ProgramKind::kRuntimeColorFilter ||
+         this->programKind() == ProgramKind::kRuntimeShader)) {
+        // We're compiling a runtime effect, but we're not enforcing ES2 restrictions. Add the
+        // nonsquare matrix types to the symbol table to allow them to be tested.
+        fSymbolTable->addAlias("mat2x2", fContext.fTypes.fFloat2x2.get());
+        fSymbolTable->addAlias("mat2x3", fContext.fTypes.fFloat2x3.get());
+        fSymbolTable->addAlias("mat2x4", fContext.fTypes.fFloat2x4.get());
+        fSymbolTable->addAlias("mat3x2", fContext.fTypes.fFloat3x2.get());
+        fSymbolTable->addAlias("mat3x3", fContext.fTypes.fFloat3x3.get());
+        fSymbolTable->addAlias("mat3x4", fContext.fTypes.fFloat3x4.get());
+        fSymbolTable->addAlias("mat4x2", fContext.fTypes.fFloat4x2.get());
+        fSymbolTable->addAlias("mat4x3", fContext.fTypes.fFloat4x3.get());
+        fSymbolTable->addAlias("mat4x4", fContext.fTypes.fFloat4x4.get());
+
+        fSymbolTable->addAlias("float2x3", fContext.fTypes.fFloat2x3.get());
+        fSymbolTable->addAlias("float2x4", fContext.fTypes.fFloat2x4.get());
+        fSymbolTable->addAlias("float3x2", fContext.fTypes.fFloat3x2.get());
+        fSymbolTable->addAlias("float3x4", fContext.fTypes.fFloat3x4.get());
+        fSymbolTable->addAlias("float4x2", fContext.fTypes.fFloat4x2.get());
+        fSymbolTable->addAlias("float4x3", fContext.fTypes.fFloat4x3.get());
+
+        fSymbolTable->addAlias("half2x3", fContext.fTypes.fHalf2x3.get());
+        fSymbolTable->addAlias("half2x4", fContext.fTypes.fHalf2x4.get());
+        fSymbolTable->addAlias("half3x2", fContext.fTypes.fHalf3x2.get());
+        fSymbolTable->addAlias("half3x4", fContext.fTypes.fHalf3x4.get());
+        fSymbolTable->addAlias("half4x2", fContext.fTypes.fHalf4x2.get());
+        fSymbolTable->addAlias("half4x3", fContext.fTypes.fHalf4x3.get());
+    }
 }
 
 IRGenerator::IRBundle IRGenerator::finish() {
diff --git a/src/sksl/SkSLIRGenerator.h b/src/sksl/SkSLIRGenerator.h
index 7875823..c92c0fd 100644
--- a/src/sksl/SkSLIRGenerator.h
+++ b/src/sksl/SkSLIRGenerator.h
@@ -114,7 +114,7 @@
     };
 
     /**
-     * If externalFuncs is supplied, those values are registered in the symbol table of the
+     * If externalFunctions is supplied, those values are registered in the symbol table of the
      * Program, but ownership is *not* transferred. It is up to the caller to keep them alive.
      */
     IRBundle convertProgram(
diff --git a/tests/SkSLTest.cpp b/tests/SkSLTest.cpp
index dc1e9fc..acd51a6 100644
--- a/tests/SkSLTest.cpp
+++ b/tests/SkSLTest.cpp
@@ -122,10 +122,11 @@
 }
 
 static void test_es3(skiatest::Reporter* r, GrDirectContext* ctx, const char* testFile) {
-    // We don't have an ES2 caps bit, so we check for integer support and derivatives support.
-    // Our ES2 bots should return false for these.
+    // We don't have an ES2 caps bit, so we check the caps bits for features that ES2 explicitly
+    // doesn't support. Our ES2 bots should return false for these.
     if (!ctx->priv().caps()->shaderCaps()->shaderDerivativeSupport() ||
-        !ctx->priv().caps()->shaderCaps()->integerSupport()) {
+        !ctx->priv().caps()->shaderCaps()->integerSupport() ||
+        !ctx->priv().caps()->shaderCaps()->nonsquareMatrixSupport()) {
         return;
     }
     // ES3-only tests never run on the CPU, because SkVM lacks support for many non-ES2 features.
@@ -236,6 +237,7 @@
 SKSL_TEST(SkSLHelloWorld,                      "shared/HelloWorld.sksl")
 SKSL_TEST(SkSLHex,                             "shared/Hex.sksl")
 SKSL_TEST(SkSLMatrices,                        "shared/Matrices.sksl")
+SKSL_TEST_ES3(SkSLMatricesNonsquare,           "shared/MatricesNonsquare.sksl")
 SKSL_TEST(SkSLMatrixEquality,                  "shared/MatrixEquality.sksl")
 SKSL_TEST(SkSLMultipleAssignments,             "shared/MultipleAssignments.sksl")
 SKSL_TEST(SkSLNegatedVectorLiteral,            "shared/NegatedVectorLiteral.sksl")