Declare sk_InvocationID programmatically

This lets us declare it correctly depending on caps, rather than editing
the modifiers of a (shared) global variable.

Change-Id: Ifcdc5e0a8e9b852685ee03a46b537b986b5d35de
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/325623
Reviewed-by: John Stiles <johnstiles@google.com>
Commit-Queue: Brian Osman <brianosman@google.com>
diff --git a/src/sksl/SkSLIRGenerator.cpp b/src/sksl/SkSLIRGenerator.cpp
index b636b27..c94fd7b 100644
--- a/src/sksl/SkSLIRGenerator.cpp
+++ b/src/sksl/SkSLIRGenerator.cpp
@@ -455,11 +455,6 @@
         fInvocations = modifiers.fLayout.fInvocations;
         if (fSettings->fCaps && !fSettings->fCaps->gsInvocationsSupport()) {
             modifiers.fLayout.fInvocations = -1;
-            Variable& invocationId = (*fSymbolTable)["sk_InvocationID"]->as<Variable>();
-            Modifiers modifiers = invocationId.modifiers();
-            modifiers.fFlags = 0;
-            modifiers.fLayout.fBuiltin = -1;
-            invocationId.setModifiersHandle(fModifiers->handle(modifiers));
             if (modifiers.fLayout.description() == "") {
                 return nullptr;
             }
@@ -2942,6 +2937,27 @@
 
     this->pushSymbolTable();
 
+    if (kind == Program::kGeometry_Kind && !fIsBuiltinCode) {
+        // Declare sk_InvocationID programmatically. With invocations support, it's an 'in' builtin.
+        // If we're applying the workaround, then it's a plain global.
+        bool workaround = fSettings->fCaps && !fSettings->fCaps->gsInvocationsSupport();
+        Modifiers m;
+        if (!workaround) {
+            m.fFlags = Modifiers::kIn_Flag;
+            m.fLayout.fBuiltin = SK_INVOCATIONID_BUILTIN;
+        }
+        auto var = std::make_unique<Variable>(-1, fModifiers->handle(m), "sk_InvocationID",
+                                              fContext.fInt_Type.get(), false,
+                                              Variable::Storage::kGlobal);
+        auto decl = std::make_unique<VarDeclaration>(
+                var.get(), fContext.fInt_Type.get(),
+                /*sizes=*/std::vector<std::unique_ptr<Expression>>{},
+                /*value=*/nullptr);
+        fSymbolTable->add(std::move(var));
+        fProgramElements->push_back(
+                std::make_unique<GlobalVarDeclaration>(/*offset=*/-1, std::move(decl)));
+    }
+
     if (externalValues) {
         // Add any external values to the new symbol table, so they're only visible to this Program
         for (const auto& ev : *externalValues) {
diff --git a/src/sksl/generated/sksl_geom.dehydrated.sksl b/src/sksl/generated/sksl_geom.dehydrated.sksl
index 885a598..1db94d5 100644
--- a/src/sksl/generated/sksl_geom.dehydrated.sksl
+++ b/src/sksl/generated/sksl_geom.dehydrated.sksl
@@ -1,20 +1,19 @@
-static uint8_t SKSL_INCLUDE_sksl_geom[] = {150,0,
+static uint8_t SKSL_INCLUDE_sksl_geom[] = {134,0,
 12,115,107,95,80,101,114,86,101,114,116,101,120,
 11,115,107,95,80,111,115,105,116,105,111,110,
 6,102,108,111,97,116,52,
 12,115,107,95,80,111,105,110,116,83,105,122,101,
 5,102,108,111,97,116,
 5,115,107,95,105,110,
-15,115,107,95,73,110,118,111,99,97,116,105,111,110,73,68,
-3,105,110,116,
 6,115,116,114,101,97,109,
+3,105,110,116,
 16,69,109,105,116,83,116,114,101,97,109,86,101,114,116,101,120,
 4,118,111,105,100,
 18,69,110,100,83,116,114,101,97,109,80,114,105,109,105,116,105,118,101,
 10,69,109,105,116,86,101,114,116,101,120,
 12,69,110,100,80,114,105,109,105,116,105,118,101,
 0,
-42,13,0,
+42,12,0,
 37,1,0,2,0,2,
 29,
 5,0,0,0,15,0,
@@ -41,47 +40,38 @@
 16,7,0,0,
 16,7,0,1,
 46,8,0,
-29,
-5,8,0,2,59,0,
-43,9,0,75,0,0,
-46,10,0,
-9,79,0,
-40,9,0,3,
-22,11,0,
+9,59,0,
+43,9,0,66,0,3,
+22,10,0,
 30,
-8,0,16,0,0,86,0,1,10,0,
-43,12,0,103,0,
-46,13,0,
-9,79,0,
+8,0,16,0,0,70,0,1,8,0,
+43,11,0,87,0,
+46,12,0,
+9,59,0,
 40,9,0,3,
+22,13,0,
+30,
+8,0,16,0,0,92,0,1,12,0,
+40,11,0,
 22,14,0,
 30,
-8,0,16,0,0,108,0,1,13,0,
-40,12,0,
+8,0,16,0,0,111,0,0,
+40,11,0,
 22,15,0,
 30,
-8,0,16,0,0,127,0,0,
-40,12,0,
-22,16,0,
-30,
-8,0,16,0,0,138,0,0,
-40,12,0,8,0,
-8,0,
-11,0,
-12,0,
+8,0,16,0,0,122,0,0,
+40,11,0,7,0,
+7,0,
 10,0,
-6,0,
+11,0,
+9,0,
 5,0,
 4,0,
 1,0,
-12,3,
+12,2,
 26,
 40,4,0,2,0,53,0,1,
 50,
 26,
-40,7,0,2,0,151,0,0,
-48,
-47,8,0,
-40,9,0,0,
-50,};
+40,7,0,2,0,135,0,0,};
 static constexpr size_t SKSL_INCLUDE_sksl_geom_LENGTH = sizeof(SKSL_INCLUDE_sksl_geom);
diff --git a/src/sksl/sksl_geom.sksl b/src/sksl/sksl_geom.sksl
index 544a89f..a3144ff 100644
--- a/src/sksl/sksl_geom.sksl
+++ b/src/sksl/sksl_geom.sksl
@@ -10,7 +10,8 @@
     layout(builtin=1) float sk_PointSize;
 };
 
-layout(builtin=8) in int sk_InvocationID;
+// sk_InvocationID exists, but is declared programmatically (to support a workaround)
+// layout(builtin=8) in int sk_InvocationID;
 
 sk_has_side_effects void EmitStreamVertex(int stream);
 sk_has_side_effects void EndStreamPrimitive(int stream);