blob: 79c31a34d0a37986fa1871bb316494d39a1c4f8e [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
Mike Kleinc0bd9f92019-04-23 12:05:21 -05008#include "src/gpu/vk/GrVkFramebuffer.h"
Greg Daniel164a9f02016-02-22 09:56:40 -05009
Greg Danielde4bbdb2021-04-13 14:23:23 -040010#include "src/gpu/vk/GrVkCommandBuffer.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050011#include "src/gpu/vk/GrVkGpu.h"
Greg Daniel2bc96d62021-09-13 13:08:02 -040012#include "src/gpu/vk/GrVkImage.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050013#include "src/gpu/vk/GrVkImageView.h"
14#include "src/gpu/vk/GrVkRenderPass.h"
Greg Daniel164a9f02016-02-22 09:56:40 -050015
Greg Daniel805c6222021-04-20 12:44:48 -040016sk_sp<const GrVkFramebuffer> GrVkFramebuffer::Make(
Greg Daniela92d7872021-04-07 11:08:36 -040017 GrVkGpu* gpu,
Greg Daniel60ec6172021-04-16 11:31:58 -040018 SkISize dimensions,
Greg Daniel805c6222021-04-20 12:44:48 -040019 sk_sp<const GrVkRenderPass> compatibleRenderPass,
Greg Daniel2bc96d62021-09-13 13:08:02 -040020 GrVkImage* colorAttachment,
21 GrVkImage* resolveAttachment,
22 GrVkImage* stencilAttachment,
Greg Daniela92d7872021-04-07 11:08:36 -040023 GrVkResourceProvider::CompatibleRPHandle compatibleRenderPassHandle) {
Greg Daniel164a9f02016-02-22 09:56:40 -050024 // At the very least we need a renderPass and a colorAttachment
Greg Daniel805c6222021-04-20 12:44:48 -040025 SkASSERT(compatibleRenderPass);
Greg Daniel164a9f02016-02-22 09:56:40 -050026 SkASSERT(colorAttachment);
halcanary9d524f22016-03-29 09:03:52 -070027
Greg Daniel164a9f02016-02-22 09:56:40 -050028 VkImageView attachments[3];
Greg Daniel38517c22021-03-29 16:01:19 -040029 attachments[0] = colorAttachment->framebufferView()->imageView();
Greg Daniel164a9f02016-02-22 09:56:40 -050030 int numAttachments = 1;
Greg Daniel7acddf52020-12-16 15:15:51 -050031 if (resolveAttachment) {
Greg Daniel38517c22021-03-29 16:01:19 -040032 attachments[numAttachments++] = resolveAttachment->framebufferView()->imageView();
Greg Daniel7acddf52020-12-16 15:15:51 -050033 }
Greg Daniel164a9f02016-02-22 09:56:40 -050034 if (stencilAttachment) {
Greg Daniel38517c22021-03-29 16:01:19 -040035 attachments[numAttachments++] = stencilAttachment->framebufferView()->imageView();
Greg Daniel164a9f02016-02-22 09:56:40 -050036 }
halcanary9d524f22016-03-29 09:03:52 -070037
Greg Daniel164a9f02016-02-22 09:56:40 -050038 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;
Greg Daniel805c6222021-04-20 12:44:48 -040043 createInfo.renderPass = compatibleRenderPass->vkRenderPass();
Greg Daniel164a9f02016-02-22 09:56:40 -050044 createInfo.attachmentCount = numAttachments;
45 createInfo.pAttachments = attachments;
Greg Daniel60ec6172021-04-16 11:31:58 -040046 createInfo.width = dimensions.width();
47 createInfo.height = dimensions.height();
Greg Daniel164a9f02016-02-22 09:56:40 -050048 createInfo.layers = 1;
halcanary9d524f22016-03-29 09:03:52 -070049
Greg Daniel164a9f02016-02-22 09:56:40 -050050 VkFramebuffer framebuffer;
Greg Danielfa3adf72019-11-07 09:53:41 -050051 VkResult err;
52 GR_VK_CALL_RESULT(gpu, err, CreateFramebuffer(gpu->device(), &createInfo, nullptr,
53 &framebuffer));
Greg Daniel164a9f02016-02-22 09:56:40 -050054 if (err) {
55 return nullptr;
56 }
57
Greg Daniel805c6222021-04-20 12:44:48 -040058 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);
Greg Daniel164a9f02016-02-22 09:56:40 -050062}
63
Greg Danielde4bbdb2021-04-13 14:23:23 -040064GrVkFramebuffer::GrVkFramebuffer(const GrVkGpu* gpu,
65 VkFramebuffer framebuffer,
Greg Daniel2bc96d62021-09-13 13:08:02 -040066 sk_sp<GrVkImage> colorAttachment,
67 sk_sp<GrVkImage> resolveAttachment,
68 sk_sp<GrVkImage> stencilAttachment,
Greg Daniel805c6222021-04-20 12:44:48 -040069 sk_sp<const GrVkRenderPass> compatibleRenderPass,
Greg Danielde4bbdb2021-04-13 14:23:23 -040070 GrVkResourceProvider::CompatibleRPHandle compatibleRPHandle)
71 : GrVkManagedResource(gpu)
72 , fFramebuffer(framebuffer)
73 , fColorAttachment(std::move(colorAttachment))
74 , fResolveAttachment(std::move(resolveAttachment))
75 , fStencilAttachment(std::move(stencilAttachment))
Greg Daniel805c6222021-04-20 12:44:48 -040076 , fCompatibleRenderPass(std::move(compatibleRenderPass))
Greg Daniel60ec6172021-04-16 11:31:58 -040077 , fCompatibleRenderPassHandle(compatibleRPHandle) {
78 SkASSERT(fCompatibleRenderPassHandle.isValid());
79}
Greg Danielde4bbdb2021-04-13 14:23:23 -040080
81GrVkFramebuffer::GrVkFramebuffer(const GrVkGpu* gpu,
Greg Daniel2bc96d62021-09-13 13:08:02 -040082 sk_sp<GrVkImage> colorAttachment,
Greg Danielde4bbdb2021-04-13 14:23:23 -040083 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
Greg Daniel38517c22021-03-29 16:01:19 -040090GrVkFramebuffer::~GrVkFramebuffer() {}
91
Jim Van Verth5082df12020-03-11 16:14:51 -040092void GrVkFramebuffer::freeGPUData() const {
Greg Danielde4bbdb2021-04-13 14:23:23 -040093 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
105void GrVkFramebuffer::releaseResources() {
106 if (fExternalCommandBuffer) {
107 fExternalCommandBuffer->releaseResources();
108 fExternalCommandBuffer.reset();
109 }
110}
111
112void GrVkFramebuffer::returnExternalGrSecondaryCommandBuffer(
113 std::unique_ptr<GrVkSecondaryCommandBuffer> cmdBuffer) {
114 SkASSERT(!fExternalCommandBuffer);
115 fExternalCommandBuffer = std::move(cmdBuffer);
116}
117
118std::unique_ptr<GrVkSecondaryCommandBuffer> GrVkFramebuffer::externalCommandBuffer() {
119 SkASSERT(fExternalCommandBuffer);
120 return std::move(fExternalCommandBuffer);
Greg Daniel164a9f02016-02-22 09:56:40 -0500121}