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