Pass InterfaceBlockLinker to ProgramImpl::link.

This change is in preparation for moving the linking logic to the
Implementation.

Introduces a ProgramLinkedResources class that is passed into the Impl
and holds linking-related info such as the UBOs, Varyings, etc.

BUG=angleproject:2208

Change-Id: I2ef0824b54bfb462c79d003bffe34e9cfad60d8a
Reviewed-on: https://chromium-review.googlesource.com/746204
Reviewed-by: Jamie Madill <jmadill@chromium.org>
Commit-Queue: Jamie Madill <jmadill@chromium.org>
diff --git a/src/libANGLE/Program.cpp b/src/libANGLE/Program.cpp
index de9724c..e150711 100644
--- a/src/libANGLE/Program.cpp
+++ b/src/libANGLE/Program.cpp
@@ -258,6 +258,53 @@
     return true;
 }
 
+void InitUniformBlockLinker(const gl::Context *context,
+                            const ProgramState &state,
+                            UniformBlockLinker *blockLinker)
+{
+    if (state.getAttachedVertexShader())
+    {
+        blockLinker->addShaderBlocks(GL_VERTEX_SHADER,
+                                     &state.getAttachedVertexShader()->getUniformBlocks(context));
+    }
+
+    if (state.getAttachedFragmentShader())
+    {
+        blockLinker->addShaderBlocks(GL_FRAGMENT_SHADER,
+                                     &state.getAttachedFragmentShader()->getUniformBlocks(context));
+    }
+
+    if (state.getAttachedComputeShader())
+    {
+        blockLinker->addShaderBlocks(GL_COMPUTE_SHADER,
+                                     &state.getAttachedComputeShader()->getUniformBlocks(context));
+    }
+}
+
+void InitShaderStorageBlockLinker(const gl::Context *context,
+                                  const ProgramState &state,
+                                  ShaderStorageBlockLinker *blockLinker)
+{
+    if (state.getAttachedVertexShader())
+    {
+        blockLinker->addShaderBlocks(
+            GL_VERTEX_SHADER, &state.getAttachedVertexShader()->getShaderStorageBlocks(context));
+    }
+
+    if (state.getAttachedFragmentShader())
+    {
+        blockLinker->addShaderBlocks(
+            GL_FRAGMENT_SHADER,
+            &state.getAttachedFragmentShader()->getShaderStorageBlocks(context));
+    }
+
+    if (state.getAttachedComputeShader())
+    {
+        blockLinker->addShaderBlocks(
+            GL_COMPUTE_SHADER, &state.getAttachedComputeShader()->getShaderStorageBlocks(context));
+    }
+}
+
 }  // anonymous namespace
 
 const char *const g_fakepath = "C:\\fakepath";
@@ -736,8 +783,14 @@
             return NoError();
         }
 
-        gl::VaryingPacking noPacking(0, PackMode::ANGLE_RELAXED);
-        ANGLE_TRY_RESULT(mProgram->link(context, noPacking, mInfoLog), mLinked);
+        ProgramLinkedResources resources = {{0, PackMode::ANGLE_RELAXED},
+                                            {&mState.mUniformBlocks, &mState.mUniforms},
+                                            {&mState.mShaderStorageBlocks}};
+
+        InitUniformBlockLinker(context, mState, &resources.uniformBlockLinker);
+        InitShaderStorageBlockLinker(context, mState, &resources.shaderStorageBlockLinker);
+
+        ANGLE_TRY_RESULT(mProgram->link(context, resources, mInfoLog), mLinked);
         if (!mLinked)
         {
             return NoError();
@@ -801,9 +854,16 @@
         // In WebGL, we use a slightly different handling for packing variables.
         auto packMode = data.getExtensions().webglCompatibility ? PackMode::WEBGL_STRICT
                                                                 : PackMode::ANGLE_RELAXED;
-        VaryingPacking varyingPacking(data.getCaps().maxVaryingVectors, packMode);
-        if (!varyingPacking.packUserVaryings(mInfoLog, packedVaryings,
-                                             mState.getTransformFeedbackVaryingNames()))
+
+        ProgramLinkedResources resources = {{data.getCaps().maxVaryingVectors, packMode},
+                                            {&mState.mUniformBlocks, &mState.mUniforms},
+                                            {&mState.mShaderStorageBlocks}};
+
+        InitUniformBlockLinker(context, mState, &resources.uniformBlockLinker);
+        InitShaderStorageBlockLinker(context, mState, &resources.shaderStorageBlockLinker);
+
+        if (!resources.varyingPacking.packUserVaryings(mInfoLog, packedVaryings,
+                                                       mState.getTransformFeedbackVaryingNames()))
         {
             return NoError();
         }
@@ -813,7 +873,7 @@
             return NoError();
         }
 
