1 //
2 // Copyright 2002 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6 
7 // Program.h: Defines the gl::Program class. Implements GL program objects
8 // and related functionality. [OpenGL ES 2.0.24] section 2.10.3 page 28.
9 
10 #ifndef LIBANGLE_PROGRAM_H_
11 #define LIBANGLE_PROGRAM_H_
12 
13 #include <GLES2/gl2.h>
14 #include <GLSLANG/ShaderVars.h>
15 
16 #include <array>
17 #include <map>
18 #include <set>
19 #include <sstream>
20 #include <string>
21 #include <vector>
22 
23 #include "common/Optional.h"
24 #include "common/angleutils.h"
25 #include "common/mathutil.h"
26 #include "common/utilities.h"
27 
28 #include "libANGLE/Constants.h"
29 #include "libANGLE/Debug.h"
30 #include "libANGLE/Error.h"
31 #include "libANGLE/InfoLog.h"
32 #include "libANGLE/ProgramExecutable.h"
33 #include "libANGLE/ProgramLinkedResources.h"
34 #include "libANGLE/RefCountObject.h"
35 #include "libANGLE/Uniform.h"
36 #include "libANGLE/angletypes.h"
37 
38 namespace rx
39 {
40 class GLImplFactory;
41 class ProgramImpl;
42 struct TranslatedAttribute;
43 }  // namespace rx
44 
45 namespace gl
46 {
47 class Buffer;
48 class BinaryInputStream;
49 class BinaryOutputStream;
50 struct Caps;
51 class Context;
52 struct Extensions;
53 class Framebuffer;
54 class ProgramExecutable;
55 class Shader;
56 class ShaderProgramManager;
57 class State;
58 struct UnusedUniform;
59 struct Version;
60 
61 extern const char *const g_fakepath;
62 
63 enum class LinkMismatchError
64 {
65     // Shared
66     NO_MISMATCH,
67     TYPE_MISMATCH,
68     ARRAY_SIZE_MISMATCH,
69     PRECISION_MISMATCH,
70     STRUCT_NAME_MISMATCH,
71     FIELD_NUMBER_MISMATCH,
72     FIELD_NAME_MISMATCH,
73 
74     // Varying specific
75     INTERPOLATION_TYPE_MISMATCH,
76     INVARIANCE_MISMATCH,
77 
78     // Uniform specific
79     BINDING_MISMATCH,
80     LOCATION_MISMATCH,
81     OFFSET_MISMATCH,
82     INSTANCE_NAME_MISMATCH,
83     FORMAT_MISMATCH,
84 
85     // Interface block specific
86     LAYOUT_QUALIFIER_MISMATCH,
87     MATRIX_PACKING_MISMATCH,
88 };
89 
90 void LogLinkMismatch(InfoLog &infoLog,
91                      const std::string &variableName,
92                      const char *variableType,
93                      LinkMismatchError linkError,
94                      const std::string &mismatchedStructOrBlockFieldName,
95                      ShaderType shaderType1,
96                      ShaderType shaderType2);
97 
98 bool IsActiveInterfaceBlock(const sh::InterfaceBlock &interfaceBlock);
99 
100 void WriteBlockMemberInfo(BinaryOutputStream *stream, const sh::BlockMemberInfo &var);
101 void LoadBlockMemberInfo(BinaryInputStream *stream, sh::BlockMemberInfo *var);
102 
103 void WriteShaderVar(BinaryOutputStream *stream, const sh::ShaderVariable &var);
104 void LoadShaderVar(BinaryInputStream *stream, sh::ShaderVariable *var);
105 
106 // Struct used for correlating uniforms/elements of uniform arrays to handles
107 struct VariableLocation
108 {
109     static constexpr unsigned int kUnused = GL_INVALID_INDEX;
110 
111     VariableLocation();
112     VariableLocation(unsigned int arrayIndex, unsigned int index);
113 
114     // If used is false, it means this location is only used to fill an empty space in an array,
115     // and there is no corresponding uniform variable for this location. It can also mean the
116     // uniform was optimized out by the implementation.
usedVariableLocation117     bool used() const { return (index != kUnused); }
markUnusedVariableLocation118     void markUnused() { index = kUnused; }
markIgnoredVariableLocation119     void markIgnored() { ignored = true; }
120 
121     bool operator==(const VariableLocation &other) const
122     {
123         return arrayIndex == other.arrayIndex && index == other.index;
124     }
125 
126     // "arrayIndex" stores the index of the innermost GLSL array. It's zero for non-arrays.
127     unsigned int arrayIndex;
128     // "index" is an index of the variable. The variable contains the indices for other than the
129     // innermost GLSL arrays.
130     unsigned int index;
131 
132     // If this location was bound to an unreferenced uniform.  Setting data on this uniform is a
133     // no-op.
134     bool ignored;
135 };
136 
137 // Information about a variable binding.
138 // Currently used by CHROMIUM_path_rendering
139 struct BindingInfo
140 {
141     // The type of binding, for example GL_FLOAT_VEC3.
142     // This can be GL_NONE if the variable is optimized away.
143     GLenum type;
144 
145     // This is the name of the variable in
146     // the translated shader program. Note that
147     // this can be empty in the case where the
148     // variable has been optimized away.
149     std::string name;
150 
151     // True if the binding is valid, otherwise false.
152     bool valid;
153 };
154 
155 struct ProgramBinding
156 {
ProgramBindingProgramBinding157     ProgramBinding() : location(GL_INVALID_INDEX), aliased(false) {}
ProgramBindingProgramBinding158     ProgramBinding(GLuint index) : location(index), aliased(false) {}
159 
160     GLuint location;
161     // Whether another binding was set that may potentially alias this.
162     bool aliased;
163 };
164 
165 class ProgramBindings final : angle::NonCopyable
166 {
167   public:
168     ProgramBindings();
169     ~ProgramBindings();
170 
171     void bindLocation(GLuint index, const std::string &name);
172     int getBindingByName(const std::string &name) const;
173     int getBinding(const sh::ShaderVariable &variable) const;
174 
175     using const_iterator = angle::HashMap<std::string, GLuint>::const_iterator;
176     const_iterator begin() const;
177     const_iterator end() const;
178 
179   private:
180     angle::HashMap<std::string, GLuint> mBindings;
181 };
182 
183 // Uniforms and Fragment Outputs require special treatment due to array notation (e.g., "[0]")
184 class ProgramAliasedBindings final : angle::NonCopyable
185 {
186   public:
187     ProgramAliasedBindings();
188     ~ProgramAliasedBindings();
189 
190     void bindLocation(GLuint index, const std::string &name);
191     int getBindingByName(const std::string &name) const;
192     int getBindingByLocation(GLuint location) const;
193     int getBinding(const sh::ShaderVariable &variable) const;
194 
195     using const_iterator = std::unordered_map<std::string, ProgramBinding>::const_iterator;
196     const_iterator begin() const;
197     const_iterator end() const;
198 
199   private:
200     std::unordered_map<std::string, ProgramBinding> mBindings;
201 };
202 
203 class ProgramState final : angle::NonCopyable
204 {
205   public:
206     ProgramState();
207     ~ProgramState();
208 
209     const std::string &getLabel();
210 
211     Shader *getAttachedShader(ShaderType shaderType) const;
getAttachedShaders()212     const gl::ShaderMap<Shader *> &getAttachedShaders() const { return mAttachedShaders; }
getTransformFeedbackVaryingNames()213     const std::vector<std::string> &getTransformFeedbackVaryingNames() const
214     {
215         return mTransformFeedbackVaryingNames;
216     }
getTransformFeedbackBufferMode()217     GLint getTransformFeedbackBufferMode() const
218     {
219         return mExecutable->getTransformFeedbackBufferMode();
220     }
getUniformBlockBinding(GLuint uniformBlockIndex)221     GLuint getUniformBlockBinding(GLuint uniformBlockIndex) const
222     {
223         return mExecutable->getUniformBlockBinding(uniformBlockIndex);
224     }
getShaderStorageBlockBinding(GLuint blockIndex)225     GLuint getShaderStorageBlockBinding(GLuint blockIndex) const
226     {
227         return mExecutable->getShaderStorageBlockBinding(blockIndex);
228     }
getActiveUniformBlockBindingsMask()229     const UniformBlockBindingMask &getActiveUniformBlockBindingsMask() const
230     {
231         return mActiveUniformBlockBindings;
232     }
getProgramInputs()233     const std::vector<sh::ShaderVariable> &getProgramInputs() const
234     {
235         return mExecutable->getProgramInputs();
236     }
getActiveOutputVariables()237     DrawBufferMask getActiveOutputVariables() const { return mActiveOutputVariables; }
getOutputVariables()238     const std::vector<sh::ShaderVariable> &getOutputVariables() const
239     {
240         return mExecutable->getOutputVariables();
241     }
getOutputLocations()242     const std::vector<VariableLocation> &getOutputLocations() const
243     {
244         return mExecutable->getOutputLocations();
245     }
getSecondaryOutputLocations()246     const std::vector<VariableLocation> &getSecondaryOutputLocations() const
247     {
248         return mSecondaryOutputLocations;
249     }
getUniforms()250     const std::vector<LinkedUniform> &getUniforms() const { return mExecutable->getUniforms(); }
getUniformLocations()251     const std::vector<VariableLocation> &getUniformLocations() const { return mUniformLocations; }
getUniformBlocks()252     const std::vector<InterfaceBlock> &getUniformBlocks() const
253     {
254         return mExecutable->getUniformBlocks();
255     }
getShaderStorageBlocks()256     const std::vector<InterfaceBlock> &getShaderStorageBlocks() const
257     {
258         return mExecutable->getShaderStorageBlocks();
259     }
getBufferVariables()260     const std::vector<BufferVariable> &getBufferVariables() const { return mBufferVariables; }
getSamplerBindings()261     const std::vector<SamplerBinding> &getSamplerBindings() const
262     {
263         return mExecutable->getSamplerBindings();
264     }
getImageBindings()265     const std::vector<ImageBinding> &getImageBindings() const
266     {
267         return getExecutable().getImageBindings();
268     }
getComputeShaderLocalSize()269     const sh::WorkGroupSize &getComputeShaderLocalSize() const { return mComputeShaderLocalSize; }
getDefaultUniformRange()270     const RangeUI &getDefaultUniformRange() const { return mExecutable->getDefaultUniformRange(); }
getSamplerUniformRange()271     const RangeUI &getSamplerUniformRange() const { return mExecutable->getSamplerUniformRange(); }
getImageUniformRange()272     const RangeUI &getImageUniformRange() const { return mExecutable->getImageUniformRange(); }
getAtomicCounterUniformRange()273     const RangeUI &getAtomicCounterUniformRange() const { return mAtomicCounterUniformRange; }
274 
getLinkedTransformFeedbackVaryings()275     const std::vector<TransformFeedbackVarying> &getLinkedTransformFeedbackVaryings() const
276     {
277         return mExecutable->getLinkedTransformFeedbackVaryings();
278     }
getTransformFeedbackStrides()279     const std::vector<GLsizei> &getTransformFeedbackStrides() const
280     {
281         return mExecutable->getTransformFeedbackStrides();
282     }
getAtomicCounterBuffers()283     const std::vector<AtomicCounterBuffer> &getAtomicCounterBuffers() const
284     {
285         return mExecutable->getAtomicCounterBuffers();
286     }
287 
288     GLuint getUniformIndexFromName(const std::string &name) const;
289     GLuint getUniformIndexFromLocation(UniformLocation location) const;
290     Optional<GLuint> getSamplerIndex(UniformLocation location) const;
291     bool isSamplerUniformIndex(GLuint index) const;
292     GLuint getSamplerIndexFromUniformIndex(GLuint uniformIndex) const;
293     GLuint getUniformIndexFromSamplerIndex(GLuint samplerIndex) const;
294     bool isImageUniformIndex(GLuint index) const;
295     GLuint getImageIndexFromUniformIndex(GLuint uniformIndex) const;
296     GLuint getAttributeLocation(const std::string &name) const;
297 
298     GLuint getBufferVariableIndexFromName(const std::string &name) const;
299 
getNumViews()300     int getNumViews() const { return mNumViews; }
usesMultiview()301     bool usesMultiview() const { return mNumViews != -1; }
302 
303     bool hasAttachedShader() const;
304 
305     ShaderType getFirstAttachedShaderStageType() const;
306     ShaderType getLastAttachedShaderStageType() const;
307 
getUniformLocationBindings()308     const ProgramAliasedBindings &getUniformLocationBindings() const
309     {
310         return mUniformLocationBindings;
311     }
312 
getExecutable()313     const ProgramExecutable &getExecutable() const
314     {
315         ASSERT(mExecutable);
316         return *mExecutable;
317     }
getExecutable()318     ProgramExecutable &getExecutable()
319     {
320         ASSERT(mExecutable);
321         return *mExecutable;
322     }
323 
hasImages()324     bool hasImages() const { return !getImageBindings().empty(); }
hasEarlyFragmentTestsOptimization()325     bool hasEarlyFragmentTestsOptimization() const { return mEarlyFramentTestsOptimization; }
326 
isShaderMarkedForDetach(gl::ShaderType shaderType)327     bool isShaderMarkedForDetach(gl::ShaderType shaderType) const
328     {
329         return mAttachedShadersMarkedForDetach[shaderType];
330     }
331 
332     // A Program can only either be graphics or compute, but never both, so it
333     // can answer isCompute() based on which shaders it has.
isCompute()334     bool isCompute() const { return mExecutable->hasLinkedShaderStage(ShaderType::Compute); }
335 
getLabel()336     const std::string &getLabel() const { return mLabel; }
getAttachedShadersMarkedForDetach()337     const ShaderMap<bool> &getAttachedShadersMarkedForDetach() const
338     {
339         return mAttachedShadersMarkedForDetach;
340     }
341 
getLocationsUsedForXfbExtension()342     uint32_t getLocationsUsedForXfbExtension() const { return mLocationsUsedForXfbExtension; }
343 
getOutputVariableTypes()344     const std::vector<GLenum> &getOutputVariableTypes() const { return mOutputVariableTypes; }
345 
getDrawBufferTypeMask()346     ComponentTypeMask getDrawBufferTypeMask() const { return mDrawBufferTypeMask; }
347 
hasBinaryRetrieveableHint()348     bool hasBinaryRetrieveableHint() const { return mBinaryRetrieveableHint; }
349 
isSeparable()350     bool isSeparable() const { return mSeparable; }
351 
getGeometryShaderInputPrimitiveType()352     PrimitiveMode getGeometryShaderInputPrimitiveType() const
353     {
354         return mGeometryShaderInputPrimitiveType;
355     }
356 
getGeometryShaderOutputPrimitiveType()357     PrimitiveMode getGeometryShaderOutputPrimitiveType() const
358     {
359         return mGeometryShaderOutputPrimitiveType;
360     }
361 
getGeometryShaderInvocations()362     int getGeometryShaderInvocations() const { return mGeometryShaderInvocations; }
363 
getGeometryShaderMaxVertices()364     int getGeometryShaderMaxVertices() const { return mGeometryShaderMaxVertices; }
365 
getDrawIDLocation()366     int getDrawIDLocation() const { return mDrawIDLocation; }
367 
getBaseVertexLocation()368     int getBaseVertexLocation() const { return mBaseVertexLocation; }
369 
getBaseInstanceLocation()370     int getBaseInstanceLocation() const { return mBaseInstanceLocation; }
371 
372   private:
373     friend class MemoryProgramCache;
374     friend class Program;
375 
376     void updateTransformFeedbackStrides();
377     void updateActiveSamplers();
378     void updateProgramInterfaceInputs();
379     void updateProgramInterfaceOutputs();
380 
381     // Scans the sampler bindings for type conflicts with sampler 'textureUnitIndex'.
382     void setSamplerUniformTextureTypeAndFormat(size_t textureUnitIndex);
383 
384     std::string mLabel;
385 
386     sh::WorkGroupSize mComputeShaderLocalSize;
387 
388     ShaderMap<Shader *> mAttachedShaders;
389     ShaderMap<bool> mAttachedShadersMarkedForDetach;
390 
391     uint32_t mLocationsUsedForXfbExtension;
392     std::vector<std::string> mTransformFeedbackVaryingNames;
393 
394     // For faster iteration on the blocks currently being bound.
395     UniformBlockBindingMask mActiveUniformBlockBindings;
396 
397     std::vector<VariableLocation> mUniformLocations;
398     std::vector<BufferVariable> mBufferVariables;
399     RangeUI mAtomicCounterUniformRange;
400 
401     // EXT_blend_func_extended secondary outputs (ones with index 1) in ESSL 3.00 shaders.
402     std::vector<VariableLocation> mSecondaryOutputLocations;
403 
404     DrawBufferMask mActiveOutputVariables;
405 
406     // Fragment output variable base types: FLOAT, INT, or UINT.  Ordered by location.
407     std::vector<GLenum> mOutputVariableTypes;
408     ComponentTypeMask mDrawBufferTypeMask;
409 
410     bool mBinaryRetrieveableHint;
411     bool mSeparable;
412     bool mEarlyFramentTestsOptimization;
413 
414     // ANGLE_multiview.
415     int mNumViews;
416 
417     // GL_EXT_geometry_shader.
418     PrimitiveMode mGeometryShaderInputPrimitiveType;
419     PrimitiveMode mGeometryShaderOutputPrimitiveType;
420     int mGeometryShaderInvocations;
421     int mGeometryShaderMaxVertices;
422 
423     // GL_ANGLE_multi_draw
424     int mDrawIDLocation;
425 
426     // GL_ANGLE_base_vertex_base_instance
427     int mBaseVertexLocation;
428     int mBaseInstanceLocation;
429     // Cached value of base vertex and base instance
430     // need to reset them to zero if using non base vertex or base instance draw calls.
431     GLint mCachedBaseVertex;
432     GLuint mCachedBaseInstance;
433 
434     // Note that this has nothing to do with binding layout qualifiers that can be set for some
435     // uniforms in GLES3.1+. It is used to pre-set the location of uniforms.
436     ProgramAliasedBindings mUniformLocationBindings;
437 
438     std::shared_ptr<ProgramExecutable> mExecutable;
439 };
440 
441 struct ProgramVaryingRef
442 {
getProgramVaryingRef443     const sh::ShaderVariable *get(ShaderType stage) const
444     {
445         ASSERT(stage == frontShaderStage || stage == backShaderStage);
446         const sh::ShaderVariable *ref = stage == frontShaderStage ? frontShader : backShader;
447         ASSERT(ref);
448         return ref;
449     }
450 
451     const sh::ShaderVariable *frontShader = nullptr;
452     const sh::ShaderVariable *backShader  = nullptr;
453     ShaderType frontShaderStage           = ShaderType::InvalidEnum;
454     ShaderType backShaderStage            = ShaderType::InvalidEnum;
455 };
456 
457 using ProgramMergedVaryings = std::vector<ProgramVaryingRef>;
458 
459 class Program final : public LabeledObject, public angle::Subject
460 {
461   public:
462     Program(rx::GLImplFactory *factory, ShaderProgramManager *manager, ShaderProgramID handle);
463     void onDestroy(const Context *context);
464 
465     ShaderProgramID id() const;
466 
467     void setLabel(const Context *context, const std::string &label) override;
468     const std::string &getLabel() const override;
469 
getImplementation()470     ANGLE_INLINE rx::ProgramImpl *getImplementation() const
471     {
472         ASSERT(!mLinkingState);
473         return mProgram;
474     }
475 
476     void attachShader(const Context *context, Shader *shader);
477     void detachShader(const Context *context, Shader *shader);
478     int getAttachedShadersCount() const;
479 
480     const Shader *getAttachedShader(ShaderType shaderType) const;
481 
482     void bindAttributeLocation(GLuint index, const char *name);
483     void bindUniformLocation(UniformLocation location, const char *name);
484 
485     // EXT_blend_func_extended
486     void bindFragmentOutputLocation(GLuint index, const char *name);
487     void bindFragmentOutputIndex(GLuint index, const char *name);
488 
489     angle::Result linkMergedVaryings(const Context *context,
490                                      const ProgramExecutable &executable,
491                                      const ProgramMergedVaryings &mergedVaryings);
492 
493     // KHR_parallel_shader_compile
494     // Try to link the program asynchrously. As a result, background threads may be launched to
495     // execute the linking tasks concurrently.
496     angle::Result link(const Context *context);
497 
498     // Peek whether there is any running linking tasks.
499     bool isLinking() const;
500 
isLinked()501     bool isLinked() const
502     {
503         ASSERT(!mLinkingState);
504         return mLinked;
505     }
506 
507     angle::Result loadBinary(const Context *context,
508                              GLenum binaryFormat,
509                              const void *binary,
510                              GLsizei length);
511     angle::Result saveBinary(Context *context,
512                              GLenum *binaryFormat,
513                              void *binary,
514                              GLsizei bufSize,
515                              GLsizei *length) const;
516     GLint getBinaryLength(Context *context) const;
517     void setBinaryRetrievableHint(bool retrievable);
518     bool getBinaryRetrievableHint() const;
519 
520     void setSeparable(bool separable);
521     bool isSeparable() const;
522 
523     void getAttachedShaders(GLsizei maxCount, GLsizei *count, ShaderProgramID *shaders) const;
524 
525     GLuint getAttributeLocation(const std::string &name) const;
526 
527     void getActiveAttribute(GLuint index,
528                             GLsizei bufsize,
529                             GLsizei *length,
530                             GLint *size,
531                             GLenum *type,
532                             GLchar *name) const;
533     GLint getActiveAttributeCount() const;
534     GLint getActiveAttributeMaxLength() const;
535     const std::vector<sh::ShaderVariable> &getAttributes() const;
536 
537     GLint getFragDataLocation(const std::string &name) const;
538     size_t getOutputResourceCount() const;
539     const std::vector<GLenum> &getOutputVariableTypes() const;
getActiveOutputVariables()540     DrawBufferMask getActiveOutputVariables() const
541     {
542         ASSERT(!mLinkingState);
543         return mState.mActiveOutputVariables;
544     }
545 
546     // EXT_blend_func_extended
547     GLint getFragDataIndex(const std::string &name) const;
548 
549     void getActiveUniform(GLuint index,
550                           GLsizei bufsize,
551                           GLsizei *length,
552                           GLint *size,
553                           GLenum *type,
554                           GLchar *name) const;
555     GLint getActiveUniformCount() const;
556     size_t getActiveBufferVariableCount() const;
557     GLint getActiveUniformMaxLength() const;
558     bool isValidUniformLocation(UniformLocation location) const;
559     const LinkedUniform &getUniformByLocation(UniformLocation location) const;
560     const VariableLocation &getUniformLocation(UniformLocation location) const;
561 
getUniformLocations()562     const std::vector<VariableLocation> &getUniformLocations() const
563     {
564         ASSERT(!mLinkingState);
565         return mState.mUniformLocations;
566     }
567 
getUniformByIndex(GLuint index)568     const LinkedUniform &getUniformByIndex(GLuint index) const
569     {
570         ASSERT(!mLinkingState);
571         return mState.mExecutable->getUniformByIndex(index);
572     }
573 
574     const BufferVariable &getBufferVariableByIndex(GLuint index) const;
575 
576     enum SetUniformResult
577     {
578         SamplerChanged,
579         NoSamplerChange,
580     };
581 
582     UniformLocation getUniformLocation(const std::string &name) const;
583     GLuint getUniformIndex(const std::string &name) const;
584     void setUniform1fv(UniformLocation location, GLsizei count, const GLfloat *v);
585     void setUniform2fv(UniformLocation location, GLsizei count, const GLfloat *v);
586     void setUniform3fv(UniformLocation location, GLsizei count, const GLfloat *v);
587     void setUniform4fv(UniformLocation location, GLsizei count, const GLfloat *v);
588     void setUniform1iv(Context *context, UniformLocation location, GLsizei count, const GLint *v);
589     void setUniform2iv(UniformLocation location, GLsizei count, const GLint *v);
590     void setUniform3iv(UniformLocation location, GLsizei count, const GLint *v);
591     void setUniform4iv(UniformLocation location, GLsizei count, const GLint *v);
592     void setUniform1uiv(UniformLocation location, GLsizei count, const GLuint *v);
593     void setUniform2uiv(UniformLocation location, GLsizei count, const GLuint *v);
594     void setUniform3uiv(UniformLocation location, GLsizei count, const GLuint *v);
595     void setUniform4uiv(UniformLocation location, GLsizei count, const GLuint *v);
596     void setUniformMatrix2fv(UniformLocation location,
597                              GLsizei count,
598                              GLboolean transpose,
599                              const GLfloat *value);
600     void setUniformMatrix3fv(UniformLocation location,
601                              GLsizei count,
602                              GLboolean transpose,
603                              const GLfloat *value);
604     void setUniformMatrix4fv(UniformLocation location,
605                              GLsizei count,
606                              GLboolean transpose,
607                              const GLfloat *value);
608     void setUniformMatrix2x3fv(UniformLocation location,
609                                GLsizei count,
610                                GLboolean transpose,
611                                const GLfloat *value);
612     void setUniformMatrix3x2fv(UniformLocation location,
613                                GLsizei count,
614                                GLboolean transpose,
615                                const GLfloat *value);
616     void setUniformMatrix2x4fv(UniformLocation location,
617                                GLsizei count,
618                                GLboolean transpose,
619                                const GLfloat *value);
620     void setUniformMatrix4x2fv(UniformLocation location,
621                                GLsizei count,
622                                GLboolean transpose,
623                                const GLfloat *value);
624     void setUniformMatrix3x4fv(UniformLocation location,
625                                GLsizei count,
626                                GLboolean transpose,
627                                const GLfloat *value);
628     void setUniformMatrix4x3fv(UniformLocation location,
629                                GLsizei count,
630                                GLboolean transpose,
631                                const GLfloat *value);
632 
633     void getUniformfv(const Context *context, UniformLocation location, GLfloat *params) const;
634     void getUniformiv(const Context *context, UniformLocation location, GLint *params) const;
635     void getUniformuiv(const Context *context, UniformLocation location, GLuint *params) const;
636 
637     void getActiveUniformBlockName(const GLuint blockIndex,
638                                    GLsizei bufSize,
639                                    GLsizei *length,
640                                    GLchar *blockName) const;
641     void getActiveShaderStorageBlockName(const GLuint blockIndex,
642                                          GLsizei bufSize,
643                                          GLsizei *length,
644                                          GLchar *blockName) const;
645 
getActiveUniformBlockCount()646     ANGLE_INLINE GLuint getActiveUniformBlockCount() const
647     {
648         ASSERT(!mLinkingState);
649         return static_cast<GLuint>(mState.mExecutable->getActiveUniformBlockCount());
650     }
651 
getActiveAtomicCounterBufferCount()652     ANGLE_INLINE GLuint getActiveAtomicCounterBufferCount() const
653     {
654         ASSERT(!mLinkingState);
655         return static_cast<GLuint>(mState.mExecutable->getActiveAtomicCounterBufferCount());
656     }
657 
getActiveShaderStorageBlockCount()658     ANGLE_INLINE GLuint getActiveShaderStorageBlockCount() const
659     {
660         ASSERT(!mLinkingState);
661         return static_cast<GLuint>(mState.mExecutable->getActiveShaderStorageBlockCount());
662     }
663 
664     GLint getActiveUniformBlockMaxNameLength() const;
665     GLint getActiveShaderStorageBlockMaxNameLength() const;
666 
667     GLuint getUniformBlockIndex(const std::string &name) const;
668     GLuint getShaderStorageBlockIndex(const std::string &name) const;
669 
670     void bindUniformBlock(GLuint uniformBlockIndex, GLuint uniformBlockBinding);
671     GLuint getUniformBlockBinding(GLuint uniformBlockIndex) const;
672     GLuint getShaderStorageBlockBinding(GLuint shaderStorageBlockIndex) const;
673 
674     const InterfaceBlock &getUniformBlockByIndex(GLuint index) const;
675     const InterfaceBlock &getShaderStorageBlockByIndex(GLuint index) const;
676 
677     void setTransformFeedbackVaryings(GLsizei count,
678                                       const GLchar *const *varyings,
679                                       GLenum bufferMode);
680     void getTransformFeedbackVarying(GLuint index,
681                                      GLsizei bufSize,
682                                      GLsizei *length,
683                                      GLsizei *size,
684                                      GLenum *type,
685                                      GLchar *name) const;
686     GLsizei getTransformFeedbackVaryingCount() const;
687     GLsizei getTransformFeedbackVaryingMaxLength() const;
688     GLenum getTransformFeedbackBufferMode() const;
689     GLuint getTransformFeedbackVaryingResourceIndex(const GLchar *name) const;
690     const TransformFeedbackVarying &getTransformFeedbackVaryingResource(GLuint index) const;
691 
692     bool hasDrawIDUniform() const;
693     void setDrawIDUniform(GLint drawid);
694 
695     bool hasBaseVertexUniform() const;
696     void setBaseVertexUniform(GLint baseVertex);
697     bool hasBaseInstanceUniform() const;
698     void setBaseInstanceUniform(GLuint baseInstance);
699 
addRef()700     ANGLE_INLINE void addRef()
701     {
702         ASSERT(!mLinkingState);
703         mRefCount++;
704     }
705 
release(const Context * context)706     ANGLE_INLINE void release(const Context *context)
707     {
708         ASSERT(!mLinkingState);
709         mRefCount--;
710 
711         if (mRefCount == 0 && mDeleteStatus)
712         {
713             deleteSelf(context);
714         }
715     }
716 
717     unsigned int getRefCount() const;
isInUse()718     bool isInUse() const { return getRefCount() != 0; }
719     void flagForDeletion();
720     bool isFlaggedForDeletion() const;
721 
722     void validate(const Caps &caps);
validateSamplers(InfoLog * infoLog,const Caps & caps)723     bool validateSamplers(InfoLog *infoLog, const Caps &caps)
724     {
725         // Skip cache if we're using an infolog, so we get the full error.
726         // Also skip the cache if the sample mapping has changed, or if we haven't ever validated.
727         if (infoLog == nullptr && mCachedValidateSamplersResult.valid())
728         {
729             return mCachedValidateSamplersResult.value();
730         }
731 
732         return validateSamplersImpl(infoLog, caps);
733     }
734 
735     bool isValidated() const;
736 
getCachedValidateSamplersResult()737     Optional<bool> getCachedValidateSamplersResult() { return mCachedValidateSamplersResult; }
setCachedValidateSamplersResult(bool result)738     void setCachedValidateSamplersResult(bool result) { mCachedValidateSamplersResult = result; }
739 
getImageBindings()740     const std::vector<ImageBinding> &getImageBindings() const
741     {
742         ASSERT(!mLinkingState);
743         return getExecutable().getImageBindings();
744     }
745     const sh::WorkGroupSize &getComputeShaderLocalSize() const;
746     PrimitiveMode getGeometryShaderInputPrimitiveType() const;
747     PrimitiveMode getGeometryShaderOutputPrimitiveType() const;
748     GLint getGeometryShaderInvocations() const;
749     GLint getGeometryShaderMaxVertices() const;
750 
getState()751     const ProgramState &getState() const
752     {
753         ASSERT(!mLinkingState);
754         return mState;
755     }
756 
757     static LinkMismatchError LinkValidateVariablesBase(
758         const sh::ShaderVariable &variable1,
759         const sh::ShaderVariable &variable2,
760         bool validatePrecision,
761         bool validateArraySize,
762         std::string *mismatchedStructOrBlockMemberName);
763 
764     GLuint getInputResourceIndex(const GLchar *name) const;
765     GLuint getOutputResourceIndex(const GLchar *name) const;
766     void getInputResourceName(GLuint index, GLsizei bufSize, GLsizei *length, GLchar *name) const;
767     void getOutputResourceName(GLuint index, GLsizei bufSize, GLsizei *length, GLchar *name) const;
768     void getUniformResourceName(GLuint index, GLsizei bufSize, GLsizei *length, GLchar *name) const;
769     void getBufferVariableResourceName(GLuint index,
770                                        GLsizei bufSize,
771                                        GLsizei *length,
772                                        GLchar *name) const;
773     const sh::ShaderVariable &getInputResource(size_t index) const;
774     GLuint getResourceMaxNameSize(const sh::ShaderVariable &resource, GLint max) const;
775     GLuint getInputResourceMaxNameSize() const;
776     GLuint getOutputResourceMaxNameSize() const;
777     GLuint getResourceLocation(const GLchar *name, const sh::ShaderVariable &variable) const;
778     GLuint getInputResourceLocation(const GLchar *name) const;
779     GLuint getOutputResourceLocation(const GLchar *name) const;
780     const std::string getResourceName(const sh::ShaderVariable &resource) const;
781     const std::string getInputResourceName(GLuint index) const;
782     const std::string getOutputResourceName(GLuint index) const;
783     const sh::ShaderVariable &getOutputResource(size_t index) const;
784 
785     const ProgramBindings &getAttributeBindings() const;
786     const ProgramAliasedBindings &getUniformLocationBindings() const;
787     const ProgramAliasedBindings &getFragmentOutputLocations() const;
788     const ProgramAliasedBindings &getFragmentOutputIndexes() const;
789 
getNumViews()790     int getNumViews() const
791     {
792         ASSERT(!mLinkingState);
793         return mState.getNumViews();
794     }
795 
usesMultiview()796     bool usesMultiview() const { return mState.usesMultiview(); }
797 
798     ComponentTypeMask getDrawBufferTypeMask() const;
799 
800     const std::vector<GLsizei> &getTransformFeedbackStrides() const;
801 
802     // Program dirty bits.
803     enum DirtyBitType
804     {
805         DIRTY_BIT_UNIFORM_BLOCK_BINDING_0,
806         DIRTY_BIT_UNIFORM_BLOCK_BINDING_MAX =
807             DIRTY_BIT_UNIFORM_BLOCK_BINDING_0 + IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS,
808 
809         DIRTY_BIT_COUNT = DIRTY_BIT_UNIFORM_BLOCK_BINDING_MAX,
810     };
811 
812     using DirtyBits = angle::BitSet<DIRTY_BIT_COUNT>;
813 
814     angle::Result syncState(const Context *context);
815 
816     // Try to resolve linking. Inlined to make sure its overhead is as low as possible.
resolveLink(const Context * context)817     void resolveLink(const Context *context)
818     {
819         if (mLinkingState)
820         {
821             resolveLinkImpl(context);
822         }
823     }
824 
hasAnyDirtyBit()825     ANGLE_INLINE bool hasAnyDirtyBit() const { return mDirtyBits.any(); }
826 
827     // Writes a program's binary to the output memory buffer.
828     angle::Result serialize(const Context *context, angle::MemoryBuffer *binaryOut) const;
829 
serial()830     rx::Serial serial() const { return mSerial; }
831 
getExecutable()832     const ProgramExecutable &getExecutable() const { return mState.getExecutable(); }
getExecutable()833     ProgramExecutable &getExecutable() { return mState.getExecutable(); }
834 
835     const char *validateDrawStates(const State &state, const gl::Extensions &extensions) const;
836 
837     static void getFilteredVaryings(const std::vector<sh::ShaderVariable> &varyings,
838                                     std::vector<const sh::ShaderVariable *> *filteredVaryingsOut);
839     static bool doShaderVariablesMatch(int outputShaderVersion,
840                                        ShaderType outputShaderType,
841                                        ShaderType inputShaderType,
842                                        const sh::ShaderVariable &input,
843                                        const sh::ShaderVariable &output,
844                                        bool validateGeometryShaderInputs,
845                                        bool isSeparable,
846                                        gl::InfoLog &infoLog);
847     static bool linkValidateShaderInterfaceMatching(
848         const std::vector<sh::ShaderVariable> &outputVaryings,
849         const std::vector<sh::ShaderVariable> &inputVaryings,
850         ShaderType outputShaderType,
851         ShaderType inputShaderType,
852         int outputShaderVersion,
853         int inputShaderVersion,
854         bool isSeparable,
855         InfoLog &infoLog);
856     static bool linkValidateBuiltInVaryings(const std::vector<sh::ShaderVariable> &vertexVaryings,
857                                             const std::vector<sh::ShaderVariable> &fragmentVaryings,
858                                             int vertexShaderVersion,
859                                             InfoLog &infoLog);
860 
861     void fillProgramStateMap(ShaderMap<const ProgramState *> *programStatesOut);
862 
863   private:
864     struct LinkingState;
865 
866     ~Program() override;
867 
868     // Loads program state according to the specified binary blob.
869     angle::Result deserialize(const Context *context, BinaryInputStream &stream, InfoLog &infoLog);
870 
871     void unlink();
872     void deleteSelf(const Context *context);
873 
874     angle::Result linkImpl(const Context *context);
875 
876     bool linkValidateShaders(InfoLog &infoLog);
877     bool linkAttributes(const Context *context, InfoLog &infoLog);
878     bool linkInterfaceBlocks(const Caps &caps,
879                              const Version &version,
880                              bool webglCompatibility,
881                              InfoLog &infoLog,
882                              GLuint *combinedShaderStorageBlocksCount);
883     bool linkVaryings(InfoLog &infoLog) const;
884 
885     bool linkUniforms(const Caps &caps,
886                       const Version &version,
887                       InfoLog &infoLog,
888                       const ProgramAliasedBindings &uniformLocationBindings,
889                       GLuint *combinedImageUniformsCount,
890                       std::vector<UnusedUniform> *unusedUniforms);
891     void linkSamplerAndImageBindings(GLuint *combinedImageUniformsCount);
892     bool linkAtomicCounterBuffers();
893 
894     void updateLinkedShaderStages();
895 
896     static LinkMismatchError LinkValidateVaryings(const sh::ShaderVariable &outputVarying,
897                                                   const sh::ShaderVariable &inputVarying,
898                                                   int shaderVersion,
899                                                   bool validateGeometryShaderInputVarying,
900                                                   bool isSeparable,
901                                                   std::string *mismatchedStructFieldName);
902 
903     bool linkValidateTransformFeedback(const Version &version,
904                                        InfoLog &infoLog,
905                                        const ProgramMergedVaryings &linkedVaryings,
906                                        ShaderType stage,
907                                        const Caps &caps) const;
908 
909     void gatherTransformFeedbackVaryings(const ProgramMergedVaryings &varyings, ShaderType stage);
910 
911     ProgramMergedVaryings getMergedVaryings() const;
912     int getOutputLocationForLink(const sh::ShaderVariable &outputVariable) const;
913     bool isOutputSecondaryForLink(const sh::ShaderVariable &outputVariable) const;
914     bool linkOutputVariables(const Caps &caps,
915                              const Extensions &extensions,
916                              const Version &version,
917                              GLuint combinedImageUniformsCount,
918                              GLuint combinedShaderStorageBlocksCount);
919 
920     void setUniformValuesFromBindingQualifiers();
921     bool shouldIgnoreUniform(UniformLocation location) const;
922 
923     void initInterfaceBlockBindings();
924 
925     // Both these function update the cached uniform values and return a modified "count"
926     // so that the uniform update doesn't overflow the uniform.
927     template <typename T>
928     GLsizei clampUniformCount(const VariableLocation &locationInfo,
929                               GLsizei count,
930                               int vectorSize,
931                               const T *v);
932     template <size_t cols, size_t rows, typename T>
933     GLsizei clampMatrixUniformCount(UniformLocation location,
934                                     GLsizei count,
935                                     GLboolean transpose,
936                                     const T *v);
937 
938     void updateSamplerUniform(Context *context,
939                               const VariableLocation &locationInfo,
940                               GLsizei clampedCount,
941                               const GLint *v);
942 
943     template <typename DestT>
944     void getUniformInternal(const Context *context,
945                             DestT *dataOut,
946                             UniformLocation location,
947                             GLenum nativeType,
948                             int components) const;
949 
950     void getResourceName(const std::string name,
951                          GLsizei bufSize,
952                          GLsizei *length,
953                          GLchar *dest) const;
954 
955     template <typename T>
956     GLint getActiveInterfaceBlockMaxNameLength(const std::vector<T> &resources) const;
957 
958     GLuint getSamplerUniformBinding(const VariableLocation &uniformLocation) const;
959     GLuint getImageUniformBinding(const VariableLocation &uniformLocation) const;
960 
961     bool validateSamplersImpl(InfoLog *infoLog, const Caps &caps);
962 
963     // Block until linking is finished and resolve it.
964     void resolveLinkImpl(const gl::Context *context);
965 
966     void postResolveLink(const gl::Context *context);
967 
968     rx::Serial mSerial;
969     ProgramState mState;
970     rx::ProgramImpl *mProgram;
971 
972     bool mValidated;
973 
974     ProgramBindings mAttributeBindings;
975 
976     // EXT_blend_func_extended
977     ProgramAliasedBindings mFragmentOutputLocations;
978     ProgramAliasedBindings mFragmentOutputIndexes;
979 
980     bool mLinked;
981     std::unique_ptr<LinkingState> mLinkingState;
982     bool mDeleteStatus;  // Flag to indicate that the program can be deleted when no longer in use
983 
984     unsigned int mRefCount;
985 
986     ShaderProgramManager *mResourceManager;
987     const ShaderProgramID mHandle;
988 
989     // Cache for sampler validation
990     Optional<bool> mCachedValidateSamplersResult;
991 
992     DirtyBits mDirtyBits;
993 };
994 }  // namespace gl
995 
996 #endif  // LIBANGLE_PROGRAM_H_
997