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