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 
GrVkResourceProvider(GrVkGpu * gpu)20 GrVkResourceProvider::GrVkResourceProvider(GrVkGpu* gpu) : fGpu(gpu) {
21 }
22 
~GrVkResourceProvider()23 GrVkResourceProvider::~GrVkResourceProvider() {
24     SkASSERT(0 == fSimpleRenderPasses.count());
25 }
26 
createPipeline(const GrPipeline & pipeline,const GrPrimitiveProcessor & primProc,VkPipelineShaderStageCreateInfo * shaderStageInfo,int shaderStageCount,GrPrimitiveType primitiveType,const GrVkRenderPass & renderPass,VkPipelineLayout layout)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*
findOrCreateCompatibleRenderPass(const GrVkRenderTarget & target)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 
findOrCreateCompatibleDescriptorPool(const GrVkDescriptorPool::DescriptorTypeCounts & typeCounts)60 GrVkDescriptorPool* GrVkResourceProvider::findOrCreateCompatibleDescriptorPool(
61                                        const GrVkDescriptorPool::DescriptorTypeCounts& typeCounts) {
62     return new GrVkDescriptorPool(fGpu, typeCounts);
63 }
64 
createCommandBuffer()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 
checkCommandBuffers()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 
destroyResources()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 
abandonResources()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 }