• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 = std::unordered_map<std::string, GLuint>::const_iterator;
176     const_iterator begin() const;
177     const_iterator end() const;
178 
179   private:
180     std::unordered_map<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 { return mSamplerBindings; }
getImageBindings()262     const std::vector<ImageBinding> &getImageBindings() const { return mImageBindings; }
getComputeShaderLocalSize()263     const sh::WorkGroupSize &getComputeShaderLocalSize() const { return mComputeShaderLocalSize; }
getDefaultUniformRange()264     const RangeUI &getDefaultUniformRange() const { return mDefaultUniformRange; }
getSamplerUniformRange()265     const RangeUI &getSamplerUniformRange() const { return mExecutable->getSamplerUniformRange(); }
getImageUniformRange()266     const RangeUI &getImageUniformRange() const { return mExecutable->getImageUniformRange(); }
getAtomicCounterUniformRange()267     const RangeUI &getAtomicCounterUniformRange() const { return mAtomicCounterUniformRange; }
268 
getLinkedTransformFeedbackVaryings()269     const std::vector<TransformFeedbackVarying> &getLinkedTransformFeedbackVaryings() const
270     {
271         return mExecutable->getLinkedTransformFeedbackVaryings();
272     }
getTransformFeedbackStrides()273     const std::vector<GLsizei> &getTransformFeedbackStrides() const
274     {
275         return mExecutable->getTransformFeedbackStrides();
276     }
getAtomicCounterBuffers()277     const std::vector<AtomicCounterBuffer> &getAtomicCounterBuffers() const
278     {
279         return mExecutable->getAtomicCounterBuffers();
280     }
281 
282     GLuint getUniformIndexFromName(const std::string &name) const;
283     GLuint getUniformIndexFromLocation(UniformLocation location) const;
284     Optional<GLuint> getSamplerIndex(UniformLocation location) const;
285     bool isSamplerUniformIndex(GLuint index) const;
286     GLuint getSamplerIndexFromUniformIndex(GLuint uniformIndex) const;
287     GLuint getUniformIndexFromSamplerIndex(GLuint samplerIndex) const;
288     bool isImageUniformIndex(GLuint index) const;
289     GLuint getImageIndexFromUniformIndex(GLuint uniformIndex) const;
290     GLuint getUniformIndexFromImageIndex(GLuint imageIndex) const;
291     GLuint getAttributeLocation(const std::string &name) const;
292 
293     GLuint getBufferVariableIndexFromName(const std::string &name) const;
294 
getNumViews()295     int getNumViews() const { return mNumViews; }
usesMultiview()296     bool usesMultiview() const { return mNumViews != -1; }
297 
298     bool hasAttachedShader() const;
299 
300     ShaderType getFirstAttachedShaderStageType() const;
301     ShaderType getLastAttachedShaderStageType() const;
302 
getUniformLocationBindings()303     const ProgramAliasedBindings &getUniformLocationBindings() const
304     {
305         return mUniformLocationBindings;
306     }
307 
getExecutable()308     const ProgramExecutable &getExecutable() const
309     {
310         ASSERT(mExecutable);
311         return *mExecutable;
312     }
getExecutable()313     ProgramExecutable &getExecutable()
314     {
315         ASSERT(mExecutable);
316         return *mExecutable;
317     }
318 
hasDefaultUniforms()319     bool hasDefaultUniforms() const { return !getDefaultUniformRange().empty(); }
hasTextures()320     bool hasTextures() const { return !getSamplerBindings().empty(); }
hasImages()321     bool hasImages() const { return !getImageBindings().empty(); }
hasEarlyFragmentTestsOptimization()322     bool hasEarlyFragmentTestsOptimization() const { return mEarlyFramentTestsOptimization; }
323 
isShaderMarkedForDetach(gl::ShaderType shaderType)324     bool isShaderMarkedForDetach(gl::ShaderType shaderType) const
325     {
326         return mAttachedShadersMarkedForDetach[shaderType];
327     }
328 
329     // A Program can only either be graphics or compute, but never both, so it
330     // can answer isCompute() based on which shaders it has.
isCompute()331     bool isCompute() const { return mExecutable->hasLinkedShaderStage(ShaderType::Compute); }
332 
333   private:
334     friend class MemoryProgramCache;
335     friend class Program;
336 
337     void updateTransformFeedbackStrides();
338     void updateActiveSamplers();
339     void updateActiveImages();
340     void updateProgramInterfaceInputs();
341     void updateProgramInterfaceOutputs();
342 
343     // Scans the sampler bindings for type conflicts with sampler 'textureUnitIndex'.
344     void setSamplerUniformTextureTypeAndFormat(size_t textureUnitIndex);
345 
346     std::string mLabel;
347 
348     sh::WorkGroupSize mComputeShaderLocalSize;
349 
350     ShaderMap<Shader *> mAttachedShaders;
351     ShaderMap<bool> mAttachedShadersMarkedForDetach;
352 
353     uint32_t mLocationsUsedForXfbExtension;
354     std::vector<std::string> mTransformFeedbackVaryingNames;
355 
356     // For faster iteration on the blocks currently being bound.
357     UniformBlockBindingMask mActiveUniformBlockBindings;
358 
359     std::vector<VariableLocation> mUniformLocations;
360     std::vector<BufferVariable> mBufferVariables;
361     RangeUI mDefaultUniformRange;
362     RangeUI mAtomicCounterUniformRange;
363 
364     // An array of the samplers that are used by the program
365     std::vector<SamplerBinding> mSamplerBindings;
366 
367     // An array of the images that are used by the program
368     std::vector<ImageBinding> mImageBindings;
369 
370     // EXT_blend_func_extended secondary outputs (ones with index 1) in ESSL 3.00 shaders.
371     std::vector<VariableLocation> mSecondaryOutputLocations;
372 
373     DrawBufferMask mActiveOutputVariables;
374 
375     // Fragment output variable base types: FLOAT, INT, or UINT.  Ordered by location.
376     std::vector<GLenum> mOutputVariableTypes;
377     ComponentTypeMask mDrawBufferTypeMask;
378 
379     bool mBinaryRetrieveableHint;
380     bool mSeparable;
381     bool mEarlyFramentTestsOptimization;
382 
383     // ANGLE_multiview.
384     int mNumViews;
385 
386     // GL_EXT_geometry_shader.
387     PrimitiveMode mGeometryShaderInputPrimitiveType;
388     PrimitiveMode mGeometryShaderOutputPrimitiveType;
389     int mGeometryShaderInvocations;
390     int mGeometryShaderMaxVertices;
391 
392     // GL_ANGLE_multi_draw
393     int mDrawIDLocation;
394 
395     // GL_ANGLE_base_vertex_base_instance
396     int mBaseVertexLocation;
397     int mBaseInstanceLocation;
398     // Cached value of base vertex and base instance
399     // need to reset them to zero if using non base vertex or base instance draw calls.
400     GLint mCachedBaseVertex;
401     GLuint mCachedBaseInstance;
402 
403     // Note that this has nothing to do with binding layout qualifiers that can be set for some
404     // uniforms in GLES3.1+. It is used to pre-set the location of uniforms.
405     ProgramAliasedBindings mUniformLocationBindings;
406 
407     std::shared_ptr<ProgramExecutable> mExecutable;
408 };
409 
410 struct ProgramVaryingRef
411 {
getProgramVaryingRef412     const sh::ShaderVariable *get(ShaderType stage) const
413     {
414         ASSERT(stage == frontShaderStage || stage == backShaderStage);
415         const sh::ShaderVariable *ref = stage == frontShaderStage ? frontShader : backShader;
416         ASSERT(ref);
417         return ref;
418     }
419 
420     const sh::ShaderVariable *frontShader = nullptr;
421     const sh::ShaderVariable *backShader  = nullptr;
422     ShaderType frontShaderStage           = ShaderType::InvalidEnum;
423     ShaderType backShaderStage            = ShaderType::InvalidEnum;
424 };
425 
426 using ProgramMergedVaryings = std::vector<ProgramVaryingRef>;
427 
428 class Program final : angle::NonCopyable, public LabeledObject
429 {
430   public:
431     Program(rx::GLImplFactory *factory, ShaderProgramManager *manager, ShaderProgramID handle);
432     void onDestroy(const Context *context);
433 
434     ShaderProgramID id() const;
435 
436     void setLabel(const Context *context, const std::string &label) override;
437     const std::string &getLabel() const override;
438 
getImplementation()439     ANGLE_INLINE rx::ProgramImpl *getImplementation() const
440     {
441         ASSERT(!mLinkingState);
442         return mProgram;
443     }
444 
445     void attachShader(const Context *context, Shader *shader);
446     void detachShader(const Context *context, Shader *shader);
447     int getAttachedShadersCount() const;
448 
449     const Shader *getAttachedShader(ShaderType shaderType) const;
450 
451     void bindAttributeLocation(GLuint index, const char *name);
452     void bindUniformLocation(UniformLocation location, const char *name);
453 
454     // EXT_blend_func_extended
455     void bindFragmentOutputLocation(GLuint index, const char *name);
456     void bindFragmentOutputIndex(GLuint index, const char *name);
457 
458     angle::Result linkMergedVaryings(const Context *context,
459                                      const ProgramExecutable &executable,
460                                      const ProgramMergedVaryings &mergedVaryings);
461 
462     // KHR_parallel_shader_compile
463     // Try to link the program asynchrously. As a result, background threads may be launched to
464     // execute the linking tasks concurrently.
465     angle::Result link(const Context *context);
466 
467     // Peek whether there is any running linking tasks.
468     bool isLinking() const;
469 
isLinked()470     bool isLinked() const
471     {
472         ASSERT(!mLinkingState);
473         return mLinked;
474     }
475 
476     angle::Result loadBinary(const Context *context,
477                              GLenum binaryFormat,
478                              const void *binary,
479                              GLsizei length);
480     angle::Result saveBinary(Context *context,
481                              GLenum *binaryFormat,
482                              void *binary,
483                              GLsizei bufSize,
484                              GLsizei *length) const;
485     GLint getBinaryLength(Context *context) const;
486     void setBinaryRetrievableHint(bool retrievable);
487     bool getBinaryRetrievableHint() const;
488 
489     void setSeparable(bool separable);
490     bool isSeparable() const;
491 
492     void getAttachedShaders(GLsizei maxCount, GLsizei *count, ShaderProgramID *shaders) const;
493 
494     GLuint getAttributeLocation(const std::string &name) const;
495 
496     void getActiveAttribute(GLuint index,
497                             GLsizei bufsize,
498                             GLsizei *length,
499                             GLint *size,
500                             GLenum *type,
501                             GLchar *name) const;
502     GLint getActiveAttributeCount() const;
503     GLint getActiveAttributeMaxLength() const;
504     const std::vector<sh::ShaderVariable> &getAttributes() const;
505 
506     GLint getFragDataLocation(const std::string &name) const;
507     size_t getOutputResourceCount() const;
508     const std::vector<GLenum> &getOutputVariableTypes() const;
getActiveOutputVariables()509     DrawBufferMask getActiveOutputVariables() const
510     {
511         ASSERT(!mLinkingState);
512         return mState.mActiveOutputVariables;
513     }
514 
515     // EXT_blend_func_extended
516     GLint getFragDataIndex(const std::string &name) const;
517 
518     void getActiveUniform(GLuint index,
519                           GLsizei bufsize,
520                           GLsizei *length,
521                           GLint *size,
522                           GLenum *type,
523                           GLchar *name) const;
524     GLint getActiveUniformCount() const;
525     size_t getActiveBufferVariableCount() const;
526     GLint getActiveUniformMaxLength() const;
527     bool isValidUniformLocation(UniformLocation location) const;
528     const LinkedUniform &getUniformByLocation(UniformLocation location) const;
529     const VariableLocation &getUniformLocation(UniformLocation location) const;
530 
getUniformLocations()531     const std::vector<VariableLocation> &getUniformLocations() const
532     {
533         ASSERT(!mLinkingState);
534         return mState.mUniformLocations;
535     }
536 
getUniformByIndex(GLuint index)537     const LinkedUniform &getUniformByIndex(GLuint index) const
538     {
539         ASSERT(!mLinkingState);
540         return mState.mExecutable->getUniformByIndex(index);
541     }
542 
543     const BufferVariable &getBufferVariableByIndex(GLuint index) const;
544 
545     enum SetUniformResult
546     {
547         SamplerChanged,
548         NoSamplerChange,
549     };
550 
551     UniformLocation getUniformLocation(const std::string &name) const;
552     GLuint getUniformIndex(const std::string &name) const;
553     void setUniform1fv(UniformLocation location, GLsizei count, const GLfloat *v);
554     void setUniform2fv(UniformLocation location, GLsizei count, const GLfloat *v);
555     void setUniform3fv(UniformLocation location, GLsizei count, const GLfloat *v);
556     void setUniform4fv(UniformLocation location, GLsizei count, const GLfloat *v);
557     void setUniform1iv(Context *context, UniformLocation location, GLsizei count, const GLint *v);
558     void setUniform2iv(UniformLocation location, GLsizei count, const GLint *v);
559     void setUniform3iv(UniformLocation location, GLsizei count, const GLint *v);
560     void setUniform4iv(UniformLocation location, GLsizei count, const GLint *v);
561     void setUniform1uiv(UniformLocation location, GLsizei count, const GLuint *v);
562     void setUniform2uiv(UniformLocation location, GLsizei count, const GLuint *v);
563     void setUniform3uiv(UniformLocation location, GLsizei count, const GLuint *v);
564     void setUniform4uiv(UniformLocation location, GLsizei count, const GLuint *v);
565     void setUniformMatrix2fv(UniformLocation location,
566                              GLsizei count,
567                              GLboolean transpose,
568                              const GLfloat *value);
569     void setUniformMatrix3fv(UniformLocation location,
570                              GLsizei count,
571                              GLboolean transpose,
572                              const GLfloat *value);
573     void setUniformMatrix4fv(UniformLocation location,
574                              GLsizei count,
575                              GLboolean transpose,
576                              const GLfloat *value);
577     void setUniformMatrix2x3fv(UniformLocation location,
578                                GLsizei count,
579                                GLboolean transpose,
580                                const GLfloat *value);
581     void setUniformMatrix3x2fv(UniformLocation location,
582                                GLsizei count,
583                                GLboolean transpose,
584                                const GLfloat *value);
585     void setUniformMatrix2x4fv(UniformLocation location,
586                                GLsizei count,
587                                GLboolean transpose,
588                                const GLfloat *value);
589     void setUniformMatrix4x2fv(UniformLocation location,
590                                GLsizei count,
591                                GLboolean transpose,
592                                const GLfloat *value);
593     void setUniformMatrix3x4fv(UniformLocation location,
594                                GLsizei count,
595                                GLboolean transpose,
596                                const GLfloat *value);
597     void setUniformMatrix4x3fv(UniformLocation location,
598                                GLsizei count,
599                                GLboolean transpose,
600                                const GLfloat *value);
601 
602     void getUniformfv(const Context *context, UniformLocation location, GLfloat *params) const;
603     void getUniformiv(const Context *context, UniformLocation location, GLint *params) const;
604     void getUniformuiv(const Context *context, UniformLocation location, GLuint *params) const;
605 
606     void getActiveUniformBlockName(const GLuint blockIndex,
607                                    GLsizei bufSize,
608                                    GLsizei *length,
609                                    GLchar *blockName) const;
610     void getActiveShaderStorageBlockName(const GLuint blockIndex,
611                                          GLsizei bufSize,
612                                          GLsizei *length,
613                                          GLchar *blockName) const;
614 
getActiveUniformBlockCount()615     ANGLE_INLINE GLuint getActiveUniformBlockCount() const
616     {
617         ASSERT(!mLinkingState);
618         return static_cast<GLuint>(mState.mExecutable->getActiveUniformBlockCount());
619     }
620 
getActiveAtomicCounterBufferCount()621     ANGLE_INLINE GLuint getActiveAtomicCounterBufferCount() const
622     {
623         ASSERT(!mLinkingState);
624         return static_cast<GLuint>(mState.mExecutable->getActiveAtomicCounterBufferCount());
625     }
626 
getActiveShaderStorageBlockCount()627     ANGLE_INLINE GLuint getActiveShaderStorageBlockCount() const
628     {
629         ASSERT(!mLinkingState);
630         return static_cast<GLuint>(mState.mExecutable->getActiveShaderStorageBlockCount());
631     }
632 
633     GLint getActiveUniformBlockMaxNameLength() const;
634     GLint getActiveShaderStorageBlockMaxNameLength() const;
635 
636     GLuint getUniformBlockIndex(const std::string &name) const;
637     GLuint getShaderStorageBlockIndex(const std::string &name) const;
638 
639     void bindUniformBlock(GLuint uniformBlockIndex, GLuint uniformBlockBinding);
640     GLuint getUniformBlockBinding(GLuint uniformBlockIndex) const;
641     GLuint getShaderStorageBlockBinding(GLuint shaderStorageBlockIndex) const;
642 
643     const InterfaceBlock &getUniformBlockByIndex(GLuint index) const;
644     const InterfaceBlock &getShaderStorageBlockByIndex(GLuint index) const;
645 
646     void setTransformFeedbackVaryings(GLsizei count,
647                                       const GLchar *const *varyings,
648                                       GLenum bufferMode);
649     void getTransformFeedbackVarying(GLuint index,
650                                      GLsizei bufSize,
651                                      GLsizei *length,
652                                      GLsizei *size,
653                                      GLenum *type,
654                                      GLchar *name) const;
655     GLsizei getTransformFeedbackVaryingCount() const;
656     GLsizei getTransformFeedbackVaryingMaxLength() const;
657     GLenum getTransformFeedbackBufferMode() const;
658     GLuint getTransformFeedbackVaryingResourceIndex(const GLchar *name) const;
659     const TransformFeedbackVarying &getTransformFeedbackVaryingResource(GLuint index) const;
660 
661     bool hasDrawIDUniform() const;
662     void setDrawIDUniform(GLint drawid);
663 
664     bool hasBaseVertexUniform() const;
665     void setBaseVertexUniform(GLint baseVertex);
666     bool hasBaseInstanceUniform() const;
667     void setBaseInstanceUniform(GLuint baseInstance);
668 
addRef()669     ANGLE_INLINE void addRef()
670     {
671         ASSERT(!mLinkingState);
672         mRefCount++;
673     }
674 
release(const Context * context)675     ANGLE_INLINE void release(const Context *context)
676     {
677         ASSERT(!mLinkingState);
678         mRefCount--;
679 
680         if (mRefCount == 0 && mDeleteStatus)
681         {
682             deleteSelf(context);
683         }
684     }
685 
686     unsigned int getRefCount() const;
isInUse()687     bool isInUse() const { return getRefCount() != 0; }
688     void flagForDeletion();
689     bool isFlaggedForDeletion() const;
690 
691     void validate(const Caps &caps);
validateSamplers(InfoLog * infoLog,const Caps & caps)692     bool validateSamplers(InfoLog *infoLog, const Caps &caps)
693     {
694         // Skip cache if we're using an infolog, so we get the full error.
695         // Also skip the cache if the sample mapping has changed, or if we haven't ever validated.
696         if (infoLog == nullptr && mCachedValidateSamplersResult.valid())
697         {
698             return mCachedValidateSamplersResult.value();
699         }
700 
701         return validateSamplersImpl(infoLog, caps);
702     }
703 
704     bool isValidated() const;
705 
getCachedValidateSamplersResult()706     Optional<bool> getCachedValidateSamplersResult() { return mCachedValidateSamplersResult; }
setCachedValidateSamplersResult(bool result)707     void setCachedValidateSamplersResult(bool result) { mCachedValidateSamplersResult = result; }
708 
709     const std::vector<SamplerBinding> &getSamplerBindings() const;
getImageBindings()710     const std::vector<ImageBinding> &getImageBindings() const
711     {
712         ASSERT(!mLinkingState);
713         return mState.mImageBindings;
714     }
715     const sh::WorkGroupSize &getComputeShaderLocalSize() const;
716     PrimitiveMode getGeometryShaderInputPrimitiveType() const;
717     PrimitiveMode getGeometryShaderOutputPrimitiveType() const;
718     GLint getGeometryShaderInvocations() const;
719     GLint getGeometryShaderMaxVertices() const;
720 
getState()721     const ProgramState &getState() const
722     {
723         ASSERT(!mLinkingState);
724         return mState;
725     }
726 
727     static LinkMismatchError LinkValidateVariablesBase(
728         const sh::ShaderVariable &variable1,
729         const sh::ShaderVariable &variable2,
730         bool validatePrecision,
731         bool validateArraySize,
732         std::string *mismatchedStructOrBlockMemberName);
733 
734     GLuint getInputResourceIndex(const GLchar *name) const;
735     GLuint getOutputResourceIndex(const GLchar *name) const;
736     void getInputResourceName(GLuint index, GLsizei bufSize, GLsizei *length, GLchar *name) const;
737     void getOutputResourceName(GLuint index, GLsizei bufSize, GLsizei *length, GLchar *name) const;
738     void getUniformResourceName(GLuint index, GLsizei bufSize, GLsizei *length, GLchar *name) const;
739     void getBufferVariableResourceName(GLuint index,
740                                        GLsizei bufSize,
741                                        GLsizei *length,
742                                        GLchar *name) const;
743     const sh::ShaderVariable &getInputResource(size_t index) const;
744     GLuint getResourceMaxNameSize(const sh::ShaderVariable &resource, GLint max) const;
745     GLuint getInputResourceMaxNameSize() const;
746     GLuint getOutputResourceMaxNameSize() const;
747     GLuint getResourceLocation(const GLchar *name, const sh::ShaderVariable &variable) const;
748     GLuint getInputResourceLocation(const GLchar *name) const;
749     GLuint getOutputResourceLocation(const GLchar *name) const;
750     const std::string getResourceName(const sh::ShaderVariable &resource) const;
751     const std::string getInputResourceName(GLuint index) const;
752     const std::string getOutputResourceName(GLuint index) const;
753     const sh::ShaderVariable &getOutputResource(size_t index) const;
754 
755     const ProgramBindings &getAttributeBindings() const;
756     const ProgramAliasedBindings &getUniformLocationBindings() const;
757     const ProgramAliasedBindings &getFragmentOutputLocations() const;
758     const ProgramAliasedBindings &getFragmentOutputIndexes() const;
759 
getNumViews()760     int getNumViews() const
761     {
762         ASSERT(!mLinkingState);
763         return mState.getNumViews();
764     }
765 
usesMultiview()766     bool usesMultiview() const { return mState.usesMultiview(); }
767 
768     ComponentTypeMask getDrawBufferTypeMask() const;
769 
770     const std::vector<GLsizei> &getTransformFeedbackStrides() const;
771 
772     // Program dirty bits.
773     enum DirtyBitType
774     {
775         DIRTY_BIT_UNIFORM_BLOCK_BINDING_0,
776         DIRTY_BIT_UNIFORM_BLOCK_BINDING_MAX =
777             DIRTY_BIT_UNIFORM_BLOCK_BINDING_0 + IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS,
778 
779         DIRTY_BIT_COUNT = DIRTY_BIT_UNIFORM_BLOCK_BINDING_MAX,
780     };
781 
782     using DirtyBits = angle::BitSet<DIRTY_BIT_COUNT>;
783 
784     angle::Result syncState(const Context *context);
785 
786     // Try to resolve linking. Inlined to make sure its overhead is as low as possible.
resolveLink(const Context * context)787     void resolveLink(const Context *context)
788     {
789         if (mLinkingState)
790         {
791             resolveLinkImpl(context);
792         }
793     }
794 
hasAnyDirtyBit()795     ANGLE_INLINE bool hasAnyDirtyBit() const { return mDirtyBits.any(); }
796 
797     // Writes a program's binary to the output memory buffer.
798     angle::Result serialize(const Context *context, angle::MemoryBuffer *binaryOut) const;
799 
serial()800     rx::Serial serial() const { return mSerial; }
801 
getExecutable()802     const ProgramExecutable &getExecutable() const { return mState.getExecutable(); }
getExecutable()803     ProgramExecutable &getExecutable() { return mState.getExecutable(); }
804 
805     const char *validateDrawStates(const State &state, const gl::Extensions &extensions) const;
806 
807     static void getFilteredVaryings(const std::vector<sh::ShaderVariable> &varyings,
808                                     std::vector<const sh::ShaderVariable *> *filteredVaryingsOut);
809     static bool doShaderVariablesMatch(int outputShaderVersion,
810                                        ShaderType outputShaderType,
811                                        ShaderType inputShaderType,
812                                        const sh::ShaderVariable &input,
813                                        const sh::ShaderVariable &output,
814                                        bool validateGeometryShaderInputs,
815                                        bool isSeparable,
816                                        gl::InfoLog &infoLog);
817     static bool linkValidateShaderInterfaceMatching(
818         const std::vector<sh::ShaderVariable> &outputVaryings,
819         const std::vector<sh::ShaderVariable> &inputVaryings,
820         ShaderType outputShaderType,
821         ShaderType inputShaderType,
822         int outputShaderVersion,
823         int inputShaderVersion,
824         bool isSeparable,
825         InfoLog &infoLog);
826     static bool linkValidateBuiltInVaryings(const std::vector<sh::ShaderVariable> &vertexVaryings,
827                                             const std::vector<sh::ShaderVariable> &fragmentVaryings,
828                                             int vertexShaderVersion,
829                                             InfoLog &infoLog);
830 
831   private:
832     struct LinkingState;
833 
834     ~Program() override;
835 
836     // Loads program state according to the specified binary blob.
837     angle::Result deserialize(const Context *context, BinaryInputStream &stream, InfoLog &infoLog);
838 
839     void unlink();
840     void deleteSelf(const Context *context);
841 
842     angle::Result linkImpl(const Context *context);
843 
844     bool linkValidateShaders(InfoLog &infoLog);
845     bool linkAttributes(const Context *context, InfoLog &infoLog);
846     bool linkInterfaceBlocks(const Caps &caps,
847                              const Version &version,
848                              bool webglCompatibility,
849                              InfoLog &infoLog,
850                              GLuint *combinedShaderStorageBlocksCount);
851     bool linkVaryings(InfoLog &infoLog) const;
852 
853     bool linkUniforms(const Caps &caps,
854                       const Version &version,
855                       InfoLog &infoLog,
856                       const ProgramAliasedBindings &uniformLocationBindings,
857                       GLuint *combinedImageUniformsCount,
858                       std::vector<UnusedUniform> *unusedUniforms);
859     void linkSamplerAndImageBindings(GLuint *combinedImageUniformsCount);
860     bool linkAtomicCounterBuffers();
861 
862     void updateLinkedShaderStages();
863 
864     static LinkMismatchError LinkValidateVaryings(const sh::ShaderVariable &outputVarying,
865                                                   const sh::ShaderVariable &inputVarying,
866                                                   int shaderVersion,
867                                                   bool validateGeometryShaderInputVarying,
868                                                   bool isSeparable,
869                                                   std::string *mismatchedStructFieldName);
870 
871     bool linkValidateTransformFeedback(const Version &version,
872                                        InfoLog &infoLog,
873                                        const ProgramMergedVaryings &linkedVaryings,
874                                        ShaderType stage,
875                                        const Caps &caps) const;
876 
877     void gatherTransformFeedbackVaryings(const ProgramMergedVaryings &varyings, ShaderType stage);
878 
879     ProgramMergedVaryings getMergedVaryings() const;
880     int getOutputLocationForLink(const sh::ShaderVariable &outputVariable) const;
881     bool isOutputSecondaryForLink(const sh::ShaderVariable &outputVariable) const;
882     bool linkOutputVariables(const Caps &caps,
883                              const Extensions &extensions,
884                              const Version &version,
885                              GLuint combinedImageUniformsCount,
886                              GLuint combinedShaderStorageBlocksCount);
887 
888     void setUniformValuesFromBindingQualifiers();
889     bool shouldIgnoreUniform(UniformLocation location) const;
890 
891     void initInterfaceBlockBindings();
892 
893     // Both these function update the cached uniform values and return a modified "count"
894     // so that the uniform update doesn't overflow the uniform.
895     template <typename T>
896     GLsizei clampUniformCount(const VariableLocation &locationInfo,
897                               GLsizei count,
898                               int vectorSize,
899                               const T *v);
900     template <size_t cols, size_t rows, typename T>
901     GLsizei clampMatrixUniformCount(UniformLocation location,
902                                     GLsizei count,
903                                     GLboolean transpose,
904                                     const T *v);
905 
906     void updateSamplerUniform(Context *context,
907                               const VariableLocation &locationInfo,
908                               GLsizei clampedCount,
909                               const GLint *v);
910 
911     template <typename DestT>
912     void getUniformInternal(const Context *context,
913                             DestT *dataOut,
914                             UniformLocation location,
915                             GLenum nativeType,
916                             int components) const;
917 
918     void getResourceName(const std::string name,
919                          GLsizei bufSize,
920                          GLsizei *length,
921                          GLchar *dest) const;
922 
923     template <typename T>
924     GLint getActiveInterfaceBlockMaxNameLength(const std::vector<T> &resources) const;
925 
926     GLuint getSamplerUniformBinding(const VariableLocation &uniformLocation) const;
927     GLuint getImageUniformBinding(const VariableLocation &uniformLocation) const;
928 
929     bool validateSamplersImpl(InfoLog *infoLog, const Caps &caps);
930 
931     // Block until linking is finished and resolve it.
932     void resolveLinkImpl(const gl::Context *context);
933 
934     void postResolveLink(const gl::Context *context);
935 
936     rx::Serial mSerial;
937     ProgramState mState;
938     rx::ProgramImpl *mProgram;
939 
940     bool mValidated;
941 
942     ProgramBindings mAttributeBindings;
943 
944     // EXT_blend_func_extended
945     ProgramAliasedBindings mFragmentOutputLocations;
946     ProgramAliasedBindings mFragmentOutputIndexes;
947 
948     bool mLinked;
949     std::unique_ptr<LinkingState> mLinkingState;
950     bool mDeleteStatus;  // Flag to indicate that the program can be deleted when no longer in use
951 
952     unsigned int mRefCount;
953 
954     ShaderProgramManager *mResourceManager;
955     const ShaderProgramID mHandle;
956 
957     // Cache for sampler validation
958     Optional<bool> mCachedValidateSamplersResult;
959 
960     DirtyBits mDirtyBits;
961 };
962 }  // namespace gl
963 
964 #endif  // LIBANGLE_PROGRAM_H_
965