Pass GL caps and version to compiler.

This allows us to get rid of some of the reliance on storing the
current context client version in the Renderer. A subsequent
patch will allow us to remove the client version ugly hack.

BUG=angle:789

Change-Id: I139e0f66e1d39e5cd41a484c841a7101b1f29540
Reviewed-on: https://chromium-review.googlesource.com/227712
Reviewed-by: Brandon Jones <bajones@chromium.org>
Reviewed-by: Geoff Lang <geofflang@chromium.org>
Tested-by: Jamie Madill <jmadill@chromium.org>
diff --git a/src/libGLESv2/Context.cpp b/src/libGLESv2/Context.cpp
index bb59e7b..88babf4 100644
--- a/src/libGLESv2/Context.cpp
+++ b/src/libGLESv2/Context.cpp
@@ -658,7 +658,7 @@
 {
     Program *programObject = mResourceManager->getProgram(program);
 
-    Error error = programObject->link(getCaps());
+    Error error = programObject->link(getData());
     if (error.isError())
     {
         return error;
diff --git a/src/libGLESv2/Program.cpp b/src/libGLESv2/Program.cpp
index 990bcec..3faa8c5 100644
--- a/src/libGLESv2/Program.cpp
+++ b/src/libGLESv2/Program.cpp
@@ -244,7 +244,7 @@
 // Links the HLSL code of the vertex and pixel shader by matching up their varyings,
 // compiling them into binaries, determining the attribute mappings, and collecting
 // a list of uniforms
-Error Program::link(const Caps &caps)
+Error Program::link(const Data &data)
 {
     unlink(false);
 
@@ -252,8 +252,8 @@
     resetUniformBlockBindings();
 
     mProgramBinary.set(new ProgramBinary(mRenderer->createProgram()));
-    LinkResult result = mProgramBinary->link(mInfoLog, mAttributeBindings, mFragmentShader, mVertexShader,
-                                             mTransformFeedbackVaryings, mTransformFeedbackBufferMode, caps);
+    LinkResult result = mProgramBinary->link(data, mInfoLog, mAttributeBindings, mFragmentShader, mVertexShader,
+                                             mTransformFeedbackVaryings, mTransformFeedbackBufferMode);
     if (result.error.isError())
     {
         return result.error;
diff --git a/src/libGLESv2/Program.h b/src/libGLESv2/Program.h
index 9b437d3..b92349e 100644
--- a/src/libGLESv2/Program.h
+++ b/src/libGLESv2/Program.h
@@ -29,6 +29,7 @@
 namespace gl
 {
 struct Caps;
+struct Data;
 class ResourceManager;
 class Shader;
 
@@ -77,7 +78,7 @@
 
     void bindAttributeLocation(GLuint index, const char *name);
 
-    Error link(const Caps &caps);
+    Error link(const Data &data);
     bool isLinked();
     Error setProgramBinary(GLenum binaryFormat, const void *binary, GLsizei length);
     ProgramBinary *getProgramBinary() const;
diff --git a/src/libGLESv2/ProgramBinary.cpp b/src/libGLESv2/ProgramBinary.cpp
index 40f1e8c..c5cb8a4 100644
--- a/src/libGLESv2/ProgramBinary.cpp
+++ b/src/libGLESv2/ProgramBinary.cpp
@@ -495,8 +495,10 @@
     return length;
 }
 
-LinkResult ProgramBinary::link(InfoLog &infoLog, const AttributeBindings &attributeBindings, Shader *fragmentShader, Shader *vertexShader,
-                               const std::vector<std::string>& transformFeedbackVaryings, GLenum transformFeedbackBufferMode, const Caps &caps)
+LinkResult ProgramBinary::link(const Data &data, InfoLog &infoLog, const AttributeBindings &attributeBindings,
+                               Shader *fragmentShader, Shader *vertexShader,
+                               const std::vector<std::string> &transformFeedbackVaryings,
+                               GLenum transformFeedbackBufferMode)
 {
     if (!fragmentShader || !fragmentShader->isCompiled())
     {
@@ -514,8 +516,8 @@
 
     int registers;
     std::vector<LinkedVarying> linkedVaryings;
-    LinkResult result = mProgram->link(infoLog, fragmentShader, vertexShader, transformFeedbackVaryings, transformFeedbackBufferMode,
-                                       &registers, &linkedVaryings, &mOutputVariables, caps);
+    LinkResult result = mProgram->link(data, infoLog, fragmentShader, vertexShader, transformFeedbackVaryings, transformFeedbackBufferMode,
+                                       &registers, &linkedVaryings, &mOutputVariables);
     if (result.error.isError() || !result.linkSuccess)
     {
         return result;
@@ -526,18 +528,18 @@
         return LinkResult(false, Error(GL_NO_ERROR));
     }
 
-    if (!mProgram->linkUniforms(infoLog, *vertexShader, *fragmentShader, caps))
+    if (!mProgram->linkUniforms(infoLog, *vertexShader, *fragmentShader, *data.caps))
     {
         return LinkResult(false, Error(GL_NO_ERROR));
     }
 
-    if (!linkUniformBlocks(infoLog, *vertexShader, *fragmentShader, caps))
+    if (!linkUniformBlocks(infoLog, *vertexShader, *fragmentShader, *data.caps))
     {
         return LinkResult(false, Error(GL_NO_ERROR));
     }
 
     if (!gatherTransformFeedbackLinkedVaryings(infoLog, linkedVaryings, transformFeedbackVaryings,
-                                               transformFeedbackBufferMode, &mProgram->getTransformFeedbackLinkedVaryings(), caps))
+                                               transformFeedbackBufferMode, &mProgram->getTransformFeedbackLinkedVaryings(), *data.caps))
     {
         return LinkResult(false, Error(GL_NO_ERROR));
     }
diff --git a/src/libGLESv2/ProgramBinary.h b/src/libGLESv2/ProgramBinary.h
index 50cb198..3142d66 100644
--- a/src/libGLESv2/ProgramBinary.h
+++ b/src/libGLESv2/ProgramBinary.h
@@ -52,6 +52,7 @@
 class AttributeBindings;
 class Buffer;
 class Framebuffer;
+struct Data;
 
 // Struct used for correlating uniforms/elements of uniform arrays to handles
 struct VariableLocation
@@ -147,9 +148,10 @@
     Error save(GLenum *binaryFormat, void *binary, GLsizei bufSize, GLsizei *length);
     GLint getLength();
 
-    LinkResult link(InfoLog &infoLog, const AttributeBindings &attributeBindings, Shader *fragmentShader, Shader *vertexShader,
-                    const std::vector<std::string>& transformFeedbackVaryings, GLenum transformFeedbackBufferMode,
-                    const Caps &caps);
+    LinkResult link(const Data &data, InfoLog &infoLog, const AttributeBindings &attributeBindings,
+                    Shader *fragmentShader, Shader *vertexShader,
+                    const std::vector<std::string> &transformFeedbackVaryings,
+                    GLenum transformFeedbackBufferMode);
 
     void getActiveAttribute(GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name) const;
     GLint getActiveAttributeCount() const;
diff --git a/src/libGLESv2/renderer/ProgramImpl.h b/src/libGLESv2/renderer/ProgramImpl.h
index 9796092..6aaa23c 100644
--- a/src/libGLESv2/renderer/ProgramImpl.h
+++ b/src/libGLESv2/renderer/ProgramImpl.h
@@ -55,10 +55,12 @@
     virtual gl::LinkResult load(gl::InfoLog &infoLog, gl::BinaryInputStream *stream) = 0;
     virtual gl::Error save(gl::BinaryOutputStream *stream) = 0;
 
-    virtual gl::LinkResult link(gl::InfoLog &infoLog, gl::Shader *fragmentShader, gl::Shader *vertexShader,
-                                const std::vector<std::string> &transformFeedbackVaryings, GLenum transformFeedbackBufferMode,
+    virtual gl::LinkResult link(const gl::Data &data, gl::InfoLog &infoLog,
+                                gl::Shader *fragmentShader, gl::Shader *vertexShader,
+                                const std::vector<std::string> &transformFeedbackVaryings,
+                                GLenum transformFeedbackBufferMode,
                                 int *registers, std::vector<gl::LinkedVarying> *linkedVaryings,
-                                std::map<int, gl::VariableLocation> *outputVariables, const gl::Caps &caps) = 0;
+                                std::map<int, gl::VariableLocation> *outputVariables) = 0;
 
     virtual void setUniform1fv(GLint location, GLsizei count, const GLfloat *v) = 0;
     virtual void setUniform2fv(GLint location, GLsizei count, const GLfloat *v) = 0;
diff --git a/src/libGLESv2/renderer/d3d/DynamicHLSL.cpp b/src/libGLESv2/renderer/d3d/DynamicHLSL.cpp
index 8f05fa1..99a04f8 100644
--- a/src/libGLESv2/renderer/d3d/DynamicHLSL.cpp
+++ b/src/libGLESv2/renderer/d3d/DynamicHLSL.cpp
@@ -9,9 +9,9 @@
 #include "libGLESv2/renderer/d3d/DynamicHLSL.h"
 #include "libGLESv2/renderer/d3d/ShaderD3D.h"
 #include "libGLESv2/renderer/d3d/RendererD3D.h"
-#include "libGLESv2/Shader.h"
 #include "libGLESv2/Program.h"
 #include "libGLESv2/ProgramBinary.h"
+#include "libGLESv2/Shader.h"
 #include "libGLESv2/formatutils.h"
 
 #include "common/utilities.h"
@@ -226,7 +226,7 @@
 // Packs varyings into generic varying registers, using the algorithm from [OpenGL ES Shading Language 1.00 rev. 17] appendix A section 7 page 111
 // Returns the number of used varying registers, or -1 if unsuccesful
 int DynamicHLSL::packVaryings(InfoLog &infoLog, VaryingPacking packing, rx::ShaderD3D *fragmentShader,
-                              rx::ShaderD3D *vertexShader, const std::vector<std::string>& transformFeedbackVaryings)
+                              rx::ShaderD3D *vertexShader, const std::vector<std::string> &transformFeedbackVaryings)
 {
     // TODO (geofflang):  Use context's caps
     const int maxVaryingVectors = mRenderer->getRendererCaps().maxVaryingVectors;
@@ -669,10 +669,11 @@
     }
 }
 
-bool DynamicHLSL::generateShaderLinkHLSL(InfoLog &infoLog, int registers, const VaryingPacking packing,
-                                         std::string& pixelHLSL, std::string& vertexHLSL,
+bool DynamicHLSL::generateShaderLinkHLSL(const gl::Data &data, InfoLog &infoLog, int registers,
+                                         const VaryingPacking packing,
+                                         std::string &pixelHLSL, std::string &vertexHLSL,
                                          rx::ShaderD3D *fragmentShader, rx::ShaderD3D *vertexShader,
-                                         const std::vector<std::string>& transformFeedbackVaryings,
+                                         const std::vector<std::string> &transformFeedbackVaryings,
                                          std::vector<LinkedVarying> *linkedVaryings,
                                          std::map<int, VariableLocation> *programOutputVars,
                                          std::vector<PixelShaderOutputVariable> *outPixelShaderKey,
@@ -698,21 +699,17 @@
 
     // Write the HLSL input/output declarations
     const int shaderModel = mRenderer->getMajorShaderModel();
-
-    // TODO (geofflang):  Use context's caps
-    const int maxVaryingVectors = mRenderer->getRendererCaps().maxVaryingVectors;
-
     const int registersNeeded = registers + (usesFragCoord ? 1 : 0) + (usesPointCoord ? 1 : 0);
 
     // Two cases when writing to gl_FragColor and using ESSL 1.0:
     // - with a 3.0 context, the output color is copied to channel 0
     // - with a 2.0 context, the output color is broadcast to all channels
-    const bool broadcast = (fragmentShader->mUsesFragColor && mRenderer->getCurrentClientVersion() < 3);
-    const unsigned int numRenderTargets = (broadcast || usesMRT ? mRenderer->getRendererCaps().maxDrawBuffers : 1);
+    const bool broadcast = (fragmentShader->mUsesFragColor && data.clientVersion < 3);
+    const unsigned int numRenderTargets = (broadcast || usesMRT ? data.caps->maxDrawBuffers : 1);
 
     int shaderVersion = vertexShader->getShaderVersion();
 
-    if (registersNeeded > maxVaryingVectors)
+    if (static_cast<GLuint>(registersNeeded) > data.caps->maxVaryingVectors)
     {
         infoLog.append("No varying registers left to support gl_FragCoord/gl_PointCoord");
         return false;
@@ -779,7 +776,7 @@
 
                 for (int row = 0; row < variableRows; row++)
                 {
-                    int r = varying.registerIndex + varying.columnIndex * mRenderer->getRendererCaps().maxVaryingVectors + elementIndex * variableRows + row;
+                    int r = varying.registerIndex + varying.columnIndex * data.caps->maxVaryingVectors + elementIndex * variableRows + row;
                     vertexHLSL += "    output.v" + Str(r);
 
                     vertexHLSL += " = _" + varying.name;
@@ -927,7 +924,7 @@
                 int variableRows = (varying.isStruct() ? 1 : VariableRowCount(transposedType));
                 for (int row = 0; row < variableRows; row++)
                 {
-                    std::string n = Str(varying.registerIndex + varying.columnIndex * mRenderer->getRendererCaps().maxVaryingVectors + elementIndex * variableRows + row);
+                    std::string n = Str(varying.registerIndex + varying.columnIndex * data.caps->maxVaryingVectors + elementIndex * variableRows + row);
                     pixelHLSL += "    _" + varying.name;
 
                     if (varying.isArray())
diff --git a/src/libGLESv2/renderer/d3d/DynamicHLSL.h b/src/libGLESv2/renderer/d3d/DynamicHLSL.h
index 3847233..f5769a8 100644
--- a/src/libGLESv2/renderer/d3d/DynamicHLSL.h
+++ b/src/libGLESv2/renderer/d3d/DynamicHLSL.h
@@ -31,6 +31,7 @@
 struct VertexAttribute;
 struct VertexFormat;
 struct PackedVarying;
+struct Data;
 }
 
 namespace rx
@@ -59,10 +60,11 @@
                                                    const sh::Attribute shaderAttributes[]) const;
     std::string generatePixelShaderForOutputSignature(const std::string &sourceShader, const std::vector<PixelShaderOutputVariable> &outputVariables,
                                                       bool usesFragDepth, const std::vector<GLenum> &outputLayout) const;
-    bool generateShaderLinkHLSL(gl::InfoLog &infoLog, int registers, const VaryingPacking packing,
-                                std::string& pixelHLSL, std::string& vertexHLSL,
+    bool generateShaderLinkHLSL(const gl::Data &data, gl::InfoLog &infoLog, int registers,
+                                const VaryingPacking packing,
+                                std::string &pixelHLSL, std::string &vertexHLSL,
                                 rx::ShaderD3D *fragmentShader, rx::ShaderD3D *vertexShader,
-                                const std::vector<std::string>& transformFeedbackVaryings,
+                                const std::vector<std::string> &transformFeedbackVaryings,
                                 std::vector<gl::LinkedVarying> *linkedVaryings,
                                 std::map<int, gl::VariableLocation> *programOutputVars,
                                 std::vector<PixelShaderOutputVariable> *outPixelShaderKey,
diff --git a/src/libGLESv2/renderer/d3d/ProgramD3D.cpp b/src/libGLESv2/renderer/d3d/ProgramD3D.cpp
index e36135d..35f869c 100644
--- a/src/libGLESv2/renderer/d3d/ProgramD3D.cpp
+++ b/src/libGLESv2/renderer/d3d/ProgramD3D.cpp
@@ -980,16 +980,18 @@
     return gl::LinkResult(linkSuccess, gl::Error(GL_NO_ERROR));
 }
 
-gl::LinkResult ProgramD3D::link(gl::InfoLog &infoLog, gl::Shader *fragmentShader, gl::Shader *vertexShader,
-                                const std::vector<std::string> &transformFeedbackVaryings, GLenum transformFeedbackBufferMode,
+gl::LinkResult ProgramD3D::link(const gl::Data &data, gl::InfoLog &infoLog,
+                                gl::Shader *fragmentShader, gl::Shader *vertexShader,
+                                const std::vector<std::string> &transformFeedbackVaryings,
+                                GLenum transformFeedbackBufferMode,
                                 int *registers, std::vector<gl::LinkedVarying> *linkedVaryings,
-                                std::map<int, gl::VariableLocation> *outputVariables, const gl::Caps &caps)
+                                std::map<int, gl::VariableLocation> *outputVariables)
 {
     ShaderD3D *vertexShaderD3D = ShaderD3D::makeShaderD3D(vertexShader->getImplementation());
     ShaderD3D *fragmentShaderD3D = ShaderD3D::makeShaderD3D(fragmentShader->getImplementation());
 
-    mSamplersPS.resize(caps.maxTextureImageUnits);
-    mSamplersVS.resize(caps.maxVertexTextureImageUnits);
+    mSamplersPS.resize(data.caps->maxTextureImageUnits);
+    mSamplersVS.resize(data.caps->maxVertexTextureImageUnits);
 
     mTransformFeedbackBufferMode = transformFeedbackBufferMode;
 
@@ -1014,7 +1016,7 @@
         return gl::LinkResult(false, gl::Error(GL_NO_ERROR));
     }
 
-    if (!mDynamicHLSL->generateShaderLinkHLSL(infoLog, *registers, packing, mPixelHLSL, mVertexHLSL,
+    if (!mDynamicHLSL->generateShaderLinkHLSL(data, infoLog, *registers, packing, mPixelHLSL, mVertexHLSL,
                                               fragmentShaderD3D, vertexShaderD3D, transformFeedbackVaryings,
                                               linkedVaryings, outputVariables, &mPixelShaderKey, &mUsesFragDepth))
     {
diff --git a/src/libGLESv2/renderer/d3d/ProgramD3D.h b/src/libGLESv2/renderer/d3d/ProgramD3D.h
index 7d7744a..85b72e1 100644
--- a/src/libGLESv2/renderer/d3d/ProgramD3D.h
+++ b/src/libGLESv2/renderer/d3d/ProgramD3D.h
@@ -62,10 +62,12 @@
     gl::LinkResult compileProgramExecutables(gl::InfoLog &infoLog, gl::Shader *fragmentShader, gl::Shader *vertexShader,
                                              int registers);
 
-    gl::LinkResult link(gl::InfoLog &infoLog, gl::Shader *fragmentShader, gl::Shader *vertexShader,
-                        const std::vector<std::string> &transformFeedbackVaryings, GLenum transformFeedbackBufferMode,
+    gl::LinkResult link(const gl::Data &data, gl::InfoLog &infoLog,
+                        gl::Shader *fragmentShader, gl::Shader *vertexShader,
+                        const std::vector<std::string> &transformFeedbackVaryings,
+                        GLenum transformFeedbackBufferMode,
                         int *registers, std::vector<gl::LinkedVarying> *linkedVaryings,
-                        std::map<int, gl::VariableLocation> *outputVariables, const gl::Caps &caps);
+                        std::map<int, gl::VariableLocation> *outputVariables);
 
     void getInputLayoutSignature(const gl::VertexFormat inputLayout[], GLenum signature[]) const;