• 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 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) override;
237     GLboolean validate(const gl::Caps &caps, gl::InfoLog *infoLog) override;
238 
239     void updateUniformBufferCache(const gl::Caps &caps);
240 
241     unsigned int getAtomicCounterBufferRegisterIndex(GLuint binding,
242                                                      gl::ShaderType shaderType) const;
243 
244     unsigned int getShaderStorageBufferRegisterIndex(GLuint blockIndex,
245                                                      gl::ShaderType shaderType) const;
246     const std::vector<D3DUBOCache> &getShaderUniformBufferCache(gl::ShaderType shaderType) const;
247     const std::vector<D3DUBOCacheUseSB> &getShaderUniformBufferCacheUseSB(
248         gl::ShaderType shaderType) const;
249 
250     void dirtyAllUniforms();
251 
252     void setUniform1fv(GLint location, GLsizei count, const GLfloat *v) override;
253     void setUniform2fv(GLint location, GLsizei count, const GLfloat *v) override;
254     void setUniform3fv(GLint location, GLsizei count, const GLfloat *v) override;
255     void setUniform4fv(GLint location, GLsizei count, const GLfloat *v) override;
256     void setUniform1iv(GLint location, GLsizei count, const GLint *v) override;
257     void setUniform2iv(GLint location, GLsizei count, const GLint *v) override;
258     void setUniform3iv(GLint location, GLsizei count, const GLint *v) override;
259     void setUniform4iv(GLint location, GLsizei count, const GLint *v) override;
260     void setUniform1uiv(GLint location, GLsizei count, const GLuint *v) override;
261     void setUniform2uiv(GLint location, GLsizei count, const GLuint *v) override;
262     void setUniform3uiv(GLint location, GLsizei count, const GLuint *v) override;
263     void setUniform4uiv(GLint location, GLsizei count, const GLuint *v) override;
264     void setUniformMatrix2fv(GLint location,
265                              GLsizei count,
266                              GLboolean transpose,
267                              const GLfloat *value) override;
268     void setUniformMatrix3fv(GLint location,
269                              GLsizei count,
270                              GLboolean transpose,
271                              const GLfloat *value) override;
272     void setUniformMatrix4fv(GLint location,
273                              GLsizei count,
274                              GLboolean transpose,
275                              const GLfloat *value) override;
276     void setUniformMatrix2x3fv(GLint location,
277                                GLsizei count,
278                                GLboolean transpose,
279                                const GLfloat *value) override;
280     void setUniformMatrix3x2fv(GLint location,
281                                GLsizei count,
282                                GLboolean transpose,
283                                const GLfloat *value) override;
284     void setUniformMatrix2x4fv(GLint location,
285                                GLsizei count,
286                                GLboolean transpose,
287                                const GLfloat *value) override;
288     void setUniformMatrix4x2fv(GLint location,
289                                GLsizei count,
290                                GLboolean transpose,
291                                const GLfloat *value) override;
292     void setUniformMatrix3x4fv(GLint location,
293                                GLsizei count,
294                                GLboolean transpose,
295                                const GLfloat *value) override;
296     void setUniformMatrix4x3fv(GLint location,
297                                GLsizei count,
298                                GLboolean transpose,
299                                const GLfloat *value) override;
300 
301     void getUniformfv(const gl::Context *context, GLint location, GLfloat *params) const override;
302     void getUniformiv(const gl::Context *context, GLint location, GLint *params) const override;
303     void getUniformuiv(const gl::Context *context, GLint location, GLuint *params) const override;
304 
getShaderUniformStorage(gl::ShaderType shaderType)305     UniformStorageD3D *getShaderUniformStorage(gl::ShaderType shaderType) const
306     {
307         return mShaderUniformStorages[shaderType].get();
308     }
309 
310     unsigned int getSerial() const;
311 
getAttribLocationToD3DSemantics()312     const AttribIndexArray &getAttribLocationToD3DSemantics() const
313     {
314         return mAttribLocationToD3DSemantic;
315     }
316 
317     void updateCachedInputLayout(Serial associatedSerial, const gl::State &state);
318     void updateCachedOutputLayout(const gl::Context *context, const gl::Framebuffer *framebuffer);
319     void updateCachedComputeImage2DBindLayout(const gl::Context *context);
320 
isSamplerMappingDirty()321     bool isSamplerMappingDirty() { return mDirtySamplerMapping; }
322 
323     // Checks if we need to recompile certain shaders.
324     bool hasVertexExecutableForCachedInputLayout();
325     bool hasGeometryExecutableForPrimitiveType(const gl::State &state, gl::PrimitiveMode drawMode);
326     bool hasPixelExecutableForCachedOutputLayout();
327     bool hasComputeExecutableForCachedImage2DBindLayout();
328 
anyShaderUniformsDirty()329     bool anyShaderUniformsDirty() const { return mShaderUniformsDirty.any(); }
330 
areShaderUniformsDirty(gl::ShaderType shaderType)331     bool areShaderUniformsDirty(gl::ShaderType shaderType) const
332     {
333         return mShaderUniformsDirty[shaderType];
334     }
getD3DUniforms()335     const std::vector<D3DUniform *> &getD3DUniforms() const { return mD3DUniforms; }
336     void markUniformsClean();
337 
getState()338     const gl::ProgramState &getState() const { return mState; }
339 
hasShaderStage(gl::ShaderType shaderType)340     bool hasShaderStage(gl::ShaderType shaderType) const
341     {
342         return mState.getProgramExecutable().getLinkedShaderStages()[shaderType];
343     }
344 
345     void assignImage2DRegisters(unsigned int startImageIndex,
346                                 int startLogicalImageUnit,
347                                 bool readonly);
348     bool hasNamedUniform(const std::string &name);
349 
usesVertexID()350     bool usesVertexID() const { return mUsesVertexID; }
351 
352   private:
353     // These forward-declared tasks are used for multi-thread shader compiles.
354     class GetExecutableTask;
355     class GetVertexExecutableTask;
356     class GetPixelExecutableTask;
357     class GetGeometryExecutableTask;
358     class GetComputeExecutableTask;
359     class GraphicsProgramLinkEvent;
360     class ComputeProgramLinkEvent;
361 
362     class LoadBinaryTask;
363     class LoadBinaryLinkEvent;
364 
365     class VertexExecutable
366     {
367       public:
368         enum HLSLAttribType
369         {
370             FLOAT,
371             UNSIGNED_INT,
372             SIGNED_INT,
373         };
374 
375         typedef std::vector<HLSLAttribType> Signature;
376 
377         VertexExecutable(const gl::InputLayout &inputLayout,
378                          const Signature &signature,
379                          ShaderExecutableD3D *shaderExecutable);
380         ~VertexExecutable();
381 
382         bool matchesSignature(const Signature &signature) const;
383         static void getSignature(RendererD3D *renderer,
384                                  const gl::InputLayout &inputLayout,
385                                  Signature *signatureOut);
386 
inputs()387         const gl::InputLayout &inputs() const { return mInputs; }
signature()388         const Signature &signature() const { return mSignature; }
shaderExecutable()389         ShaderExecutableD3D *shaderExecutable() const { return mShaderExecutable; }
390 
391       private:
392         static HLSLAttribType GetAttribType(GLenum type);
393 
394         gl::InputLayout mInputs;
395         Signature mSignature;
396         ShaderExecutableD3D *mShaderExecutable;
397     };
398 
399     class PixelExecutable
400     {
401       public:
402         PixelExecutable(const std::vector<GLenum> &outputSignature,
403                         ShaderExecutableD3D *shaderExecutable);
404         ~PixelExecutable();
405 
matchesSignature(const std::vector<GLenum> & signature)406         bool matchesSignature(const std::vector<GLenum> &signature) const
407         {
408             return mOutputSignature == signature;
409         }
410 
outputSignature()411         const std::vector<GLenum> &outputSignature() const { return mOutputSignature; }
shaderExecutable()412         ShaderExecutableD3D *shaderExecutable() const { return mShaderExecutable; }
413 
414       private:
415         std::vector<GLenum> mOutputSignature;
416         ShaderExecutableD3D *mShaderExecutable;
417     };
418 
419     class ComputeExecutable
420     {
421       public:
422         ComputeExecutable(const gl::ImageUnitTextureTypeMap &signature,
423                           std::unique_ptr<ShaderExecutableD3D> shaderExecutable);
424         ~ComputeExecutable();
425 
matchesSignature(const gl::ImageUnitTextureTypeMap & signature)426         bool matchesSignature(const gl::ImageUnitTextureTypeMap &signature) const
427         {
428             return mSignature == signature;
429         }
430 
signature()431         const gl::ImageUnitTextureTypeMap &signature() const { return mSignature; }
shaderExecutable()432         ShaderExecutableD3D *shaderExecutable() const { return mShaderExecutable.get(); }
433 
434       private:
435         gl::ImageUnitTextureTypeMap mSignature;
436         std::unique_ptr<ShaderExecutableD3D> mShaderExecutable;
437     };
438 
439     struct Sampler
440     {
441         Sampler();
442 
443         bool active;
444         GLint logicalTextureUnit;
445         gl::TextureType textureType;
446     };
447 
448     struct Image
449     {
450         Image();
451         bool active;
452         GLint logicalImageUnit;
453     };
454 
455     void initializeUniformStorage(const gl::ShaderBitSet &availableShaderStages);
456 
457     void defineUniformsAndAssignRegisters();
458     void defineUniformBase(const gl::Shader *shader,
459                            const sh::ShaderVariable &uniform,
460                            D3DUniformMap *uniformMap);
461     void assignAllSamplerRegisters();
462     void assignSamplerRegisters(size_t uniformIndex);
463 
464     static void AssignSamplers(unsigned int startSamplerIndex,
465                                const gl::UniformTypeInfo &typeInfo,
466                                unsigned int samplerCount,
467                                std::vector<Sampler> &outSamplers,
468                                gl::RangeUI *outUsedRange);
469 
470     void assignAllImageRegisters();
471     void assignAllAtomicCounterRegisters();
472     void assignImageRegisters(size_t uniformIndex);
473     static void AssignImages(unsigned int startImageIndex,
474                              int startLogicalImageUnit,
475                              unsigned int imageCount,
476                              std::vector<Image> &outImages,
477                              gl::RangeUI *outUsedRange);
478 
479     template <typename DestT>
480     void getUniformInternal(GLint location, DestT *dataOut) const;
481 
482     template <typename T>
483     void setUniformImpl(const gl::VariableLocation &locationInfo,
484                         GLsizei count,
485                         const T *v,
486                         uint8_t *targetData,
487                         GLenum uniformType);
488 
489     template <typename T>
490     void setUniformInternal(GLint location, GLsizei count, const T *v, GLenum uniformType);
491 
492     template <int cols, int rows>
493     void setUniformMatrixfvInternal(GLint location,
494                                     GLsizei count,
495                                     GLboolean transpose,
496                                     const GLfloat *value);
497 
498     std::unique_ptr<LinkEvent> compileProgramExecutables(const gl::Context *context,
499                                                          gl::InfoLog &infoLog);
500     std::unique_ptr<LinkEvent> compileComputeExecutable(const gl::Context *context,
501                                                         gl::InfoLog &infoLog);
502 
503     angle::Result loadBinaryShaderExecutables(d3d::Context *contextD3D,
504                                               gl::BinaryInputStream *stream,
505                                               gl::InfoLog &infoLog);
506 
507     void gatherTransformFeedbackVaryings(const gl::VaryingPacking &varyings,
508                                          const BuiltinInfo &builtins);
509     D3DUniform *getD3DUniformFromLocation(GLint location);
510     const D3DUniform *getD3DUniformFromLocation(GLint location) const;
511 
512     void initAttribLocationsToD3DSemantic();
513 
514     void reset();
515     void initializeUniformBlocks();
516     void initializeShaderStorageBlocks();
517 
518     void updateCachedInputLayoutFromShader();
519     void updateCachedOutputLayoutFromShader();
520     void updateCachedImage2DBindLayoutFromComputeShader();
521     void updateCachedVertexExecutableIndex();
522     void updateCachedPixelExecutableIndex();
523     void updateCachedComputeExecutableIndex();
524 
525     void linkResources(const gl::ProgramLinkedResources &resources);
526 
527     RendererD3D *mRenderer;
528     DynamicHLSL *mDynamicHLSL;
529 
530     std::vector<std::unique_ptr<VertexExecutable>> mVertexExecutables;
531     std::vector<std::unique_ptr<PixelExecutable>> mPixelExecutables;
532     angle::PackedEnumMap<gl::PrimitiveMode, std::unique_ptr<ShaderExecutableD3D>>
533         mGeometryExecutables;
534     std::vector<std::unique_ptr<ComputeExecutable>> mComputeExecutables;
535 
536     gl::ShaderMap<std::string> mShaderHLSL;
537     gl::ShaderMap<angle::CompilerWorkaroundsD3D> mShaderWorkarounds;
538 
539     bool mUsesFragDepth;
540     bool mHasANGLEMultiviewEnabled;
541     bool mUsesVertexID;
542     bool mUsesViewID;
543     std::vector<PixelShaderOutputVariable> mPixelShaderKey;
544 
545     // Common code for all dynamic geometry shaders. Consists mainly of the GS input and output
546     // structures, built from the linked varying info. We store the string itself instead of the
547     // packed varyings for simplicity.
548     std::string mGeometryShaderPreamble;
549 
550     bool mUsesPointSize;
551     bool mUsesFlatInterpolation;
552 
553     gl::ShaderMap<std::unique_ptr<UniformStorageD3D>> mShaderUniformStorages;
554 
555     gl::ShaderMap<std::vector<Sampler>> mShaderSamplers;
556     gl::ShaderMap<gl::RangeUI> mUsedShaderSamplerRanges;
557     bool mDirtySamplerMapping;
558 
559     std::vector<Image> mImagesCS;
560     std::vector<Image> mReadonlyImagesCS;
561     gl::RangeUI mUsedComputeImageRange;
562     gl::RangeUI mUsedComputeReadonlyImageRange;
563     gl::RangeUI mUsedComputeAtomicCounterRange;
564 
565     // Cache for pixel shader output layout to save reallocations.
566     std::vector<GLenum> mPixelShaderOutputLayoutCache;
567     Optional<size_t> mCachedPixelExecutableIndex;
568 
569     AttribIndexArray mAttribLocationToD3DSemantic;
570 
571     unsigned int mSerial;
572 
573     gl::ShaderMap<std::vector<D3DUBOCache>> mShaderUBOCaches;
574     gl::ShaderMap<std::vector<D3DUBOCacheUseSB>> mShaderUBOCachesUseSB;
575     VertexExecutable::Signature mCachedVertexSignature;
576     gl::InputLayout mCachedInputLayout;
577     Optional<size_t> mCachedVertexExecutableIndex;
578 
579     std::vector<D3DVarying> mStreamOutVaryings;
580     std::vector<D3DUniform *> mD3DUniforms;
581     std::map<std::string, int> mImageBindingMap;
582     std::map<std::string, int> mAtomicBindingMap;
583     std::vector<D3DUniformBlock> mD3DUniformBlocks;
584     std::vector<D3DInterfaceBlock> mD3DShaderStorageBlocks;
585     std::array<unsigned int, gl::IMPLEMENTATION_MAX_ATOMIC_COUNTER_BUFFERS>
586         mComputeAtomicCounterBufferRegisterIndices;
587 
588     std::vector<sh::ShaderVariable> mImage2DUniforms;
589     gl::ImageUnitTextureTypeMap mComputeShaderImage2DBindLayoutCache;
590     Optional<size_t> mCachedComputeExecutableIndex;
591 
592     gl::ShaderBitSet mShaderUniformsDirty;
593 
594     static unsigned int issueSerial();
595     static unsigned int mCurrentSerial;
596 
597     Serial mCurrentVertexArrayStateSerial;
598 };
599 }  // namespace rx
600 
601 #endif  // LIBANGLE_RENDERER_D3D_PROGRAMD3D_H_
602