GrVkPipelineStateCache.cpp 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. /*
  2. * Copyright 2016 Google Inc.
  3. *
  4. * Use of this source code is governed by a BSD-style license that can be
  5. * found in the LICENSE file.
  6. */
  7. #include "src/core/SkOpts.h"
  8. #include "src/gpu/GrProcessor.h"
  9. #include "src/gpu/GrRenderTargetPriv.h"
  10. #include "src/gpu/GrStencilSettings.h"
  11. #include "src/gpu/glsl/GrGLSLFragmentProcessor.h"
  12. #include "src/gpu/glsl/GrGLSLProgramDataManager.h"
  13. #include "src/gpu/vk/GrVkGpu.h"
  14. #include "src/gpu/vk/GrVkPipelineState.h"
  15. #include "src/gpu/vk/GrVkPipelineStateBuilder.h"
  16. #include "src/gpu/vk/GrVkResourceProvider.h"
  17. #ifdef GR_PIPELINE_STATE_CACHE_STATS
  18. // Display pipeline state cache usage
  19. static const bool c_DisplayVkPipelineCache{false};
  20. #endif
  21. struct GrVkResourceProvider::PipelineStateCache::Entry {
  22. Entry(GrVkGpu* gpu, GrVkPipelineState* pipelineState)
  23. : fGpu(gpu)
  24. , fPipelineState(pipelineState) {}
  25. ~Entry() {
  26. if (fPipelineState) {
  27. fPipelineState->freeGPUResources(fGpu);
  28. }
  29. }
  30. GrVkGpu* fGpu;
  31. std::unique_ptr<GrVkPipelineState> fPipelineState;
  32. };
  33. GrVkResourceProvider::PipelineStateCache::PipelineStateCache(GrVkGpu* gpu)
  34. : fMap(kMaxEntries)
  35. , fGpu(gpu)
  36. #ifdef GR_PIPELINE_STATE_CACHE_STATS
  37. , fTotalRequests(0)
  38. , fCacheMisses(0)
  39. #endif
  40. {}
  41. GrVkResourceProvider::PipelineStateCache::~PipelineStateCache() {
  42. SkASSERT(0 == fMap.count());
  43. // dump stats
  44. #ifdef GR_PIPELINE_STATE_CACHE_STATS
  45. if (c_DisplayVkPipelineCache) {
  46. SkDebugf("--- Pipeline State Cache ---\n");
  47. SkDebugf("Total requests: %d\n", fTotalRequests);
  48. SkDebugf("Cache misses: %d\n", fCacheMisses);
  49. SkDebugf("Cache miss %%: %f\n", (fTotalRequests > 0) ?
  50. 100.f * fCacheMisses / fTotalRequests :
  51. 0.f);
  52. SkDebugf("---------------------\n");
  53. }
  54. #endif
  55. }
  56. void GrVkResourceProvider::PipelineStateCache::abandon() {
  57. fMap.foreach([](std::unique_ptr<Entry>* e) {
  58. (*e)->fPipelineState->abandonGPUResources();
  59. (*e)->fPipelineState = nullptr;
  60. });
  61. fMap.reset();
  62. }
  63. void GrVkResourceProvider::PipelineStateCache::release() {
  64. fMap.reset();
  65. }
  66. GrVkPipelineState* GrVkResourceProvider::PipelineStateCache::refPipelineState(
  67. GrRenderTarget* renderTarget,
  68. GrSurfaceOrigin origin,
  69. const GrPrimitiveProcessor& primProc,
  70. const GrTextureProxy* const primProcProxies[],
  71. const GrPipeline& pipeline,
  72. GrPrimitiveType primitiveType,
  73. VkRenderPass compatibleRenderPass) {
  74. #ifdef GR_PIPELINE_STATE_CACHE_STATS
  75. ++fTotalRequests;
  76. #endif
  77. GrStencilSettings stencil;
  78. if (pipeline.isStencilEnabled()) {
  79. // TODO: attach stencil and create settings during render target flush.
  80. SkASSERT(renderTarget->renderTargetPriv().getStencilAttachment());
  81. stencil.reset(*pipeline.getUserStencil(), pipeline.hasStencilClip(),
  82. renderTarget->renderTargetPriv().numStencilBits());
  83. }
  84. // Get GrVkProgramDesc
  85. GrVkPipelineStateBuilder::Desc desc;
  86. if (!GrVkPipelineStateBuilder::Desc::Build(&desc, renderTarget, primProc, pipeline, stencil,
  87. primitiveType, fGpu)) {
  88. GrCapsDebugf(fGpu->caps(), "Failed to build vk program descriptor!\n");
  89. return nullptr;
  90. }
  91. // If we knew the shader won't depend on origin, we could skip this (and use the same program
  92. // for both origins). Instrumenting all fragment processors would be difficult and error prone.
  93. desc.setSurfaceOriginKey(GrGLSLFragmentShaderBuilder::KeyForSurfaceOrigin(origin));
  94. std::unique_ptr<Entry>* entry = fMap.find(desc);
  95. if (!entry) {
  96. #ifdef GR_PIPELINE_STATE_CACHE_STATS
  97. ++fCacheMisses;
  98. #endif
  99. GrVkPipelineState* pipelineState(GrVkPipelineStateBuilder::CreatePipelineState(
  100. fGpu, renderTarget, origin, primProc, primProcProxies, pipeline, stencil,
  101. primitiveType, &desc, compatibleRenderPass));
  102. if (nullptr == pipelineState) {
  103. return nullptr;
  104. }
  105. entry = fMap.insert(desc, std::unique_ptr<Entry>(new Entry(fGpu, pipelineState)));
  106. return (*entry)->fPipelineState.get();
  107. }
  108. return (*entry)->fPipelineState.get();
  109. }