ProgramExecutable.h (20443B)
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 "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 gl 22 { 23 24 // This small structure encapsulates binding sampler uniforms to active GL textures. 25 struct SamplerBinding 26 { 27 SamplerBinding(TextureType textureTypeIn, 28 GLenum samplerTypeIn, 29 SamplerFormat formatIn, 30 size_t elementCount); 31 SamplerBinding(const SamplerBinding &other); 32 ~SamplerBinding(); 33 34 // Necessary for retrieving active textures from the GL state. 35 TextureType textureType; 36 37 GLenum samplerType; 38 39 SamplerFormat format; 40 41 // List of all textures bound to this sampler, of type textureType. 42 // Cropped by the amount of unused elements reported by the driver. 43 std::vector<GLuint> boundTextureUnits; 44 }; 45 46 struct ImageBinding 47 { 48 ImageBinding(size_t count, TextureType textureTypeIn); 49 ImageBinding(GLuint imageUnit, size_t count, TextureType textureTypeIn); 50 ImageBinding(const ImageBinding &other); 51 ~ImageBinding(); 52 53 // Necessary for distinguishing between textures with images and texture buffers. 54 TextureType textureType; 55 56 // List of all textures bound. 57 // Cropped by the amount of unused elements reported by the driver. 58 std::vector<GLuint> boundImageUnits; 59 }; 60 61 // A varying with transform feedback enabled. If it's an array, either the whole array or one of its 62 // elements specified by 'arrayIndex' can set to be enabled. 63 struct TransformFeedbackVarying : public sh::ShaderVariable 64 { 65 TransformFeedbackVarying(const sh::ShaderVariable &varyingIn, GLuint arrayIndexIn) 66 : sh::ShaderVariable(varyingIn), arrayIndex(arrayIndexIn) 67 { 68 ASSERT(!isArrayOfArrays()); 69 } 70 71 TransformFeedbackVarying(const sh::ShaderVariable &field, const sh::ShaderVariable &parent) 72 : arrayIndex(GL_INVALID_INDEX) 73 { 74 sh::ShaderVariable *thisVar = this; 75 *thisVar = field; 76 interpolation = parent.interpolation; 77 isInvariant = parent.isInvariant; 78 ASSERT(parent.isShaderIOBlock || !parent.name.empty()); 79 if (!parent.name.empty()) 80 { 81 name = parent.name + "." + name; 82 mappedName = parent.mappedName + "." + mappedName; 83 } 84 structOrBlockName = parent.structOrBlockName; 85 mappedStructOrBlockName = parent.mappedStructOrBlockName; 86 } 87 88 std::string nameWithArrayIndex() const 89 { 90 std::stringstream fullNameStr; 91 fullNameStr << name; 92 if (arrayIndex != GL_INVALID_INDEX) 93 { 94 fullNameStr << "[" << arrayIndex << "]"; 95 } 96 return fullNameStr.str(); 97 } 98 GLsizei size() const 99 { 100 return (isArray() && arrayIndex == GL_INVALID_INDEX ? getOutermostArraySize() : 1); 101 } 102 103 GLuint arrayIndex; 104 }; 105 106 class ProgramState; 107 class ProgramPipelineState; 108 109 class ProgramExecutable final : public angle::Subject 110 { 111 public: 112 ProgramExecutable(); 113 ProgramExecutable(const ProgramExecutable &other); 114 ~ProgramExecutable() override; 115 116 void reset(bool clearInfoLog); 117 118 void save(bool isSeparable, gl::BinaryOutputStream *stream) const; 119 void load(bool isSeparable, gl::BinaryInputStream *stream); 120 121 int getInfoLogLength() const; 122 InfoLog &getInfoLog() { return mInfoLog; } 123 void getInfoLog(GLsizei bufSize, GLsizei *length, char *infoLog) const; 124 std::string getInfoLogString() const; 125 void resetInfoLog() { mInfoLog.reset(); } 126 127 void resetLinkedShaderStages() { mLinkedShaderStages.reset(); } 128 const ShaderBitSet &getLinkedShaderStages() const { return mLinkedShaderStages; } 129 void setLinkedShaderStages(ShaderType shaderType) 130 { 131 mLinkedShaderStages.set(shaderType); 132 updateCanDrawWith(); 133 } 134 bool hasLinkedShaderStage(ShaderType shaderType) const 135 { 136 ASSERT(shaderType != ShaderType::InvalidEnum); 137 return mLinkedShaderStages[shaderType]; 138 } 139 size_t getLinkedShaderStageCount() const { return mLinkedShaderStages.count(); } 140 bool hasLinkedGraphicsShader() const 141 { 142 return mLinkedShaderStages.any() && 143 mLinkedShaderStages != gl::ShaderBitSet{gl::ShaderType::Compute}; 144 } 145 bool hasLinkedTessellationShader() const 146 { 147 return mLinkedShaderStages[ShaderType::TessEvaluation]; 148 } 149 150 ShaderType getLinkedTransformFeedbackStage() const; 151 152 const AttributesMask &getActiveAttribLocationsMask() const 153 { 154 return mActiveAttribLocationsMask; 155 } 156 bool isAttribLocationActive(size_t attribLocation) const; 157 const AttributesMask &getNonBuiltinAttribLocationsMask() const { return mAttributesMask; } 158 unsigned int getMaxActiveAttribLocation() const { return mMaxActiveAttribLocation; } 159 const ComponentTypeMask &getAttributesTypeMask() const { return mAttributesTypeMask; } 160 AttributesMask getAttributesMask() const; 161 162 const ActiveTextureMask &getActiveSamplersMask() const { return mActiveSamplersMask; } 163 void setActiveTextureMask(ActiveTextureMask mask) { mActiveSamplersMask = mask; } 164 SamplerFormat getSamplerFormatForTextureUnitIndex(size_t textureUnitIndex) const 165 { 166 return mActiveSamplerFormats[textureUnitIndex]; 167 } 168 const ShaderBitSet getSamplerShaderBitsForTextureUnitIndex(size_t textureUnitIndex) const 169 { 170 return mActiveSamplerShaderBits[textureUnitIndex]; 171 } 172 const ActiveTextureMask &getActiveImagesMask() const { return mActiveImagesMask; } 173 void setActiveImagesMask(ActiveTextureMask mask) { mActiveImagesMask = mask; } 174 const ActiveTextureArray<ShaderBitSet> &getActiveImageShaderBits() const 175 { 176 return mActiveImageShaderBits; 177 } 178 179 const ActiveTextureMask &getActiveYUVSamplers() const { return mActiveSamplerYUV; } 180 181 const ActiveTextureArray<TextureType> &getActiveSamplerTypes() const 182 { 183 return mActiveSamplerTypes; 184 } 185 186 void setActive(size_t textureUnit, 187 const SamplerBinding &samplerBinding, 188 const gl::LinkedUniform &samplerUniform); 189 void setInactive(size_t textureUnit); 190 void hasSamplerTypeConflict(size_t textureUnit); 191 void hasSamplerFormatConflict(size_t textureUnit); 192 193 void updateActiveSamplers(const ProgramState &programState); 194 195 bool hasDefaultUniforms() const; 196 bool hasTextures() const; 197 bool hasUniformBuffers() const; 198 bool hasStorageBuffers() const; 199 bool hasAtomicCounterBuffers() const; 200 bool hasImages() const; 201 bool hasTransformFeedbackOutput() const 202 { 203 return !getLinkedTransformFeedbackVaryings().empty(); 204 } 205 bool usesFramebufferFetch() const; 206 207 // Count the number of uniform and storage buffer declarations, counting arrays as one. 208 size_t getTransformFeedbackBufferCount() const { return mTransformFeedbackStrides.size(); } 209 210 void updateCanDrawWith(); 211 bool hasVertexShader() const { return mCanDrawWith; } 212 213 const std::vector<sh::ShaderVariable> &getProgramInputs() const { return mProgramInputs; } 214 const std::vector<sh::ShaderVariable> &getOutputVariables() const { return mOutputVariables; } 215 const std::vector<VariableLocation> &getOutputLocations() const { return mOutputLocations; } 216 const std::vector<VariableLocation> &getSecondaryOutputLocations() const 217 { 218 return mSecondaryOutputLocations; 219 } 220 const std::vector<LinkedUniform> &getUniforms() const { return mUniforms; } 221 const std::vector<InterfaceBlock> &getUniformBlocks() const { return mUniformBlocks; } 222 const UniformBlockBindingMask &getActiveUniformBlockBindings() const 223 { 224 return mActiveUniformBlockBindings; 225 } 226 const std::vector<SamplerBinding> &getSamplerBindings() const { return mSamplerBindings; } 227 const std::vector<ImageBinding> &getImageBindings() const { return mImageBindings; } 228 std::vector<ImageBinding> *getImageBindings() { return &mImageBindings; } 229 const RangeUI &getDefaultUniformRange() const { return mDefaultUniformRange; } 230 const RangeUI &getSamplerUniformRange() const { return mSamplerUniformRange; } 231 const RangeUI &getImageUniformRange() const { return mImageUniformRange; } 232 const RangeUI &getAtomicCounterUniformRange() const { return mAtomicCounterUniformRange; } 233 const RangeUI &getFragmentInoutRange() const { return mFragmentInoutRange; } 234 bool hasDiscard() const { return mHasDiscard; } 235 bool enablesPerSampleShading() const { return mEnablesPerSampleShading; } 236 BlendEquationBitSet getAdvancedBlendEquations() const { return mAdvancedBlendEquations; } 237 const std::vector<TransformFeedbackVarying> &getLinkedTransformFeedbackVaryings() const 238 { 239 return mLinkedTransformFeedbackVaryings; 240 } 241 GLint getTransformFeedbackBufferMode() const { return mTransformFeedbackBufferMode; } 242 GLuint getUniformBlockBinding(GLuint uniformBlockIndex) const 243 { 244 ASSERT(uniformBlockIndex < mUniformBlocks.size()); 245 return mUniformBlocks[uniformBlockIndex].binding; 246 } 247 GLuint getShaderStorageBlockBinding(GLuint blockIndex) const 248 { 249 ASSERT(blockIndex < mShaderStorageBlocks.size()); 250 return mShaderStorageBlocks[blockIndex].binding; 251 } 252 const std::vector<GLsizei> &getTransformFeedbackStrides() const 253 { 254 return mTransformFeedbackStrides; 255 } 256 const std::vector<AtomicCounterBuffer> &getAtomicCounterBuffers() const 257 { 258 return mAtomicCounterBuffers; 259 } 260 const std::vector<InterfaceBlock> &getShaderStorageBlocks() const 261 { 262 return mShaderStorageBlocks; 263 } 264 const LinkedUniform &getUniformByIndex(GLuint index) const 265 { 266 ASSERT(index < static_cast<size_t>(mUniforms.size())); 267 return mUniforms[index]; 268 } 269 270 ANGLE_INLINE GLuint getActiveUniformBlockCount() const 271 { 272 return static_cast<GLuint>(mUniformBlocks.size()); 273 } 274 275 ANGLE_INLINE GLuint getActiveAtomicCounterBufferCount() const 276 { 277 return static_cast<GLuint>(mAtomicCounterBuffers.size()); 278 } 279 280 ANGLE_INLINE GLuint getActiveShaderStorageBlockCount() const 281 { 282 size_t shaderStorageBlocksSize = mShaderStorageBlocks.size(); 283 return static_cast<GLuint>(shaderStorageBlocksSize); 284 } 285 286 GLuint getUniformIndexFromImageIndex(GLuint imageIndex) const; 287 288 GLuint getUniformIndexFromSamplerIndex(GLuint samplerIndex) const; 289 290 void saveLinkedStateInfo(const Context *context, const ProgramState &state); 291 const std::vector<sh::ShaderVariable> &getLinkedOutputVaryings(ShaderType shaderType) const 292 { 293 return mLinkedOutputVaryings[shaderType]; 294 } 295 const std::vector<sh::ShaderVariable> &getLinkedInputVaryings(ShaderType shaderType) const 296 { 297 return mLinkedInputVaryings[shaderType]; 298 } 299 300 const std::vector<sh::ShaderVariable> &getLinkedUniforms(ShaderType shaderType) const 301 { 302 return mLinkedUniforms[shaderType]; 303 } 304 305 const std::vector<sh::InterfaceBlock> &getLinkedUniformBlocks(ShaderType shaderType) const 306 { 307 return mLinkedUniformBlocks[shaderType]; 308 } 309 310 int getLinkedShaderVersion(ShaderType shaderType) const 311 { 312 return mLinkedShaderVersions[shaderType]; 313 } 314 315 bool isYUVOutput() const; 316 317 PrimitiveMode getGeometryShaderInputPrimitiveType() const 318 { 319 return mGeometryShaderInputPrimitiveType; 320 } 321 322 PrimitiveMode getGeometryShaderOutputPrimitiveType() const 323 { 324 return mGeometryShaderOutputPrimitiveType; 325 } 326 327 int getGeometryShaderInvocations() const { return mGeometryShaderInvocations; } 328 329 int getGeometryShaderMaxVertices() const { return mGeometryShaderMaxVertices; } 330 331 GLenum getTessGenMode() const { return mTessGenMode; } 332 333 void resetCachedValidateSamplersResult() { mCachedValidateSamplersResult.reset(); } 334 bool validateSamplers(InfoLog *infoLog, const Caps &caps) const 335 { 336 // Use the cache if: 337 // - we aren't using an info log (which gives the full error). 338 // - The sample mapping hasn't changed and we've already validated. 339 if (infoLog == nullptr && mCachedValidateSamplersResult.valid()) 340 { 341 return mCachedValidateSamplersResult.value(); 342 } 343 344 return validateSamplersImpl(infoLog, caps); 345 } 346 347 ComponentTypeMask getFragmentOutputsTypeMask() const { return mDrawBufferTypeMask; } 348 DrawBufferMask getActiveOutputVariablesMask() const { return mActiveOutputVariablesMask; } 349 350 bool linkUniforms(const Context *context, 351 const ShaderMap<std::vector<sh::ShaderVariable>> &shaderUniforms, 352 InfoLog &infoLog, 353 const ProgramAliasedBindings &uniformLocationBindings, 354 GLuint *combinedImageUniformsCount, 355 std::vector<UnusedUniform> *unusedUniforms, 356 std::vector<VariableLocation> *uniformLocationsOutOrNull); 357 358 void copyInputsFromProgram(const ProgramState &programState); 359 void copyShaderBuffersFromProgram(const ProgramState &programState, ShaderType shaderType); 360 void clearSamplerBindings(); 361 void copySamplerBindingsFromProgram(const ProgramState &programState); 362 void copyImageBindingsFromProgram(const ProgramState &programState); 363 void copyOutputsFromProgram(const ProgramState &programState); 364 void copyUniformsFromProgramMap(const ShaderMap<Program *> &programs); 365 366 private: 367 friend class Program; 368 friend class ProgramPipeline; 369 friend class ProgramState; 370 371 void updateActiveImages(const ProgramExecutable &executable); 372 373 // Scans the sampler bindings for type conflicts with sampler 'textureUnitIndex'. 374 void setSamplerUniformTextureTypeAndFormat(size_t textureUnitIndex, 375 std::vector<SamplerBinding> &samplerBindings); 376 377 bool linkMergedVaryings(const Context *context, 378 const ProgramMergedVaryings &mergedVaryings, 379 const std::vector<std::string> &transformFeedbackVaryingNames, 380 const LinkingVariables &linkingVariables, 381 bool isSeparable, 382 ProgramVaryingPacking *varyingPacking); 383 384 bool linkValidateTransformFeedback( 385 const Context *context, 386 const ProgramMergedVaryings &varyings, 387 ShaderType stage, 388 const std::vector<std::string> &transformFeedbackVaryingNames); 389 390 void gatherTransformFeedbackVaryings( 391 const ProgramMergedVaryings &varyings, 392 ShaderType stage, 393 const std::vector<std::string> &transformFeedbackVaryingNames); 394 395 void updateTransformFeedbackStrides(); 396 397 bool validateSamplersImpl(InfoLog *infoLog, const Caps &caps) const; 398 399 bool linkValidateOutputVariables(const Caps &caps, 400 const Extensions &extensions, 401 const Version &version, 402 GLuint combinedImageUniformsCount, 403 GLuint combinedShaderStorageBlocksCount, 404 const std::vector<sh::ShaderVariable> &outputVariables, 405 int fragmentShaderVersion, 406 const ProgramAliasedBindings &fragmentOutputLocations, 407 const ProgramAliasedBindings &fragmentOutputIndices); 408 409 void linkSamplerAndImageBindings(GLuint *combinedImageUniformsCount); 410 bool linkAtomicCounterBuffers(const Context *context, InfoLog &infoLog); 411 412 InfoLog mInfoLog; 413 414 ShaderBitSet mLinkedShaderStages; 415 416 angle::BitSet<MAX_VERTEX_ATTRIBS> mActiveAttribLocationsMask; 417 unsigned int mMaxActiveAttribLocation; 418 ComponentTypeMask mAttributesTypeMask; 419 // mAttributesMask is identical to mActiveAttribLocationsMask with built-in attributes removed. 420 AttributesMask mAttributesMask; 421 422 // Cached mask of active samplers and sampler types. 423 ActiveTextureMask mActiveSamplersMask; 424 ActiveTextureArray<uint32_t> mActiveSamplerRefCounts; 425 ActiveTextureArray<TextureType> mActiveSamplerTypes; 426 ActiveTextureMask mActiveSamplerYUV; 427 ActiveTextureArray<SamplerFormat> mActiveSamplerFormats; 428 ActiveTextureArray<ShaderBitSet> mActiveSamplerShaderBits; 429 430 // Cached mask of active images. 431 ActiveTextureMask mActiveImagesMask; 432 ActiveTextureArray<ShaderBitSet> mActiveImageShaderBits; 433 434 bool mCanDrawWith; 435 436 // Names and mapped names of output variables that are arrays include [0] in the end, similarly 437 // to uniforms. 438 std::vector<sh::ShaderVariable> mOutputVariables; 439 std::vector<VariableLocation> mOutputLocations; 440 DrawBufferMask mActiveOutputVariablesMask; 441 // EXT_blend_func_extended secondary outputs (ones with index 1) 442 std::vector<VariableLocation> mSecondaryOutputLocations; 443 bool mYUVOutput; 444 // Vertex attributes, Fragment input varyings, etc. 445 std::vector<sh::ShaderVariable> mProgramInputs; 446 std::vector<TransformFeedbackVarying> mLinkedTransformFeedbackVaryings; 447 // The size of the data written to each transform feedback buffer per vertex. 448 std::vector<GLsizei> mTransformFeedbackStrides; 449 GLenum mTransformFeedbackBufferMode; 450 // Uniforms are sorted in order: 451 // 1. Non-opaque uniforms 452 // 2. Sampler uniforms 453 // 3. Image uniforms 454 // 4. Atomic counter uniforms 455 // 5. Subpass Input uniforms (Only for Vulkan) 456 // 6. Uniform block uniforms 457 // This makes opaque uniform validation easier, since we don't need a separate list. 458 // For generating the entries and naming them we follow the spec: GLES 3.1 November 2016 section 459 // 7.3.1.1 Naming Active Resources. There's a separate entry for each struct member and each 460 // inner array of an array of arrays. Names and mapped names of uniforms that are arrays include 461 // [0] in the end. This makes implementation of queries simpler. 462 std::vector<LinkedUniform> mUniforms; 463 RangeUI mDefaultUniformRange; 464 RangeUI mSamplerUniformRange; 465 RangeUI mImageUniformRange; 466 RangeUI mAtomicCounterUniformRange; 467 std::vector<InterfaceBlock> mUniformBlocks; 468 469 // For faster iteration on the blocks currently being bound. 470 UniformBlockBindingMask mActiveUniformBlockBindings; 471 472 std::vector<AtomicCounterBuffer> mAtomicCounterBuffers; 473 std::vector<InterfaceBlock> mShaderStorageBlocks; 474 475 RangeUI mFragmentInoutRange; 476 bool mHasDiscard; 477 bool mEnablesPerSampleShading; 478 479 // KHR_blend_equation_advanced supported equation list 480 BlendEquationBitSet mAdvancedBlendEquations; 481 482 // An array of the samplers that are used by the program 483 std::vector<SamplerBinding> mSamplerBindings; 484 485 // An array of the images that are used by the program 486 std::vector<ImageBinding> mImageBindings; 487 488 ShaderMap<std::vector<sh::ShaderVariable>> mLinkedOutputVaryings; 489 ShaderMap<std::vector<sh::ShaderVariable>> mLinkedInputVaryings; 490 ShaderMap<std::vector<sh::ShaderVariable>> mLinkedUniforms; 491 ShaderMap<std::vector<sh::InterfaceBlock>> mLinkedUniformBlocks; 492 493 ShaderMap<int> mLinkedShaderVersions; 494 495 // GL_EXT_geometry_shader. 496 PrimitiveMode mGeometryShaderInputPrimitiveType; 497 PrimitiveMode mGeometryShaderOutputPrimitiveType; 498 int mGeometryShaderInvocations; 499 int mGeometryShaderMaxVertices; 500 501 // GL_EXT_tessellation_shader 502 int mTessControlShaderVertices; 503 GLenum mTessGenMode; 504 GLenum mTessGenSpacing; 505 GLenum mTessGenVertexOrder; 506 GLenum mTessGenPointMode; 507 508 // Fragment output variable base types: FLOAT, INT, or UINT. Ordered by location. 509 std::vector<GLenum> mOutputVariableTypes; 510 ComponentTypeMask mDrawBufferTypeMask; 511 512 // Cache for sampler validation 513 mutable Optional<bool> mCachedValidateSamplersResult; 514 }; 515 } // namespace gl 516 517 #endif // LIBANGLE_PROGRAMEXECUTABLE_H_