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 7 // ProgramExecutableVk.h: Collects the information and interfaces common to both ProgramVks and 8 // ProgramPipelineVks in order to execute/draw with either. 9 10 #ifndef LIBANGLE_RENDERER_VULKAN_PROGRAMEXECUTABLEVK_H_ 11 #define LIBANGLE_RENDERER_VULKAN_PROGRAMEXECUTABLEVK_H_ 12 13 #include "common/bitset_utils.h" 14 #include "common/mathutil.h" 15 #include "common/utilities.h" 16 #include "libANGLE/Context.h" 17 #include "libANGLE/InfoLog.h" 18 #include "libANGLE/ProgramExecutable.h" 19 #include "libANGLE/renderer/ProgramExecutableImpl.h" 20 #include "libANGLE/renderer/vulkan/ContextVk.h" 21 #include "libANGLE/renderer/vulkan/ShaderInterfaceVariableInfoMap.h" 22 #include "libANGLE/renderer/vulkan/spv_utils.h" 23 #include "libANGLE/renderer/vulkan/vk_cache_utils.h" 24 #include "libANGLE/renderer/vulkan/vk_helpers.h" 25 26 namespace rx 27 { 28 29 class ShaderInfo final : angle::NonCopyable 30 { 31 public: 32 ShaderInfo(); 33 ~ShaderInfo(); 34 35 angle::Result initShaders(vk::Context *context, 36 const gl::ShaderBitSet &linkedShaderStages, 37 const gl::ShaderMap<const angle::spirv::Blob *> &spirvBlobs, 38 const ShaderInterfaceVariableInfoMap &variableInfoMap, 39 bool isGLES1); 40 void initShaderFromProgram(gl::ShaderType shaderType, const ShaderInfo &programShaderInfo); 41 void clear(); 42 valid()43 ANGLE_INLINE bool valid() const { return mIsInitialized; } 44 getSpirvBlobs()45 const gl::ShaderMap<angle::spirv::Blob> &getSpirvBlobs() const { return mSpirvBlobs; } 46 47 // Save and load implementation for GLES Program Binary support. 48 void load(gl::BinaryInputStream *stream); 49 void save(gl::BinaryOutputStream *stream); 50 51 private: 52 gl::ShaderMap<angle::spirv::Blob> mSpirvBlobs; 53 bool mIsInitialized = false; 54 }; 55 56 union ProgramTransformOptions final 57 { 58 struct 59 { 60 uint8_t surfaceRotation : 1; 61 uint8_t removeTransformFeedbackEmulation : 1; 62 uint8_t multiSampleFramebufferFetch : 1; 63 uint8_t enableSampleShading : 1; 64 uint8_t reserved : 4; // must initialize to zero 65 }; 66 uint8_t permutationIndex; 67 static constexpr uint32_t kPermutationCount = 0x1 << 4; 68 }; 69 static_assert(sizeof(ProgramTransformOptions) == 1, "Size check failed"); 70 static_assert(static_cast<int>(SurfaceRotation::EnumCount) <= 8, "Size check failed"); 71 72 class ProgramInfo final : angle::NonCopyable 73 { 74 public: 75 ProgramInfo(); 76 ~ProgramInfo(); 77 78 angle::Result initProgram(vk::Context *context, 79 gl::ShaderType shaderType, 80 bool isLastPreFragmentStage, 81 bool isTransformFeedbackProgram, 82 const ShaderInfo &shaderInfo, 83 ProgramTransformOptions optionBits, 84 const ShaderInterfaceVariableInfoMap &variableInfoMap); 85 void release(ContextVk *contextVk); 86 valid(gl::ShaderType shaderType)87 ANGLE_INLINE bool valid(gl::ShaderType shaderType) const 88 { 89 return mProgramHelper.valid(shaderType); 90 } 91 getShaderProgram()92 vk::ShaderProgramHelper &getShaderProgram() { return mProgramHelper; } 93 94 private: 95 vk::ShaderProgramHelper mProgramHelper; 96 vk::ShaderModuleMap mShaders; 97 }; 98 99 using ImmutableSamplerIndexMap = angle::HashMap<vk::YcbcrConversionDesc, uint32_t>; 100 101 class ProgramExecutableVk : public ProgramExecutableImpl 102 { 103 public: 104 ProgramExecutableVk(const gl::ProgramExecutable *executable); 105 ~ProgramExecutableVk() override; 106 107 void destroy(const gl::Context *context) override; 108 109 void save(ContextVk *contextVk, bool isSeparable, gl::BinaryOutputStream *stream); 110 angle::Result load(ContextVk *contextVk, 111 bool isSeparable, 112 gl::BinaryInputStream *stream, 113 egl::CacheGetResult *resultOut); 114 115 void setUniform1fv(GLint location, GLsizei count, const GLfloat *v) override; 116 void setUniform2fv(GLint location, GLsizei count, const GLfloat *v) override; 117 void setUniform3fv(GLint location, GLsizei count, const GLfloat *v) override; 118 void setUniform4fv(GLint location, GLsizei count, const GLfloat *v) override; 119 void setUniform1iv(GLint location, GLsizei count, const GLint *v) override; 120 void setUniform2iv(GLint location, GLsizei count, const GLint *v) override; 121 void setUniform3iv(GLint location, GLsizei count, const GLint *v) override; 122 void setUniform4iv(GLint location, GLsizei count, const GLint *v) override; 123 void setUniform1uiv(GLint location, GLsizei count, const GLuint *v) override; 124 void setUniform2uiv(GLint location, GLsizei count, const GLuint *v) override; 125 void setUniform3uiv(GLint location, GLsizei count, const GLuint *v) override; 126 void setUniform4uiv(GLint location, GLsizei count, const GLuint *v) override; 127 void setUniformMatrix2fv(GLint location, 128 GLsizei count, 129 GLboolean transpose, 130 const GLfloat *value) override; 131 void setUniformMatrix3fv(GLint location, 132 GLsizei count, 133 GLboolean transpose, 134 const GLfloat *value) override; 135 void setUniformMatrix4fv(GLint location, 136 GLsizei count, 137 GLboolean transpose, 138 const GLfloat *value) override; 139 void setUniformMatrix2x3fv(GLint location, 140 GLsizei count, 141 GLboolean transpose, 142 const GLfloat *value) override; 143 void setUniformMatrix3x2fv(GLint location, 144 GLsizei count, 145 GLboolean transpose, 146 const GLfloat *value) override; 147 void setUniformMatrix2x4fv(GLint location, 148 GLsizei count, 149 GLboolean transpose, 150 const GLfloat *value) override; 151 void setUniformMatrix4x2fv(GLint location, 152 GLsizei count, 153 GLboolean transpose, 154 const GLfloat *value) override; 155 void setUniformMatrix3x4fv(GLint location, 156 GLsizei count, 157 GLboolean transpose, 158 const GLfloat *value) override; 159 void setUniformMatrix4x3fv(GLint location, 160 GLsizei count, 161 GLboolean transpose, 162 const GLfloat *value) override; 163 164 void getUniformfv(const gl::Context *context, GLint location, GLfloat *params) const override; 165 void getUniformiv(const gl::Context *context, GLint location, GLint *params) const override; 166 void getUniformuiv(const gl::Context *context, GLint location, GLuint *params) const override; 167 168 void clearVariableInfoMap(); 169 getCurrentDefaultUniformBufferSerial()170 vk::BufferSerial getCurrentDefaultUniformBufferSerial() const 171 { 172 return mCurrentDefaultUniformBufferSerial; 173 } 174 175 // Get the graphics pipeline if already created. 176 angle::Result getGraphicsPipeline(ContextVk *contextVk, 177 vk::GraphicsPipelineSubset pipelineSubset, 178 const vk::GraphicsPipelineDesc &desc, 179 const vk::GraphicsPipelineDesc **descPtrOut, 180 vk::PipelineHelper **pipelineOut); 181 182 angle::Result createGraphicsPipeline(ContextVk *contextVk, 183 vk::GraphicsPipelineSubset pipelineSubset, 184 vk::PipelineCacheAccess *pipelineCache, 185 PipelineSource source, 186 const vk::GraphicsPipelineDesc &desc, 187 const vk::GraphicsPipelineDesc **descPtrOut, 188 vk::PipelineHelper **pipelineOut); 189 190 angle::Result linkGraphicsPipelineLibraries(ContextVk *contextVk, 191 vk::PipelineCacheAccess *pipelineCache, 192 const vk::GraphicsPipelineDesc &desc, 193 vk::PipelineHelper *vertexInputPipeline, 194 vk::PipelineHelper *shadersPipeline, 195 vk::PipelineHelper *fragmentOutputPipeline, 196 const vk::GraphicsPipelineDesc **descPtrOut, 197 vk::PipelineHelper **pipelineOut); 198 199 angle::Result getOrCreateComputePipeline(vk::Context *context, 200 vk::PipelineCacheAccess *pipelineCache, 201 PipelineSource source, 202 vk::PipelineRobustness pipelineRobustness, 203 vk::PipelineProtectedAccess pipelineProtectedAccess, 204 vk::PipelineHelper **pipelineOut); 205 getPipelineLayout()206 const vk::PipelineLayout &getPipelineLayout() const { return *mPipelineLayout; } 207 void resetLayout(ContextVk *contextVk); 208 angle::Result createPipelineLayout(vk::Context *context, 209 PipelineLayoutCache *pipelineLayoutCache, 210 DescriptorSetLayoutCache *descriptorSetLayoutCache, 211 gl::ActiveTextureArray<TextureVk *> *activeTextures); 212 angle::Result initializeDescriptorPools( 213 vk::Context *context, 214 DescriptorSetLayoutCache *descriptorSetLayoutCache, 215 vk::DescriptorSetArray<vk::MetaDescriptorPool> *metaDescriptorPools); 216 217 angle::Result updateTexturesDescriptorSet(vk::Context *context, 218 uint32_t currentFrame, 219 const gl::ActiveTextureArray<TextureVk *> &textures, 220 const gl::SamplerBindingVector &samplers, 221 PipelineType pipelineType, 222 UpdateDescriptorSetsBuilder *updateBuilder); 223 224 angle::Result updateShaderResourcesDescriptorSet( 225 vk::Context *context, 226 uint32_t currentFrame, 227 UpdateDescriptorSetsBuilder *updateBuilder, 228 const vk::WriteDescriptorDescs &writeDescriptorDescs, 229 const vk::DescriptorSetDescBuilder &shaderResourcesDesc, 230 vk::SharedDescriptorSetCacheKey *newSharedCacheKeyOut); 231 232 angle::Result updateUniformsAndXfbDescriptorSet( 233 vk::Context *context, 234 uint32_t currentFrame, 235 UpdateDescriptorSetsBuilder *updateBuilder, 236 const vk::WriteDescriptorDescs &writeDescriptorDescs, 237 vk::BufferHelper *defaultUniformBuffer, 238 vk::DescriptorSetDescBuilder *uniformsAndXfbDesc, 239 vk::SharedDescriptorSetCacheKey *sharedCacheKeyOut); 240 241 template <typename CommandBufferT> 242 angle::Result bindDescriptorSets(vk::Context *context, 243 uint32_t currentFrame, 244 vk::CommandBufferHelperCommon *commandBufferHelper, 245 CommandBufferT *commandBuffer, 246 PipelineType pipelineType); 247 usesDynamicUniformBufferDescriptors()248 bool usesDynamicUniformBufferDescriptors() const 249 { 250 return mUniformBufferDescriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC; 251 } getUniformBufferDescriptorType()252 VkDescriptorType getUniformBufferDescriptorType() const { return mUniformBufferDescriptorType; } usesDynamicShaderStorageBufferDescriptors()253 bool usesDynamicShaderStorageBufferDescriptors() const { return false; } getStorageBufferDescriptorType()254 VkDescriptorType getStorageBufferDescriptorType() const 255 { 256 return VK_DESCRIPTOR_TYPE_STORAGE_BUFFER; 257 } getAtomicCounterBufferDescriptorType()258 VkDescriptorType getAtomicCounterBufferDescriptorType() const 259 { 260 return VK_DESCRIPTOR_TYPE_STORAGE_BUFFER; 261 } usesDynamicAtomicCounterBufferDescriptors()262 bool usesDynamicAtomicCounterBufferDescriptors() const { return false; } 263 areImmutableSamplersCompatible(const ImmutableSamplerIndexMap & immutableSamplerIndexMap)264 bool areImmutableSamplersCompatible( 265 const ImmutableSamplerIndexMap &immutableSamplerIndexMap) const 266 { 267 return (mImmutableSamplerIndexMap == immutableSamplerIndexMap); 268 } 269 getDefaultUniformAlignedSize(vk::Context * context,gl::ShaderType shaderType)270 size_t getDefaultUniformAlignedSize(vk::Context *context, gl::ShaderType shaderType) const 271 { 272 vk::Renderer *renderer = context->getRenderer(); 273 size_t alignment = static_cast<size_t>( 274 renderer->getPhysicalDeviceProperties().limits.minUniformBufferOffsetAlignment); 275 return roundUp(mDefaultUniformBlocks[shaderType]->uniformData.size(), alignment); 276 } 277 getSharedDefaultUniformBlock(gl::ShaderType shaderType)278 std::shared_ptr<BufferAndLayout> &getSharedDefaultUniformBlock(gl::ShaderType shaderType) 279 { 280 return mDefaultUniformBlocks[shaderType]; 281 } 282 updateAndCheckDirtyUniforms()283 bool updateAndCheckDirtyUniforms() 284 { 285 if (ANGLE_LIKELY(!mExecutable->IsPPO())) 286 { 287 return mDefaultUniformBlocksDirty.any(); 288 } 289 290 const auto &ppoExecutables = mExecutable->getPPOProgramExecutables(); 291 for (gl::ShaderType shaderType : mExecutable->getLinkedShaderStages()) 292 { 293 ProgramExecutableVk *executableVk = vk::GetImpl(ppoExecutables[shaderType].get()); 294 if (executableVk->mDefaultUniformBlocksDirty.test(shaderType)) 295 { 296 mDefaultUniformBlocksDirty.set(shaderType); 297 // Note: this relies on onProgramBind marking everything as dirty 298 executableVk->mDefaultUniformBlocksDirty.reset(shaderType); 299 } 300 } 301 302 return mDefaultUniformBlocksDirty.any(); 303 } 304 305 void setAllDefaultUniformsDirty(); 306 angle::Result updateUniforms(vk::Context *context, 307 uint32_t currentFrame, 308 UpdateDescriptorSetsBuilder *updateBuilder, 309 vk::BufferHelper *emptyBuffer, 310 vk::DynamicBuffer *defaultUniformStorage, 311 bool isTransformFeedbackActiveUnpaused, 312 TransformFeedbackVk *transformFeedbackVk); 313 void onProgramBind(); 314 getVariableInfoMap()315 const ShaderInterfaceVariableInfoMap &getVariableInfoMap() const { return mVariableInfoMap; } 316 warmUpPipelineCache(vk::Renderer * renderer,vk::PipelineRobustness pipelineRobustness,vk::PipelineProtectedAccess pipelineProtectedAccess)317 angle::Result warmUpPipelineCache(vk::Renderer *renderer, 318 vk::PipelineRobustness pipelineRobustness, 319 vk::PipelineProtectedAccess pipelineProtectedAccess) 320 { 321 return getPipelineCacheWarmUpTasks(renderer, pipelineRobustness, pipelineProtectedAccess, 322 nullptr); 323 } 324 angle::Result getPipelineCacheWarmUpTasks( 325 vk::Renderer *renderer, 326 vk::PipelineRobustness pipelineRobustness, 327 vk::PipelineProtectedAccess pipelineProtectedAccess, 328 std::vector<std::shared_ptr<LinkSubTask>> *postLinkSubTasksOut); 329 waitForPostLinkTasks(const gl::Context * context)330 void waitForPostLinkTasks(const gl::Context *context) override 331 { 332 ContextVk *contextVk = vk::GetImpl(context); 333 waitForPostLinkTasksImpl(contextVk); 334 } waitForComputePostLinkTasks(ContextVk * contextVk)335 void waitForComputePostLinkTasks(ContextVk *contextVk) 336 { 337 ASSERT(mExecutable->hasLinkedShaderStage(gl::ShaderType::Compute)); 338 waitForPostLinkTasksImpl(contextVk); 339 } 340 void waitForGraphicsPostLinkTasks(ContextVk *contextVk, 341 const vk::GraphicsPipelineDesc ¤tGraphicsPipelineDesc); 342 343 angle::Result mergePipelineCacheToRenderer(vk::Context *context) const; 344 getShaderResourceWriteDescriptorDescs()345 const vk::WriteDescriptorDescs &getShaderResourceWriteDescriptorDescs() const 346 { 347 return mShaderResourceWriteDescriptorDescs; 348 } getDefaultUniformWriteDescriptorDescs(TransformFeedbackVk * transformFeedbackVk)349 const vk::WriteDescriptorDescs &getDefaultUniformWriteDescriptorDescs( 350 TransformFeedbackVk *transformFeedbackVk) const 351 { 352 return transformFeedbackVk == nullptr ? mDefaultUniformWriteDescriptorDescs 353 : mDefaultUniformAndXfbWriteDescriptorDescs; 354 } 355 getTextureWriteDescriptorDescs()356 const vk::WriteDescriptorDescs &getTextureWriteDescriptorDescs() const 357 { 358 return mTextureWriteDescriptorDescs; 359 } 360 // The following functions are for internal use of programs, including from a threaded link job: 361 angle::Result resizeUniformBlockMemory(vk::Context *context, 362 const gl::ShaderMap<size_t> &requiredBufferSize); 363 void resolvePrecisionMismatch(const gl::ProgramMergedVaryings &mergedVaryings); initShaders(vk::Context * context,const gl::ShaderBitSet & linkedShaderStages,const gl::ShaderMap<const angle::spirv::Blob * > & spirvBlobs,bool isGLES1)364 angle::Result initShaders(vk::Context *context, 365 const gl::ShaderBitSet &linkedShaderStages, 366 const gl::ShaderMap<const angle::spirv::Blob *> &spirvBlobs, 367 bool isGLES1) 368 { 369 return mOriginalShaderInfo.initShaders(context, linkedShaderStages, spirvBlobs, 370 mVariableInfoMap, isGLES1); 371 } assignAllSpvLocations(vk::Context * context,const gl::ProgramState & programState,const gl::ProgramLinkedResources & resources)372 void assignAllSpvLocations(vk::Context *context, 373 const gl::ProgramState &programState, 374 const gl::ProgramLinkedResources &resources) 375 { 376 SpvSourceOptions options = SpvCreateSourceOptions( 377 context->getFeatures(), context->getRenderer()->getMaxColorInputAttachmentCount()); 378 SpvAssignAllLocations(options, programState, resources, &mVariableInfoMap); 379 } 380 381 private: 382 class WarmUpTaskCommon; 383 class WarmUpComputeTask; 384 class WarmUpGraphicsTask; 385 386 friend class ProgramVk; 387 friend class ProgramPipelineVk; 388 389 void reset(ContextVk *contextVk); 390 391 void addInterfaceBlockDescriptorSetDesc(const std::vector<gl::InterfaceBlock> &blocks, 392 gl::ShaderBitSet shaderTypes, 393 VkDescriptorType descType, 394 vk::DescriptorSetLayoutDesc *descOut); 395 void addAtomicCounterBufferDescriptorSetDesc( 396 const std::vector<gl::AtomicCounterBuffer> &atomicCounterBuffers, 397 vk::DescriptorSetLayoutDesc *descOut); 398 void addImageDescriptorSetDesc(vk::DescriptorSetLayoutDesc *descOut); 399 void addInputAttachmentDescriptorSetDesc(vk::Context *context, 400 vk::DescriptorSetLayoutDesc *descOut); 401 angle::Result addTextureDescriptorSetDesc( 402 vk::Context *context, 403 const gl::ActiveTextureArray<TextureVk *> *activeTextures, 404 vk::DescriptorSetLayoutDesc *descOut); 405 406 size_t calcUniformUpdateRequiredSpace(vk::Context *context, 407 gl::ShaderMap<VkDeviceSize> *uniformOffsets) const; 408 initProgram(vk::Context * context,gl::ShaderType shaderType,bool isLastPreFragmentStage,bool isTransformFeedbackProgram,ProgramTransformOptions optionBits,ProgramInfo * programInfo,const ShaderInterfaceVariableInfoMap & variableInfoMap)409 ANGLE_INLINE angle::Result initProgram(vk::Context *context, 410 gl::ShaderType shaderType, 411 bool isLastPreFragmentStage, 412 bool isTransformFeedbackProgram, 413 ProgramTransformOptions optionBits, 414 ProgramInfo *programInfo, 415 const ShaderInterfaceVariableInfoMap &variableInfoMap) 416 { 417 ASSERT(mOriginalShaderInfo.valid()); 418 419 // Create the program pipeline. This is done lazily and once per combination of 420 // specialization constants. 421 if (!programInfo->valid(shaderType)) 422 { 423 ANGLE_TRY(programInfo->initProgram(context, shaderType, isLastPreFragmentStage, 424 isTransformFeedbackProgram, mOriginalShaderInfo, 425 optionBits, variableInfoMap)); 426 } 427 ASSERT(programInfo->valid(shaderType)); 428 429 return angle::Result::Continue; 430 } 431 initGraphicsShaderProgram(vk::Context * context,gl::ShaderType shaderType,bool isLastPreFragmentStage,bool isTransformFeedbackProgram,ProgramTransformOptions optionBits,ProgramInfo * programInfo,const ShaderInterfaceVariableInfoMap & variableInfoMap)432 ANGLE_INLINE angle::Result initGraphicsShaderProgram( 433 vk::Context *context, 434 gl::ShaderType shaderType, 435 bool isLastPreFragmentStage, 436 bool isTransformFeedbackProgram, 437 ProgramTransformOptions optionBits, 438 ProgramInfo *programInfo, 439 const ShaderInterfaceVariableInfoMap &variableInfoMap) 440 { 441 mValidGraphicsPermutations.set(optionBits.permutationIndex); 442 return initProgram(context, shaderType, isLastPreFragmentStage, isTransformFeedbackProgram, 443 optionBits, programInfo, variableInfoMap); 444 } 445 initComputeProgram(vk::Context * context,ProgramInfo * programInfo,const ShaderInterfaceVariableInfoMap & variableInfoMap,const vk::ComputePipelineOptions & pipelineOptions)446 ANGLE_INLINE angle::Result initComputeProgram( 447 vk::Context *context, 448 ProgramInfo *programInfo, 449 const ShaderInterfaceVariableInfoMap &variableInfoMap, 450 const vk::ComputePipelineOptions &pipelineOptions) 451 { 452 mValidComputePermutations.set(pipelineOptions.permutationIndex); 453 ProgramTransformOptions optionBits = {}; 454 return initProgram(context, gl::ShaderType::Compute, false, false, optionBits, programInfo, 455 variableInfoMap); 456 } 457 458 ProgramTransformOptions getTransformOptions(ContextVk *contextVk, 459 const vk::GraphicsPipelineDesc &desc); 460 angle::Result initGraphicsShaderPrograms(vk::Context *context, 461 ProgramTransformOptions transformOptions); 462 angle::Result initProgramThenCreateGraphicsPipeline(vk::Context *context, 463 ProgramTransformOptions transformOptions, 464 vk::GraphicsPipelineSubset pipelineSubset, 465 vk::PipelineCacheAccess *pipelineCache, 466 PipelineSource source, 467 const vk::GraphicsPipelineDesc &desc, 468 const vk::RenderPass &compatibleRenderPass, 469 const vk::GraphicsPipelineDesc **descPtrOut, 470 vk::PipelineHelper **pipelineOut); 471 angle::Result createGraphicsPipelineImpl(vk::Context *context, 472 ProgramTransformOptions transformOptions, 473 vk::GraphicsPipelineSubset pipelineSubset, 474 vk::PipelineCacheAccess *pipelineCache, 475 PipelineSource source, 476 const vk::GraphicsPipelineDesc &desc, 477 const vk::RenderPass &compatibleRenderPass, 478 const vk::GraphicsPipelineDesc **descPtrOut, 479 vk::PipelineHelper **pipelineOut); 480 angle::Result prepareForWarmUpPipelineCache( 481 vk::Context *context, 482 vk::PipelineRobustness pipelineRobustness, 483 vk::PipelineProtectedAccess pipelineProtectedAccess, 484 vk::GraphicsPipelineSubset subset, 485 bool *isComputeOut, 486 angle::FixedVector<bool, 2> *surfaceRotationVariationsOut, 487 vk::GraphicsPipelineDesc **graphicsPipelineDescOut, 488 vk::RenderPass *renderPassOut); 489 angle::Result warmUpComputePipelineCache(vk::Context *context, 490 vk::PipelineRobustness pipelineRobustness, 491 vk::PipelineProtectedAccess pipelineProtectedAccess); 492 angle::Result warmUpGraphicsPipelineCache(vk::Context *context, 493 vk::PipelineRobustness pipelineRobustness, 494 vk::PipelineProtectedAccess pipelineProtectedAccess, 495 vk::GraphicsPipelineSubset subset, 496 const bool isSurfaceRotated, 497 const vk::GraphicsPipelineDesc &graphicsPipelineDesc, 498 const vk::RenderPass &renderPass, 499 vk::PipelineHelper *placeholderPipelineHelper); 500 void waitForPostLinkTasksImpl(ContextVk *contextVk); 501 502 angle::Result getOrAllocateDescriptorSet(vk::Context *context, 503 uint32_t currentFrame, 504 UpdateDescriptorSetsBuilder *updateBuilder, 505 const vk::DescriptorSetDescBuilder &descriptorSetDesc, 506 const vk::WriteDescriptorDescs &writeDescriptorDescs, 507 DescriptorSetIndex setIndex, 508 vk::SharedDescriptorSetCacheKey *newSharedCacheKeyOut); 509 510 // When loading from cache / binary, initialize the pipeline cache with given data. Otherwise 511 // the cache is lazily created as needed. 512 angle::Result initializePipelineCache(vk::Context *context, 513 bool compressed, 514 const std::vector<uint8_t> &pipelineData); 515 angle::Result ensurePipelineCacheInitialized(vk::Context *context); 516 517 void initializeWriteDescriptorDesc(vk::Context *context); 518 519 // Descriptor sets and pools for shader resources for this program. 520 vk::DescriptorSetArray<vk::DescriptorSetPointer> mDescriptorSets; 521 vk::DescriptorSetArray<vk::DynamicDescriptorPoolPointer> mDynamicDescriptorPools; 522 vk::BufferSerial mCurrentDefaultUniformBufferSerial; 523 524 // We keep a reference to the pipeline and descriptor set layouts. This ensures they don't get 525 // deleted while this program is in use. 526 uint32_t mImmutableSamplersMaxDescriptorCount; 527 ImmutableSamplerIndexMap mImmutableSamplerIndexMap; 528 vk::PipelineLayoutPtr mPipelineLayout; 529 vk::DescriptorSetLayoutPointerArray mDescriptorSetLayouts; 530 531 // A set of dynamic offsets used with vkCmdBindDescriptorSets for the default uniform buffers. 532 VkDescriptorType mUniformBufferDescriptorType; 533 gl::ShaderVector<uint32_t> mDynamicUniformDescriptorOffsets; 534 std::vector<uint32_t> mDynamicShaderResourceDescriptorOffsets; 535 536 ShaderInterfaceVariableInfoMap mVariableInfoMap; 537 538 static_assert((ProgramTransformOptions::kPermutationCount == 16), 539 "ProgramTransformOptions::kPermutationCount must be 16."); 540 angle::BitSet16<ProgramTransformOptions::kPermutationCount> mValidGraphicsPermutations; 541 542 static_assert((vk::ComputePipelineOptions::kPermutationCount == 4), 543 "ComputePipelineOptions::kPermutationCount must be 4."); 544 angle::BitSet8<vk::ComputePipelineOptions::kPermutationCount> mValidComputePermutations; 545 546 // We store all permutations of surface rotation and transformed SPIR-V programs here. We may 547 // need some LRU algorithm to free least used programs to reduce the number of programs. 548 ProgramInfo mGraphicsProgramInfos[ProgramTransformOptions::kPermutationCount]; 549 ProgramInfo mComputeProgramInfo; 550 551 // Pipeline caches. The pipelines are tightly coupled with the shaders they are created for, so 552 // they live in the program executable. With VK_EXT_graphics_pipeline_library, the pipeline is 553 // divided in subsets; the "shaders" subset is created based on the shaders, so its cache lives 554 // in the program executable. The "vertex input" and "fragment output" pipelines are 555 // independent, and live in the context. 556 CompleteGraphicsPipelineCache 557 mCompleteGraphicsPipelines[ProgramTransformOptions::kPermutationCount]; 558 ShadersGraphicsPipelineCache 559 mShadersGraphicsPipelines[ProgramTransformOptions::kPermutationCount]; 560 vk::ComputePipelineCache mComputePipelines; 561 562 DefaultUniformBlockMap mDefaultUniformBlocks; 563 gl::ShaderBitSet mDefaultUniformBlocksDirty; 564 565 ShaderInfo mOriginalShaderInfo; 566 567 // The pipeline cache specific to this program executable. Currently: 568 // 569 // - This is used during warm up (at link time) 570 // - The contents are merged to Renderer's pipeline cache immediately after warm up 571 // - The contents are returned as part of program binary 572 // - Draw-time pipeline creation uses Renderer's cache 573 // 574 // Without VK_EXT_graphics_pipeline_library, this cache is not used for draw-time pipeline 575 // creations to allow reuse of other blobs that are independent of the actual shaders; vertex 576 // input fetch, fragment output and blend. 577 // 578 // With VK_EXT_graphics_pipeline_library, this cache is used for the "shaders" subset of the 579 // pipeline. 580 vk::PipelineCache mPipelineCache; 581 582 vk::GraphicsPipelineDesc mWarmUpGraphicsPipelineDesc; 583 584 // The "layout" information for descriptorSets 585 vk::WriteDescriptorDescs mShaderResourceWriteDescriptorDescs; 586 vk::WriteDescriptorDescs mTextureWriteDescriptorDescs; 587 vk::WriteDescriptorDescs mDefaultUniformWriteDescriptorDescs; 588 vk::WriteDescriptorDescs mDefaultUniformAndXfbWriteDescriptorDescs; 589 590 vk::DescriptorSetLayoutDesc mShaderResourceSetDesc; 591 vk::DescriptorSetLayoutDesc mTextureSetDesc; 592 vk::DescriptorSetLayoutDesc mDefaultUniformAndXfbSetDesc; 593 }; 594 595 } // namespace rx 596 597 #endif // LIBANGLE_RENDERER_VULKAN_PROGRAMEXECUTABLEVK_H_ 598