• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 ShaderStorageBlock
110 {
111     std::string name;
112     unsigned int arraySize     = 0;
113     unsigned int registerIndex = 0;
114 };
115 
116 struct D3DUBOCache
117 {
118     unsigned int registerIndex;
119     int binding;
120 };
121 
122 struct D3DUBOCacheUseSB : D3DUBOCache
123 {
124     unsigned int byteWidth;
125     unsigned int structureByteStride;
126 };
127 
128 struct D3DVarying final
129 {
130     D3DVarying();
131     D3DVarying(const std::string &semanticNameIn,
132                unsigned int semanticIndexIn,
133                unsigned int componentCountIn,
134                unsigned int outputSlotIn);
135 
136     D3DVarying(const D3DVarying &) = default;
137     D3DVarying &operator=(const D3DVarying &) = default;
138 
139     std::string semanticName;
140     unsigned int semanticIndex;
141     unsigned int componentCount;
142     unsigned int outputSlot;
143 };
144 
145 class ProgramD3DMetadata final : angle::NonCopyable
146 {
147   public:
148     ProgramD3DMetadata(RendererD3D *renderer,
149                        const gl::ShaderMap<const ShaderD3D *> &attachedShaders,
150                        EGLenum clientType);
151     ~ProgramD3DMetadata();
152 
153     int getRendererMajorShaderModel() const;
154     bool usesBroadcast(const gl::State &data) const;
155     bool usesSecondaryColor() const;
156     bool usesFragDepth() const;
157     bool usesPointCoord() const;
158     bool usesFragCoord() const;
159     bool usesPointSize() const;
160     bool usesInsertedPointCoordValue() const;
161     bool usesViewScale() const;
162     bool hasANGLEMultiviewEnabled() const;
163     bool usesVertexID() const;
164     bool usesViewID() const;
165     bool canSelectViewInVertexShader() const;
166     bool addsPointCoordToVertexShader() const;
167     bool usesTransformFeedbackGLPosition() const;
168     bool usesSystemValuePointSize() const;
169     bool usesMultipleFragmentOuts() const;
170     bool usesCustomOutVars() const;
171     const ShaderD3D *getFragmentShader() const;
172 
173   private:
174     const int mRendererMajorShaderModel;
175     const std::string mShaderModelSuffix;
176     const bool mUsesInstancedPointSpriteEmulation;
177     const bool mUsesViewScale;
178     const bool mCanSelectViewInVertexShader;
179     const gl::ShaderMap<const ShaderD3D *> mAttachedShaders;
180     const EGLenum mClientType;
181 };
182 
183 using D3DUniformMap = std::map<std::string, D3DUniform *>;
184 
185 class ProgramD3D : public ProgramImpl
186 {
187   public:
188     ProgramD3D(const gl::ProgramState &data, RendererD3D *renderer);
189     ~ProgramD3D() override;
190 
getPixelShaderKey()191     const std::vector<PixelShaderOutputVariable> &getPixelShaderKey() { return mPixelShaderKey; }
192 
193     GLint getSamplerMapping(gl::ShaderType type,
194                             unsigned int samplerIndex,
195                             const gl::Caps &caps) const;
196     gl::TextureType getSamplerTextureType(gl::ShaderType type, unsigned int samplerIndex) const;
197     gl::RangeUI getUsedSamplerRange(gl::ShaderType type) const;
198 
199     enum SamplerMapping
200     {
201         WasDirty,
202         WasClean,
203     };
204 
205     SamplerMapping updateSamplerMapping();
206 
207     GLint getImageMapping(gl::ShaderType type,
208                           unsigned int imageIndex,
209                           bool readonly,
210                           const gl::Caps &caps) const;
211     gl::RangeUI getUsedImageRange(gl::ShaderType type, bool readonly) const;
212 
usesPointSize()213     bool usesPointSize() const { return mUsesPointSize; }
214     bool usesPointSpriteEmulation() const;
215     bool usesGeometryShader(const gl::State &state, gl::PrimitiveMode drawMode) const;
216     bool usesGeometryShaderForPointSpriteEmulation() const;
217     bool usesGetDimensionsIgnoresBaseLevel() const;
218     bool usesInstancedPointSpriteEmulation() const;
219 
220     std::unique_ptr<LinkEvent> load(const gl::Context *context,
221                                     gl::BinaryInputStream *stream,
222                                     gl::InfoLog &infoLog) override;
223     void save(const gl::Context *context, gl::BinaryOutputStream *stream) override;
224     void setBinaryRetrievableHint(bool retrievable) override;
225     void setSeparable(bool separable) override;
226 
227     angle::Result getVertexExecutableForCachedInputLayout(d3d::Context *context,
228                                                           ShaderExecutableD3D **outExectuable,
229                                                           gl::InfoLog *infoLog);
230     angle::Result getGeometryExecutableForPrimitiveType(d3d::Context *errContext,
231                                                         const gl::State &state,
232                                                         gl::PrimitiveMode drawMode,
233                                                         ShaderExecutableD3D **outExecutable,
234                                                         gl::InfoLog *infoLog);
235     angle::Result getPixelExecutableForCachedOutputLayout(d3d::Context *context,
236                                                           ShaderExecutableD3D **outExectuable,
237                                                           gl::InfoLog *infoLog);
238     angle::Result getComputeExecutableForImage2DBindLayout(d3d::Context *context,
239                                                            ShaderExecutableD3D **outExecutable,
240                                                            gl::InfoLog *infoLog);
241     std::unique_ptr<LinkEvent> link(const gl::Context *context,
242                                     const gl::ProgramLinkedResources &resources,
243                                     gl::InfoLog &infoLog,
244                                     const gl::ProgramMergedVaryings &mergedVaryings) override;
245     GLboolean validate(const gl::Caps &caps, gl::InfoLog *infoLog) override;
246 
247     void updateUniformBufferCache(const gl::Caps &caps);
248 
249     unsigned int getAtomicCounterBufferRegisterIndex(GLuint binding,
250                                                      gl::ShaderType shaderType) const;
251 
252     unsigned int getShaderStorageBufferRegisterIndex(GLuint blockIndex,
253                                                      gl::ShaderType shaderType) const;
254     const std::vector<D3DUBOCache> &getShaderUniformBufferCache(gl::ShaderType shaderType) const;
255     const std::vector<D3DUBOCacheUseSB> &getShaderUniformBufferCacheUseSB(
256         gl::ShaderType shaderType) const;
257 
258     void dirtyAllUniforms();
259 
260     void setUniform1fv(GLint location, GLsizei count, const GLfloat *v) override;
261     void setUniform2fv(GLint location, GLsizei count, const GLfloat *v) override;
262     void setUniform3fv(GLint location, GLsizei count, const GLfloat *v) override;
263     void setUniform4fv(GLint location, GLsizei count, const GLfloat *v) override;
264     void setUniform1iv(GLint location, GLsizei count, const GLint *v) override;
265     void setUniform2iv(GLint location, GLsizei count, const GLint *v) override;
266     void setUniform3iv(GLint location, GLsizei count, const GLint *v) override;
267     void setUniform4iv(GLint location, GLsizei count, const GLint *v) override;
268     void setUniform1uiv(GLint location, GLsizei count, const GLuint *v) override;
269     void setUniform2uiv(GLint location, GLsizei count, const GLuint *v) override;
270     void setUniform3uiv(GLint location, GLsizei count, const GLuint *v) override;
271     void setUniform4uiv(GLint location, GLsizei count, const GLuint *v) override;
272     void setUniformMatrix2fv(GLint location,
273                              GLsizei count,
274                              GLboolean transpose,
275                              const GLfloat *value) override;
276     void setUniformMatrix3fv(GLint location,
277                              GLsizei count,
278                              GLboolean transpose,
279                              const GLfloat *value) override;
280     void setUniformMatrix4fv(GLint location,
281                              GLsizei count,
282                              GLboolean transpose,
283                              const GLfloat *value) override;
284     void setUniformMatrix2x3fv(GLint location,
285                                GLsizei count,
286                                GLboolean transpose,
287                                const GLfloat *value) override;
288     void setUniformMatrix3x2fv(GLint location,
289                                GLsizei count,
290                                GLboolean transpose,
291                                const GLfloat *value) override;
292     void setUniformMatrix2x4fv(GLint location,
293                                GLsizei count,
294                                GLboolean transpose,
295                                const GLfloat *value) override;
296     void setUniformMatrix4x2fv(GLint location,
297                                GLsizei count,
298                                GLboolean transpose,
299                                const GLfloat *value) override;
300     void setUniformMatrix3x4fv(GLint location,
301                                GLsizei count,
302                                GLboolean transpose,
303                                const GLfloat *value) override;
304     void setUniformMatrix4x3fv(GLint location,
305                                GLsizei count,
306                                GLboolean transpose,
307                                const GLfloat *value) override;
308 
309     void getUniformfv(const gl::Context *context, GLint location, GLfloat *params) const override;
310     void getUniformiv(const gl::Context *context, GLint location, GLint *params) const override;
311     void getUniformuiv(const gl::Context *context, GLint location, GLuint *params) const override;
312 
getShaderUniformStorage(gl::ShaderType shaderType)313     UniformStorageD3D *getShaderUniformStorage(gl::ShaderType shaderType) const
314     {
315         return mShaderUniformStorages[shaderType].get();
316     }
317 
318     unsigned int getSerial() const;
319 
getAttribLocationToD3DSemantics()320     const AttribIndexArray &getAttribLocationToD3DSemantics() const
321     {
322         return mAttribLocationToD3DSemantic;
323     }
324 
325     void updateCachedInputLayout(Serial associatedSerial, const gl::State &state);
326     void updateCachedOutputLayout(const gl::Context *context, const gl::Framebuffer *framebuffer);
327     void updateCachedComputeImage2DBindLayout(const gl::Context *context);
328 
isSamplerMappingDirty()329     bool isSamplerMappingDirty() { return mDirtySamplerMapping; }
330 
331     // Checks if we need to recompile certain shaders.
332     bool hasVertexExecutableForCachedInputLayout();
333     bool hasGeometryExecutableForPrimitiveType(const gl::State &state, gl::PrimitiveMode drawMode);
334     bool hasPixelExecutableForCachedOutputLayout();
335     bool hasComputeExecutableForCachedImage2DBindLayout();
336 
anyShaderUniformsDirty()337     bool anyShaderUniformsDirty() const { return mShaderUniformsDirty.any(); }
338 
areShaderUniformsDirty(gl::ShaderType shaderType)339     bool areShaderUniformsDirty(gl::ShaderType shaderType) const
340     {
341         return mShaderUniformsDirty[shaderType];
342     }
getD3DUniforms()343     const std::vector<D3DUniform *> &getD3DUniforms() const { return mD3DUniforms; }
344     void markUniformsClean();
345 
getState()346     const gl::ProgramState &getState() const { return mState; }
347 
hasShaderStage(gl::ShaderType shaderType)348     bool hasShaderStage(gl::ShaderType shaderType) const
349     {
350         return mState.getExecutable().getLinkedShaderStages()[shaderType];
351     }
352 
353     void assignImage2DRegisters(gl::ShaderType shaderType,
354                                 unsigned int startImageIndex,
355                                 int startLogicalImageUnit,
356                                 bool readonly);
357     bool hasNamedUniform(const std::string &name);
358 
usesVertexID()359     bool usesVertexID() const { return mUsesVertexID; }
360 
361   private:
362     // These forward-declared tasks are used for multi-thread shader compiles.
363     class GetExecutableTask;
364     class GetVertexExecutableTask;
365     class GetPixelExecutableTask;
366     class GetGeometryExecutableTask;
367     class GetComputeExecutableTask;
368     class GraphicsProgramLinkEvent;
369     class ComputeProgramLinkEvent;
370 
371     class LoadBinaryTask;
372     class LoadBinaryLinkEvent;
373 
374     class VertexExecutable
375     {
376       public:
377         enum HLSLAttribType
378         {
379             FLOAT,
380             UNSIGNED_INT,
381             SIGNED_INT,
382         };
383 
384         typedef std::vector<HLSLAttribType> Signature;
385 
386         VertexExecutable(const gl::InputLayout &inputLayout,
387                          const Signature &signature,
388                          ShaderExecutableD3D *shaderExecutable);
389         ~VertexExecutable();
390 
391         bool matchesSignature(const Signature &signature) const;
392         static void getSignature(RendererD3D *renderer,
393                                  const gl::InputLayout &inputLayout,
394                                  Signature *signatureOut);
395 
inputs()396         const gl::InputLayout &inputs() const { return mInputs; }
signature()397         const Signature &signature() const { return mSignature; }
shaderExecutable()398         ShaderExecutableD3D *shaderExecutable() const { return mShaderExecutable; }
399 
400       private:
401         static HLSLAttribType GetAttribType(GLenum type);
402 
403         gl::InputLayout mInputs;
404         Signature mSignature;
405         ShaderExecutableD3D *mShaderExecutable;
406     };
407 
408     class PixelExecutable
409     {
410       public:
411         PixelExecutable(const std::vector<GLenum> &outputSignature,
412                         ShaderExecutableD3D *shaderExecutable);
413         ~PixelExecutable();
414 
matchesSignature(const std::vector<GLenum> & signature)415         bool matchesSignature(const std::vector<GLenum> &signature) const
416         {
417             return mOutputSignature == signature;
418         }
419 
outputSignature()420         const std::vector<GLenum> &outputSignature() const { return mOutputSignature; }
shaderExecutable()421         ShaderExecutableD3D *shaderExecutable() const { return mShaderExecutable; }
422 
423       private:
424         std::vector<GLenum> mOutputSignature;
425         ShaderExecutableD3D *mShaderExecutable;
426     };
427 
428     class ComputeExecutable
429     {
430       public:
431         ComputeExecutable(const gl::ImageUnitTextureTypeMap &signature,
432                           std::unique_ptr<ShaderExecutableD3D> shaderExecutable);
433         ~ComputeExecutable();
434 
matchesSignature(const gl::ImageUnitTextureTypeMap & signature)435         bool matchesSignature(const gl::ImageUnitTextureTypeMap &signature) const
436         {
437             return mSignature == signature;
438         }
439 
signature()440         const gl::ImageUnitTextureTypeMap &signature() const { return mSignature; }
shaderExecutable()441         ShaderExecutableD3D *shaderExecutable() const { return mShaderExecutable.get(); }
442 
443       private:
444         gl::ImageUnitTextureTypeMap mSignature;
445         std::unique_ptr<ShaderExecutableD3D> mShaderExecutable;
446     };
447 
448     struct Sampler
449     {
450         Sampler();
451 
452         bool active;
453         GLint logicalTextureUnit;
454         gl::TextureType textureType;
455     };
456 
457     struct Image
458     {
459         Image();
460         bool active;
461         GLint logicalImageUnit;
462     };
463 
464     void initializeUniformStorage(const gl::ShaderBitSet &availableShaderStages);
465 
466     void defineUniformsAndAssignRegisters();
467     void defineUniformBase(const gl::Shader *shader,
468                            const sh::ShaderVariable &uniform,
469                            D3DUniformMap *uniformMap);
470     void assignAllSamplerRegisters();
471     void assignSamplerRegisters(size_t uniformIndex);
472 
473     static void AssignSamplers(unsigned int startSamplerIndex,
474                                const gl::UniformTypeInfo &typeInfo,
475                                unsigned int samplerCount,
476                                std::vector<Sampler> &outSamplers,
477                                gl::RangeUI *outUsedRange);
478 
479     void assignAllImageRegisters();
480     void assignAllAtomicCounterRegisters();
481     void assignImageRegisters(size_t uniformIndex);
482     static void AssignImages(unsigned int startImageIndex,
483                              int startLogicalImageUnit,
484                              unsigned int imageCount,
485                              std::vector<Image> &outImages,
486                              gl::RangeUI *outUsedRange);
487 
488     template <typename DestT>
489     void getUniformInternal(GLint location, DestT *dataOut) const;
490 
491     template <typename T>
492     void setUniformImpl(D3DUniform *targetUniform,
493                         const gl::VariableLocation &locationInfo,
494                         GLsizei count,
495                         const T *v,
496                         uint8_t *targetData,
497                         GLenum uniformType);
498 
499     template <typename T>
500     void setUniformInternal(GLint location, GLsizei count, const T *v, GLenum uniformType);
501 
502     template <int cols, int rows>
503     void setUniformMatrixfvInternal(GLint location,
504                                     GLsizei count,
505                                     GLboolean transpose,
506                                     const GLfloat *value);
507 
508     std::unique_ptr<LinkEvent> compileProgramExecutables(const gl::Context *context,
509                                                          gl::InfoLog &infoLog);
510     std::unique_ptr<LinkEvent> compileComputeExecutable(const gl::Context *context,
511                                                         gl::InfoLog &infoLog);
512 
513     angle::Result loadBinaryShaderExecutables(d3d::Context *contextD3D,
514                                               gl::BinaryInputStream *stream,
515                                               gl::InfoLog &infoLog);
516 
517     void gatherTransformFeedbackVaryings(const gl::VaryingPacking &varyings,
518                                          const BuiltinInfo &builtins);
519     D3DUniform *getD3DUniformFromLocation(GLint location);
520     const D3DUniform *getD3DUniformFromLocation(GLint location) const;
521 
522     void initAttribLocationsToD3DSemantic();
523 
524     void reset();
525     void initializeUniformBlocks();
526     void initializeShaderStorageBlocks();
527 
528     void updateCachedInputLayoutFromShader();
529     void updateCachedOutputLayoutFromShader();
530     void updateCachedImage2DBindLayoutFromShader(gl::ShaderType shaderType);
531     void updateCachedVertexExecutableIndex();
532     void updateCachedPixelExecutableIndex();
533     void updateCachedComputeExecutableIndex();
534 
535     void linkResources(const gl::ProgramLinkedResources &resources);
536 
537     RendererD3D *mRenderer;
538     DynamicHLSL *mDynamicHLSL;
539 
540     std::vector<std::unique_ptr<VertexExecutable>> mVertexExecutables;
541     std::vector<std::unique_ptr<PixelExecutable>> mPixelExecutables;
542     angle::PackedEnumMap<gl::PrimitiveMode, std::unique_ptr<ShaderExecutableD3D>>
543         mGeometryExecutables;
544     std::vector<std::unique_ptr<ComputeExecutable>> mComputeExecutables;
545 
546     gl::ShaderMap<std::string> mShaderHLSL;
547     gl::ShaderMap<CompilerWorkaroundsD3D> mShaderWorkarounds;
548 
549     bool mUsesFragDepth;
550     bool mHasANGLEMultiviewEnabled;
551     bool mUsesVertexID;
552     bool mUsesViewID;
553     std::vector<PixelShaderOutputVariable> mPixelShaderKey;
554 
555     // Common code for all dynamic geometry shaders. Consists mainly of the GS input and output
556     // structures, built from the linked varying info. We store the string itself instead of the
557     // packed varyings for simplicity.
558     std::string mGeometryShaderPreamble;
559 
560     bool mUsesPointSize;
561     bool mUsesFlatInterpolation;
562 
563     gl::ShaderMap<std::unique_ptr<UniformStorageD3D>> mShaderUniformStorages;
564 
565     gl::ShaderMap<std::vector<Sampler>> mShaderSamplers;
566     gl::ShaderMap<gl::RangeUI> mUsedShaderSamplerRanges;
567     bool mDirtySamplerMapping;
568 
569     gl::ShaderMap<std::vector<Image>> mImages;
570     gl::ShaderMap<std::vector<Image>> mReadonlyImages;
571     gl::ShaderMap<gl::RangeUI> mUsedImageRange;
572     gl::ShaderMap<gl::RangeUI> mUsedReadonlyImageRange;
573     gl::ShaderMap<gl::RangeUI> mUsedAtomicCounterRange;
574 
575     // Cache for pixel shader output layout to save reallocations.
576     std::vector<GLenum> mPixelShaderOutputLayoutCache;
577     Optional<size_t> mCachedPixelExecutableIndex;
578 
579     AttribIndexArray mAttribLocationToD3DSemantic;
580 
581     unsigned int mSerial;
582 
583     gl::ShaderMap<std::vector<D3DUBOCache>> mShaderUBOCaches;
584     gl::ShaderMap<std::vector<D3DUBOCacheUseSB>> mShaderUBOCachesUseSB;
585     VertexExecutable::Signature mCachedVertexSignature;
586     gl::InputLayout mCachedInputLayout;
587     Optional<size_t> mCachedVertexExecutableIndex;
588 
589     std::vector<D3DVarying> mStreamOutVaryings;
590     std::vector<D3DUniform *> mD3DUniforms;
591     std::map<std::string, int> mImageBindingMap;
592     std::map<std::string, int> mAtomicBindingMap;
593     std::vector<D3DUniformBlock> mD3DUniformBlocks;
594     std::vector<D3DInterfaceBlock> mD3DShaderStorageBlocks;
595     gl::ShaderMap<std::vector<ShaderStorageBlock>> mShaderStorageBlocks;
596     std::array<unsigned int, gl::IMPLEMENTATION_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS>
597         mComputeAtomicCounterBufferRegisterIndices;
598 
599     gl::ShaderMap<std::vector<sh::ShaderVariable>> mImage2DUniforms;
600     gl::ShaderMap<gl::ImageUnitTextureTypeMap> mImage2DBindLayoutCache;
601     Optional<size_t> mCachedComputeExecutableIndex;
602 
603     gl::ShaderBitSet mShaderUniformsDirty;
604 
605     static unsigned int issueSerial();
606     static unsigned int mCurrentSerial;
607 
608     Serial mCurrentVertexArrayStateSerial;
609 };
610 }  // namespace rx
611 
612 #endif  // LIBANGLE_RENDERER_D3D_PROGRAMD3D_H_
613