/* * 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 GrVkFramebuffer::Make( GrVkGpu* gpu, SkISize dimensions, sk_sp 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(fb); } GrVkFramebuffer::GrVkFramebuffer(const GrVkGpu* gpu, VkFramebuffer framebuffer, sk_sp colorAttachment, sk_sp resolveAttachment, sk_sp stencilAttachment, sk_sp 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 colorAttachment, sk_sp renderPass, std::unique_ptr 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(this); nonConstThis->releaseResources(); } void GrVkFramebuffer::releaseResources() { if (fExternalCommandBuffer) { fExternalCommandBuffer->releaseResources(); fExternalCommandBuffer.reset(); } } void GrVkFramebuffer::returnExternalGrSecondaryCommandBuffer( std::unique_ptr cmdBuffer) { SkASSERT(!fExternalCommandBuffer); fExternalCommandBuffer = std::move(cmdBuffer); } std::unique_ptr GrVkFramebuffer::externalCommandBuffer() { SkASSERT(fExternalCommandBuffer); return std::move(fExternalCommandBuffer); }