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