xref: /aosp_15_r20/external/skia/src/gpu/ganesh/vk/GrVkFramebuffer.cpp (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
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