| // Copyright 2020 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/scenic/lib/flatland/renderer/gpu_mem.h" |
| |
| #include "src/ui/lib/escher/util/bit_ops.h" |
| |
| namespace { |
| |
| escher::GpuMemPtr CreateGPUMem(const vk::Device& device, vk::MemoryAllocateInfo* alloc_info) { |
| FX_DCHECK(device); |
| vk::DeviceMemory memory = nullptr; |
| vk::Result err = device.allocateMemory(alloc_info, nullptr, &memory); |
| if (err != vk::Result::eSuccess) { |
| FX_LOGS(ERROR) << "Could not successfully allocate memory."; |
| return nullptr; |
| } |
| return escher::GpuMem::AdoptVkMemory(device, vk::DeviceMemory(memory), alloc_info->allocationSize, |
| /*needs_mapped_ptr*/ false); |
| } |
| |
| } // anonymous namespace |
| |
| namespace flatland { |
| |
| vk::ImageCreateInfo GpuImageInfo::NewVkImageCreateInfo(uint32_t width, uint32_t height, |
| vk::ImageUsageFlags usage) const { |
| vk::ImageCreateInfo create_info; |
| create_info.imageType = vk::ImageType::e2D; |
| create_info.extent = vk::Extent3D{width, height, 1}; |
| create_info.flags = vk::ImageCreateFlagBits::eMutableFormat; |
| |
| // Hardcode a single viable pixel format. We want to be able to test every single possible |
| // format that is allowed into Flatland, and so we start with just one. |
| create_info.format = vk::Format::eB8G8R8A8Unorm; |
| create_info.mipLevels = 1; |
| create_info.arrayLayers = 1; |
| create_info.samples = vk::SampleCountFlagBits::e1; |
| create_info.tiling = vk::ImageTiling::eOptimal; |
| create_info.usage = usage; |
| create_info.sharingMode = vk::SharingMode::eExclusive; |
| create_info.initialLayout = vk::ImageLayout::eUndefined; |
| |
| if (p_extension_) { |
| create_info.setPNext(&(*p_extension_)); |
| } |
| |
| if (is_protected_) { |
| create_info.flags = vk::ImageCreateFlagBits::eProtected; |
| } |
| return create_info; |
| } |
| |
| GpuImageInfo GpuImageInfo::New(const vk::Device& device, const vk::DispatchLoaderDynamic& vk_loader, |
| const fuchsia::sysmem::BufferCollectionInfo_2& info, |
| const vk::BufferCollectionFUCHSIA& vk_buffer_collection, |
| uint32_t index) { |
| FX_DCHECK(device); |
| FX_DCHECK(vk_loader.vkGetBufferCollectionPropertiesFUCHSIA); |
| |
| // Check the provided index against actually allocated number of buffers. |
| if (info.buffer_count <= index) { |
| FX_LOGS(ERROR) << "Specified vmo index is out of bounds: " << index; |
| return GpuImageInfo(); |
| } |
| |
| // Currently only support a single format. |
| FX_DCHECK(info.settings.image_format_constraints.pixel_format.type == |
| fuchsia::sysmem::PixelFormatType::BGRA32); |
| |
| // Get a handle to the vmo and extract the size of its buffer. |
| zx::vmo vmo; |
| zx_status_t status = info.buffers[index].vmo.duplicate(ZX_RIGHT_SAME_RIGHTS, &vmo); |
| FX_DCHECK(status == ZX_OK); |
| uint64_t vmo_size; |
| status = vmo.get_size(&vmo_size); |
| FX_DCHECK(status == ZX_OK); |
| |
| auto collection_properties = |
| device.getBufferCollectionPropertiesFUCHSIA(vk_buffer_collection, vk_loader); |
| if (collection_properties.result != vk::Result::eSuccess) { |
| FX_LOGS(ERROR) << "Could not get collection properties for vk_buffer_collection.h"; |
| return GpuImageInfo(); |
| } |
| |
| // We are setting up the information here to import the buffer collection vmo at the |
| // specified index into GPU memory. |
| const uint32_t memory_type_index = |
| escher::CountTrailingZeros(collection_properties.value.memoryTypeBits); |
| vk::ImportMemoryBufferCollectionFUCHSIA import_info; |
| import_info.collection = vk_buffer_collection; |
| import_info.index = index; |
| vk::MemoryAllocateInfo alloc_info; |
| alloc_info.setPNext(&import_info); |
| alloc_info.memoryTypeIndex = memory_type_index; |
| alloc_info.allocationSize = vmo_size; |
| |
| return GpuImageInfo(CreateGPUMem(device, &alloc_info), vk_buffer_collection, index, |
| info.settings.buffer_settings.is_secure); |
| } |
| |
| GpuImageInfo::GpuImageInfo(escher::GpuMemPtr mem, vk::BufferCollectionFUCHSIA vk_buffer_collection, |
| uint32_t vmo_index, bool is_protected) |
| : mem_(mem), is_protected_(is_protected) { |
| vk::BufferCollectionImageCreateInfoFUCHSIA p_extension; |
| p_extension.collection = vk_buffer_collection; |
| p_extension.index = vmo_index; |
| p_extension_ = p_extension; |
| } |
| |
| } // namespace flatland |