-        ANGLE_TRY_RESULT(mProgram->link(context, varyingPacking, mInfoLog), mLinked);
+        ANGLE_TRY_RESULT(mProgram->link(context, resources, mInfoLog), mLinked);
         if (!mLinked)
         {
             return NoError();
@@ -2829,24 +2889,7 @@
 void Program::gatherUniformBlockInfo(const gl::Context *context)
 {
     UniformBlockLinker blockLinker(&mState.mUniformBlocks, &mState.mUniforms);
-
-    if (mState.mAttachedVertexShader)
-    {
-        blockLinker.addShaderBlocks(GL_VERTEX_SHADER,
-                                    &mState.mAttachedVertexShader->getUniformBlocks(context));
-    }
-
-    if (mState.mAttachedFragmentShader)
-    {
-        blockLinker.addShaderBlocks(GL_FRAGMENT_SHADER,
-                                    &mState.mAttachedFragmentShader->getUniformBlocks(context));
-    }
-
-    if (mState.mAttachedComputeShader)
-    {
-        blockLinker.addShaderBlocks(GL_COMPUTE_SHADER,
-                                    &mState.mAttachedComputeShader->getUniformBlocks(context));
-    }
+    InitUniformBlockLinker(context, mState, &blockLinker);
 
     auto getImplBlockSize = [this](const std::string &name, const std::string &mappedName,
                                    size_t *sizeOut) {
@@ -2864,24 +2907,7 @@
 void Program::gatherShaderStorageBlockInfo(const gl::Context *context)
 {
     ShaderStorageBlockLinker blockLinker(&mState.mShaderStorageBlocks);
-
-    if (mState.mAttachedVertexShader)
-    {
-        blockLinker.addShaderBlocks(GL_VERTEX_SHADER,
-                                    &mState.mAttachedVertexShader->getShaderStorageBlocks(context));
-    }
-
-    if (mState.mAttachedFragmentShader)
-    {
-        blockLinker.addShaderBlocks(
-            GL_FRAGMENT_SHADER, &mState.mAttachedFragmentShader->getShaderStorageBlocks(context));
-    }
-
-    if (mState.mAttachedComputeShader)
-    {
-        blockLinker.addShaderBlocks(
-            GL_COMPUTE_SHADER, &mState.mAttachedComputeShader->getShaderStorageBlocks(context));
-    }
+    InitShaderStorageBlockLinker(context, mState, &blockLinker);
 
     // We don't have a way of determining block info for shader storage blocks yet.
     // TODO(jiajia.qin@intel.com): Determine correct block size and layout.
diff --git a/src/libANGLE/UniformLinker.h b/src/libANGLE/UniformLinker.h
index 3aac690..ee2e90b 100644
--- a/src/libANGLE/UniformLinker.h
+++ b/src/libANGLE/UniformLinker.h
@@ -13,6 +13,7 @@
 
 #include "libANGLE/Program.h"
 #include "libANGLE/Uniform.h"
+#include "libANGLE/VaryingPacking.h"
 
 #include <functional>
 
@@ -194,6 +195,16 @@
     size_t getCurrentBlockMemberIndex() const override;
 };
 
+// The link operation is responsible for finishing the link of uniform and interface blocks.
+// This way it can filter out unreferenced resources and still have access to the info.
+// TODO(jmadill): Integrate uniform linking/filtering as well as interface blocks.
+struct ProgramLinkedResources
+{
+    VaryingPacking varyingPacking;
+    UniformBlockLinker uniformBlockLinker;
+    ShaderStorageBlockLinker shaderStorageBlockLinker;
+};
+
 }  // namespace gl
 
 #endif  // LIBANGLE_UNIFORMLINKER_H_
diff --git a/src/libANGLE/renderer/ProgramImpl.h b/src/libANGLE/renderer/ProgramImpl.h
index f8b2c26..7c5fce7 100644
--- a/src/libANGLE/renderer/ProgramImpl.h
+++ b/src/libANGLE/renderer/ProgramImpl.h
@@ -20,7 +20,7 @@
 namespace gl
 {
 class Context;
-class VaryingPacking;
+struct ProgramLinkedResources;
 }
 
 namespace sh
@@ -30,7 +30,6 @@
 
 namespace rx
 {
-
 class ProgramImpl : angle::NonCopyable
 {
   public:
@@ -46,8 +45,8 @@
     virtual void setSeparable(bool separable)               = 0;
 
     virtual gl::LinkResult link(const gl::Context *context,
-                                const gl::VaryingPacking &packing,
-                                gl::InfoLog &infoLog) = 0;
+                                const gl::ProgramLinkedResources &resources,
+                                gl::InfoLog &infoLog)                      = 0;
     virtual GLboolean validate(const gl::Caps &caps, gl::InfoLog *infoLog) = 0;
 
     virtual void setUniform1fv(GLint location, GLsizei count, const GLfloat *v) = 0;
diff --git a/src/libANGLE/renderer/ProgramImpl_mock.h b/src/libANGLE/renderer/ProgramImpl_mock.h
index f975102..5f1850c 100644
--- a/src/libANGLE/renderer/ProgramImpl_mock.h
+++ b/src/libANGLE/renderer/ProgramImpl_mock.h
@@ -12,6 +12,7 @@
 
 #include "gmock/gmock.h"
 
+#include "libANGLE/UniformLinker.h"
 #include "libANGLE/renderer/ProgramImpl.h"
 
 namespace rx
@@ -29,7 +30,9 @@
     MOCK_METHOD1(setSeparable, void(bool));
 
     MOCK_METHOD3(link,
-                 gl::LinkResult(const gl::Context *, const gl::VaryingPacking &, gl::InfoLog &));
+                 gl::LinkResult(const gl::Context *,
+                                const gl::ProgramLinkedResources &,
+                                gl::InfoLog &));
     MOCK_METHOD2(validate, GLboolean(const gl::Caps &, gl::InfoLog *));
 
     MOCK_METHOD3(setUniform1fv, void(GLint, GLsizei, const GLfloat *));
diff --git a/src/libANGLE/renderer/d3d/ProgramD3D.cpp b/src/libANGLE/renderer/d3d/ProgramD3D.cpp
index 41f9f9d..1fb7e12 100644
--- a/src/libANGLE/renderer/d3d/ProgramD3D.cpp
+++ b/src/libANGLE/renderer/d3d/ProgramD3D.cpp
@@ -16,7 +16,7 @@
 #include "libANGLE/FramebufferAttachment.h"
 #include "libANGLE/Program.h"
 #include "libANGLE/Uniform.h"
-#include "libANGLE/VaryingPacking.h"
+#include "libANGLE/UniformLinker.h"
 #include "libANGLE/VertexArray.h"
 #include "libANGLE/features.h"
 #include "libANGLE/queryconversions.h"
@@ -1480,7 +1480,7 @@
 }
 
 gl::LinkResult ProgramD3D::link(const gl::Context *context,
-                                const gl::VaryingPacking &packing,
+                                const gl::ProgramLinkedResources &resources,
                                 gl::InfoLog &infoLog)
 {
     const auto &data = context->getContextState();
@@ -1535,17 +1535,17 @@
         // We can fail here because we use one semantic per GLSL varying. D3D11 can pack varyings
         // intelligently, but D3D9 assumes one semantic per register.
         if (mRenderer->getRendererClass() == RENDERER_D3D9 &&
-            packing.getMaxSemanticIndex() > data.getCaps().maxVaryingVectors)
+            resources.varyingPacking.getMaxSemanticIndex() > data.getCaps().maxVaryingVectors)
         {
             infoLog << "Cannot pack these varyings on D3D9.";
             return false;
         }
 
         ProgramD3DMetadata metadata(mRenderer, vertexShaderD3D, fragmentShaderD3D);
-        BuiltinVaryingsD3D builtins(metadata, packing);
+        BuiltinVaryingsD3D builtins(metadata, resources.varyingPacking);
 
-        mDynamicHLSL->generateShaderLinkHLSL(context, mState, metadata, packing, builtins,
-                                             &mPixelHLSL, &mVertexHLSL);
+        mDynamicHLSL->generateShaderLinkHLSL(context, mState, metadata, resources.varyingPacking,
+                                             builtins, &mPixelHLSL, &mVertexHLSL);
 
         mUsesPointSize = vertexShaderD3D->usesPointSize();
         mDynamicHLSL->getPixelShaderOutputKey(data, mState, metadata, &mPixelShaderKey);
@@ -1561,7 +1561,7 @@
         if (mRenderer->getMajorShaderModel() >= 4)
         {
             mGeometryShaderPreamble = mDynamicHLSL->generateGeometryShaderPreamble(
-                packing, builtins, mHasANGLEMultiviewEnabled,
+                resources.varyingPacking, builtins, mHasANGLEMultiviewEnabled,
                 metadata.canSelectViewInVertexShader());
         }
 
@@ -1569,7 +1569,7 @@
 
         defineUniformsAndAssignRegisters(context);
 
-        gatherTransformFeedbackVaryings(packing, builtins[SHADER_VERTEX]);
+        gatherTransformFeedbackVaryings(resources.varyingPacking, builtins[SHADER_VERTEX]);
 
         gl::LinkResult result = compileProgramExecutables(context, infoLog);
         if (result.isError())
diff --git a/src/libANGLE/renderer/d3d/ProgramD3D.h b/src/libANGLE/renderer/d3d/ProgramD3D.h
index d66a431..0d8996d 100644
--- a/src/libANGLE/renderer/d3d/ProgramD3D.h
+++ b/src/libANGLE/renderer/d3d/ProgramD3D.h
@@ -192,7 +192,7 @@
                                                       gl::InfoLog *infoLog);
     gl::Error getComputeExecutable(ShaderExecutableD3D **outExecutable);
     gl::LinkResult link(const gl::Context *context,
-                        const gl::VaryingPacking &packing,
+                        const gl::ProgramLinkedResources &resources,
                         gl::InfoLog &infoLog) override;
     GLboolean validate(const gl::Caps &caps, gl::InfoLog *infoLog) override;
 
