• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/GrVkCommandBuffer.h"
11 #include "src/gpu/vk/GrVkGpu.h"
12 #include "src/gpu/vk/GrVkImage.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,GrVkImage * colorAttachment,GrVkImage * resolveAttachment,GrVkImage * stencilAttachment,GrVkResourceProvider::CompatibleRPHandle compatibleRenderPassHandle)16 sk_sp<const GrVkFramebuffer> GrVkFramebuffer::Make(
17         GrVkGpu* gpu,
18         SkISize dimensions,
19         sk_sp<const GrVkRenderPass> compatibleRenderPass,
20         GrVkImage* colorAttachment,
21         GrVkImage* resolveAttachment,
22         GrVkImage* 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<GrVkImage> colorAttachment,sk_sp<GrVkImage> resolveAttachment,sk_sp<GrVkImage> stencilAttachment,sk_sp<const GrVkRenderPass> compatibleRenderPass,GrVkResourceProvider::CompatibleRPHandle compatibleRPHandle)64 GrVkFramebuffer::GrVkFramebuffer(const GrVkGpu* gpu,
65                                  VkFramebuffer framebuffer,
66                                  sk_sp<GrVkImage> colorAttachment,
67                                  sk_sp<GrVkImage> resolveAttachment,
68                                  sk_sp<GrVkImage> 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<GrVkImage> colorAttachment,sk_sp<const GrVkRenderPass> renderPass,std::unique_ptr<GrVkSecondaryCommandBuffer> externalCommandBuffer)81 GrVkFramebuffer::GrVkFramebuffer(const GrVkGpu* gpu,
82                                  sk_sp<GrVkImage> 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