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