diff --git a/src/libANGLE/renderer/gl/ProgramGL.cpp b/src/libANGLE/renderer/gl/ProgramGL.cpp
index 4045eeb..0ebf74b 100644
--- a/src/libANGLE/renderer/gl/ProgramGL.cpp
+++ b/src/libANGLE/renderer/gl/ProgramGL.cpp
@@ -124,7 +124,7 @@
 }
 
 gl::LinkResult ProgramGL::link(const gl::Context *context,
-                               const gl::VaryingPacking &packing,
+                               const gl::ProgramLinkedResources &resources,
                                gl::InfoLog &infoLog)
 {
     preLink();
diff --git a/src/libANGLE/renderer/gl/ProgramGL.h b/src/libANGLE/renderer/gl/ProgramGL.h
index ee5ffe8..fc92511 100644
--- a/src/libANGLE/renderer/gl/ProgramGL.h
+++ b/src/libANGLE/renderer/gl/ProgramGL.h
@@ -39,7 +39,7 @@
     void setSeparable(bool separable) override;
 
     gl::LinkResult link(const gl::Context *contextImpl,
-                        const gl::VaryingPacking &packing,
+                        const gl::ProgramLinkedResources &resources,
                         gl::InfoLog &infoLog) override;
     GLboolean validate(const gl::Caps &caps, gl::InfoLog *infoLog) override;
 
diff --git a/src/libANGLE/renderer/null/ProgramNULL.cpp b/src/libANGLE/renderer/null/ProgramNULL.cpp
index d41cfcc..d312fd7 100644
--- a/src/libANGLE/renderer/null/ProgramNULL.cpp
+++ b/src/libANGLE/renderer/null/ProgramNULL.cpp
@@ -42,7 +42,7 @@
 }
 
 gl::LinkResult ProgramNULL::link(const gl::Context *contextImpl,
-                                 const gl::VaryingPacking &packing,
+                                 const gl::ProgramLinkedResources &resources,
                                  gl::InfoLog &infoLog)
 {
     return true;
diff --git a/src/libANGLE/renderer/null/ProgramNULL.h b/src/libANGLE/renderer/null/ProgramNULL.h
index 5f8c464..61ff61b 100644
--- a/src/libANGLE/renderer/null/ProgramNULL.h
+++ b/src/libANGLE/renderer/null/ProgramNULL.h
@@ -29,7 +29,7 @@
     void setSeparable(bool separable) override;
 
     gl::LinkResult link(const gl::Context *context,
-                        const gl::VaryingPacking &packing,
+                        const gl::ProgramLinkedResources &resources,
                         gl::InfoLog &infoLog) override;
     GLboolean validate(const gl::Caps &caps, gl::InfoLog *infoLog) override;
 
diff --git a/src/libANGLE/renderer/vulkan/ProgramVk.cpp b/src/libANGLE/renderer/vulkan/ProgramVk.cpp
index 7902353..0eebb99 100644
--- a/src/libANGLE/renderer/vulkan/ProgramVk.cpp
+++ b/src/libANGLE/renderer/vulkan/ProgramVk.cpp
@@ -199,7 +199,7 @@
 }
 
 gl::LinkResult ProgramVk::link(const gl::Context *glContext,
-                               const gl::VaryingPacking &packing,
+                               const gl::ProgramLinkedResources &resources,
                                gl::InfoLog &infoLog)
 {
     ContextVk *contextVk           = vk::GetImpl(glContext);
diff --git a/src/libANGLE/renderer/vulkan/ProgramVk.h b/src/libANGLE/renderer/vulkan/ProgramVk.h
index 262162c..e31c9f9 100644
--- a/src/libANGLE/renderer/vulkan/ProgramVk.h
+++ b/src/libANGLE/renderer/vulkan/ProgramVk.h
@@ -34,7 +34,7 @@
     void setSeparable(bool separable) override;
 
     gl::LinkResult link(const gl::Context *context,
-                        const gl::VaryingPacking &packing,
+                        const gl::ProgramLinkedResources &resources,
                         gl::InfoLog &infoLog) override;
     GLboolean validate(const gl::Caps &caps, gl::InfoLog *infoLog) override;