Alter array instanced uniform buffer objects to use direct references to HLSL constant buffers.

This avoids using a shader scoped static storage buffer, with copies.

TRAC #23299

Signed-off-by: Nicolas Capens
Signed-off-by: Shannon Woods
Authored-by: Jamie Madill
diff --git a/src/compiler/OutputHLSL.cpp b/src/compiler/OutputHLSL.cpp
index f183ab5..2bf96e5 100644
--- a/src/compiler/OutputHLSL.cpp
+++ b/src/compiler/OutputHLSL.cpp
@@ -291,7 +291,6 @@
 
     TString uniforms;
     TString interfaceBlocks;
-    TString interfaceBlockInit;
     TString varyings;
     TString attributes;
 
@@ -346,16 +345,9 @@
 
         if (arraySize > 0)
         {
-            interfaceBlocks += "static " + interfaceBlockStructName(interfaceBlockType) + " " + decorate(interfaceBlockType.getInstanceName()) +
-                               arrayString(interfaceBlockType) + ";\n\n";
-
             for (unsigned int arrayIndex = 0; arrayIndex < arraySize; arrayIndex++)
             {
                 interfaceBlocks += interfaceBlockString(interfaceBlockType, interfaceBlock.registerIndex + arrayIndex, arrayIndex);
-
-                const TString &instanceName = interfaceBlockType.getInstanceName();
-                interfaceBlockInit += "   " + decorate(instanceName) + "[" + str(arrayIndex) + "] = " +
-                                      interfaceBlockInstanceString(interfaceBlockType, arrayIndex) + ";\n";
             }
         }
         else
@@ -364,14 +356,6 @@
         }
     }
 
-    if (!interfaceBlockInit.empty())
-    {
-        interfaceBlocks += "void dx_initConstantBuffers()\n"
-                           "{\n" +
-                           interfaceBlockInit +
-                           "}\n\n";
-    }
-
     for (ReferencedSymbols::const_iterator varying = mReferencedVaryings.begin(); varying != mReferencedVaryings.end(); varying++)
     {
         const TType &type = varying->second->getType();
@@ -1566,8 +1550,27 @@
         }
         break;
       case EOpDivAssign:               outputTriplet(visit, "(", " /= ", ")");          break;
-      case EOpIndexDirect:             outputTriplet(visit, "", "[", "]");              break;
-      case EOpIndexIndirect:           outputTriplet(visit, "", "[", "]");              break;
+      case EOpIndexDirect:
+        if (node->getLeft()->getBasicType() == EbtInterfaceBlock)
+        {
+            if (visit == PreVisit)
+            {
+                const TType &interfaceBlockType = node->getLeft()->getType();
+                mReferencedInterfaceBlocks[interfaceBlockType.getInstanceName()] = node->getLeft()->getAsSymbolNode();
+                out << interfaceBlockInstanceString(interfaceBlockType, node->getRight()->getAsConstantUnion()->getIConst(0));
+                return false;
+            }
+        }
+        else
+        {
+            outputTriplet(visit, "", "[", "]");
+        }
+        break;
+      case EOpIndexIndirect:
+        // We do not currently support indirect references to interface blocks
+        ASSERT(node->getLeft()->getBasicType() != EbtInterfaceBlock);
+        outputTriplet(visit, "", "[", "]");
+        break;
       case EOpIndexDirectStruct:
       case EOpIndexDirectInterfaceBlock:
         if (visit == InVisit)