| // Copyright 2018 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/image_view.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/util/image_utils.h" |
| #include "src/ui/lib/escher/vk/image.h" |
| |
| namespace escher { |
| |
| const ResourceTypeInfo ImageView::kTypeInfo("ImageView", ResourceType::kResource, |
| ResourceType::kImageView); |
| |
| ImageView::ImageView(ResourceRecycler* resource_recycler, ImagePtr image, |
| vk::ImageAspectFlags aspect_mask, void* extension_data) |
| : Resource(resource_recycler), |
| image_(std::move(image)), |
| width_(image_->width()), |
| height_(image_->height()) { |
| if (!aspect_mask) { |
| auto pair = image_utils::IsDepthStencilFormat(image_->format()); |
| if (!pair.first && !pair.second) { |
| // Assume color. |
| aspect_mask = vk::ImageAspectFlagBits::eColor; |
| } else { |
| if (pair.first) { |
| aspect_mask |= vk::ImageAspectFlagBits::eDepth; |
| } |
| if (pair.second) { |
| aspect_mask |= vk::ImageAspectFlagBits::eStencil; |
| } |
| } |
| } |
| |
| vk::ImageViewCreateInfo view_info; |
| view_info.pNext = extension_data; |
| view_info.viewType = vk::ImageViewType::e2D; |
| view_info.subresourceRange.baseMipLevel = 0; |
| view_info.subresourceRange.levelCount = 1; |
| view_info.subresourceRange.baseArrayLayer = 0; |
| view_info.subresourceRange.layerCount = 1; |
| view_info.subresourceRange.aspectMask = aspect_mask; |
| view_info.format = image_->format(); |
| view_info.image = image_->vk(); |
| image_view_ = ESCHER_CHECKED_VK_RESULT(vk_device().createImageView(view_info)); |
| } |
| |
| ImageView::~ImageView() { vk_device().destroyImageView(image_view_); } |
| |
| ImageViewPtr ImageView::New(ImagePtr image, vk::ImageAspectFlags aspect_mask) { |
| FXL_CHECK(image && image->escher()); |
| return fxl::MakeRefCounted<ImageView>(image->escher()->resource_recycler(), std::move(image), |
| aspect_mask); |
| } |
| |
| ImageViewPtr ImageView::New(ResourceRecycler* recycler, ImagePtr image, |
| vk::ImageAspectFlags aspect_mask) { |
| return fxl::MakeRefCounted<ImageView>(recycler, std::move(image), aspect_mask); |
| } |
| |
| ImageViewAllocator::ImageViewAllocator(ResourceRecycler* resource_recycler) |
| : resource_recycler_(resource_recycler) {} |
| |
| ImageViewPtr ImageViewAllocator::ObtainImageView(ImagePtr image, vk::ImageAspectFlags aspect_mask) { |
| Hasher h; |
| h.pointer(image.get()); |
| h.u64(static_cast<VkFlags>(aspect_mask)); |
| auto pair = image_view_cache_.Obtain(h.value()); |
| if (!pair.second) { |
| pair.first->image_view = ImageView::New(resource_recycler_, image, aspect_mask); |
| } |
| return pair.first->image_view; |
| } |
| |
| } // namespace escher |