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