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