blob: 2f713cb222ed22c812212751551bb0f4b1b75e93 [file] [log] [blame]
// Copyright 2016 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "src/ui/lib/escher/vk/framebuffer.h"
#include "src/ui/lib/escher/escher.h"
#include "src/ui/lib/escher/impl/command_buffer.h"
#include "src/ui/lib/escher/impl/vulkan_utils.h"
#include "src/ui/lib/escher/resources/resource_recycler.h"
#include "src/ui/lib/escher/vk/image.h"
namespace escher {
const ResourceTypeInfo Framebuffer::kTypeInfo("Framebuffer", ResourceType::kResource,
ResourceType::kFramebuffer);
Framebuffer::Framebuffer(Escher* escher, ImagePtr color_image, vk::RenderPass render_pass)
: Framebuffer(escher, color_image->width(), color_image->height(),
std::vector<ImagePtr>{std::move(color_image)}, render_pass) {}
Framebuffer::Framebuffer(Escher* escher, ImagePtr color_image, ImagePtr depth_image,
vk::RenderPass render_pass)
: Framebuffer(escher, color_image->width(), color_image->height(),
std::vector<ImagePtr>{std::move(color_image), std::move(depth_image)},
render_pass) {}
Framebuffer::Framebuffer(Escher* escher, uint32_t width, uint32_t height,
std::vector<ImagePtr> images, vk::RenderPass render_pass)
: Resource(escher->resource_recycler()),
width_(width),
height_(height),
images_(std::move(images)) {
vk::Device device = vulkan_context().device;
// For each image, construct a corresponding view.
image_views_.reserve(images_.size());
for (auto& im : images_) {
FX_DCHECK(width == im->width());
FX_DCHECK(height == im->height());
vk::ImageViewCreateInfo info;
info.viewType = vk::ImageViewType::e2D;
info.subresourceRange.baseMipLevel = 0;
info.subresourceRange.levelCount = 1;
info.subresourceRange.baseArrayLayer = 0;
info.subresourceRange.layerCount = 1;
info.format = im->format();
info.image = im->vk();
if (im->has_depth() || im->has_stencil()) {
if (im->has_depth())
info.subresourceRange.aspectMask |= vk::ImageAspectFlagBits::eDepth;
if (im->has_stencil())
info.subresourceRange.aspectMask |= vk::ImageAspectFlagBits::eStencil;
} else {
info.subresourceRange.aspectMask = vk::ImageAspectFlagBits::eColor;
}
auto im_view = ESCHER_CHECKED_VK_RESULT(device.createImageView(info));
image_views_.push_back(im_view);
}
vk::FramebufferCreateInfo info;
info.renderPass = render_pass;
info.attachmentCount = static_cast<uint32_t>(image_views_.size());
info.pAttachments = image_views_.data();
info.width = width;
info.height = height;
info.layers = 1;
framebuffer_ = ESCHER_CHECKED_VK_RESULT(device.createFramebuffer(info));
}
Framebuffer::~Framebuffer() {
vk::Device device = vulkan_context().device;
for (auto& image_view : image_views_) {
device.destroyImageView(image_view);
}
device.destroyFramebuffer(framebuffer_);
}
} // namespace escher