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 "src/gpu/vk/GrVkFramebuffer.h"
9
10 #include "src/gpu/vk/GrVkAttachment.h"
11 #include "src/gpu/vk/GrVkCommandBuffer.h"
12 #include "src/gpu/vk/GrVkGpu.h"
13 #include "src/gpu/vk/GrVkImageView.h"
14 #include "src/gpu/vk/GrVkRenderPass.h"
15
Make(GrVkGpu * gpu,SkISize dimensions,sk_sp<const GrVkRenderPass> compatibleRenderPass,GrVkAttachment * colorAttachment,GrVkAttachment * resolveAttachment,GrVkAttachment * stencilAttachment,GrVkResourceProvider::CompatibleRPHandle compatibleRenderPassHandle)16 sk_sp<const GrVkFramebuffer> GrVkFramebuffer::Make(
17 GrVkGpu* gpu,
18 SkISize dimensions,
19 sk_sp<const GrVkRenderPass> compatibleRenderPass,
20 GrVkAttachment* colorAttachment,
21 GrVkAttachment* resolveAttachment,
22 GrVkAttachment* stencilAttachment,
23 GrVkResourceProvider::CompatibleRPHandle compatibleRenderPassHandle) {
24 // At the very least we need a renderPass and a colorAttachment
25 SkASSERT(compatibleRenderPass);
26 SkASSERT(colorAttachment);
27
28 VkImageView attachments[3];
29 attachments[0] = colorAttachment->framebufferView()->imageView();
30 int numAttachments = 1;
31 if (resolveAttachment) {
32 attachments[numAttachments++] = resolveAttachment->framebufferView()->imageView();
33 }
34 if (stencilAttachment) {
35 attachments[numAttachments++] = stencilAttachment->framebufferView()->imageView();
36 }
37
38 VkFramebufferCreateInfo createInfo;
39 memset(&createInfo, 0, sizeof(VkFramebufferCreateInfo));
40 createInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
41 createInfo.pNext = nullptr;
42 createInfo.flags = 0;
43 createInfo.renderPass = compatibleRenderPass->vkRenderPass();
44 createInfo.attachmentCount = numAttachments;
45 createInfo.pAttachments = attachments;
46 createInfo.width = dimensions.width();
47 createInfo.height = dimensions.height();
48 createInfo.layers = 1;
49
50 VkFramebuffer framebuffer;
51 VkResult err;
52 GR_VK_CALL_RESULT(gpu, err, CreateFramebuffer(gpu->device(), &createInfo, nullptr,
53 &framebuffer));
54 if (err) {
55 return nullptr;
56 }
57
58 auto fb = new GrVkFramebuffer(gpu, framebuffer, sk_ref_sp(colorAttachment),
59 sk_ref_sp(resolveAttachment), sk_ref_sp(stencilAttachment),
60 std::move(compatibleRenderPass), compatibleRenderPassHandle);
61 return sk_sp<const GrVkFramebuffer>(fb);
62 }
63
GrVkFramebuffer(const GrVkGpu * gpu,VkFramebuffer framebuffer,sk_sp<GrVkAttachment> colorAttachment,sk_sp<GrVkAttachment> resolveAttachment,sk_sp<GrVkAttachment> stencilAttachment,sk_sp<const GrVkRenderPass> compatibleRenderPass,GrVkResourceProvider::CompatibleRPHandle compatibleRPHandle)64 GrVkFramebuffer::GrVkFramebuffer(const GrVkGpu* gpu,
65 VkFramebuffer framebuffer,
66 sk_sp<GrVkAttachment> colorAttachment,
67 sk_sp<GrVkAttachment> resolveAttachment,
68 sk_sp<GrVkAttachment> stencilAttachment,
69 sk_sp<const GrVkRenderPass> compatibleRenderPass,
70 GrVkResourceProvider::CompatibleRPHandle compatibleRPHandle)
71 : GrVkManagedResource(gpu)
72 , fFramebuffer(framebuffer)
73 , fColorAttachment(std::move(colorAttachment))
74 , fResolveAttachment(std::move(resolveAttachment))
75 , fStencilAttachment(std::move(stencilAttachment))
76 , fCompatibleRenderPass(std::move(compatibleRenderPass))
77 , fCompatibleRenderPassHandle(compatibleRPHandle) {
78 SkASSERT(fCompatibleRenderPassHandle.isValid());
79 }
80
GrVkFramebuffer(const GrVkGpu * gpu,sk_sp<GrVkAttachment> colorAttachment,sk_sp<const GrVkRenderPass> renderPass,std::unique_ptr<GrVkSecondaryCommandBuffer> externalCommandBuffer)81 GrVkFramebuffer::GrVkFramebuffer(const GrVkGpu* gpu,
82 sk_sp<GrVkAttachment> colorAttachment,
83 sk_sp<const GrVkRenderPass> renderPass,
84 std::unique_ptr<GrVkSecondaryCommandBuffer> externalCommandBuffer)
85 : GrVkManagedResource(gpu)
86 , fColorAttachment(std::move(colorAttachment))
87 , fExternalRenderPass(std::move(renderPass))
88 , fExternalCommandBuffer(std::move(externalCommandBuffer)) {}
89
~GrVkFramebuffer()90 GrVkFramebuffer::~GrVkFramebuffer() {}
91
freeGPUData() const92 void GrVkFramebuffer::freeGPUData() const {
93 SkASSERT(this->isExternal() || fFramebuffer != VK_NULL_HANDLE);
94 if (!this->isExternal()) {
95 GR_VK_CALL(fGpu->vkInterface(), DestroyFramebuffer(fGpu->device(), fFramebuffer, nullptr));
96 }
97
98 // TODO: having freeGPUData virtual on GrManagedResource be const seems like a bad restriction
99 // since we are changing the internal objects of these classes when it is called. We should go
100 // back a revisit how much of a headache it would be to make this function non-const
101 GrVkFramebuffer* nonConstThis = const_cast<GrVkFramebuffer*>(this);
102 nonConstThis->releaseResources();
103 }
104
releaseResources()105 void GrVkFramebuffer::releaseResources() {
106 if (fExternalCommandBuffer) {
107 fExternalCommandBuffer->releaseResources();
108 fExternalCommandBuffer.reset();
109 }
110 }
111
returnExternalGrSecondaryCommandBuffer(std::unique_ptr<GrVkSecondaryCommandBuffer> cmdBuffer)112 void GrVkFramebuffer::returnExternalGrSecondaryCommandBuffer(
113 std::unique_ptr<GrVkSecondaryCommandBuffer> cmdBuffer) {
114 SkASSERT(!fExternalCommandBuffer);
115 fExternalCommandBuffer = std::move(cmdBuffer);
116 }
117
externalCommandBuffer()118 std::unique_ptr<GrVkSecondaryCommandBuffer> GrVkFramebuffer::externalCommandBuffer() {
119 SkASSERT(fExternalCommandBuffer);
120 return std::move(fExternalCommandBuffer);
121 }
122