1 //
2 // Copyright 2014 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 // ProgramD3D.h: Defines the rx::ProgramD3D class which implements rx::ProgramImpl.
8 
9 #ifndef LIBANGLE_RENDERER_D3D_PROGRAMD3D_H_
10 #define LIBANGLE_RENDERER_D3D_PROGRAMD3D_H_
11 
12 #include <string>
13 #include <vector>
14 
15 #include "compiler/translator/blocklayoutHLSL.h"
16 #include "libANGLE/Constants.h"
17 #include "libANGLE/formatutils.h"
18 #include "libANGLE/renderer/ProgramImpl.h"
19 #include "libANGLE/renderer/d3d/DynamicHLSL.h"
20 #include "libANGLE/renderer/d3d/RendererD3D.h"
21 #include "platform/FeaturesD3D.h"
22 
23 namespace rx
24 {
25 class RendererD3D;
26 class UniformStorageD3D;
27 class ShaderExecutableD3D;
28 
29 #if !defined(ANGLE_COMPILE_OPTIMIZATION_LEVEL)
30 // WARNING: D3DCOMPILE_OPTIMIZATION_LEVEL3 may lead to a DX9 shader compiler hang.
31 // It should only be used selectively to work around specific bugs.
32 #    define ANGLE_COMPILE_OPTIMIZATION_LEVEL D3DCOMPILE_OPTIMIZATION_LEVEL1
33 #endif
34 
35 enum class HLSLRegisterType : uint8_t
36 {
37     None                = 0,
38     Texture             = 1,
39     UnorderedAccessView = 2
40 };
41 
42 // Helper struct representing a single shader uniform
43 // TODO(jmadill): Make uniform blocks shared between all programs, so we don't need separate
44 // register indices.
45 struct D3DUniform : private angle::NonCopyable
46 {
47     D3DUniform(GLenum type,
48                HLSLRegisterType reg,
49                const std::string &nameIn,
50                const std::vector<unsigned int> &arraySizesIn,
51                bool defaultBlock);
52     ~D3DUniform();
53 
54     bool isSampler() const;
55     bool isImage() const;
56     bool isImage2D() const;
isArrayD3DUniform57     bool isArray() const { return !arraySizes.empty(); }
58     unsigned int getArraySizeProduct() const;
59     bool isReferencedByShader(gl::ShaderType shaderType) const;
60 
61     const uint8_t *firstNonNullData() const;
62     const uint8_t *getDataPtrToElement(size_t elementIndex) const;
63 
64     // Duplicated from the GL layer
65     const gl::UniformTypeInfo &typeInfo;
66     std::string name;  // Names of arrays don't include [0], unlike at the GL layer.
67     std::vector<unsigned int> arraySizes;
68 
69     // Pointer to a system copies of the data. Separate pointers for each uniform storage type.
70     gl::ShaderMap<uint8_t *> mShaderData;
71 
72     // Register information.
73     HLSLRegisterType regType;
74     gl::ShaderMap<unsigned int> mShaderRegisterIndexes;
75     unsigned int registerCount;
76 
77     // Register "elements" are used for uniform structs in ES3, to appropriately identify single
78     // uniforms
79     // inside aggregate types, which are packed according C-like structure rules.
80     unsigned int registerElement;
81 
82     // Special buffer for sampler values.
83     std::vector<GLint> mSamplerData;
84 };
85 
86 struct D3DInterfaceBlock
87 {
88     D3DInterfaceBlock();
89     D3DInterfaceBlock(const D3DInterfaceBlock &other);
90 
activeInShaderD3DInterfaceBlock91     bool activeInShader(gl::ShaderType shaderType) const
92     {
93         return mShaderRegisterIndexes[shaderType] != GL_INVALID_INDEX;
94     }
95 
96     gl::ShaderMap<unsigned int> mShaderRegisterIndexes;
97 };
98 
99 struct D3DUniformBlock : D3DInterfaceBlock
100 {
101     D3DUniformBlock();
102     D3DUniformBlock(const D3DUniformBlock &other);
103 
104     gl::ShaderMap<bool> mUseStructuredBuffers;
105     gl::ShaderMap<unsigned int> mByteWidths;
106     gl::ShaderMap<unsigned int> mStructureByteStrides;
107 };
108 
109 struct D3DUBOCache
110 {
111     unsigned int registerIndex;
112     int binding;
113 };
114 
115 struct D3DUBOCacheUseSB : D3DUBOCache
116 {
117     unsigned int byteWidth;
118     unsigned int structureByteStride;
119 };
120 
121 struct D3DVarying final
122 {
123     D3DVarying();
124     D3DVarying(const std::string &semanticNameIn,
125                unsigned int semanticIndexIn,
126                unsigned int componentCountIn,
127                unsigned int outputSlotIn);
128 
129     D3DVarying(const D3DVarying &) = default;
130     D3DVarying &operator=(const D3DVarying &) = default;
131 
132     std::string semanticName;
133     unsigned int semanticIndex;
134     unsigned int componentCount;
135     unsigned int outputSlot;
136 };
137 
138 class ProgramD3DMetadata final : angle::NonCopyable
139 {
140   public:
141     ProgramD3DMetadata(RendererD3D *renderer,
142                        const gl::ShaderMap<const ShaderD3D *> &attachedShaders,
143                        EGLenum clientType);
144     ~ProgramD3DMetadata();
145 
146     int getRendererMajorShaderModel() const;
147     bool usesBroadcast(const gl::State &data) const;
148     bool usesSecondaryColor() const;
149     bool usesFragDepth() const;
150     bool usesPointCoord() const;
151     bool usesFragCoord() const;
152     bool usesPointSize() const;
153     bool usesInsertedPointCoordValue() const;
154     bool usesViewScale() const;
155     bool hasANGLEMultiviewEnabled() const;
156     bool usesVertexID() const;
157     bool usesViewID() const;
158     bool canSelectViewInVertexShader() const;
159     bool addsPointCoordToVertexShader() const;
160     bool usesTransformFeedbackGLPosition() const;
161     bool usesSystemValuePointSize() const;
162     bool usesMultipleFragmentOuts() const;
163     bool usesCustomOutVars() const;
164     const ShaderD3D *getFragmentShader() const;
165 
166   private:
167     const int mRendererMajorShaderModel;
168     const std::string mShaderModelSuffix;
169     const bool mUsesInstancedPointSpriteEmulation;
170     const bool mUsesViewScale;
171     const bool mCanSelectViewInVertexShader;
172     const gl::ShaderMap<const ShaderD3D *> mAttachedShaders;
173     const EGLenum mClientType;
174 };
175 
176 using D3DUniformMap = std::map<std::string, D3DUniform *>;
177 
178 class ProgramD3D : public ProgramImpl
179 {
180   public:
181     ProgramD3D(const gl::ProgramState &data, RendererD3D *renderer);
182     ~ProgramD3D() override;
183 
getPixelShaderKey()184     const std::vector<PixelShaderOutputVariable> &getPixelShaderKey() { return mPixelShaderKey; }
185 
186     GLint getSamplerMapping(gl::ShaderType type,
187                             unsigned int samplerIndex,
188                             const gl::Caps &caps) const;
189     gl::TextureType getSamplerTextureType(gl::ShaderType type, unsigned int samplerIndex) const;
190     gl::RangeUI getUsedSamplerRange(gl::ShaderType type) const;
191 
192     enum SamplerMapping
193     {
194         WasDirty,
195         WasClean,
196     };
197 
198     SamplerMapping updateSamplerMapping();
199 
200     GLint getImageMapping(gl::ShaderType type,
201                           unsigned int imageIndex,
202                           bool readonly,
203                           const gl::Caps &caps) const;
204     gl::RangeUI getUsedImageRange(gl::ShaderType type, bool readonly) const;
205 
usesPointSize()206     bool usesPointSize() const { return mUsesPointSize; }
207     bool usesPointSpriteEmulation() const;
208     bool usesGeometryShader(const gl::State &state, gl::PrimitiveMode drawMode) const;
209     bool usesGeometryShaderForPointSpriteEmulation() const;
210     bool usesGetDimensionsIgnoresBaseLevel() const;
211     bool usesInstancedPointSpriteEmulation() const;
212 
213     std::unique_ptr<LinkEvent> load(const gl::Context *context,
214                                     gl::BinaryInputStream *stream,
215                                     gl::InfoLog &infoLog) override;
216     void save(const gl::Context *context, gl::BinaryOutputStream *stream) override;
217     void setBinaryRetrievableHint(bool retrievable) override;
218     void setSeparable(bool separable) override;
219 
220     angle::Result getVertexExecutableForCachedInputLayout(d3d::Context *context,
221                                                           ShaderExecutableD3D **outExectuable,
222                                                           gl::InfoLog *infoLog);
223     angle::Result getGeometryExecutableForPrimitiveType(d3d::Context *errContext,
224                                                         const gl::State &state,
225                                                         gl::PrimitiveMode drawMode,
226                                                         ShaderExecutableD3D **outExecutable,
227                                                         gl::InfoLog *infoLog);
228     angle::Result getPixelExecutableForCachedOutputLayout(d3d::Context *context,
229                                                           ShaderExecutableD3D **outExectuable,
230                                                           gl::InfoLog *infoLog);
231     angle::Result getComputeExecutableForImage2DBindLayout(d3d::Context *context,
232                                                            ShaderExecutableD3D **outExecutable,
233                                                            gl::InfoLog *infoLog);
234     std::unique_ptr<LinkEvent> link(const gl::Context *context,
235                                     const gl::ProgramLinkedResources &resources,
236                                     gl::InfoLog &infoLog,
237                                     const gl::ProgramMergedVaryings &mergedVaryings) override;
238     GLboolean validate(const gl::Caps &caps, gl::InfoLog *infoLog) override;
239 
240     void updateUniformBufferCache(const gl::Caps &caps);
241 
242     unsigned int getAtomicCounterBufferRegisterIndex(GLuint binding,
243                                                      gl::ShaderType shaderType) const;
244 
245     unsigned int getShaderStorageBufferRegisterIndex(GLuint blockIndex,
246                                                      gl::ShaderType shaderType) const;
247     const std::vector<D3DUBOCache> &getShaderUniformBufferCache(gl::ShaderType shaderType) const;
248     const std::vector<D3DUBOCacheUseSB> &getShaderUniformBufferCacheUseSB(
249         gl::ShaderType shaderType) const;
250 
251     void dirtyAllUniforms();
252 
253     void setUniform1fv(GLint location, GLsizei count, const GLfloat *v) override;
254     void setUniform2fv(GLint location, GLsizei count, const GLfloat *v) override;
255     void setUniform3fv(GLint location, GLsizei count, const GLfloat *v) override;
256     void setUniform4fv(GLint location, GLsizei count, const GLfloat *v) override;
257     void setUniform1iv(GLint location, GLsizei count, const GLint *v) override;
258     void setUniform2iv(GLint location, GLsizei count, const GLint *v) override;
259     void setUniform3iv(GLint location, GLsizei count, const GLint *v) override;
260     void setUniform4iv(GLint location, GLsizei count, const GLint *v) override;
261     void setUniform1uiv(GLint location, GLsizei count, const GLuint *v) override;
262     void setUniform2uiv(GLint location, GLsizei count, const GLuint *v) override;
263     void setUniform3uiv(GLint location, GLsizei count, const GLuint *v) override;
264     void setUniform4uiv(GLint location, GLsizei count, const GLuint *v) override;
265     void setUniformMatrix2fv(GLint location,
266                              GLsizei count,
267                              GLboolean transpose,
268                              const GLfloat *value) override;
269     void setUniformMatrix3fv(GLint location,
270                              GLsizei count,
271                              GLboolean transpose,
272                              const GLfloat *value) override;
273     void setUniformMatrix4fv(GLint location,
274                              GLsizei count,
275                              GLboolean transpose,
276                              const GLfloat *value) override;
277     void setUniformMatrix2x3fv(GLint location,
278                                GLsizei count,
279                                GLboolean transpose,
280                                const GLfloat *value) override;
281     void setUniformMatrix3x2fv(GLint location,
282                                GLsizei count,
283                                GLboolean transpose,
284                                const GLfloat *value) override;
285     void setUniformMatrix2x4fv(GLint location,
286                                GLsizei count,
287                                GLboolean transpose,
288                                const GLfloat *value) override;
289     void setUniformMatrix4x2fv(GLint location,
290                                GLsizei count,
291                                GLboolean transpose,
292                                const GLfloat *value) override;
293     void setUniformMatrix3x4fv(GLint location,
294                                GLsizei count,
295                                GLboolean transpose,
296                                const GLfloat *value) override;
297     void setUniformMatrix4x3fv(GLint location,
298                                GLsizei count,
299                                GLboolean transpose,
300                                const GLfloat *value) override;
301 
302     void getUniformfv(const gl::Context *context, GLint location, GLfloat *params) const override;
303     void getUniformiv(const gl::Context *context, GLint location, GLint *params) const override;
304     void getUniformuiv(const gl::Context *context, GLint location, GLuint *params) const override;
305 
getShaderUniformStorage(gl::ShaderType shaderType)306     UniformStorageD3D *getShaderUniformStorage(gl::ShaderType shaderType) const
307     {
308         return mShaderUniformStorages[shaderType].get();
309     }
310 
311     unsigned int getSerial() const;
312 
getAttribLocationToD3DSemantics()313     const AttribIndexArray &getAttribLocationToD3DSemantics() const
314     {
315         return mAttribLocationToD3DSemantic;
316     }
317 
318     void updateCachedInputLayout(Serial associatedSerial, const gl::State &state);
319     void updateCachedOutputLayout(const gl::Context *context, const gl::Framebuffer *framebuffer);
320     void updateCachedComputeImage2DBindLayout(const gl::Context *context);
321 
isSamplerMappingDirty()322     bool isSamplerMappingDirty() { return mDirtySamplerMapping; }
323 
324     // Checks if we need to recompile certain shaders.
325     bool hasVertexExecutableForCachedInputLayout();
326     bool hasGeometryExecutableForPrimitiveType(const gl::State &state, gl::PrimitiveMode drawMode);
327     bool hasPixelExecutableForCachedOutputLayout();
328     bool hasComputeExecutableForCachedImage2DBindLayout();
329 
anyShaderUniformsDirty()330     bool anyShaderUniformsDirty() const { return mShaderUniformsDirty.any(); }
331 
areShaderUniformsDirty(gl::ShaderType shaderType)332     bool areShaderUniformsDirty(gl::ShaderType shaderType) const
333     {
334         return mShaderUniformsDirty[shaderType];
335     }
getD3DUniforms()336     const std::vector<D3DUniform *> &getD3DUniforms() const { return mD3DUniforms; }
337     void markUniformsClean();
338 
getState()339     const gl::ProgramState &getState() const { return mState; }
340 
hasShaderStage(gl::ShaderType shaderType)341     bool hasShaderStage(gl::ShaderType shaderType) const
342     {
343         return mState.getExecutable().getLinkedShaderStages()[shaderType];
344     }
345 
346     void assignImage2DRegisters(unsigned int startImageIndex,
347                                 int startLogicalImageUnit,
348                                 bool readonly);
349     bool hasNamedUniform(const std::string &name);
350 
usesVertexID()351     bool usesVertexID() const { return mUsesVertexID; }
352 
353   private:
354     // These forward-declared tasks are used for multi-thread shader compiles.
355     class GetExecutableTask;
356     class GetVertexExecutableTask;
357     class GetPixelExecutableTask;
358     class GetGeometryExecutableTask;
359     class GetComputeExecutableTask;
360     class GraphicsProgramLinkEvent;
361     class ComputeProgramLinkEvent;
362 
363     class LoadBinaryTask;
364     class LoadBinaryLinkEvent;
365 
366     class VertexExecutable
367     {
368       public:
369         enum HLSLAttribType
370         {
371             FLOAT,
372             UNSIGNED_INT,
373             SIGNED_INT,
374         };
375 
376         typedef std::vector<HLSLAttribType> Signature;
377 
378         VertexExecutable(const gl::InputLayout &inputLayout,
379                          const Signature &signature,
380                          ShaderExecutableD3D *shaderExecutable);
381         ~VertexExecutable();
382 
383         bool matchesSignature(const Signature &signature) const;
384         static void getSignature(RendererD3D *renderer,
385                                  const gl::InputLayout &inputLayout,
386                                  Signature *signatureOut);
387 
inputs()388         const gl::InputLayout &inputs() const { return mInputs; }
signature()389         const Signature &signature() const { return mSignature; }
shaderExecutable()390         ShaderExecutableD3D *shaderExecutable() const { return mShaderExecutable; }
391 
392       private:
393         static HLSLAttribType GetAttribType(GLenum type);
394 
395         gl::InputLayout mInputs;
396         Signature mSignature;
397         ShaderExecutableD3D *mShaderExecutable;
398     };
399 
400     class PixelExecutable
401     {
402       public:
403         PixelExecutable(const std::vector<GLenum> &outputSignature,
404                         ShaderExecutableD3D *shaderExecutable);
405         ~PixelExecutable();
406 
matchesSignature(const std::vector<GLenum> & signature)407         bool matchesSignature(const std::vector<GLenum> &signature) const
408         {
409             return mOutputSignature == signature;
410         }
411 
outputSignature()412         const std::vector<GLenum> &outputSignature() const { return mOutputSignature; }
shaderExecutable()413         ShaderExecutableD3D *shaderExecutable() const { return mShaderExecutable; }
414 
415       private:
416         std::vector<GLenum> mOutputSignature;
417         ShaderExecutableD3D *mShaderExecutable;
418     };
419 
420     class ComputeExecutable
421     {
422       public:
423         ComputeExecutable(const gl::ImageUnitTextureTypeMap &signature,
424                           std::unique_ptr<ShaderExecutableD3D> shaderExecutable);
425         ~ComputeExecutable();
426 
matchesSignature(const gl::ImageUnitTextureTypeMap & signature)427         bool matchesSignature(const gl::ImageUnitTextureTypeMap &signature) const
428         {
429             return mSignature == signature;
430         }
431 
signature()432         const gl::ImageUnitTextureTypeMap &signature() const { return mSignature; }
shaderExecutable()433         ShaderExecutableD3D *shaderExecutable() const { return mShaderExecutable.get(); }
434 
435       private:
436         gl::ImageUnitTextureTypeMap mSignature;
437         std::unique_ptr<ShaderExecutableD3D> mShaderExecutable;
438     };
439 
440     struct Sampler
441     {
442         Sampler();
443 
444         bool active;
445         GLint logicalTextureUnit;
446         gl::TextureType textureType;
447     };
448 
449     struct Image
450     {
451         Image();
452         bool active;
453         GLint logicalImageUnit;
454     };
455 
456     void initializeUniformStorage(const gl::ShaderBitSet &availableShaderStages);
457 
458     void defineUniformsAndAssignRegisters();
459     void defineUniformBase(const gl::Shader *shader,
460                            const sh::ShaderVariable &uniform,
461                            D3DUniformMap *uniformMap);
462     void assignAllSamplerRegisters();
463     void assignSamplerRegisters(size_t uniformIndex);
464 
465     static void AssignSamplers(unsigned int startSamplerIndex,
466                                const gl::UniformTypeInfo &typeInfo,
467                                unsigned int samplerCount,
468                                std::vector<Sampler> &outSamplers,
469                                gl::RangeUI *outUsedRange);
470 
471     void assignAllImageRegisters();
472     void assignAllAtomicCounterRegisters();
473     void assignImageRegisters(size_t uniformIndex);
474     static void AssignImages(unsigned int startImageIndex,
475                              int startLogicalImageUnit,
476                              unsigned int imageCount,
477                              std::vector<Image> &outImages,
478                              gl::RangeUI *outUsedRange);
479 
480     template <typename DestT>
481     void getUniformInternal(GLint location, DestT *dataOut) const;
482 
483     template <typename T>
484     void setUniformImpl(D3DUniform *targetUniform,
485                         const gl::VariableLocation &locationInfo,
486                         GLsizei count,
487                         const T *v,
488                         uint8_t *targetData,
489                         GLenum uniformType);
490 
491     template <typename T>
492     void setUniformInternal(GLint location, GLsizei count, const T *v, GLenum uniformType);
493 
494     template <int cols, int rows>
495     void setUniformMatrixfvInternal(GLint location,
496                                     GLsizei count,
497                                     GLboolean transpose,
498                                     const GLfloat *value);
499 
500     std::unique_ptr<LinkEvent> compileProgramExecutables(const gl::Context *context,
501                                                          gl::InfoLog &infoLog);
502     std::unique_ptr<LinkEvent> compileComputeExecutable(const gl::Context *context,
503                                                         gl::InfoLog &infoLog);
504 
505     angle::Result loadBinaryShaderExecutables(d3d::Context *contextD3D,
506                                               gl::BinaryInputStream *stream,
507                                               gl::InfoLog &infoLog);
508 
509     void gatherTransformFeedbackVaryings(const gl::VaryingPacking &varyings,
510                                          const BuiltinInfo &builtins);
511     D3DUniform *getD3DUniformFromLocation(GLint location);
512     const D3DUniform *getD3DUniformFromLocation(GLint location) const;
513 
514     void initAttribLocationsToD3DSemantic();
515 
516     void reset();
517     void initializeUniformBlocks();
518     void initializeShaderStorageBlocks();
519 
520     void updateCachedInputLayoutFromShader();
521     void updateCachedOutputLayoutFromShader();
522     void updateCachedImage2DBindLayoutFromComputeShader();
523     void updateCachedVertexExecutableIndex();
524     void updateCachedPixelExecutableIndex();
525     void updateCachedComputeExecutableIndex();
526 
527     void linkResources(const gl::ProgramLinkedResources &resources);
528 
529     RendererD3D *mRenderer;
530     DynamicHLSL *mDynamicHLSL;
531 
532     std::vector<std::unique_ptr<VertexExecutable>> mVertexExecutables;
533     std::vector<std::unique_ptr<PixelExecutable>> mPixelExecutables;
534     angle::PackedEnumMap<gl::PrimitiveMode, std::unique_ptr<ShaderExecutableD3D>>
535         mGeometryExecutables;
536     std::vector<std::unique_ptr<ComputeExecutable>> mComputeExecutables;
537 
538     gl::ShaderMap<std::string> mShaderHLSL;
539     gl::ShaderMap<angle::CompilerWorkaroundsD3D> mShaderWorkarounds;
540 
541     bool mUsesFragDepth;
542     bool mHasANGLEMultiviewEnabled;
543     bool mUsesVertexID;
544     bool mUsesViewID;
545     std::vector<PixelShaderOutputVariable> mPixelShaderKey;
546 
547     // Common code for all dynamic geometry shaders. Consists mainly of the GS input and output
548     // structures, built from the linked varying info. We store the string itself instead of the
549     // packed varyings for simplicity.
550     std::string mGeometryShaderPreamble;
551 
552     bool mUsesPointSize;
553     bool mUsesFlatInterpolation;
554 
555     gl::ShaderMap<std::unique_ptr<UniformStorageD3D>> mShaderUniformStorages;
556 
557     gl::ShaderMap<std::vector<Sampler>> mShaderSamplers;
558     gl::ShaderMap<gl::RangeUI> mUsedShaderSamplerRanges;
559     bool mDirtySamplerMapping;
560 
561     std::vector<Image> mImagesCS;
562     std::vector<Image> mReadonlyImagesCS;
563     gl::RangeUI mUsedComputeImageRange;
564     gl::RangeUI mUsedComputeReadonlyImageRange;
565     gl::RangeUI mUsedComputeAtomicCounterRange;
566 
567     // Cache for pixel shader output layout to save reallocations.
568     std::vector<GLenum> mPixelShaderOutputLayoutCache;
569     Optional<size_t> mCachedPixelExecutableIndex;
570 
571     AttribIndexArray mAttribLocationToD3DSemantic;
572 
573     unsigned int mSerial;
574 
575     gl::ShaderMap<std::vector<D3DUBOCache>> mShaderUBOCaches;
576     gl::ShaderMap<std::vector<D3DUBOCacheUseSB>> mShaderUBOCachesUseSB;
577     VertexExecutable::Signature mCachedVertexSignature;
578     gl::InputLayout mCachedInputLayout;
579     Optional<size_t> mCachedVertexExecutableIndex;
580 
581     std::vector<D3DVarying> mStreamOutVaryings;
582     std::vector<D3DUniform *> mD3DUniforms;
583     std::map<std::string, int> mImageBindingMap;
584     std::map<std::string, int> mAtomicBindingMap;
585     std::vector<D3DUniformBlock> mD3DUniformBlocks;
586     std::vector<D3DInterfaceBlock> mD3DShaderStorageBlocks;
587     std::array<unsigned int, gl::IMPLEMENTATION_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS>
588         mComputeAtomicCounterBufferRegisterIndices;
589 
590     std::vector<sh::ShaderVariable> mImage2DUniforms;
591     gl::ImageUnitTextureTypeMap mComputeShaderImage2DBindLayoutCache;
592     Optional<size_t> mCachedComputeExecutableIndex;
593 
594     gl::ShaderBitSet mShaderUniformsDirty;
595 
596     static unsigned int issueSerial();
597     static unsigned int mCurrentSerial;
598 
599     Serial mCurrentVertexArrayStateSerial;
600 };
601 }  // namespace rx
602 
603 #endif  // LIBANGLE_RENDERER_D3D_PROGRAMD3D_H_
604