xref: /aosp_15_r20/external/angle/src/libANGLE/ProgramExecutable.h (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
1 //
2 // Copyright 2020 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 // ProgramExecutable.h: Collects the information and interfaces common to both Programs and
7 // ProgramPipelines in order to execute/draw with either.
8 
9 #ifndef LIBANGLE_PROGRAMEXECUTABLE_H_
10 #define LIBANGLE_PROGRAMEXECUTABLE_H_
11 
12 #include "common/BinaryStream.h"
13 #include "libANGLE/Caps.h"
14 #include "libANGLE/InfoLog.h"
15 #include "libANGLE/ProgramLinkedResources.h"
16 #include "libANGLE/Shader.h"
17 #include "libANGLE/Uniform.h"
18 #include "libANGLE/VaryingPacking.h"
19 #include "libANGLE/angletypes.h"
20 
21 namespace rx
22 {
23 class GLImplFactory;
24 class LinkSubTask;
25 class ProgramExecutableImpl;
26 }  // namespace rx
27 
28 namespace gl
29 {
30 
31 // This small structure encapsulates binding sampler uniforms to active GL textures.
32 ANGLE_ENABLE_STRUCT_PADDING_WARNINGS
33 struct SamplerBinding
34 {
35     SamplerBinding() = default;
SamplerBindingSamplerBinding36     SamplerBinding(TextureType textureTypeIn,
37                    GLenum samplerTypeIn,
38                    SamplerFormat formatIn,
39                    uint16_t startIndex,
40                    uint16_t elementCount)
41         : textureType(textureTypeIn),
42           format(formatIn),
43           textureUnitsStartIndex(startIndex),
44           textureUnitsCount(elementCount)
45     {
46         SetBitField(samplerType, samplerTypeIn);
47     }
48 
getTextureUnitSamplerBinding49     GLuint getTextureUnit(const std::vector<GLuint> &boundTextureUnits,
50                           unsigned int arrayIndex) const
51     {
52         return boundTextureUnits[textureUnitsStartIndex + arrayIndex];
53     }
54 
55     // Necessary for retrieving active textures from the GL state.
56     TextureType textureType;
57     SamplerFormat format;
58     uint16_t samplerType;
59     // [textureUnitsStartIndex, textureUnitsStartIndex+textureUnitsCount) Points to the subset in
60     // mSamplerBoundTextureUnits that stores the texture unit bound to this sampler. Cropped by the
61     // amount of unused elements reported by the driver.
62     uint16_t textureUnitsStartIndex;
63     uint16_t textureUnitsCount;
64 };
65 ANGLE_DISABLE_STRUCT_PADDING_WARNINGS
66 
67 struct ImageBinding
68 {
69     ImageBinding() = default;
ImageBindingImageBinding70     ImageBinding(size_t count, TextureType textureTypeIn)
71         : textureType(textureTypeIn), boundImageUnits(count, 0)
72     {}
73     ImageBinding(GLuint imageUnit, size_t count, TextureType textureTypeIn);
74 
75     // Necessary for distinguishing between textures with images and texture buffers.
76     TextureType textureType;
77 
78     // List of all textures bound.
79     // Cropped by the amount of unused elements reported by the driver.
80     std::vector<GLuint> boundImageUnits;
81 };
82 
83 ANGLE_ENABLE_STRUCT_PADDING_WARNINGS
84 struct ProgramInput
85 {
86     ProgramInput() = default;
87     ProgramInput(const sh::ShaderVariable &var);
88 
getTypeProgramInput89     GLenum getType() const { return pod.type; }
isBuiltInProgramInput90     bool isBuiltIn() const { return pod.flagBits.isBuiltIn; }
isArrayProgramInput91     bool isArray() const { return pod.flagBits.isArray; }
isActiveProgramInput92     bool isActive() const { return pod.flagBits.active; }
isPatchProgramInput93     bool isPatch() const { return pod.flagBits.isPatch; }
getLocationProgramInput94     int getLocation() const { return pod.location; }
getBasicTypeElementCountProgramInput95     unsigned int getBasicTypeElementCount() const { return pod.basicTypeElementCount; }
getArraySizeProductProgramInput96     unsigned int getArraySizeProduct() const { return pod.arraySizeProduct; }
getIdProgramInput97     uint32_t getId() const { return pod.id; }
getInterpolationProgramInput98     sh::InterpolationType getInterpolation() const
99     {
100         return static_cast<sh::InterpolationType>(pod.interpolation);
101     }
102 
setLocationProgramInput103     void setLocation(int location) { pod.location = location; }
resetEffectiveLocationProgramInput104     void resetEffectiveLocation()
105     {
106         if (pod.flagBits.hasImplicitLocation)
107         {
108             pod.location = -1;
109         }
110     }
111 
112     std::string name;
113     std::string mappedName;
114 
115     // The struct bellow must only contain data of basic type so that entire struct can memcpy-able.
116     struct PODStruct
117     {
118         uint16_t type;  // GLenum
119         uint16_t arraySizeProduct;
120 
121         int location;
122 
123         uint8_t interpolation;  // sh::InterpolationType
124         union
125         {
126             struct
127             {
128                 uint8_t active : 1;
129                 uint8_t isPatch : 1;
130                 uint8_t hasImplicitLocation : 1;
131                 uint8_t isArray : 1;
132                 uint8_t isBuiltIn : 1;
133                 uint8_t padding : 3;
134             } flagBits;
135             uint8_t flagBitsAsUByte;
136         };
137         int16_t basicTypeElementCount;
138 
139         uint32_t id;
140     } pod;
141 };
142 ANGLE_DISABLE_STRUCT_PADDING_WARNINGS
143 
144 ANGLE_ENABLE_STRUCT_PADDING_WARNINGS
145 struct ProgramOutput
146 {
147     ProgramOutput() = default;
148     ProgramOutput(const sh::ShaderVariable &var);
isBuiltInProgramOutput149     bool isBuiltIn() const { return pod.isBuiltIn; }
isArrayProgramOutput150     bool isArray() const { return pod.isArray; }
getLocationProgramOutput151     int getLocation() const { return pod.location; }
getOutermostArraySizeProgramOutput152     unsigned int getOutermostArraySize() const { return pod.outermostArraySize; }
resetEffectiveLocationProgramOutput153     void resetEffectiveLocation()
154     {
155         if (pod.hasImplicitLocation)
156         {
157             pod.location = -1;
158         }
159     }
160 
161     std::string name;
162     std::string mappedName;
163 
164     struct PODStruct
165     {
166         GLenum type;
167         int location;
168         int index;
169         uint32_t id;
170 
171         uint16_t outermostArraySize;
172         uint16_t basicTypeElementCount;
173 
174         uint32_t isPatch : 1;
175         uint32_t yuv : 1;
176         uint32_t isBuiltIn : 1;
177         uint32_t isArray : 1;
178         uint32_t hasImplicitLocation : 1;
179         uint32_t hasShaderAssignedLocation : 1;
180         uint32_t hasApiAssignedLocation : 1;
181         uint32_t pad : 25;
182     } pod;
183 };
184 ANGLE_DISABLE_STRUCT_PADDING_WARNINGS
185 
186 // A varying with transform feedback enabled. If it's an array, either the whole array or one of its
187 // elements specified by 'arrayIndex' can set to be enabled.
188 struct TransformFeedbackVarying : public sh::ShaderVariable
189 {
190     TransformFeedbackVarying() = default;
191 
TransformFeedbackVaryingTransformFeedbackVarying192     TransformFeedbackVarying(const sh::ShaderVariable &varyingIn, GLuint arrayIndexIn)
193         : sh::ShaderVariable(varyingIn), arrayIndex(arrayIndexIn)
194     {
195         ASSERT(!isArrayOfArrays());
196     }
197 
TransformFeedbackVaryingTransformFeedbackVarying198     TransformFeedbackVarying(const sh::ShaderVariable &field, const sh::ShaderVariable &parent)
199         : arrayIndex(GL_INVALID_INDEX)
200     {
201         sh::ShaderVariable *thisVar = this;
202         *thisVar                    = field;
203         interpolation               = parent.interpolation;
204         isInvariant                 = parent.isInvariant;
205         ASSERT(parent.isShaderIOBlock || !parent.name.empty());
206         if (!parent.name.empty())
207         {
208             name       = parent.name + "." + name;
209             mappedName = parent.mappedName + "." + mappedName;
210         }
211         structOrBlockName       = parent.structOrBlockName;
212         mappedStructOrBlockName = parent.mappedStructOrBlockName;
213     }
214 
nameWithArrayIndexTransformFeedbackVarying215     std::string nameWithArrayIndex() const
216     {
217         std::stringstream fullNameStr;
218         fullNameStr << name;
219         if (arrayIndex != GL_INVALID_INDEX)
220         {
221             fullNameStr << "[" << arrayIndex << "]";
222         }
223         return fullNameStr.str();
224     }
sizeTransformFeedbackVarying225     GLsizei size() const
226     {
227         return (isArray() && arrayIndex == GL_INVALID_INDEX ? getOutermostArraySize() : 1);
228     }
229 
230     GLuint arrayIndex;
231 };
232 
233 class ProgramState;
234 class ProgramPipelineState;
235 
236 class ProgramExecutable;
237 using SharedProgramExecutable = std::shared_ptr<ProgramExecutable>;
238 
239 class ProgramExecutable final : public angle::Subject
240 {
241   public:
242     ProgramExecutable(rx::GLImplFactory *factory, InfoLog *infoLog);
243     ~ProgramExecutable() override;
244 
245     void destroy(const Context *context);
246 
getImplementation()247     ANGLE_INLINE rx::ProgramExecutableImpl *getImplementation() const { return mImplementation; }
248 
249     void save(gl::BinaryOutputStream *stream) const;
250     void load(gl::BinaryInputStream *stream);
251 
getInfoLog()252     InfoLog &getInfoLog() const { return *mInfoLog; }
253     std::string getInfoLogString() const;
resetInfoLog()254     void resetInfoLog() const { mInfoLog->reset(); }
255 
resetLinkedShaderStages()256     void resetLinkedShaderStages() { mPod.linkedShaderStages.reset(); }
getLinkedShaderStages()257     const ShaderBitSet getLinkedShaderStages() const { return mPod.linkedShaderStages; }
setLinkedShaderStages(ShaderType shaderType)258     void setLinkedShaderStages(ShaderType shaderType)
259     {
260         mPod.linkedShaderStages.set(shaderType);
261         updateCanDrawWith();
262     }
hasLinkedShaderStage(ShaderType shaderType)263     bool hasLinkedShaderStage(ShaderType shaderType) const
264     {
265         ASSERT(shaderType != ShaderType::InvalidEnum);
266         return mPod.linkedShaderStages[shaderType];
267     }
getLinkedShaderStageCount()268     size_t getLinkedShaderStageCount() const { return mPod.linkedShaderStages.count(); }
hasLinkedGraphicsShader()269     bool hasLinkedGraphicsShader() const
270     {
271         return mPod.linkedShaderStages.any() &&
272                mPod.linkedShaderStages != gl::ShaderBitSet{gl::ShaderType::Compute};
273     }
hasLinkedTessellationShader()274     bool hasLinkedTessellationShader() const
275     {
276         return mPod.linkedShaderStages[ShaderType::TessEvaluation];
277     }
278     ShaderType getFirstLinkedShaderStageType() const;
279     ShaderType getLastLinkedShaderStageType() const;
280 
getLinkedTransformFeedbackStage()281     ShaderType getLinkedTransformFeedbackStage() const
282     {
283         return GetLastPreFragmentStage(mPod.linkedShaderStages);
284     }
285 
getActiveAttribLocationsMask()286     const AttributesMask &getActiveAttribLocationsMask() const
287     {
288         return mPod.activeAttribLocationsMask;
289     }
isAttribLocationActive(size_t attribLocation)290     bool isAttribLocationActive(size_t attribLocation) const
291     {
292         ASSERT(attribLocation < mPod.activeAttribLocationsMask.size());
293         return mPod.activeAttribLocationsMask[attribLocation];
294     }
295 
getNonBuiltinAttribLocationsMask()296     AttributesMask getNonBuiltinAttribLocationsMask() const { return mPod.attributesMask; }
getMaxActiveAttribLocation()297     unsigned int getMaxActiveAttribLocation() const { return mPod.maxActiveAttribLocation; }
getAttributesTypeMask()298     ComponentTypeMask getAttributesTypeMask() const { return mPod.attributesTypeMask; }
getAttributesMask()299     AttributesMask getAttributesMask() const { return mPod.attributesMask; }
300 
getActiveSamplersMask()301     const ActiveTextureMask &getActiveSamplersMask() const { return mActiveSamplersMask; }
setActiveTextureMask(ActiveTextureMask mask)302     void setActiveTextureMask(ActiveTextureMask mask) { mActiveSamplersMask = mask; }
getSamplerFormatForTextureUnitIndex(size_t textureUnitIndex)303     SamplerFormat getSamplerFormatForTextureUnitIndex(size_t textureUnitIndex) const
304     {
305         return mActiveSamplerFormats[textureUnitIndex];
306     }
getSamplerShaderBitsForTextureUnitIndex(size_t textureUnitIndex)307     const ShaderBitSet getSamplerShaderBitsForTextureUnitIndex(size_t textureUnitIndex) const
308     {
309         return mActiveSamplerShaderBits[textureUnitIndex];
310     }
getActiveImagesMask()311     const ActiveTextureMask &getActiveImagesMask() const { return mActiveImagesMask; }
setActiveImagesMask(ActiveTextureMask mask)312     void setActiveImagesMask(ActiveTextureMask mask) { mActiveImagesMask = mask; }
getActiveImageShaderBits()313     const ActiveTextureArray<ShaderBitSet> &getActiveImageShaderBits() const
314     {
315         return mActiveImageShaderBits;
316     }
317 
getActiveYUVSamplers()318     const ActiveTextureMask &getActiveYUVSamplers() const { return mActiveSamplerYUV; }
319 
getActiveSamplerTypes()320     const ActiveTextureArray<TextureType> &getActiveSamplerTypes() const
321     {
322         return mActiveSamplerTypes;
323     }
324 
325     void setActive(size_t textureUnit,
326                    const SamplerBinding &samplerBinding,
327                    const gl::LinkedUniform &samplerUniform);
328     void setInactive(size_t textureUnit);
329     void hasSamplerTypeConflict(size_t textureUnit);
330     void hasSamplerFormatConflict(size_t textureUnit);
331 
332     void updateActiveSamplers(const ProgramExecutable &executable);
333 
hasDefaultUniforms()334     bool hasDefaultUniforms() const { return !getDefaultUniformRange().empty(); }
hasTextures()335     bool hasTextures() const { return !getSamplerBindings().empty(); }
hasUniformBuffers()336     bool hasUniformBuffers() const { return !mUniformBlocks.empty(); }
hasStorageBuffers()337     bool hasStorageBuffers() const { return !mShaderStorageBlocks.empty(); }
hasAtomicCounterBuffers()338     bool hasAtomicCounterBuffers() const { return !mAtomicCounterBuffers.empty(); }
hasImages()339     bool hasImages() const { return !mImageBindings.empty(); }
hasTransformFeedbackOutput()340     bool hasTransformFeedbackOutput() const
341     {
342         return !getLinkedTransformFeedbackVaryings().empty();
343     }
usesColorFramebufferFetch()344     bool usesColorFramebufferFetch() const { return mPod.fragmentInoutIndices.any(); }
usesDepthFramebufferFetch()345     bool usesDepthFramebufferFetch() const { return mPod.hasDepthInputAttachment; }
usesStencilFramebufferFetch()346     bool usesStencilFramebufferFetch() const { return mPod.hasStencilInputAttachment; }
347 
348     // Count the number of uniform and storage buffer declarations, counting arrays as one.
getTransformFeedbackBufferCount()349     size_t getTransformFeedbackBufferCount() const { return mTransformFeedbackStrides.size(); }
350 
updateCanDrawWith()351     void updateCanDrawWith() { mPod.canDrawWith = hasLinkedShaderStage(ShaderType::Vertex); }
hasVertexShader()352     bool hasVertexShader() const { return mPod.canDrawWith; }
353 
getProgramInputs()354     const std::vector<ProgramInput> &getProgramInputs() const { return mProgramInputs; }
getOutputVariables()355     const std::vector<ProgramOutput> &getOutputVariables() const { return mOutputVariables; }
getOutputLocations()356     const std::vector<VariableLocation> &getOutputLocations() const { return mOutputLocations; }
getSecondaryOutputLocations()357     const std::vector<VariableLocation> &getSecondaryOutputLocations() const
358     {
359         return mSecondaryOutputLocations;
360     }
getUniforms()361     const std::vector<LinkedUniform> &getUniforms() const { return mUniforms; }
getUniformNames()362     const std::vector<std::string> &getUniformNames() const { return mUniformNames; }
getUniformMappedNames()363     const std::vector<std::string> &getUniformMappedNames() const { return mUniformMappedNames; }
getUniformBlocks()364     const std::vector<InterfaceBlock> &getUniformBlocks() const { return mUniformBlocks; }
getUniformLocations()365     const std::vector<VariableLocation> &getUniformLocations() const { return mUniformLocations; }
getSamplerBindings()366     const std::vector<SamplerBinding> &getSamplerBindings() const { return mSamplerBindings; }
getSamplerBoundTextureUnits()367     const std::vector<GLuint> &getSamplerBoundTextureUnits() const
368     {
369         return mSamplerBoundTextureUnits;
370     }
getImageBindings()371     const std::vector<ImageBinding> &getImageBindings() const { return mImageBindings; }
getPixelLocalStorageFormats()372     const std::vector<ShPixelLocalStorageFormat> &getPixelLocalStorageFormats() const
373     {
374         return mPixelLocalStorageFormats;
375     }
getImageBindings()376     std::vector<ImageBinding> *getImageBindings() { return &mImageBindings; }
getDefaultUniformRange()377     const RangeUI &getDefaultUniformRange() const { return mPod.defaultUniformRange; }
getSamplerUniformRange()378     const RangeUI &getSamplerUniformRange() const { return mPod.samplerUniformRange; }
getImageUniformRange()379     const RangeUI &getImageUniformRange() const { return mPod.imageUniformRange; }
getAtomicCounterUniformRange()380     const RangeUI &getAtomicCounterUniformRange() const { return mPod.atomicCounterUniformRange; }
getFragmentInoutIndices()381     DrawBufferMask getFragmentInoutIndices() const { return mPod.fragmentInoutIndices; }
hasClipDistance()382     bool hasClipDistance() const { return mPod.hasClipDistance; }
hasDiscard()383     bool hasDiscard() const { return mPod.hasDiscard; }
hasDepthInputAttachment()384     bool hasDepthInputAttachment() const { return mPod.hasDepthInputAttachment; }
hasStencilInputAttachment()385     bool hasStencilInputAttachment() const { return mPod.hasStencilInputAttachment; }
enablesPerSampleShading()386     bool enablesPerSampleShading() const { return mPod.enablesPerSampleShading; }
getAdvancedBlendEquations()387     BlendEquationBitSet getAdvancedBlendEquations() const { return mPod.advancedBlendEquations; }
getLinkedTransformFeedbackVaryings()388     const std::vector<TransformFeedbackVarying> &getLinkedTransformFeedbackVaryings() const
389     {
390         return mLinkedTransformFeedbackVaryings;
391     }
getTransformFeedbackBufferMode()392     GLint getTransformFeedbackBufferMode() const { return mPod.transformFeedbackBufferMode; }
getComputeShaderLocalSize()393     const sh::WorkGroupSize &getComputeShaderLocalSize() const
394     {
395         return mPod.computeShaderLocalSize;
396     }
397     void remapUniformBlockBinding(UniformBlockIndex uniformBlockIndex, GLuint uniformBlockBinding);
getUniformBlockBinding(size_t uniformBlockIndex)398     GLuint getUniformBlockBinding(size_t uniformBlockIndex) const
399     {
400         ASSERT(uniformBlockIndex < mUniformBlocks.size());
401 
402         // Unlike SSBOs and atomic counter buffers, GLES allows UBOs bindings to be remapped.  Note
403         // that desktop GL allows SSBO bindings to also be remapped, but that's not allowed in GLES.
404         //
405         // It's therefore important to never directly reference block.pod.inShaderBinding unless the
406         // specific shader-specified binding is required.
407         return mUniformBlockIndexToBufferBinding[uniformBlockIndex];
408     }
getShaderStorageBlockBinding(size_t blockIndex)409     GLuint getShaderStorageBlockBinding(size_t blockIndex) const
410     {
411         ASSERT(blockIndex < mShaderStorageBlocks.size());
412         // The buffer binding for SSBOs is the one specified in the shader
413         return mShaderStorageBlocks[blockIndex].pod.inShaderBinding;
414     }
getAtomicCounterBufferBinding(size_t blockIndex)415     GLuint getAtomicCounterBufferBinding(size_t blockIndex) const
416     {
417         ASSERT(blockIndex < mAtomicCounterBuffers.size());
418         // The buffer binding for atomic counter buffers is the one specified in the shader
419         return mAtomicCounterBuffers[blockIndex].pod.inShaderBinding;
420     }
getUniformBlockByIndex(size_t index)421     const InterfaceBlock &getUniformBlockByIndex(size_t index) const
422     {
423         ASSERT(index < mUniformBlocks.size());
424         return mUniformBlocks[index];
425     }
getShaderStorageBlockByIndex(size_t index)426     const InterfaceBlock &getShaderStorageBlockByIndex(size_t index) const
427     {
428         ASSERT(index < mShaderStorageBlocks.size());
429         return mShaderStorageBlocks[index];
430     }
getBufferVariableByIndex(size_t index)431     const BufferVariable &getBufferVariableByIndex(size_t index) const
432     {
433         ASSERT(index < mBufferVariables.size());
434         return mBufferVariables[index];
435     }
getTransformFeedbackStrides()436     const std::vector<GLsizei> &getTransformFeedbackStrides() const
437     {
438         return mTransformFeedbackStrides;
439     }
getAtomicCounterBuffers()440     const std::vector<AtomicCounterBuffer> &getAtomicCounterBuffers() const
441     {
442         return mAtomicCounterBuffers;
443     }
getShaderStorageBlocks()444     const std::vector<InterfaceBlock> &getShaderStorageBlocks() const
445     {
446         return mShaderStorageBlocks;
447     }
getBufferVariables()448     const std::vector<BufferVariable> &getBufferVariables() const { return mBufferVariables; }
getUniformByIndex(size_t index)449     const LinkedUniform &getUniformByIndex(size_t index) const
450     {
451         ASSERT(index < static_cast<size_t>(mUniforms.size()));
452         return mUniforms[index];
453     }
getUniformNameByIndex(size_t index)454     const std::string &getUniformNameByIndex(size_t index) const
455     {
456         ASSERT(index < static_cast<size_t>(mUniforms.size()));
457         return mUniformNames[index];
458     }
459 
getUniformIndexFromImageIndex(size_t imageIndex)460     GLuint getUniformIndexFromImageIndex(size_t imageIndex) const
461     {
462         ASSERT(imageIndex < mPod.imageUniformRange.length());
463         return static_cast<GLuint>(imageIndex) + mPod.imageUniformRange.low();
464     }
465 
getUniformIndexFromSamplerIndex(size_t samplerIndex)466     GLuint getUniformIndexFromSamplerIndex(size_t samplerIndex) const
467     {
468         ASSERT(samplerIndex < mPod.samplerUniformRange.length());
469         return static_cast<GLuint>(samplerIndex) + mPod.samplerUniformRange.low();
470     }
471 
472     void saveLinkedStateInfo(const ProgramState &state);
getLinkedOutputVaryings(ShaderType shaderType)473     const std::vector<sh::ShaderVariable> &getLinkedOutputVaryings(ShaderType shaderType) const
474     {
475         return mLinkedOutputVaryings[shaderType];
476     }
getLinkedInputVaryings(ShaderType shaderType)477     const std::vector<sh::ShaderVariable> &getLinkedInputVaryings(ShaderType shaderType) const
478     {
479         return mLinkedInputVaryings[shaderType];
480     }
481 
getLinkedUniforms(ShaderType shaderType)482     const std::vector<sh::ShaderVariable> &getLinkedUniforms(ShaderType shaderType) const
483     {
484         return mLinkedUniforms[shaderType];
485     }
486 
getLinkedUniformBlocks(ShaderType shaderType)487     const std::vector<sh::InterfaceBlock> &getLinkedUniformBlocks(ShaderType shaderType) const
488     {
489         return mLinkedUniformBlocks[shaderType];
490     }
491 
getLinkedShaderVersion(ShaderType shaderType)492     int getLinkedShaderVersion(ShaderType shaderType) const
493     {
494         return mPod.linkedShaderVersions[shaderType];
495     }
496 
isYUVOutput()497     bool isYUVOutput() const { return mPod.hasYUVOutput; }
498 
getGeometryShaderInputPrimitiveType()499     PrimitiveMode getGeometryShaderInputPrimitiveType() const
500     {
501         return mPod.geometryShaderInputPrimitiveType;
502     }
503 
getGeometryShaderOutputPrimitiveType()504     PrimitiveMode getGeometryShaderOutputPrimitiveType() const
505     {
506         return mPod.geometryShaderOutputPrimitiveType;
507     }
508 
getGeometryShaderInvocations()509     int getGeometryShaderInvocations() const { return mPod.geometryShaderInvocations; }
510 
getGeometryShaderMaxVertices()511     int getGeometryShaderMaxVertices() const { return mPod.geometryShaderMaxVertices; }
512 
getTessControlShaderVertices()513     GLint getTessControlShaderVertices() const { return mPod.tessControlShaderVertices; }
getTessGenMode()514     GLenum getTessGenMode() const { return mPod.tessGenMode; }
getTessGenPointMode()515     GLenum getTessGenPointMode() const { return mPod.tessGenPointMode; }
getTessGenSpacing()516     GLenum getTessGenSpacing() const { return mPod.tessGenSpacing; }
getTessGenVertexOrder()517     GLenum getTessGenVertexOrder() const { return mPod.tessGenVertexOrder; }
518 
getNumViews()519     int getNumViews() const { return mPod.numViews; }
usesMultiview()520     bool usesMultiview() const { return mPod.numViews != -1; }
521 
getSpecConstUsageBits()522     rx::SpecConstUsageBits getSpecConstUsageBits() const { return mPod.specConstUsageBits; }
523 
getDrawIDLocation()524     int getDrawIDLocation() const { return mPod.drawIDLocation; }
getBaseVertexLocation()525     int getBaseVertexLocation() const { return mPod.baseVertexLocation; }
getBaseInstanceLocation()526     int getBaseInstanceLocation() const { return mPod.baseInstanceLocation; }
527 
hasDrawIDUniform()528     bool hasDrawIDUniform() const { return getDrawIDLocation() >= 0; }
hasBaseVertexUniform()529     bool hasBaseVertexUniform() const { return getBaseVertexLocation() >= 0; }
hasBaseInstanceUniform()530     bool hasBaseInstanceUniform() const { return getBaseInstanceLocation() >= 0; }
531 
resetCachedValidateSamplersResult()532     void resetCachedValidateSamplersResult() { mCachedValidateSamplersResult.reset(); }
validateSamplers(const Caps & caps)533     bool validateSamplers(const Caps &caps) const
534     {
535         // Use the cache if:
536         // - we aren't using an info log (which gives the full error).
537         // - The sample mapping hasn't changed and we've already validated.
538         if (mCachedValidateSamplersResult.valid())
539         {
540             return mCachedValidateSamplersResult.value();
541         }
542 
543         return validateSamplersImpl(caps);
544     }
545 
getFragmentOutputsTypeMask()546     ComponentTypeMask getFragmentOutputsTypeMask() const { return mPod.drawBufferTypeMask; }
getActiveOutputVariablesMask()547     DrawBufferMask getActiveOutputVariablesMask() const { return mPod.activeOutputVariablesMask; }
getActiveSecondaryOutputVariablesMask()548     DrawBufferMask getActiveSecondaryOutputVariablesMask() const
549     {
550         return mPod.activeSecondaryOutputVariablesMask;
551     }
552 
553     GLuint getInputResourceIndex(const GLchar *name) const;
554     GLuint getOutputResourceIndex(const GLchar *name) const;
555     void getInputResourceName(GLuint index, GLsizei bufSize, GLsizei *length, GLchar *name) const;
556     void getOutputResourceName(GLuint index, GLsizei bufSize, GLsizei *length, GLchar *name) const;
557     void getUniformResourceName(GLuint index, GLsizei bufSize, GLsizei *length, GLchar *name) const;
558     void getBufferVariableResourceName(GLuint index,
559                                        GLsizei bufSize,
560                                        GLsizei *length,
561                                        GLchar *name) const;
getInputResource(size_t index)562     const ProgramInput &getInputResource(size_t index) const
563     {
564         ASSERT(index < mProgramInputs.size());
565         return mProgramInputs[index];
566     }
567     GLuint getInputResourceMaxNameSize() const;
568     GLuint getOutputResourceMaxNameSize() const;
569     GLuint getInputResourceLocation(const GLchar *name) const;
570     GLuint getOutputResourceLocation(const GLchar *name) const;
571     const std::string getInputResourceName(GLuint index) const;
572     const std::string getOutputResourceName(GLuint index) const;
getOutputResource(size_t index)573     const gl::ProgramOutput &getOutputResource(size_t index) const
574     {
575         ASSERT(index < mOutputVariables.size());
576         return mOutputVariables[index];
577     }
578 
579     GLint getFragDataLocation(const std::string &name) const;
580 
581     // EXT_blend_func_extended
582     GLint getFragDataIndex(const std::string &name) const;
583 
584     GLsizei getTransformFeedbackVaryingMaxLength() const;
585     GLuint getTransformFeedbackVaryingResourceIndex(const GLchar *name) const;
586     const TransformFeedbackVarying &getTransformFeedbackVaryingResource(GLuint index) const;
587     void getTransformFeedbackVarying(GLuint index,
588                                      GLsizei bufSize,
589                                      GLsizei *length,
590                                      GLsizei *size,
591                                      GLenum *type,
592                                      GLchar *name) const;
593 
594     void getActiveAttribute(GLuint index,
595                             GLsizei bufsize,
596                             GLsizei *length,
597                             GLint *size,
598                             GLenum *type,
599                             GLchar *name) const;
600     GLint getActiveAttributeMaxLength() const;
601     GLuint getAttributeLocation(const std::string &name) const;
602 
603     void getActiveUniform(GLuint index,
604                           GLsizei bufsize,
605                           GLsizei *length,
606                           GLint *size,
607                           GLenum *type,
608                           GLchar *name) const;
609     GLint getActiveUniformMaxLength() const;
610     bool isValidUniformLocation(UniformLocation location) const;
611     const LinkedUniform &getUniformByLocation(UniformLocation location) const;
612     const VariableLocation &getUniformLocation(UniformLocation location) const;
613     UniformLocation getUniformLocation(const std::string &name) const;
614     GLuint getUniformIndex(const std::string &name) const;
615 
616     void getActiveUniformBlockName(const Context *context,
617                                    const UniformBlockIndex blockIndex,
618                                    GLsizei bufSize,
619                                    GLsizei *length,
620                                    GLchar *blockName) const;
621     void getActiveShaderStorageBlockName(const GLuint blockIndex,
622                                          GLsizei bufSize,
623                                          GLsizei *length,
624                                          GLchar *blockName) const;
625 
626     GLint getActiveUniformBlockMaxNameLength() const;
627     GLint getActiveShaderStorageBlockMaxNameLength() const;
628 
629     GLuint getUniformBlockIndex(const std::string &name) const;
630     GLuint getShaderStorageBlockIndex(const std::string &name) const;
631 
632     GLuint getUniformIndexFromName(const std::string &name) const;
633     GLuint getUniformIndexFromLocation(UniformLocation location) const;
634     Optional<GLuint> getSamplerIndex(UniformLocation location) const;
635     bool isSamplerUniformIndex(GLuint index) const;
636     GLuint getSamplerIndexFromUniformIndex(GLuint uniformIndex) const;
637     bool isImageUniformIndex(GLuint index) const;
638     GLuint getImageIndexFromUniformIndex(GLuint uniformIndex) const;
639     GLuint getBufferVariableIndexFromName(const std::string &name) const;
640 
641     bool linkUniforms(const Caps &caps,
642                       const ShaderMap<std::vector<sh::ShaderVariable>> &shaderUniforms,
643                       const ProgramAliasedBindings &uniformLocationBindings,
644                       GLuint *combinedImageUniformsCount,
645                       std::vector<UnusedUniform> *unusedUniforms);
646 
647     void copyInputsFromProgram(const ProgramExecutable &executable);
648     void copyUniformBuffersFromProgram(const ProgramExecutable &executable,
649                                        ShaderType shaderType,
650                                        ProgramUniformBlockArray<GLuint> *ppoUniformBlockMap);
651     void copyStorageBuffersFromProgram(const ProgramExecutable &executable, ShaderType shaderType);
652     void clearSamplerBindings();
653     void copySamplerBindingsFromProgram(const ProgramExecutable &executable);
654     void copyImageBindingsFromProgram(const ProgramExecutable &executable);
655     void copyOutputsFromProgram(const ProgramExecutable &executable);
656     void copyUniformsFromProgramMap(const ShaderMap<SharedProgramExecutable> &executables);
657 
658     void setUniform1fv(UniformLocation location, GLsizei count, const GLfloat *v);
659     void setUniform2fv(UniformLocation location, GLsizei count, const GLfloat *v);
660     void setUniform3fv(UniformLocation location, GLsizei count, const GLfloat *v);
661     void setUniform4fv(UniformLocation location, GLsizei count, const GLfloat *v);
662     void setUniform1iv(Context *context, UniformLocation location, GLsizei count, const GLint *v);
663     void setUniform2iv(UniformLocation location, GLsizei count, const GLint *v);
664     void setUniform3iv(UniformLocation location, GLsizei count, const GLint *v);
665     void setUniform4iv(UniformLocation location, GLsizei count, const GLint *v);
666     void setUniform1uiv(UniformLocation location, GLsizei count, const GLuint *v);
667     void setUniform2uiv(UniformLocation location, GLsizei count, const GLuint *v);
668     void setUniform3uiv(UniformLocation location, GLsizei count, const GLuint *v);
669     void setUniform4uiv(UniformLocation location, GLsizei count, const GLuint *v);
670     void setUniformMatrix2fv(UniformLocation location,
671                              GLsizei count,
672                              GLboolean transpose,
673                              const GLfloat *value);
674     void setUniformMatrix3fv(UniformLocation location,
675                              GLsizei count,
676                              GLboolean transpose,
677                              const GLfloat *value);
678     void setUniformMatrix4fv(UniformLocation location,
679                              GLsizei count,
680                              GLboolean transpose,
681                              const GLfloat *value);
682     void setUniformMatrix2x3fv(UniformLocation location,
683                                GLsizei count,
684                                GLboolean transpose,
685                                const GLfloat *value);
686     void setUniformMatrix3x2fv(UniformLocation location,
687                                GLsizei count,
688                                GLboolean transpose,
689                                const GLfloat *value);
690     void setUniformMatrix2x4fv(UniformLocation location,
691                                GLsizei count,
692                                GLboolean transpose,
693                                const GLfloat *value);
694     void setUniformMatrix4x2fv(UniformLocation location,
695                                GLsizei count,
696                                GLboolean transpose,
697                                const GLfloat *value);
698     void setUniformMatrix3x4fv(UniformLocation location,
699                                GLsizei count,
700                                GLboolean transpose,
701                                const GLfloat *value);
702     void setUniformMatrix4x3fv(UniformLocation location,
703                                GLsizei count,
704                                GLboolean transpose,
705                                const GLfloat *value);
706 
707     void getUniformfv(const Context *context, UniformLocation location, GLfloat *params) const;
708     void getUniformiv(const Context *context, UniformLocation location, GLint *params) const;
709     void getUniformuiv(const Context *context, UniformLocation location, GLuint *params) const;
710 
711     void setDrawIDUniform(GLint drawid);
712     void setBaseVertexUniform(GLint baseVertex);
713     void setBaseInstanceUniform(GLuint baseInstance);
714 
getUniformBufferBlocksMappedToBinding(size_t uniformBufferIndex)715     ProgramUniformBlockMask getUniformBufferBlocksMappedToBinding(size_t uniformBufferIndex)
716     {
717         return mUniformBufferBindingToUniformBlocks[uniformBufferIndex];
718     }
719 
getUniformBlockIndexToBufferBindingForCapture()720     const ProgramUniformBlockArray<GLuint> &getUniformBlockIndexToBufferBindingForCapture() const
721     {
722         return mUniformBlockIndexToBufferBinding;
723     }
724 
getPPOProgramExecutables()725     const ShaderMap<SharedProgramExecutable> &getPPOProgramExecutables() const
726     {
727         return mPPOProgramExecutables;
728     }
729 
IsPPO()730     bool IsPPO() const { return mIsPPO; }
731 
732     // Post-link task helpers
getPostLinkSubTasks()733     const std::vector<std::shared_ptr<rx::LinkSubTask>> &getPostLinkSubTasks() const
734     {
735         return mPostLinkSubTasks;
736     }
737 
getPostLinkSubTaskWaitableEvents()738     const std::vector<std::shared_ptr<angle::WaitableEvent>> &getPostLinkSubTaskWaitableEvents()
739         const
740     {
741         return mPostLinkSubTaskWaitableEvents;
742     }
743 
onPostLinkTasksComplete()744     void onPostLinkTasksComplete() const
745     {
746         mPostLinkSubTasks.clear();
747         mPostLinkSubTaskWaitableEvents.clear();
748     }
749 
750     void waitForPostLinkTasks(const Context *context);
751 
752   private:
753     friend class Program;
754     friend class ProgramPipeline;
755     friend class ProgramState;
756     friend class ProgramPipelineState;
757 
758     void reset();
759 
760     void updateActiveImages(const ProgramExecutable &executable);
761 
762     bool linkMergedVaryings(const Caps &caps,
763                             const Limitations &limitations,
764                             const Version &clientVersion,
765                             bool webglCompatibility,
766                             const ProgramMergedVaryings &mergedVaryings,
767                             const LinkingVariables &linkingVariables,
768                             ProgramVaryingPacking *varyingPacking);
769 
770     bool linkValidateTransformFeedback(const Caps &caps,
771                                        const Version &clientVersion,
772                                        const ProgramMergedVaryings &varyings,
773                                        ShaderType stage);
774 
775     void gatherTransformFeedbackVaryings(const ProgramMergedVaryings &varyings, ShaderType stage);
776 
777     void updateTransformFeedbackStrides();
778 
779     bool validateSamplersImpl(const Caps &caps) const;
780 
781     bool linkValidateOutputVariables(const Caps &caps,
782                                      const Version &version,
783                                      GLuint combinedImageUniformsCount,
784                                      GLuint combinedShaderStorageBlocksCount,
785                                      int fragmentShaderVersion,
786                                      const ProgramAliasedBindings &fragmentOutputLocations,
787                                      const ProgramAliasedBindings &fragmentOutputIndices);
788 
789     bool gatherOutputTypes();
790 
791     void linkSamplerAndImageBindings(GLuint *combinedImageUniformsCount);
792     bool linkAtomicCounterBuffers(const Caps &caps);
793 
794     void getResourceName(const std::string name,
795                          GLsizei bufSize,
796                          GLsizei *length,
797                          GLchar *dest) const;
798     bool shouldIgnoreUniform(UniformLocation location) const;
799     GLuint getSamplerUniformBinding(const VariableLocation &uniformLocation) const;
800     GLuint getImageUniformBinding(const VariableLocation &uniformLocation) const;
801 
802     void initInterfaceBlockBindings();
803     void setUniformValuesFromBindingQualifiers();
804 
805     // Both these function update the cached uniform values and return a modified "count"
806     // so that the uniform update doesn't overflow the uniform.
807     template <typename T>
808     GLsizei clampUniformCount(const VariableLocation &locationInfo,
809                               GLsizei count,
810                               int vectorSize,
811                               const T *v);
812     template <size_t cols, size_t rows, typename T>
813     GLsizei clampMatrixUniformCount(UniformLocation location,
814                                     GLsizei count,
815                                     GLboolean transpose,
816                                     const T *v);
817 
818     void updateSamplerUniform(Context *context,
819                               const VariableLocation &locationInfo,
820                               GLsizei clampedCount,
821                               const GLint *v);
822 
823     // Scans the sampler bindings for type conflicts with sampler 'textureUnitIndex'.
824     void setSamplerUniformTextureTypeAndFormat(size_t textureUnitIndex);
825 
826     template <typename DestT>
827     void getUniformInternal(const Context *context,
828                             DestT *dataOut,
829                             UniformLocation location,
830                             GLenum nativeType,
831                             int components) const;
832 
833     template <typename UniformT,
834               GLint UniformSize,
835               void (rx::ProgramExecutableImpl::*SetUniformFunc)(GLint, GLsizei, const UniformT *)>
836     void setUniformGeneric(UniformLocation location, GLsizei count, const UniformT *v);
837 
838     template <typename UniformT,
839               GLint MatrixC,
840               GLint MatrixR,
841               void (rx::ProgramExecutableImpl::*
842                         SetUniformMatrixFunc)(GLint, GLsizei, GLboolean, const UniformT *)>
843     void setUniformMatrixGeneric(UniformLocation location,
844                                  GLsizei count,
845                                  GLboolean transpose,
846                                  const UniformT *v);
847 
848     rx::ProgramExecutableImpl *mImplementation;
849 
850     // A reference to the owning object's (Program or ProgramPipeline) info log.  It's kept here for
851     // convenience as numerous functions reference it.
852     InfoLog *mInfoLog;
853 
854     ANGLE_ENABLE_STRUCT_PADDING_WARNINGS
855     struct PODStruct
856     {
857         // 8 bytes each
858         angle::BitSet<MAX_VERTEX_ATTRIBS> activeAttribLocationsMask;
859         ComponentTypeMask attributesTypeMask;
860         // attributesMask is identical to mActiveAttribLocationsMask with built-in attributes
861         // removed.
862         AttributesMask attributesMask;
863         ComponentTypeMask drawBufferTypeMask;
864 
865         // 4 bytes each
866         uint32_t maxActiveAttribLocation;
867         // KHR_blend_equation_advanced supported equation list
868         BlendEquationBitSet advancedBlendEquations;
869 
870         // 1 byte each
871         ShaderBitSet linkedShaderStages;
872         DrawBufferMask activeOutputVariablesMask;
873         DrawBufferMask activeSecondaryOutputVariablesMask;
874         uint8_t hasClipDistance : 1;
875         uint8_t hasDiscard : 1;
876         uint8_t hasYUVOutput : 1;
877         uint8_t hasDepthInputAttachment : 1;
878         uint8_t hasStencilInputAttachment : 1;
879         uint8_t enablesPerSampleShading : 1;
880         uint8_t canDrawWith : 1;
881         uint8_t isSeparable : 1;
882 
883         // 12 bytes
884         sh::WorkGroupSize computeShaderLocalSize;
885 
886         // 8 bytes each
887         RangeUI defaultUniformRange;
888         RangeUI samplerUniformRange;
889         RangeUI imageUniformRange;
890         RangeUI atomicCounterUniformRange;
891 
892         // 1 byte.  Bitset of which input attachments have been declared
893         DrawBufferMask fragmentInoutIndices;
894 
895         // GL_EXT_geometry_shader.
896         uint8_t pad0;
897         PrimitiveMode geometryShaderInputPrimitiveType;
898         PrimitiveMode geometryShaderOutputPrimitiveType;
899         int32_t geometryShaderInvocations;
900         int32_t geometryShaderMaxVertices;
901         GLenum transformFeedbackBufferMode;
902 
903         // 4 bytes each. GL_OVR_multiview / GL_OVR_multiview2
904         int32_t numViews;
905         // GL_ANGLE_multi_draw
906         int32_t drawIDLocation;
907 
908         // GL_ANGLE_base_vertex_base_instance_shader_builtin
909         int32_t baseVertexLocation;
910         int32_t baseInstanceLocation;
911 
912         // GL_EXT_tessellation_shader
913         int32_t tessControlShaderVertices;
914         GLenum tessGenMode;
915         GLenum tessGenSpacing;
916         GLenum tessGenVertexOrder;
917         GLenum tessGenPointMode;
918 
919         // 4 bytes
920         rx::SpecConstUsageBits specConstUsageBits;
921 
922         // 24 bytes
923         ShaderMap<int> linkedShaderVersions;
924     } mPod;
925     ANGLE_DISABLE_STRUCT_PADDING_WARNINGS
926 
927     // Cached mask of active samplers and sampler types.
928     ActiveTextureMask mActiveSamplersMask;
929     ActiveTextureArray<uint32_t> mActiveSamplerRefCounts;
930     ActiveTextureArray<TextureType> mActiveSamplerTypes;
931     ActiveTextureMask mActiveSamplerYUV;
932     ActiveTextureArray<SamplerFormat> mActiveSamplerFormats;
933     ActiveTextureArray<ShaderBitSet> mActiveSamplerShaderBits;
934 
935     // Cached mask of active images.
936     ActiveTextureMask mActiveImagesMask;
937     ActiveTextureArray<ShaderBitSet> mActiveImageShaderBits;
938 
939     // Names and mapped names of output variables that are arrays include [0] in the end, similarly
940     // to uniforms.
941     std::vector<ProgramOutput> mOutputVariables;
942     std::vector<VariableLocation> mOutputLocations;
943     // EXT_blend_func_extended secondary outputs (ones with index 1)
944     std::vector<VariableLocation> mSecondaryOutputLocations;
945     // Vertex attributes, Fragment input varyings, etc.
946     std::vector<ProgramInput> mProgramInputs;
947     std::vector<TransformFeedbackVarying> mLinkedTransformFeedbackVaryings;
948     // Duplicate of ProgramState::mTransformFeedbackVaryingNames.  This is cached here because the
949     // xfb names may change, relink may fail, yet program pipeline link should be able to function
950     // with the last installed executable.  In truth, program pipeline link should have been able to
951     // hoist transform feedback varyings directly from the executable, among most other things, but
952     // that is currently not done.
953     //
954     // This array is not serialized, it's already done by the program, and will be duplicated during
955     // deserialization.
956     std::vector<std::string> mTransformFeedbackVaryingNames;
957     // The size of the data written to each transform feedback buffer per vertex.
958     std::vector<GLsizei> mTransformFeedbackStrides;
959     // Uniforms are sorted in order:
960     //  1. Non-opaque uniforms
961     //  2. Sampler uniforms
962     //  3. Image uniforms
963     //  4. Atomic counter uniforms
964     //  5. Uniform block uniforms
965     // This makes opaque uniform validation easier, since we don't need a separate list.
966     // For generating the entries and naming them we follow the spec: GLES 3.1 November 2016 section
967     // 7.3.1.1 Naming Active Resources. There's a separate entry for each struct member and each
968     // inner array of an array of arrays. Names and mapped names of uniforms that are arrays include
969     // [0] in the end. This makes implementation of queries simpler.
970     std::vector<LinkedUniform> mUniforms;
971     std::vector<std::string> mUniformNames;
972     // Only used by GL and D3D backend
973     std::vector<std::string> mUniformMappedNames;
974     std::vector<InterfaceBlock> mUniformBlocks;
975     std::vector<VariableLocation> mUniformLocations;
976 
977     std::vector<AtomicCounterBuffer> mAtomicCounterBuffers;
978     std::vector<InterfaceBlock> mShaderStorageBlocks;
979     std::vector<BufferVariable> mBufferVariables;
980 
981     // An array of the samplers that are used by the program
982     std::vector<SamplerBinding> mSamplerBindings;
983     // List of all textures bound to all samplers. Each SamplerBinding will point to a subset in
984     // this vector.
985     std::vector<GLuint> mSamplerBoundTextureUnits;
986 
987     // An array of the images that are used by the program
988     std::vector<ImageBinding> mImageBindings;
989 
990     // ANGLE_shader_pixel_local_storage: A mapping from binding index to the PLS uniform format at
991     // that index.
992     std::vector<ShPixelLocalStorageFormat> mPixelLocalStorageFormats;
993 
994     ShaderMap<std::vector<sh::ShaderVariable>> mLinkedOutputVaryings;
995     ShaderMap<std::vector<sh::ShaderVariable>> mLinkedInputVaryings;
996     ShaderMap<std::vector<sh::ShaderVariable>> mLinkedUniforms;
997     ShaderMap<std::vector<sh::InterfaceBlock>> mLinkedUniformBlocks;
998 
999     // Cached value of base vertex and base instance
1000     // need to reset them to zero if using non base vertex or base instance draw calls.
1001     GLint mCachedBaseVertex;
1002     GLuint mCachedBaseInstance;
1003 
1004     // GLES allows uniform block indices in the program to be remapped to arbitrary buffer bindings
1005     // through calls to glUniformBlockBinding.  (Desktop GL also includes
1006     // glShaderStorageBlockBinding, which does not exist in GLES).
1007     // This is not a part of the link results, and must be reset on glProgramBinary, so it's not
1008     // serialized.
1009     // A map from the program uniform block index to the buffer binding it is mapped to.
1010     ProgramUniformBlockArray<GLuint> mUniformBlockIndexToBufferBinding;
1011     // The reverse of the above map, i.e. from buffer bindings to the uniform blocks that are mapped
1012     // to it.  For example, if the program's uniform blocks 1, 3 and 4 are mapped to buffer binding
1013     // 2, then mUniformBufferBindingToUniformBlocks[2] will be {1, 3, 4}.
1014     //
1015     // This is used to efficiently mark uniform blocks dirty when a buffer bound to a binding has
1016     // been modified.
1017     UniformBufferBindingArray<ProgramUniformBlockMask> mUniformBufferBindingToUniformBlocks;
1018 
1019     // PPO only: installed executables from the programs.  Note that these may be different from the
1020     // programs' current executables, because they may have been unsuccessfully relinked.
1021     ShaderMap<SharedProgramExecutable> mPPOProgramExecutables;
1022     // Flag for an easy check for PPO without inspecting mPPOProgramExecutables
1023     bool mIsPPO;
1024 
1025     // Cache for sampler validation
1026     mutable Optional<bool> mCachedValidateSamplersResult;
1027 
1028     // Post-link subtask and wait events
1029     // These tasks are not waited on in |resolveLink|, but instead they are free to
1030     // run until first usage of the program (or relink).  This is used by the backends (currently
1031     // only Vulkan) to run post-link optimization tasks which don't affect the link results.
1032     mutable std::vector<std::shared_ptr<rx::LinkSubTask>> mPostLinkSubTasks;
1033     mutable std::vector<std::shared_ptr<angle::WaitableEvent>> mPostLinkSubTaskWaitableEvents;
1034 };
1035 
1036 void InstallExecutable(const Context *context,
1037                        const SharedProgramExecutable &toInstall,
1038                        SharedProgramExecutable *executable);
1039 void UninstallExecutable(const Context *context, SharedProgramExecutable *executable);
1040 }  // namespace gl
1041 
1042 #endif  // LIBANGLE_PROGRAMEXECUTABLE_H_
1043