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 8 #include "GrVkResourceProvider.h" 9 10 #include "GrVkCommandBuffer.h" 11 #include "GrVkPipeline.h" 12 #include "GrVkRenderPass.h" 13 #include "GrVkUtil.h" 14 15 #ifdef SK_TRACE_VK_RESOURCES 16 SkTDynamicHash<GrVkResource, uint32_t> GrVkResource::fTrace; 17 SkRandom GrVkResource::fRandom; 18 #endif 19 20 GrVkResourceProvider::GrVkResourceProvider(GrVkGpu* gpu) : fGpu(gpu) { 21 } 22 23 GrVkResourceProvider::~GrVkResourceProvider() { 24 SkASSERT(0 == fSimpleRenderPasses.count()); 25 } 26 27 GrVkPipeline* GrVkResourceProvider::createPipeline(const GrPipeline& pipeline, 28 const GrPrimitiveProcessor& primProc, 29 VkPipelineShaderStageCreateInfo* shaderStageInfo, 30 int shaderStageCount, 31 GrPrimitiveType primitiveType, 32 const GrVkRenderPass& renderPass, 33 VkPipelineLayout layout) { 34 35 return GrVkPipeline::Create(fGpu, pipeline, primProc, shaderStageInfo, shaderStageCount, 36 primitiveType, renderPass, layout); 37 } 38 39 40 // To create framebuffers, we first need to create a simple RenderPass that is 41 // only used for framebuffer creation. When we actually render we will create 42 // RenderPasses as needed that are compatible with the framebuffer. 43 const GrVkRenderPass* 44 GrVkResourceProvider::findOrCreateCompatibleRenderPass(const GrVkRenderTarget& target) { 45 for (int i = 0; i < fSimpleRenderPasses.count(); ++i) { 46 GrVkRenderPass* renderPass = fSimpleRenderPasses[i]; 47 if (renderPass->isCompatible(target)) { 48 renderPass->ref(); 49 return renderPass; 50 } 51 } 52 53 GrVkRenderPass* renderPass = new GrVkRenderPass(); 54 renderPass->initSimple(fGpu, target); 55 fSimpleRenderPasses.push_back(renderPass); 56 renderPass->ref(); 57 return renderPass; 58 } 59 60 GrVkDescriptorPool* GrVkResourceProvider::findOrCreateCompatibleDescriptorPool( 61 const GrVkDescriptorPool::DescriptorTypeCounts& typeCounts) { 62 return new GrVkDescriptorPool(fGpu, typeCounts); 63 } 64 65 GrVkCommandBuffer* GrVkResourceProvider::createCommandBuffer() { 66 GrVkCommandBuffer* cmdBuffer = GrVkCommandBuffer::Create(fGpu, fGpu->cmdPool()); 67 fActiveCommandBuffers.push_back(cmdBuffer); 68 cmdBuffer->ref(); 69 return cmdBuffer; 70 } 71 72 void GrVkResourceProvider::checkCommandBuffers() { 73 for (int i = fActiveCommandBuffers.count()-1; i >= 0; --i) { 74 if (fActiveCommandBuffers[i]->finished(fGpu)) { 75 fActiveCommandBuffers[i]->unref(fGpu); 76 fActiveCommandBuffers.removeShuffle(i); 77 } 78 } 79 } 80 81 void GrVkResourceProvider::destroyResources() { 82 // release our current command buffers 83 for (int i = 0; i < fActiveCommandBuffers.count(); ++i) { 84 SkASSERT(fActiveCommandBuffers[i]->finished(fGpu)); 85 SkASSERT(fActiveCommandBuffers[i]->unique()); 86 fActiveCommandBuffers[i]->unref(fGpu); 87 } 88 fActiveCommandBuffers.reset(); 89 90 // loop over all render passes to make sure we destroy all the internal VkRenderPasses 91 for (int i = 0; i < fSimpleRenderPasses.count(); ++i) { 92 fSimpleRenderPasses[i]->unref(fGpu); 93 } 94 fSimpleRenderPasses.reset(); 95 96 #ifdef SK_TRACE_VK_RESOURCES 97 SkASSERT(0 == GrVkResource::fTrace.count()); 98 #endif 99 100 } 101 102 void GrVkResourceProvider::abandonResources() { 103 // release our current command buffers 104 for (int i = 0; i < fActiveCommandBuffers.count(); ++i) { 105 SkASSERT(fActiveCommandBuffers[i]->finished(fGpu)); 106 fActiveCommandBuffers[i]->unrefAndAbandon(); 107 } 108 fActiveCommandBuffers.reset(); 109 110 for (int i = 0; i < fSimpleRenderPasses.count(); ++i) { 111 fSimpleRenderPasses[i]->unrefAndAbandon(); 112 } 113 fSimpleRenderPasses.reset(); 114 115 #ifdef SK_TRACE_VK_RESOURCES 116 SkASSERT(0 == GrVkResource::fTrace.count()); 117 #endif 118 }