GrVkResourceProvider.cpp 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579
  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/gpu/vk/GrVkResourceProvider.h"
  8. #include "include/gpu/GrSamplerState.h"
  9. #include "src/core/SkTaskGroup.h"
  10. #include "src/gpu/GrContextPriv.h"
  11. #include "src/gpu/vk/GrVkCommandBuffer.h"
  12. #include "src/gpu/vk/GrVkCommandPool.h"
  13. #include "src/gpu/vk/GrVkGpu.h"
  14. #include "src/gpu/vk/GrVkPipeline.h"
  15. #include "src/gpu/vk/GrVkRenderTarget.h"
  16. #include "src/gpu/vk/GrVkUniformBuffer.h"
  17. #include "src/gpu/vk/GrVkUtil.h"
  18. #ifdef SK_TRACE_VK_RESOURCES
  19. std::atomic<uint32_t> GrVkResource::fKeyCounter{0};
  20. #endif
  21. GrVkResourceProvider::GrVkResourceProvider(GrVkGpu* gpu)
  22. : fGpu(gpu)
  23. , fPipelineCache(VK_NULL_HANDLE) {
  24. fPipelineStateCache = new PipelineStateCache(gpu);
  25. }
  26. GrVkResourceProvider::~GrVkResourceProvider() {
  27. SkASSERT(0 == fRenderPassArray.count());
  28. SkASSERT(0 == fExternalRenderPasses.count());
  29. SkASSERT(VK_NULL_HANDLE == fPipelineCache);
  30. delete fPipelineStateCache;
  31. }
  32. VkPipelineCache GrVkResourceProvider::pipelineCache() {
  33. if (fPipelineCache == VK_NULL_HANDLE) {
  34. VkPipelineCacheCreateInfo createInfo;
  35. memset(&createInfo, 0, sizeof(VkPipelineCacheCreateInfo));
  36. createInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO;
  37. createInfo.pNext = nullptr;
  38. createInfo.flags = 0;
  39. auto persistentCache = fGpu->getContext()->priv().getPersistentCache();
  40. sk_sp<SkData> cached;
  41. if (persistentCache) {
  42. uint32_t key = GrVkGpu::kPipelineCache_PersistentCacheKeyType;
  43. sk_sp<SkData> keyData = SkData::MakeWithoutCopy(&key, sizeof(uint32_t));
  44. cached = persistentCache->load(*keyData);
  45. }
  46. bool usedCached = false;
  47. if (cached) {
  48. uint32_t* cacheHeader = (uint32_t*)cached->data();
  49. if (cacheHeader[1] == VK_PIPELINE_CACHE_HEADER_VERSION_ONE) {
  50. // For version one of the header, the total header size is 16 bytes plus
  51. // VK_UUID_SIZE bytes. See Section 9.6 (Pipeline Cache) in the vulkan spec to see
  52. // the breakdown of these bytes.
  53. SkASSERT(cacheHeader[0] == 16 + VK_UUID_SIZE);
  54. const VkPhysicalDeviceProperties& devProps = fGpu->physicalDeviceProperties();
  55. const uint8_t* supportedPipelineCacheUUID = devProps.pipelineCacheUUID;
  56. if (cacheHeader[2] == devProps.vendorID && cacheHeader[3] == devProps.deviceID &&
  57. !memcmp(&cacheHeader[4], supportedPipelineCacheUUID, VK_UUID_SIZE)) {
  58. createInfo.initialDataSize = cached->size();
  59. createInfo.pInitialData = cached->data();
  60. usedCached = true;
  61. }
  62. }
  63. }
  64. if (!usedCached) {
  65. createInfo.initialDataSize = 0;
  66. createInfo.pInitialData = nullptr;
  67. }
  68. VkResult result = GR_VK_CALL(fGpu->vkInterface(),
  69. CreatePipelineCache(fGpu->device(), &createInfo, nullptr,
  70. &fPipelineCache));
  71. SkASSERT(VK_SUCCESS == result);
  72. if (VK_SUCCESS != result) {
  73. fPipelineCache = VK_NULL_HANDLE;
  74. }
  75. }
  76. return fPipelineCache;
  77. }
  78. void GrVkResourceProvider::init() {
  79. // Init uniform descriptor objects
  80. GrVkDescriptorSetManager* dsm = GrVkDescriptorSetManager::CreateUniformManager(fGpu);
  81. fDescriptorSetManagers.emplace_back(dsm);
  82. SkASSERT(1 == fDescriptorSetManagers.count());
  83. fUniformDSHandle = GrVkDescriptorSetManager::Handle(0);
  84. }
  85. GrVkPipeline* GrVkResourceProvider::createPipeline(int numColorSamples,
  86. const GrPrimitiveProcessor& primProc,
  87. const GrPipeline& pipeline,
  88. const GrStencilSettings& stencil,
  89. GrSurfaceOrigin origin,
  90. VkPipelineShaderStageCreateInfo* shaderStageInfo,
  91. int shaderStageCount,
  92. GrPrimitiveType primitiveType,
  93. VkRenderPass compatibleRenderPass,
  94. VkPipelineLayout layout) {
  95. return GrVkPipeline::Create(
  96. fGpu, numColorSamples, primProc, pipeline, stencil, origin, shaderStageInfo,
  97. shaderStageCount, primitiveType, compatibleRenderPass, layout, this->pipelineCache());
  98. }
  99. // To create framebuffers, we first need to create a simple RenderPass that is
  100. // only used for framebuffer creation. When we actually render we will create
  101. // RenderPasses as needed that are compatible with the framebuffer.
  102. const GrVkRenderPass*
  103. GrVkResourceProvider::findCompatibleRenderPass(const GrVkRenderTarget& target,
  104. CompatibleRPHandle* compatibleHandle) {
  105. for (int i = 0; i < fRenderPassArray.count(); ++i) {
  106. if (fRenderPassArray[i].isCompatible(target)) {
  107. const GrVkRenderPass* renderPass = fRenderPassArray[i].getCompatibleRenderPass();
  108. renderPass->ref();
  109. if (compatibleHandle) {
  110. *compatibleHandle = CompatibleRPHandle(i);
  111. }
  112. return renderPass;
  113. }
  114. }
  115. const GrVkRenderPass* renderPass =
  116. fRenderPassArray.emplace_back(fGpu, target).getCompatibleRenderPass();
  117. renderPass->ref();
  118. if (compatibleHandle) {
  119. *compatibleHandle = CompatibleRPHandle(fRenderPassArray.count() - 1);
  120. }
  121. return renderPass;
  122. }
  123. const GrVkRenderPass*
  124. GrVkResourceProvider::findCompatibleRenderPass(const CompatibleRPHandle& compatibleHandle) {
  125. SkASSERT(compatibleHandle.isValid() && compatibleHandle.toIndex() < fRenderPassArray.count());
  126. int index = compatibleHandle.toIndex();
  127. const GrVkRenderPass* renderPass = fRenderPassArray[index].getCompatibleRenderPass();
  128. renderPass->ref();
  129. return renderPass;
  130. }
  131. const GrVkRenderPass* GrVkResourceProvider::findCompatibleExternalRenderPass(
  132. VkRenderPass renderPass, uint32_t colorAttachmentIndex) {
  133. for (int i = 0; i < fExternalRenderPasses.count(); ++i) {
  134. if (fExternalRenderPasses[i]->isCompatibleExternalRP(renderPass)) {
  135. fExternalRenderPasses[i]->ref();
  136. #ifdef SK_DEBUG
  137. uint32_t cachedColorIndex;
  138. SkASSERT(fExternalRenderPasses[i]->colorAttachmentIndex(&cachedColorIndex));
  139. SkASSERT(cachedColorIndex == colorAttachmentIndex);
  140. #endif
  141. return fExternalRenderPasses[i];
  142. }
  143. }
  144. const GrVkRenderPass* newRenderPass = new GrVkRenderPass(renderPass, colorAttachmentIndex);
  145. fExternalRenderPasses.push_back(newRenderPass);
  146. newRenderPass->ref();
  147. return newRenderPass;
  148. }
  149. const GrVkRenderPass* GrVkResourceProvider::findRenderPass(
  150. const GrVkRenderTarget& target,
  151. const GrVkRenderPass::LoadStoreOps& colorOps,
  152. const GrVkRenderPass::LoadStoreOps& stencilOps,
  153. CompatibleRPHandle* compatibleHandle) {
  154. GrVkResourceProvider::CompatibleRPHandle tempRPHandle;
  155. GrVkResourceProvider::CompatibleRPHandle* pRPHandle = compatibleHandle ? compatibleHandle
  156. : &tempRPHandle;
  157. *pRPHandle = target.compatibleRenderPassHandle();
  158. // This will get us the handle to (and possible create) the compatible set for the specific
  159. // GrVkRenderPass we are looking for.
  160. this->findCompatibleRenderPass(target, compatibleHandle);
  161. return this->findRenderPass(*pRPHandle, colorOps, stencilOps);
  162. }
  163. const GrVkRenderPass*
  164. GrVkResourceProvider::findRenderPass(const CompatibleRPHandle& compatibleHandle,
  165. const GrVkRenderPass::LoadStoreOps& colorOps,
  166. const GrVkRenderPass::LoadStoreOps& stencilOps) {
  167. SkASSERT(compatibleHandle.isValid() && compatibleHandle.toIndex() < fRenderPassArray.count());
  168. CompatibleRenderPassSet& compatibleSet = fRenderPassArray[compatibleHandle.toIndex()];
  169. const GrVkRenderPass* renderPass = compatibleSet.getRenderPass(fGpu,
  170. colorOps,
  171. stencilOps);
  172. renderPass->ref();
  173. return renderPass;
  174. }
  175. GrVkDescriptorPool* GrVkResourceProvider::findOrCreateCompatibleDescriptorPool(
  176. VkDescriptorType type, uint32_t count) {
  177. return new GrVkDescriptorPool(fGpu, type, count);
  178. }
  179. GrVkSampler* GrVkResourceProvider::findOrCreateCompatibleSampler(
  180. const GrSamplerState& params, const GrVkYcbcrConversionInfo& ycbcrInfo) {
  181. GrVkSampler* sampler = fSamplers.find(GrVkSampler::GenerateKey(params, ycbcrInfo));
  182. if (!sampler) {
  183. sampler = GrVkSampler::Create(fGpu, params, ycbcrInfo);
  184. if (!sampler) {
  185. return nullptr;
  186. }
  187. fSamplers.add(sampler);
  188. }
  189. SkASSERT(sampler);
  190. sampler->ref();
  191. return sampler;
  192. }
  193. GrVkSamplerYcbcrConversion* GrVkResourceProvider::findOrCreateCompatibleSamplerYcbcrConversion(
  194. const GrVkYcbcrConversionInfo& ycbcrInfo) {
  195. GrVkSamplerYcbcrConversion* ycbcrConversion =
  196. fYcbcrConversions.find(GrVkSamplerYcbcrConversion::GenerateKey(ycbcrInfo));
  197. if (!ycbcrConversion) {
  198. ycbcrConversion = GrVkSamplerYcbcrConversion::Create(fGpu, ycbcrInfo);
  199. if (!ycbcrConversion) {
  200. return nullptr;
  201. }
  202. fYcbcrConversions.add(ycbcrConversion);
  203. }
  204. SkASSERT(ycbcrConversion);
  205. ycbcrConversion->ref();
  206. return ycbcrConversion;
  207. }
  208. GrVkPipelineState* GrVkResourceProvider::findOrCreateCompatiblePipelineState(
  209. GrRenderTarget* renderTarget, GrSurfaceOrigin origin,
  210. const GrPipeline& pipeline, const GrPrimitiveProcessor& proc,
  211. const GrTextureProxy* const primProcProxies[], GrPrimitiveType primitiveType,
  212. VkRenderPass compatibleRenderPass) {
  213. return fPipelineStateCache->refPipelineState(renderTarget, origin, proc, primProcProxies,
  214. pipeline, primitiveType, compatibleRenderPass);
  215. }
  216. void GrVkResourceProvider::getSamplerDescriptorSetHandle(VkDescriptorType type,
  217. const GrVkUniformHandler& uniformHandler,
  218. GrVkDescriptorSetManager::Handle* handle) {
  219. SkASSERT(handle);
  220. SkASSERT(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER == type ||
  221. VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER == type);
  222. for (int i = 0; i < fDescriptorSetManagers.count(); ++i) {
  223. if (fDescriptorSetManagers[i]->isCompatible(type, &uniformHandler)) {
  224. *handle = GrVkDescriptorSetManager::Handle(i);
  225. return;
  226. }
  227. }
  228. GrVkDescriptorSetManager* dsm = GrVkDescriptorSetManager::CreateSamplerManager(fGpu, type,
  229. uniformHandler);
  230. fDescriptorSetManagers.emplace_back(dsm);
  231. *handle = GrVkDescriptorSetManager::Handle(fDescriptorSetManagers.count() - 1);
  232. }
  233. void GrVkResourceProvider::getSamplerDescriptorSetHandle(VkDescriptorType type,
  234. const SkTArray<uint32_t>& visibilities,
  235. GrVkDescriptorSetManager::Handle* handle) {
  236. SkASSERT(handle);
  237. SkASSERT(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER == type ||
  238. VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER == type);
  239. for (int i = 0; i < fDescriptorSetManagers.count(); ++i) {
  240. if (fDescriptorSetManagers[i]->isCompatible(type, visibilities)) {
  241. *handle = GrVkDescriptorSetManager::Handle(i);
  242. return;
  243. }
  244. }
  245. GrVkDescriptorSetManager* dsm = GrVkDescriptorSetManager::CreateSamplerManager(fGpu, type,
  246. visibilities);
  247. fDescriptorSetManagers.emplace_back(dsm);
  248. *handle = GrVkDescriptorSetManager::Handle(fDescriptorSetManagers.count() - 1);
  249. }
  250. VkDescriptorSetLayout GrVkResourceProvider::getUniformDSLayout() const {
  251. SkASSERT(fUniformDSHandle.isValid());
  252. return fDescriptorSetManagers[fUniformDSHandle.toIndex()]->layout();
  253. }
  254. VkDescriptorSetLayout GrVkResourceProvider::getSamplerDSLayout(
  255. const GrVkDescriptorSetManager::Handle& handle) const {
  256. SkASSERT(handle.isValid());
  257. return fDescriptorSetManagers[handle.toIndex()]->layout();
  258. }
  259. const GrVkDescriptorSet* GrVkResourceProvider::getUniformDescriptorSet() {
  260. SkASSERT(fUniformDSHandle.isValid());
  261. return fDescriptorSetManagers[fUniformDSHandle.toIndex()]->getDescriptorSet(fGpu,
  262. fUniformDSHandle);
  263. }
  264. const GrVkDescriptorSet* GrVkResourceProvider::getSamplerDescriptorSet(
  265. const GrVkDescriptorSetManager::Handle& handle) {
  266. SkASSERT(handle.isValid());
  267. return fDescriptorSetManagers[handle.toIndex()]->getDescriptorSet(fGpu, handle);
  268. }
  269. void GrVkResourceProvider::recycleDescriptorSet(const GrVkDescriptorSet* descSet,
  270. const GrVkDescriptorSetManager::Handle& handle) {
  271. SkASSERT(descSet);
  272. SkASSERT(handle.isValid());
  273. int managerIdx = handle.toIndex();
  274. SkASSERT(managerIdx < fDescriptorSetManagers.count());
  275. fDescriptorSetManagers[managerIdx]->recycleDescriptorSet(descSet);
  276. }
  277. GrVkCommandPool* GrVkResourceProvider::findOrCreateCommandPool() {
  278. std::unique_lock<std::recursive_mutex> lock(fBackgroundMutex);
  279. GrVkCommandPool* result;
  280. if (fAvailableCommandPools.count()) {
  281. result = fAvailableCommandPools.back();
  282. fAvailableCommandPools.pop_back();
  283. } else {
  284. result = GrVkCommandPool::Create(fGpu);
  285. }
  286. SkASSERT(result->unique());
  287. SkDEBUGCODE(
  288. for (const GrVkCommandPool* pool : fActiveCommandPools) {
  289. SkASSERT(pool != result);
  290. }
  291. for (const GrVkCommandPool* pool : fAvailableCommandPools) {
  292. SkASSERT(pool != result);
  293. }
  294. )
  295. fActiveCommandPools.push_back(result);
  296. result->ref();
  297. return result;
  298. }
  299. void GrVkResourceProvider::checkCommandBuffers() {
  300. for (int i = fActiveCommandPools.count() - 1; i >= 0; --i) {
  301. GrVkCommandPool* pool = fActiveCommandPools[i];
  302. if (!pool->isOpen()) {
  303. GrVkPrimaryCommandBuffer* buffer = pool->getPrimaryCommandBuffer();
  304. if (buffer->finished(fGpu)) {
  305. fActiveCommandPools.removeShuffle(i);
  306. this->backgroundReset(pool);
  307. }
  308. }
  309. }
  310. }
  311. void GrVkResourceProvider::addFinishedProcToActiveCommandBuffers(
  312. GrGpuFinishedProc finishedProc, GrGpuFinishedContext finishedContext) {
  313. sk_sp<GrRefCntedCallback> procRef(new GrRefCntedCallback(finishedProc, finishedContext));
  314. for (int i = 0; i < fActiveCommandPools.count(); ++i) {
  315. GrVkCommandPool* pool = fActiveCommandPools[i];
  316. if (!pool->isOpen()) {
  317. GrVkPrimaryCommandBuffer* buffer = pool->getPrimaryCommandBuffer();
  318. buffer->addFinishedProc(procRef);
  319. }
  320. }
  321. }
  322. const GrVkResource* GrVkResourceProvider::findOrCreateStandardUniformBufferResource() {
  323. const GrVkResource* resource = nullptr;
  324. int count = fAvailableUniformBufferResources.count();
  325. if (count > 0) {
  326. resource = fAvailableUniformBufferResources[count - 1];
  327. fAvailableUniformBufferResources.removeShuffle(count - 1);
  328. } else {
  329. resource = GrVkUniformBuffer::CreateResource(fGpu, GrVkUniformBuffer::kStandardSize);
  330. }
  331. return resource;
  332. }
  333. void GrVkResourceProvider::recycleStandardUniformBufferResource(const GrVkResource* resource) {
  334. fAvailableUniformBufferResources.push_back(resource);
  335. }
  336. void GrVkResourceProvider::destroyResources(bool deviceLost) {
  337. SkTaskGroup* taskGroup = fGpu->getContext()->priv().getTaskGroup();
  338. if (taskGroup) {
  339. taskGroup->wait();
  340. }
  341. // loop over all render pass sets to make sure we destroy all the internal VkRenderPasses
  342. for (int i = 0; i < fRenderPassArray.count(); ++i) {
  343. fRenderPassArray[i].releaseResources(fGpu);
  344. }
  345. fRenderPassArray.reset();
  346. for (int i = 0; i < fExternalRenderPasses.count(); ++i) {
  347. fExternalRenderPasses[i]->unref(fGpu);
  348. }
  349. fExternalRenderPasses.reset();
  350. // Iterate through all store GrVkSamplers and unref them before resetting the hash.
  351. SkTDynamicHash<GrVkSampler, GrVkSampler::Key>::Iter iter(&fSamplers);
  352. for (; !iter.done(); ++iter) {
  353. (*iter).unref(fGpu);
  354. }
  355. fSamplers.reset();
  356. fPipelineStateCache->release();
  357. GR_VK_CALL(fGpu->vkInterface(), DestroyPipelineCache(fGpu->device(), fPipelineCache, nullptr));
  358. fPipelineCache = VK_NULL_HANDLE;
  359. for (GrVkCommandPool* pool : fActiveCommandPools) {
  360. SkASSERT(pool->unique());
  361. pool->unref(fGpu);
  362. }
  363. fActiveCommandPools.reset();
  364. for (GrVkCommandPool* pool : fAvailableCommandPools) {
  365. SkASSERT(pool->unique());
  366. pool->unref(fGpu);
  367. }
  368. fAvailableCommandPools.reset();
  369. // We must release/destroy all command buffers and pipeline states before releasing the
  370. // GrVkDescriptorSetManagers
  371. for (int i = 0; i < fDescriptorSetManagers.count(); ++i) {
  372. fDescriptorSetManagers[i]->release(fGpu);
  373. }
  374. fDescriptorSetManagers.reset();
  375. // release our uniform buffers
  376. for (int i = 0; i < fAvailableUniformBufferResources.count(); ++i) {
  377. SkASSERT(fAvailableUniformBufferResources[i]->unique());
  378. fAvailableUniformBufferResources[i]->unref(fGpu);
  379. }
  380. fAvailableUniformBufferResources.reset();
  381. }
  382. void GrVkResourceProvider::abandonResources() {
  383. SkTaskGroup* taskGroup = fGpu->getContext()->priv().getTaskGroup();
  384. if (taskGroup) {
  385. taskGroup->wait();
  386. }
  387. // Abandon all command pools
  388. for (int i = 0; i < fActiveCommandPools.count(); ++i) {
  389. SkASSERT(fActiveCommandPools[i]->unique());
  390. fActiveCommandPools[i]->unrefAndAbandon();
  391. }
  392. fActiveCommandPools.reset();
  393. for (int i = 0; i < fAvailableCommandPools.count(); ++i) {
  394. SkASSERT(fAvailableCommandPools[i]->unique());
  395. fAvailableCommandPools[i]->unrefAndAbandon();
  396. }
  397. fAvailableCommandPools.reset();
  398. // loop over all render pass sets to make sure we destroy all the internal VkRenderPasses
  399. for (int i = 0; i < fRenderPassArray.count(); ++i) {
  400. fRenderPassArray[i].abandonResources();
  401. }
  402. fRenderPassArray.reset();
  403. for (int i = 0; i < fExternalRenderPasses.count(); ++i) {
  404. fExternalRenderPasses[i]->unrefAndAbandon();
  405. }
  406. fExternalRenderPasses.reset();
  407. // Iterate through all store GrVkSamplers and unrefAndAbandon them before resetting the hash.
  408. SkTDynamicHash<GrVkSampler, GrVkSampler::Key>::Iter iter(&fSamplers);
  409. for (; !iter.done(); ++iter) {
  410. (*iter).unrefAndAbandon();
  411. }
  412. fSamplers.reset();
  413. fPipelineStateCache->abandon();
  414. fPipelineCache = VK_NULL_HANDLE;
  415. // We must abandon all command buffers and pipeline states before abandoning the
  416. // GrVkDescriptorSetManagers
  417. for (int i = 0; i < fDescriptorSetManagers.count(); ++i) {
  418. fDescriptorSetManagers[i]->abandon();
  419. }
  420. fDescriptorSetManagers.reset();
  421. // release our uniform buffers
  422. for (int i = 0; i < fAvailableUniformBufferResources.count(); ++i) {
  423. SkASSERT(fAvailableUniformBufferResources[i]->unique());
  424. fAvailableUniformBufferResources[i]->unrefAndAbandon();
  425. }
  426. fAvailableUniformBufferResources.reset();
  427. }
  428. void GrVkResourceProvider::backgroundReset(GrVkCommandPool* pool) {
  429. TRACE_EVENT0("skia.gpu", TRACE_FUNC);
  430. SkASSERT(pool->unique());
  431. pool->releaseResources(fGpu);
  432. SkTaskGroup* taskGroup = fGpu->getContext()->priv().getTaskGroup();
  433. if (taskGroup) {
  434. taskGroup->add([this, pool]() {
  435. this->reset(pool);
  436. });
  437. } else {
  438. this->reset(pool);
  439. }
  440. }
  441. void GrVkResourceProvider::reset(GrVkCommandPool* pool) {
  442. TRACE_EVENT0("skia.gpu", TRACE_FUNC);
  443. SkASSERT(pool->unique());
  444. pool->reset(fGpu);
  445. std::unique_lock<std::recursive_mutex> providerLock(fBackgroundMutex);
  446. fAvailableCommandPools.push_back(pool);
  447. }
  448. void GrVkResourceProvider::storePipelineCacheData() {
  449. size_t dataSize = 0;
  450. VkResult result = GR_VK_CALL(fGpu->vkInterface(), GetPipelineCacheData(fGpu->device(),
  451. this->pipelineCache(),
  452. &dataSize, nullptr));
  453. SkASSERT(result == VK_SUCCESS);
  454. std::unique_ptr<uint8_t[]> data(new uint8_t[dataSize]);
  455. result = GR_VK_CALL(fGpu->vkInterface(), GetPipelineCacheData(fGpu->device(),
  456. this->pipelineCache(),
  457. &dataSize,
  458. (void*)data.get()));
  459. SkASSERT(result == VK_SUCCESS);
  460. uint32_t key = GrVkGpu::kPipelineCache_PersistentCacheKeyType;
  461. sk_sp<SkData> keyData = SkData::MakeWithoutCopy(&key, sizeof(uint32_t));
  462. fGpu->getContext()->priv().getPersistentCache()->store(
  463. *keyData, *SkData::MakeWithoutCopy(data.get(), dataSize));
  464. }
  465. ////////////////////////////////////////////////////////////////////////////////
  466. GrVkResourceProvider::CompatibleRenderPassSet::CompatibleRenderPassSet(
  467. const GrVkGpu* gpu,
  468. const GrVkRenderTarget& target)
  469. : fLastReturnedIndex(0) {
  470. fRenderPasses.emplace_back(new GrVkRenderPass());
  471. fRenderPasses[0]->initSimple(gpu, target);
  472. }
  473. bool GrVkResourceProvider::CompatibleRenderPassSet::isCompatible(
  474. const GrVkRenderTarget& target) const {
  475. // The first GrVkRenderpass should always exists since we create the basic load store
  476. // render pass on create
  477. SkASSERT(fRenderPasses[0]);
  478. return fRenderPasses[0]->isCompatible(target);
  479. }
  480. GrVkRenderPass* GrVkResourceProvider::CompatibleRenderPassSet::getRenderPass(
  481. const GrVkGpu* gpu,
  482. const GrVkRenderPass::LoadStoreOps& colorOps,
  483. const GrVkRenderPass::LoadStoreOps& stencilOps) {
  484. for (int i = 0; i < fRenderPasses.count(); ++i) {
  485. int idx = (i + fLastReturnedIndex) % fRenderPasses.count();
  486. if (fRenderPasses[idx]->equalLoadStoreOps(colorOps, stencilOps)) {
  487. fLastReturnedIndex = idx;
  488. return fRenderPasses[idx];
  489. }
  490. }
  491. GrVkRenderPass* renderPass = fRenderPasses.emplace_back(new GrVkRenderPass());
  492. renderPass->init(gpu, *this->getCompatibleRenderPass(), colorOps, stencilOps);
  493. fLastReturnedIndex = fRenderPasses.count() - 1;
  494. return renderPass;
  495. }
  496. void GrVkResourceProvider::CompatibleRenderPassSet::releaseResources(GrVkGpu* gpu) {
  497. for (int i = 0; i < fRenderPasses.count(); ++i) {
  498. if (fRenderPasses[i]) {
  499. fRenderPasses[i]->unref(gpu);
  500. fRenderPasses[i] = nullptr;
  501. }
  502. }
  503. }
  504. void GrVkResourceProvider::CompatibleRenderPassSet::abandonResources() {
  505. for (int i = 0; i < fRenderPasses.count(); ++i) {
  506. if (fRenderPasses[i]) {
  507. fRenderPasses[i]->unrefAndAbandon();
  508. fRenderPasses[i] = nullptr;
  509. }
  510. }
  511. }