Commit f739ac51 authored by Peng Huang's avatar Peng Huang Committed by Commit Bot

Add VulkanImage::CreateWithExternalMemory()

VulkanImage::CreateWithExternalMemory() is for creating a VkImage
with memory which can be exported and used by foreign API. This
method also uses vkGetPhysicalDeviceImageFormatProperties2() to
query supported handle types instead of hardcoding in the
VulkanImplementation.

Bug: 848385
Change-Id: Ic8d93798b72e5c7a157c1fa924bcf3f3d15c275c
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2107704
Commit-Queue: Peng Huang <penghuang@chromium.org>
Reviewed-by: default avatarVasiliy Telezhnikov <vasilyt@chromium.org>
Cr-Commit-Position: refs/heads/master@{#751366}
parent 4824a933
...@@ -143,28 +143,6 @@ class ScopedPixelStore { ...@@ -143,28 +143,6 @@ class ScopedPixelStore {
DISALLOW_COPY_AND_ASSIGN(ScopedPixelStore); DISALLOW_COPY_AND_ASSIGN(ScopedPixelStore);
}; };
#if defined(OS_FUCHSIA)
zx::vmo GetMemoryZirconHandle(VkDevice device,
const GrVkImageInfo& image_info) {
VkMemoryGetZirconHandleInfoFUCHSIA get_handle_info = {};
get_handle_info.sType =
VK_STRUCTURE_TYPE_TEMP_MEMORY_GET_ZIRCON_HANDLE_INFO_FUCHSIA;
get_handle_info.memory = image_info.fAlloc.fMemory;
get_handle_info.handleType =
VK_EXTERNAL_MEMORY_HANDLE_TYPE_TEMP_ZIRCON_VMO_BIT_FUCHSIA;
zx::vmo vmo;
VkResult result = vkGetMemoryZirconHandleFUCHSIA(device, &get_handle_info,
vmo.reset_and_get_address());
if (result != VK_SUCCESS) {
LOG(ERROR) << "vkGetMemoryFuchsiaHandleKHR failed: " << result;
vmo.reset();
}
return vmo;
}
#endif
} // namespace } // namespace
// static // static
...@@ -205,23 +183,15 @@ std::unique_ptr<ExternalVkImageBacking> ExternalVkImageBacking::Create( ...@@ -205,23 +183,15 @@ std::unique_ptr<ExternalVkImageBacking> ExternalVkImageBacking::Create(
vulkan_implementation->enforce_protected_memory() vulkan_implementation->enforce_protected_memory()
? VK_IMAGE_CREATE_PROTECTED_BIT ? VK_IMAGE_CREATE_PROTECTED_BIT
: 0; : 0;
std::unique_ptr<VulkanImage> image;
auto handle_type = vulkan_implementation->GetExternalImageHandleType(); if (is_external) {
image = VulkanImage::CreateWithExternalMemory(device_queue, size, vk_format,
VkExternalMemoryImageCreateInfoKHR external_image_create_info = { vk_usage, vk_flags,
.sType = VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO_KHR, VK_IMAGE_TILING_OPTIMAL);
.handleTypes = handle_type, } else {
}; image = VulkanImage::Create(device_queue, size, vk_format, vk_usage,
vk_flags, VK_IMAGE_TILING_OPTIMAL);
VkExportMemoryAllocateInfoKHR external_memory_allocate_info = { }
.sType = VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO_KHR,
.handleTypes = handle_type,
};
auto image = VulkanImage::Create(
device_queue, size, vk_format, vk_usage, vk_flags,
is_external ? &external_image_create_info : nullptr,
is_external ? &external_memory_allocate_info : nullptr);
if (!image) if (!image)
return nullptr; return nullptr;
...@@ -572,13 +542,13 @@ ExternalVkImageBacking::ProduceDawn(SharedImageManager* manager, ...@@ -572,13 +542,13 @@ ExternalVkImageBacking::ProduceDawn(SharedImageManager* manager,
bool result = backend_texture_.getVkImageInfo(&image_info); bool result = backend_texture_.getVkImageInfo(&image_info);
DCHECK(result); DCHECK(result);
int memory_fd = GetMemoryFd(image_info); auto memory_fd = image_->GetMemoryFd();
if (memory_fd < 0) { if (!memory_fd.is_valid()) {
return nullptr; return nullptr;
} }
return std::make_unique<ExternalVkImageDawnRepresentation>( return std::make_unique<ExternalVkImageDawnRepresentation>(
manager, this, tracker, wgpuDevice, wgpu_format, memory_fd); manager, this, tracker, wgpuDevice, wgpu_format, std::move(memory_fd));
#else // !defined(OS_LINUX) || !BUILDFLAG(USE_DAWN) #else // !defined(OS_LINUX) || !BUILDFLAG(USE_DAWN)
NOTIMPLEMENTED_LOG_ONCE(); NOTIMPLEMENTED_LOG_ONCE();
return nullptr; return nullptr;
...@@ -595,8 +565,8 @@ GLuint ExternalVkImageBacking::ProduceGLTextureInternal() { ...@@ -595,8 +565,8 @@ GLuint ExternalVkImageBacking::ProduceGLTextureInternal() {
GLuint memory_object = 0; GLuint memory_object = 0;
if (!use_separate_gl_texture()) { if (!use_separate_gl_texture()) {
#if defined(OS_LINUX) || defined(OS_ANDROID) #if defined(OS_LINUX) || defined(OS_ANDROID)
int memory_fd = GetMemoryFd(image_info); auto memory_fd = image_->GetMemoryFd();
if (memory_fd < 0) { if (!memory_fd.is_valid()) {
return 0; return 0;
} }
...@@ -605,9 +575,10 @@ GLuint ExternalVkImageBacking::ProduceGLTextureInternal() { ...@@ -605,9 +575,10 @@ GLuint ExternalVkImageBacking::ProduceGLTextureInternal() {
api->glMemoryObjectParameterivEXTFn( api->glMemoryObjectParameterivEXTFn(
memory_object, GL_DEDICATED_MEMORY_OBJECT_EXT, &dedicated); memory_object, GL_DEDICATED_MEMORY_OBJECT_EXT, &dedicated);
api->glImportMemoryFdEXTFn(memory_object, image_info.fAlloc.fSize, api->glImportMemoryFdEXTFn(memory_object, image_info.fAlloc.fSize,
GL_HANDLE_TYPE_OPAQUE_FD_EXT, memory_fd); GL_HANDLE_TYPE_OPAQUE_FD_EXT,
memory_fd.release());
#elif defined(OS_FUCHSIA) #elif defined(OS_FUCHSIA)
zx::vmo vmo = GetMemoryZirconHandle(device(), image_info); zx::vmo vmo = image_->GetMemoryZirconHandle();
if (!vmo) if (!vmo)
return 0; return 0;
...@@ -744,23 +715,6 @@ ExternalVkImageBacking::ProduceSkia( ...@@ -744,23 +715,6 @@ ExternalVkImageBacking::ProduceSkia(
tracker); tracker);
} }
#if defined(OS_LINUX) || defined(OS_ANDROID)
int ExternalVkImageBacking::GetMemoryFd(const GrVkImageInfo& image_info) {
VkMemoryGetFdInfoKHR get_fd_info;
get_fd_info.sType = VK_STRUCTURE_TYPE_MEMORY_GET_FD_INFO_KHR;
get_fd_info.pNext = nullptr;
get_fd_info.memory = image_info.fAlloc.fMemory;
get_fd_info.handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR;
int memory_fd = -1;
vkGetMemoryFdKHR(device(), &get_fd_info, &memory_fd);
if (memory_fd < 0) {
DLOG(ERROR) << "Unable to extract file descriptor out of external VkImage";
}
return memory_fd;
}
#endif
void ExternalVkImageBacking::InstallSharedMemory( void ExternalVkImageBacking::InstallSharedMemory(
base::WritableSharedMemoryMapping shared_memory_mapping, base::WritableSharedMemoryMapping shared_memory_mapping,
size_t stride, size_t stride,
......
...@@ -26,11 +26,11 @@ ExternalVkImageDawnRepresentation::ExternalVkImageDawnRepresentation( ...@@ -26,11 +26,11 @@ ExternalVkImageDawnRepresentation::ExternalVkImageDawnRepresentation(
MemoryTypeTracker* tracker, MemoryTypeTracker* tracker,
WGPUDevice device, WGPUDevice device,
WGPUTextureFormat wgpu_format, WGPUTextureFormat wgpu_format,
int memory_fd) base::ScopedFD memory_fd)
: SharedImageRepresentationDawn(manager, backing, tracker), : SharedImageRepresentationDawn(manager, backing, tracker),
device_(device), device_(device),
wgpu_format_(wgpu_format), wgpu_format_(wgpu_format),
memory_fd_(memory_fd), memory_fd_(std::move(memory_fd)),
dawn_procs_(dawn_native::GetProcs()) { dawn_procs_(dawn_native::GetProcs()) {
DCHECK(device_); DCHECK(device_);
...@@ -67,8 +67,7 @@ WGPUTexture ExternalVkImageDawnRepresentation::BeginAccess( ...@@ -67,8 +67,7 @@ WGPUTexture ExternalVkImageDawnRepresentation::BeginAccess(
descriptor.isCleared = IsCleared(); descriptor.isCleared = IsCleared();
descriptor.allocationSize = backing_impl()->image()->device_size(); descriptor.allocationSize = backing_impl()->image()->device_size();
descriptor.memoryTypeIndex = backing_impl()->image()->memory_type_index(); descriptor.memoryTypeIndex = backing_impl()->image()->memory_type_index();
descriptor.memoryFD = memory_fd_; descriptor.memoryFD = dup(memory_fd_.get());
descriptor.waitFDs = {};
// TODO(http://crbug.com/dawn/200): We may not be obeying all of the rules // TODO(http://crbug.com/dawn/200): We may not be obeying all of the rules
// specified by Vulkan for external queue transfer barriers. Investigate this. // specified by Vulkan for external queue transfer barriers. Investigate this.
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#ifndef GPU_COMMAND_BUFFER_SERVICE_EXTERNAL_VK_IMAGE_DAWN_REPRESENTATION_H_ #ifndef GPU_COMMAND_BUFFER_SERVICE_EXTERNAL_VK_IMAGE_DAWN_REPRESENTATION_H_
#define GPU_COMMAND_BUFFER_SERVICE_EXTERNAL_VK_IMAGE_DAWN_REPRESENTATION_H_ #define GPU_COMMAND_BUFFER_SERVICE_EXTERNAL_VK_IMAGE_DAWN_REPRESENTATION_H_
#include "base/files/scoped_file.h"
#include "gpu/command_buffer/service/external_vk_image_backing.h" #include "gpu/command_buffer/service/external_vk_image_backing.h"
#include "gpu/command_buffer/service/shared_image_representation.h" #include "gpu/command_buffer/service/shared_image_representation.h"
...@@ -17,7 +18,7 @@ class ExternalVkImageDawnRepresentation : public SharedImageRepresentationDawn { ...@@ -17,7 +18,7 @@ class ExternalVkImageDawnRepresentation : public SharedImageRepresentationDawn {
MemoryTypeTracker* tracker, MemoryTypeTracker* tracker,
WGPUDevice device, WGPUDevice device,
WGPUTextureFormat dawn_format, WGPUTextureFormat dawn_format,
int memory_fd); base::ScopedFD memory_fd);
~ExternalVkImageDawnRepresentation() override; ~ExternalVkImageDawnRepresentation() override;
WGPUTexture BeginAccess(WGPUTextureUsage usage) override; WGPUTexture BeginAccess(WGPUTextureUsage usage) override;
...@@ -26,7 +27,7 @@ class ExternalVkImageDawnRepresentation : public SharedImageRepresentationDawn { ...@@ -26,7 +27,7 @@ class ExternalVkImageDawnRepresentation : public SharedImageRepresentationDawn {
private: private:
const WGPUDevice device_; const WGPUDevice device_;
const WGPUTextureFormat wgpu_format_; const WGPUTextureFormat wgpu_format_;
const int memory_fd_; base::ScopedFD memory_fd_;
WGPUTexture texture_ = nullptr; WGPUTexture texture_ = nullptr;
......
...@@ -10,9 +10,14 @@ ...@@ -10,9 +10,14 @@
#include "base/macros.h" #include "base/macros.h"
#include "base/stl_util.h" #include "base/stl_util.h"
#include "build/build_config.h"
#include "gpu/vulkan/vulkan_device_queue.h" #include "gpu/vulkan/vulkan_device_queue.h"
#include "gpu/vulkan/vulkan_function_pointers.h" #include "gpu/vulkan/vulkan_function_pointers.h"
#if defined(OS_FUCHSIA)
#include "gpu/vulkan/fuchsia/vulkan_fuchsia_ext.h"
#endif
namespace gpu { namespace gpu {
namespace { namespace {
...@@ -40,13 +45,14 @@ uint32_t FindMemoryTypeIndex(VkPhysicalDevice physical_device, ...@@ -40,13 +45,14 @@ uint32_t FindMemoryTypeIndex(VkPhysicalDevice physical_device,
std::unique_ptr<VulkanImage> VulkanImage::Create( std::unique_ptr<VulkanImage> VulkanImage::Create(
VulkanDeviceQueue* device_queue, VulkanDeviceQueue* device_queue,
const gfx::Size& size, const gfx::Size& size,
VkFormat vk_format, VkFormat format,
VkImageUsageFlags vk_usage, VkImageUsageFlags usage,
VkImageCreateFlags vk_flags, VkImageCreateFlags flags,
VkImageTiling image_tiling,
void* vk_image_create_info_next, void* vk_image_create_info_next,
void* vk_memory_allocation_info_next) { void* vk_memory_allocation_info_next) {
auto image = std::make_unique<VulkanImage>(util::PassKey<VulkanImage>()); auto image = std::make_unique<VulkanImage>(util::PassKey<VulkanImage>());
if (!image->Initialize(device_queue, size, vk_format, vk_usage, vk_flags, if (!image->Initialize(device_queue, size, format, usage, flags, image_tiling,
vk_image_create_info_next, vk_image_create_info_next,
vk_memory_allocation_info_next)) { vk_memory_allocation_info_next)) {
return nullptr; return nullptr;
...@@ -54,15 +60,31 @@ std::unique_ptr<VulkanImage> VulkanImage::Create( ...@@ -54,15 +60,31 @@ std::unique_ptr<VulkanImage> VulkanImage::Create(
return image; return image;
} }
// static
std::unique_ptr<VulkanImage> VulkanImage::CreateWithExternalMemory(
VulkanDeviceQueue* device_queue,
const gfx::Size& size,
VkFormat format,
VkImageUsageFlags usage,
VkImageCreateFlags flags,
VkImageTiling image_tiling) {
auto image = std::make_unique<VulkanImage>(util::PassKey<VulkanImage>());
if (!image->InitializeWithExternalMemory(device_queue, size, format, usage,
flags, image_tiling)) {
return nullptr;
}
return image;
}
// static // static
std::unique_ptr<VulkanImage> VulkanImage::Create( std::unique_ptr<VulkanImage> VulkanImage::Create(
VulkanDeviceQueue* device_queue, VulkanDeviceQueue* device_queue,
VkImage vk_image, VkImage vk_image,
VkDeviceMemory vk_device_memory, VkDeviceMemory vk_device_memory,
const gfx::Size& size, const gfx::Size& size,
VkFormat vk_format, VkFormat format,
VkImageTiling vk_image_tiling, VkImageTiling image_tiling,
VkDeviceSize vk_device_size, VkDeviceSize device_size,
uint32_t memory_type_index, uint32_t memory_type_index,
base::Optional<VulkanYCbCrInfo>& ycbcr_info) { base::Optional<VulkanYCbCrInfo>& ycbcr_info) {
auto image = std::make_unique<VulkanImage>(util::PassKey<VulkanImage>()); auto image = std::make_unique<VulkanImage>(util::PassKey<VulkanImage>());
...@@ -70,9 +92,9 @@ std::unique_ptr<VulkanImage> VulkanImage::Create( ...@@ -70,9 +92,9 @@ std::unique_ptr<VulkanImage> VulkanImage::Create(
image->image_ = vk_image; image->image_ = vk_image;
image->device_memory_ = vk_device_memory; image->device_memory_ = vk_device_memory;
image->size_ = size; image->size_ = size;
image->format_ = vk_format; image->format_ = format;
image->image_tiling_ = vk_image_tiling; image->image_tiling_ = image_tiling;
image->device_size_ = vk_device_size; image->device_size_ = device_size;
image->memory_type_index_ = memory_type_index; image->memory_type_index_ = memory_type_index;
image->ycbcr_info_ = ycbcr_info; image->ycbcr_info_ = ycbcr_info;
return image; return image;
...@@ -101,11 +123,57 @@ void VulkanImage::Destroy() { ...@@ -101,11 +123,57 @@ void VulkanImage::Destroy() {
device_queue_ = nullptr; device_queue_ = nullptr;
} }
#if defined(OS_POSIX)
base::ScopedFD VulkanImage::GetMemoryFd(
VkExternalMemoryHandleTypeFlagBits handle_type) {
VkMemoryGetFdInfoKHR get_fd_info = {
.sType = VK_STRUCTURE_TYPE_MEMORY_GET_FD_INFO_KHR,
.memory = device_memory_,
.handleType = handle_type,
};
VkDevice device = device_queue_->GetVulkanDevice();
int memory_fd = -1;
vkGetMemoryFdKHR(device, &get_fd_info, &memory_fd);
if (memory_fd < 0) {
DLOG(ERROR) << "Unable to extract file descriptor out of external VkImage";
return base::ScopedFD();
}
return base::ScopedFD(memory_fd);
}
#endif
#if defined(OS_FUCHSIA)
zx::vmo VulkanImage::GetMemoryZirconHandle() {
DCHECK(handle_types_ &
VK_EXTERNAL_MEMORY_HANDLE_TYPE_TEMP_ZIRCON_VMO_BIT_FUCHSIA);
VkMemoryGetZirconHandleInfoFUCHSIA get_handle_info = {
.sType = VK_STRUCTURE_TYPE_TEMP_MEMORY_GET_ZIRCON_HANDLE_INFO_FUCHSIA,
.memory = device_memory_,
.handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_TEMP_ZIRCON_VMO_BIT_FUCHSIA,
};
VkDevice device = device_queue_->GetVulkanDevice();
zx::vmo vmo;
VkResult result = vkGetMemoryZirconHandleFUCHSIA(device, &get_handle_info,
vmo.reset_and_get_address());
if (result != VK_SUCCESS) {
DLOG(ERROR) << "vkGetMemoryFuchsiaHandleKHR failed: " << result;
vmo.reset();
}
return vmo;
}
#endif
bool VulkanImage::Initialize(VulkanDeviceQueue* device_queue, bool VulkanImage::Initialize(VulkanDeviceQueue* device_queue,
const gfx::Size& size, const gfx::Size& size,
VkFormat vk_format, VkFormat format,
VkImageUsageFlags vk_usage, VkImageUsageFlags usage,
VkImageCreateFlags vk_flags, VkImageCreateFlags flags,
VkImageTiling image_tiling,
void* vk_image_create_info_next, void* vk_image_create_info_next,
void* vk_memory_allocation_info_next) { void* vk_memory_allocation_info_next) {
DCHECK(!device_queue_); DCHECK(!device_queue_);
...@@ -114,12 +182,13 @@ bool VulkanImage::Initialize(VulkanDeviceQueue* device_queue, ...@@ -114,12 +182,13 @@ bool VulkanImage::Initialize(VulkanDeviceQueue* device_queue,
device_queue_ = device_queue; device_queue_ = device_queue;
size_ = size; size_ = size;
format_ = vk_format; format_ = format;
image_tiling_ = image_tiling;
VkImageCreateInfo create_info = { VkImageCreateInfo create_info = {
.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
.pNext = vk_image_create_info_next, .pNext = vk_image_create_info_next,
.flags = vk_flags, .flags = flags,
.imageType = VK_IMAGE_TYPE_2D, .imageType = VK_IMAGE_TYPE_2D,
.format = format_, .format = format_,
.extent = {size.width(), size.height(), 1}, .extent = {size.width(), size.height(), 1},
...@@ -127,7 +196,7 @@ bool VulkanImage::Initialize(VulkanDeviceQueue* device_queue, ...@@ -127,7 +196,7 @@ bool VulkanImage::Initialize(VulkanDeviceQueue* device_queue,
.arrayLayers = 1, .arrayLayers = 1,
.samples = VK_SAMPLE_COUNT_1_BIT, .samples = VK_SAMPLE_COUNT_1_BIT,
.tiling = image_tiling_, .tiling = image_tiling_,
.usage = vk_usage, .usage = usage,
.sharingMode = VK_SHARING_MODE_EXCLUSIVE, .sharingMode = VK_SHARING_MODE_EXCLUSIVE,
.queueFamilyIndexCount = 0, .queueFamilyIndexCount = 0,
.pQueueFamilyIndices = nullptr, .pQueueFamilyIndices = nullptr,
...@@ -138,6 +207,7 @@ bool VulkanImage::Initialize(VulkanDeviceQueue* device_queue, ...@@ -138,6 +207,7 @@ bool VulkanImage::Initialize(VulkanDeviceQueue* device_queue,
vkCreateImage(vk_device, &create_info, nullptr /* pAllocator */, &image_); vkCreateImage(vk_device, &create_info, nullptr /* pAllocator */, &image_);
if (result != VK_SUCCESS) { if (result != VK_SUCCESS) {
DLOG(ERROR) << "vkCreateImage failed result:" << result; DLOG(ERROR) << "vkCreateImage failed result:" << result;
device_queue_ = VK_NULL_HANDLE;
return false; return false;
} }
...@@ -188,4 +258,77 @@ bool VulkanImage::Initialize(VulkanDeviceQueue* device_queue, ...@@ -188,4 +258,77 @@ bool VulkanImage::Initialize(VulkanDeviceQueue* device_queue,
return true; return true;
} }
bool VulkanImage::InitializeWithExternalMemory(VulkanDeviceQueue* device_queue,
const gfx::Size& size,
VkFormat format,
VkImageUsageFlags usage,
VkImageCreateFlags flags,
VkImageTiling image_tiling) {
#if defined(OS_FUCHSIA)
constexpr auto kHandleType =
VK_EXTERNAL_MEMORY_HANDLE_TYPE_TEMP_ZIRCON_VMO_BIT_FUCHSIA;
#else
constexpr auto kHandleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT;
#endif
VkPhysicalDeviceImageFormatInfo2 format_info_2 = {
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2,
.format = format,
.type = VK_IMAGE_TYPE_2D,
.tiling = image_tiling,
.usage = usage,
.flags = flags,
};
VkPhysicalDeviceExternalImageFormatInfo external_info = {
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO,
.handleType = kHandleType,
};
format_info_2.pNext = &external_info;
VkImageFormatProperties2 image_format_properties_2 = {
.sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2,
};
VkExternalImageFormatProperties external_image_format_properties = {
.sType = VK_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES,
};
image_format_properties_2.pNext = &external_image_format_properties;
auto result = vkGetPhysicalDeviceImageFormatProperties2(
device_queue->GetVulkanPhysicalDevice(), &format_info_2,
&image_format_properties_2);
if (result != VK_SUCCESS) {
DLOG(ERROR) << "External memory is not supported."
<< " format:" << format << " image_tiling:" << image_tiling
<< " usage:" << usage << " flags:" << flags;
return false;
}
const auto& external_format_properties =
external_image_format_properties.externalMemoryProperties;
if (!(external_format_properties.externalMemoryFeatures &
VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT)) {
DLOG(ERROR) << "External memroy cannot be exported."
<< " format:" << format << " image_tiling:" << image_tiling
<< " usage:" << usage << " flags:" << flags;
return false;
}
handle_types_ = external_format_properties.compatibleHandleTypes;
DCHECK(handle_types_ & kHandleType);
VkExternalMemoryImageCreateInfoKHR external_image_create_info = {
.sType = VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO_KHR,
.handleTypes = handle_types_,
};
VkExportMemoryAllocateInfoKHR external_memory_allocate_info = {
.sType = VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO_KHR,
.handleTypes = handle_types_,
};
return Initialize(device_queue, size, format, usage, flags, image_tiling,
&external_image_create_info,
&external_memory_allocate_info);
} // namespace gpu
} // namespace gpu } // namespace gpu
...@@ -7,12 +7,18 @@ ...@@ -7,12 +7,18 @@
#include <vulkan/vulkan.h> #include <vulkan/vulkan.h>
#include "base/files/scoped_file.h"
#include "base/optional.h" #include "base/optional.h"
#include "base/util/type_safety/pass_key.h" #include "base/util/type_safety/pass_key.h"
#include "build/build_config.h"
#include "gpu/ipc/common/vulkan_ycbcr_info.h" #include "gpu/ipc/common/vulkan_ycbcr_info.h"
#include "gpu/vulkan/vulkan_export.h" #include "gpu/vulkan/vulkan_export.h"
#include "ui/gfx/geometry/size.h" #include "ui/gfx/geometry/size.h"
#if defined(OS_FUCHSIA)
#include <lib/zx/vmo.h>
#endif
namespace gpu { namespace gpu {
class VulkanDeviceQueue; class VulkanDeviceQueue;
...@@ -28,25 +34,45 @@ class VULKAN_EXPORT VulkanImage { ...@@ -28,25 +34,45 @@ class VULKAN_EXPORT VulkanImage {
static std::unique_ptr<VulkanImage> Create( static std::unique_ptr<VulkanImage> Create(
VulkanDeviceQueue* device_queue, VulkanDeviceQueue* device_queue,
const gfx::Size& size, const gfx::Size& size,
VkFormat vk_format, VkFormat format,
VkImageUsageFlags vk_usage, VkImageUsageFlags usage,
VkImageCreateFlags vk_flags = 0, VkImageCreateFlags flags = 0,
VkImageTiling image_tiling = VK_IMAGE_TILING_OPTIMAL,
void* vk_image_create_info_next = nullptr, void* vk_image_create_info_next = nullptr,
void* vk_memory_allocation_info_next = nullptr); void* vk_memory_allocation_info_next = nullptr);
// Create VulkanImage with external memory, it can be exported and used by
// foreign API
static std::unique_ptr<VulkanImage> CreateWithExternalMemory(
VulkanDeviceQueue* device_queue,
const gfx::Size& size,
VkFormat format,
VkImageUsageFlags usage,
VkImageCreateFlags flags,
VkImageTiling image_tiling);
static std::unique_ptr<VulkanImage> Create( static std::unique_ptr<VulkanImage> Create(
VulkanDeviceQueue* device_queue, VulkanDeviceQueue* device_queue,
VkImage vk_image, VkImage image,
VkDeviceMemory vk_device_memory, VkDeviceMemory device_memory,
const gfx::Size& size, const gfx::Size& size,
VkFormat vk_format, VkFormat format,
VkImageTiling vk_image_tiling, VkImageTiling image_tiling,
VkDeviceSize vk_device_size, VkDeviceSize device_size,
uint32_t memory_type_index, uint32_t memory_type_index,
base::Optional<VulkanYCbCrInfo>& ycbcr_info); base::Optional<VulkanYCbCrInfo>& ycbcr_info);
void Destroy(); void Destroy();
#if defined(OS_POSIX)
base::ScopedFD GetMemoryFd(VkExternalMemoryHandleTypeFlagBits handle_type =
VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT);
#endif
#if defined(OS_FUCHSIA)
zx::vmo GetMemoryZirconHandle();
#endif
const gfx::Size& size() const { return size_; } const gfx::Size& size() const { return size_; }
VkFormat format() const { return format_; } VkFormat format() const { return format_; }
VkDeviceSize device_size() const { return device_size_; } VkDeviceSize device_size() const { return device_size_; }
...@@ -57,15 +83,23 @@ class VULKAN_EXPORT VulkanImage { ...@@ -57,15 +83,23 @@ class VULKAN_EXPORT VulkanImage {
} }
VkImage image() const { return image_; } VkImage image() const { return image_; }
VkDeviceMemory device_memory() const { return device_memory_; } VkDeviceMemory device_memory() const { return device_memory_; }
VkExternalMemoryHandleTypeFlags handle_types() const { return handle_types_; }
private: private:
bool Initialize(VulkanDeviceQueue* device_queue, bool Initialize(VulkanDeviceQueue* device_queue,
const gfx::Size& size, const gfx::Size& size,
VkFormat vk_format, VkFormat format,
VkImageUsageFlags vk_usage, VkImageUsageFlags usage,
VkImageCreateFlags vk_flags, VkImageCreateFlags flags,
void* vk_image_create_info_next, VkImageTiling image_tiling,
void* vk_memory_allocation_info_next); void* image_create_info_next,
void* memory_allocation_info_next);
bool InitializeWithExternalMemory(VulkanDeviceQueue* device_queue,
const gfx::Size& size,
VkFormat format,
VkImageUsageFlags usage,
VkImageCreateFlags flags,
VkImageTiling image_tiling);
VulkanDeviceQueue* device_queue_ = nullptr; VulkanDeviceQueue* device_queue_ = nullptr;
gfx::Size size_; gfx::Size size_;
...@@ -76,6 +110,7 @@ class VULKAN_EXPORT VulkanImage { ...@@ -76,6 +110,7 @@ class VULKAN_EXPORT VulkanImage {
base::Optional<VulkanYCbCrInfo> ycbcr_info_; base::Optional<VulkanYCbCrInfo> ycbcr_info_;
VkImage image_ = VK_NULL_HANDLE; VkImage image_ = VK_NULL_HANDLE;
VkDeviceMemory device_memory_ = VK_NULL_HANDLE; VkDeviceMemory device_memory_ = VK_NULL_HANDLE;
VkExternalMemoryHandleTypeFlags handle_types_ = 0;
}; };
} // namespace gpu } // namespace gpu
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment