blob: dfbe9d26c5a92926aa8e37acf276126accd5dc8d [file] [log] [blame]
/*
* Copyright 2016 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include "src/gpu/vk/GrVkFramebuffer.h"
#include "src/gpu/vk/GrVkAttachment.h"
#include "src/gpu/vk/GrVkCommandBuffer.h"
#include "src/gpu/vk/GrVkGpu.h"
#include "src/gpu/vk/GrVkImageView.h"
#include "src/gpu/vk/GrVkRenderPass.h"
sk_sp<const GrVkFramebuffer> GrVkFramebuffer::Make(
GrVkGpu* gpu,
SkISize dimensions,
sk_sp<const GrVkRenderPass> compatibleRenderPass,
GrVkAttachment* colorAttachment,
GrVkAttachment* resolveAttachment,
GrVkAttachment* stencilAttachment,
GrVkResourceProvider::CompatibleRPHandle compatibleRenderPassHandle) {
// At the very least we need a renderPass and a colorAttachment
SkASSERT(compatibleRenderPass);
SkASSERT(colorAttachment);
VkImageView attachments[3];
attachments[0] = colorAttachment->framebufferView()->imageView();
int numAttachments = 1;
if (resolveAttachment) {
attachments[numAttachments++] = resolveAttachment->framebufferView()->imageView();
}
if (stencilAttachment) {
attachments[numAttachments++] = stencilAttachment->framebufferView()->imageView();
}
VkFramebufferCreateInfo createInfo;
memset(&createInfo, 0, sizeof(VkFramebufferCreateInfo));
createInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
createInfo.pNext = nullptr;
createInfo.flags = 0;
createInfo.renderPass = compatibleRenderPass->vkRenderPass();
createInfo.attachmentCount = numAttachments;
createInfo.pAttachments = attachments;
createInfo.width = dimensions.width();
createInfo.height = dimensions.height();
createInfo.layers = 1;
VkFramebuffer framebuffer;
VkResult err;
GR_VK_CALL_RESULT(gpu, err, CreateFramebuffer(gpu->device(), &createInfo, nullptr,
&framebuffer));
if (err) {
return nullptr;
}
auto fb = new GrVkFramebuffer(gpu, framebuffer, sk_ref_sp(colorAttachment),
sk_ref_sp(resolveAttachment), sk_ref_sp(stencilAttachment),
std::move(compatibleRenderPass), compatibleRenderPassHandle);
return sk_sp<const GrVkFramebuffer>(fb);
}
GrVkFramebuffer::GrVkFramebuffer(const GrVkGpu* gpu,
VkFramebuffer framebuffer,
sk_sp<GrVkAttachment> colorAttachment,
sk_sp<GrVkAttachment> resolveAttachment,
sk_sp<GrVkAttachment> stencilAttachment,
sk_sp<const GrVkRenderPass> compatibleRenderPass,
GrVkResourceProvider::CompatibleRPHandle compatibleRPHandle)
: GrVkManagedResource(gpu)
, fFramebuffer(framebuffer)
, fColorAttachment(std::move(colorAttachment))
, fResolveAttachment(std::move(resolveAttachment))
, fStencilAttachment(std::move(stencilAttachment))
, fCompatibleRenderPass(std::move(compatibleRenderPass))
, fCompatibleRenderPassHandle(compatibleRPHandle) {
SkASSERT(fCompatibleRenderPassHandle.isValid());
}
GrVkFramebuffer::GrVkFramebuffer(const GrVkGpu* gpu,
sk_sp<GrVkAttachment> colorAttachment,
sk_sp<const GrVkRenderPass> renderPass,
std::unique_ptr<GrVkSecondaryCommandBuffer> externalCommandBuffer)
: GrVkManagedResource(gpu)
, fColorAttachment(std::move(colorAttachment))
, fExternalRenderPass(std::move(renderPass))
, fExternalCommandBuffer(std::move(externalCommandBuffer)) {}
GrVkFramebuffer::~GrVkFramebuffer() {}
void GrVkFramebuffer::freeGPUData() const {
SkASSERT(this->isExternal() || fFramebuffer != VK_NULL_HANDLE);
if (!this->isExternal()) {
GR_VK_CALL(fGpu->vkInterface(), DestroyFramebuffer(fGpu->device(), fFramebuffer, nullptr));
}
// TODO: having freeGPUData virtual on GrManagedResource be const seems like a bad restriction
// since we are changing the internal objects of these classes when it is called. We should go
// back a revisit how much of a headache it would be to make this function non-const
GrVkFramebuffer* nonConstThis = const_cast<GrVkFramebuffer*>(this);
nonConstThis->releaseResources();
}
void GrVkFramebuffer::releaseResources() {
if (fExternalCommandBuffer) {
fExternalCommandBuffer->releaseResources();
fExternalCommandBuffer.reset();
}
}
void GrVkFramebuffer::returnExternalGrSecondaryCommandBuffer(
std::unique_ptr<GrVkSecondaryCommandBuffer> cmdBuffer) {
SkASSERT(!fExternalCommandBuffer);
fExternalCommandBuffer = std::move(cmdBuffer);
}
std::unique_ptr<GrVkSecondaryCommandBuffer> GrVkFramebuffer::externalCommandBuffer() {
SkASSERT(fExternalCommandBuffer);
return std::move(fExternalCommandBuffer);
}