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