blob: b273e3b65dfde724b887ce1c2d8f277a82cdfb22 [file] [log] [blame]
Greg Daniel164a9f02016-02-22 09:56:40 -05001/*
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
egdaniel8b6394c2016-03-04 07:35:10 -080010#include "GrTextureParams.h"
Greg Daniel164a9f02016-02-22 09:56:40 -050011#include "GrVkCommandBuffer.h"
12#include "GrVkPipeline.h"
13#include "GrVkRenderPass.h"
egdaniel8b6394c2016-03-04 07:35:10 -080014#include "GrVkSampler.h"
Greg Daniel164a9f02016-02-22 09:56:40 -050015#include "GrVkUtil.h"
16
17#ifdef SK_TRACE_VK_RESOURCES
18SkTDynamicHash<GrVkResource, uint32_t> GrVkResource::fTrace;
19SkRandom GrVkResource::fRandom;
20#endif
21
jvanverth03509ea2016-03-02 13:19:47 -080022GrVkResourceProvider::GrVkResourceProvider(GrVkGpu* gpu) : fGpu(gpu)
23 , fPipelineCache(VK_NULL_HANDLE) {
Greg Daniel164a9f02016-02-22 09:56:40 -050024}
25
26GrVkResourceProvider::~GrVkResourceProvider() {
27 SkASSERT(0 == fSimpleRenderPasses.count());
jvanverth03509ea2016-03-02 13:19:47 -080028 SkASSERT(VK_NULL_HANDLE == fPipelineCache);
29}
30
31void GrVkResourceProvider::init() {
32 VkPipelineCacheCreateInfo createInfo;
33 memset(&createInfo, 0, sizeof(VkPipelineCacheCreateInfo));
34 createInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO;
35 createInfo.pNext = nullptr;
36 createInfo.flags = 0;
37 createInfo.initialDataSize = 0;
38 createInfo.pInitialData = nullptr;
39 VkResult result = GR_VK_CALL(fGpu->vkInterface(),
40 CreatePipelineCache(fGpu->device(), &createInfo, nullptr,
41 &fPipelineCache));
42 SkASSERT(VK_SUCCESS == result);
43 if (VK_SUCCESS != result) {
44 fPipelineCache = VK_NULL_HANDLE;
45 }
Greg Daniel164a9f02016-02-22 09:56:40 -050046}
47
48GrVkPipeline* GrVkResourceProvider::createPipeline(const GrPipeline& pipeline,
49 const GrPrimitiveProcessor& primProc,
50 VkPipelineShaderStageCreateInfo* shaderStageInfo,
51 int shaderStageCount,
52 GrPrimitiveType primitiveType,
53 const GrVkRenderPass& renderPass,
54 VkPipelineLayout layout) {
55
56 return GrVkPipeline::Create(fGpu, pipeline, primProc, shaderStageInfo, shaderStageCount,
jvanverth03509ea2016-03-02 13:19:47 -080057 primitiveType, renderPass, layout, fPipelineCache);
Greg Daniel164a9f02016-02-22 09:56:40 -050058}
59
60
61// To create framebuffers, we first need to create a simple RenderPass that is
62// only used for framebuffer creation. When we actually render we will create
63// RenderPasses as needed that are compatible with the framebuffer.
64const GrVkRenderPass*
65GrVkResourceProvider::findOrCreateCompatibleRenderPass(const GrVkRenderTarget& target) {
66 for (int i = 0; i < fSimpleRenderPasses.count(); ++i) {
67 GrVkRenderPass* renderPass = fSimpleRenderPasses[i];
68 if (renderPass->isCompatible(target)) {
69 renderPass->ref();
70 return renderPass;
71 }
72 }
73
74 GrVkRenderPass* renderPass = new GrVkRenderPass();
75 renderPass->initSimple(fGpu, target);
76 fSimpleRenderPasses.push_back(renderPass);
77 renderPass->ref();
78 return renderPass;
79}
80
81GrVkDescriptorPool* GrVkResourceProvider::findOrCreateCompatibleDescriptorPool(
82 const GrVkDescriptorPool::DescriptorTypeCounts& typeCounts) {
83 return new GrVkDescriptorPool(fGpu, typeCounts);
84}
85
egdaniel8b6394c2016-03-04 07:35:10 -080086GrVkSampler* GrVkResourceProvider::findOrCreateCompatibleSampler(const GrTextureParams& params) {
87 GrVkSampler* sampler = fSamplers.find(GrVkSampler::GenerateKey(params));
88 if (!sampler) {
89 sampler = GrVkSampler::Create(fGpu, params);
90 fSamplers.add(sampler);
91 }
92 SkASSERT(sampler);
93 sampler->ref();
94 return sampler;
95}
96
Greg Daniel164a9f02016-02-22 09:56:40 -050097GrVkCommandBuffer* GrVkResourceProvider::createCommandBuffer() {
98 GrVkCommandBuffer* cmdBuffer = GrVkCommandBuffer::Create(fGpu, fGpu->cmdPool());
99 fActiveCommandBuffers.push_back(cmdBuffer);
100 cmdBuffer->ref();
101 return cmdBuffer;
102}
103
104void GrVkResourceProvider::checkCommandBuffers() {
105 for (int i = fActiveCommandBuffers.count()-1; i >= 0; --i) {
106 if (fActiveCommandBuffers[i]->finished(fGpu)) {
107 fActiveCommandBuffers[i]->unref(fGpu);
108 fActiveCommandBuffers.removeShuffle(i);
109 }
110 }
111}
112
113void GrVkResourceProvider::destroyResources() {
114 // release our current command buffers
115 for (int i = 0; i < fActiveCommandBuffers.count(); ++i) {
116 SkASSERT(fActiveCommandBuffers[i]->finished(fGpu));
117 SkASSERT(fActiveCommandBuffers[i]->unique());
118 fActiveCommandBuffers[i]->unref(fGpu);
119 }
120 fActiveCommandBuffers.reset();
121
122 // loop over all render passes to make sure we destroy all the internal VkRenderPasses
123 for (int i = 0; i < fSimpleRenderPasses.count(); ++i) {
124 fSimpleRenderPasses[i]->unref(fGpu);
125 }
126 fSimpleRenderPasses.reset();
127
egdaniel8b6394c2016-03-04 07:35:10 -0800128 // Iterate through all store GrVkSamplers and unref them before resetting the hash.
129 SkTDynamicHash<GrVkSampler, uint8_t>::Iter iter(&fSamplers);
130 for (; !iter.done(); ++iter) {
131 (*iter).unref(fGpu);
132 }
133 fSamplers.reset();
134
Greg Daniel164a9f02016-02-22 09:56:40 -0500135#ifdef SK_TRACE_VK_RESOURCES
136 SkASSERT(0 == GrVkResource::fTrace.count());
137#endif
138
jvanverth03509ea2016-03-02 13:19:47 -0800139 GR_VK_CALL(fGpu->vkInterface(), DestroyPipelineCache(fGpu->device(), fPipelineCache, nullptr));
140 fPipelineCache = VK_NULL_HANDLE;
Greg Daniel164a9f02016-02-22 09:56:40 -0500141}
142
143void GrVkResourceProvider::abandonResources() {
144 // release our current command buffers
145 for (int i = 0; i < fActiveCommandBuffers.count(); ++i) {
146 SkASSERT(fActiveCommandBuffers[i]->finished(fGpu));
147 fActiveCommandBuffers[i]->unrefAndAbandon();
148 }
149 fActiveCommandBuffers.reset();
150
151 for (int i = 0; i < fSimpleRenderPasses.count(); ++i) {
152 fSimpleRenderPasses[i]->unrefAndAbandon();
153 }
154 fSimpleRenderPasses.reset();
155
egdaniel8b6394c2016-03-04 07:35:10 -0800156 // Iterate through all store GrVkSamplers and unrefAndAbandon them before resetting the hash.
157 SkTDynamicHash<GrVkSampler, uint8_t>::Iter iter(&fSamplers);
158 for (; !iter.done(); ++iter) {
159 (*iter).unrefAndAbandon();
160 }
161 fSamplers.reset();
162
Greg Daniel164a9f02016-02-22 09:56:40 -0500163#ifdef SK_TRACE_VK_RESOURCES
164 SkASSERT(0 == GrVkResource::fTrace.count());
165#endif
jvanverth03509ea2016-03-02 13:19:47 -0800166 fPipelineCache = VK_NULL_HANDLE;
167}