| // 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 |