Commit c4197713 by Michael Spang Committed by Commit Bot

Implement glImportMemoryZirconHandle & glImportSemaphoreZirconHandle

Implement import of fuchsia external objects passed by zircon handle. This works exactly the same as with file descriptors. Bug: angleproject:3492 Change-Id: I4d46917dfc5902f00c94550158a9f8073097f0a4 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/1642334 Commit-Queue: Michael Spang <spang@chromium.org> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org>
parent 5b78b389
...@@ -114,12 +114,24 @@ struct FeaturesVk : FeatureSetBase ...@@ -114,12 +114,24 @@ struct FeaturesVk : FeatureSetBase
"supports_external_memory_fd", FeatureCategory::VulkanFeatures, "supports_external_memory_fd", FeatureCategory::VulkanFeatures,
"VkDevice supports the VK_KHR_external_memory_fd extension", &members}; "VkDevice supports the VK_KHR_external_memory_fd extension", &members};
// Whether the VkDevice supports the VK_FUCHSIA_external_memory
// extension, on which the GL_ANGLE_memory_object_fuchsia extension can be layered.
angle::Feature supportsExternalMemoryFuchsia = {
"supports_external_memory_fuchsia", FeatureCategory::VulkanFeatures,
"VkDevice supports the VK_FUCHSIA_external_memory extension", &members};
// Whether the VkDevice supports the VK_KHR_external_semaphore_fd extension, on which the // Whether the VkDevice supports the VK_KHR_external_semaphore_fd extension, on which the
// GL_EXT_semaphore_fd extension can be layered. // GL_EXT_semaphore_fd extension can be layered.
Feature supportsExternalSemaphoreFd = { Feature supportsExternalSemaphoreFd = {
"supports_external_semaphore_fd", FeatureCategory::VulkanFeatures, "supports_external_semaphore_fd", FeatureCategory::VulkanFeatures,
"VkDevice supports the VK_KHR_external_semaphore_fd extension", &members}; "VkDevice supports the VK_KHR_external_semaphore_fd extension", &members};
// Whether the VkDevice supports the VK_FUCHSIA_external_semaphore
// extension, on which the GL_ANGLE_semaphore_fuchsia extension can be layered.
angle::Feature supportsExternalSemaphoreFuchsia = {
"supports_external_semaphore_fuchsia", FeatureCategory::VulkanFeatures,
"VkDevice supports the VK_FUCHSIA_external_semaphore extension", &members};
// Whether the VkDevice supports the VK_EXT_shader_stencil_export extension, which is used to // Whether the VkDevice supports the VK_EXT_shader_stencil_export extension, which is used to
// perform multisampled resolve of stencil buffer. A multi-step workaround is used instead if // perform multisampled resolve of stencil buffer. A multi-step workaround is used instead if
// this extension is not available. // this extension is not available.
......
//
// Copyright 2019 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// vulkan_fuchsia_ext:
// Defines Fuchsia-specific Vulkan extensions that haven't been
// upstreamed to the official Vulkan headers.
//
#ifndef COMMON_VULKAN_FUCHSIA_EXT_H_
#define COMMON_VULKAN_FUCHSIA_EXT_H_
#if !defined(VK_NO_PROTOTYPES)
# define VK_NO_PROTOTYPES
#endif
#include <vulkan/vulkan.h>
#if defined(ANGLE_PLATFORM_FUCHSIA)
# include <zircon/types.h>
#else
typedef uint32_t zx_handle_t;
# define ZX_HANDLE_INVALID ((zx_handle_t)0)
#endif
#ifdef __cplusplus
extern "C" {
#endif
const VkStructureType VK_STRUCTURE_TYPE_TEMP_IMPORT_MEMORY_ZIRCON_HANDLE_INFO_FUCHSIA =
static_cast<VkStructureType>(1001005000);
const VkStructureType VK_STRUCTURE_TYPE_TEMP_MEMORY_ZIRCON_HANDLE_PROPERTIES_FUCHSIA =
static_cast<VkStructureType>(1001005001);
const VkStructureType VK_STRUCTURE_TYPE_TEMP_MEMORY_GET_ZIRCON_HANDLE_INFO_FUCHSIA =
static_cast<VkStructureType>(1001005002);
const VkStructureType VK_STRUCTURE_TYPE_TEMP_IMPORT_SEMAPHORE_ZIRCON_HANDLE_INFO_FUCHSIA =
static_cast<VkStructureType>(1001006000);
const VkStructureType VK_STRUCTURE_TYPE_TEMP_SEMAPHORE_GET_ZIRCON_HANDLE_INFO_FUCHSIA =
static_cast<VkStructureType>(1001006001);
const VkExternalMemoryHandleTypeFlagBits
VK_EXTERNAL_MEMORY_HANDLE_TYPE_TEMP_ZIRCON_VMO_BIT_FUCHSIA =
static_cast<VkExternalMemoryHandleTypeFlagBits>(0x00100000);
const VkExternalSemaphoreHandleTypeFlagBits
VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_TEMP_ZIRCON_EVENT_BIT_FUCHSIA =
static_cast<VkExternalSemaphoreHandleTypeFlagBits>(0x00100000);
#define VK_FUCHSIA_external_memory 1
#define VK_FUCHSIA_EXTERNAL_MEMORY_SPEC_VERSION 1
#define VK_FUCHSIA_EXTERNAL_MEMORY_EXTENSION_NAME "VK_FUCHSIA_external_memory"
typedef struct VkImportMemoryZirconHandleInfoFUCHSIA
{
VkStructureType sType;
const void *pNext;
VkExternalMemoryHandleTypeFlagBits handleType;
zx_handle_t handle;
} VkImportMemoryZirconHandleInfoFUCHSIA;
typedef struct VkMemoryZirconHandlePropertiesFUCHSIA
{
VkStructureType sType;
void *pNext;
zx_handle_t memoryTypeBits;
} VkMemoryZirconHandlePropertiesFUCHSIA;
typedef struct VkMemoryGetZirconHandleInfoFUCHSIA
{
VkStructureType sType;
const void *pNext;
VkDeviceMemory memory;
VkExternalMemoryHandleTypeFlagBits handleType;
} VkMemoryGetZirconHandleInfoFUCHSIA;
typedef VkResult(VKAPI_PTR *PFN_vkGetMemoryZirconHandleFUCHSIA)(
VkDevice device,
const VkMemoryGetZirconHandleInfoFUCHSIA *pGetZirconHandleInfo,
zx_handle_t *pZirconHandle);
typedef VkResult(VKAPI_PTR *PFN_vkGetMemoryZirconHandlePropertiesFUCHSIA)(
VkDevice device,
VkExternalMemoryHandleTypeFlagBits handleType,
zx_handle_t ZirconHandle,
VkMemoryZirconHandlePropertiesFUCHSIA *pMemoryZirconHandleProperties);
#ifndef VK_NO_PROTOTYPES
VKAPI_ATTR VkResult VKAPI_CALL
vkGetMemoryZirconHandleFUCHSIA(VkDevice device,
const VkMemoryGetZirconHandleInfoFUCHSIA *pGetZirconHandleInfo,
zx_handle_t *pZirconHandle);
VKAPI_ATTR VkResult VKAPI_CALL vkGetMemoryZirconHandlePropertiesFUCHSIA(
VkDevice device,
VkExternalMemoryHandleTypeFlagBits handleType,
zx_handle_t ZirconHandle,
VkMemoryZirconHandlePropertiesFUCHSIA *pMemoryZirconHandleProperties);
#endif
#define VK_FUCHSIA_external_semaphore 1
#define VK_FUCHSIA_EXTERNAL_SEMAPHORE_SPEC_VERSION 1
#define VK_FUCHSIA_EXTERNAL_SEMAPHORE_EXTENSION_NAME "VK_FUCHSIA_external_semaphore"
typedef struct VkImportSemaphoreZirconHandleInfoFUCHSIA
{
VkStructureType sType;
const void *pNext;
VkSemaphore semaphore;
VkSemaphoreImportFlags flags;
VkExternalSemaphoreHandleTypeFlagBits handleType;
zx_handle_t handle;
} VkImportSemaphoreZirconHandleInfoFUCHSIA;
typedef struct VkSemaphoreGetZirconHandleInfoFUCHSIA
{
VkStructureType sType;
const void *pNext;
VkSemaphore semaphore;
VkExternalSemaphoreHandleTypeFlagBits handleType;
} VkSemaphoreGetZirconHandleInfoFUCHSIA;
typedef VkResult(VKAPI_PTR *PFN_vkImportSemaphoreZirconHandleFUCHSIA)(
VkDevice device,
const VkImportSemaphoreZirconHandleInfoFUCHSIA *pImportSemaphoreZirconHandleInfo);
typedef VkResult(VKAPI_PTR *PFN_vkGetSemaphoreZirconHandleFUCHSIA)(
VkDevice device,
const VkSemaphoreGetZirconHandleInfoFUCHSIA *pGetZirconHandleInfo,
zx_handle_t *pZirconHandle);
#ifndef VK_NO_PROTOTYPES
VKAPI_ATTR VkResult VKAPI_CALL vkImportSemaphoreZirconHandleFUCHSIA(
VkDevice device,
const VkImportSemaphoreZirconHandleInfoFUCHSIA *pImportSemaphoreZirconHandleInfo);
VKAPI_ATTR VkResult VKAPI_CALL
vkGetSemaphoreZirconHandleFUCHSIA(VkDevice device,
const VkSemaphoreGetZirconHandleInfoFUCHSIA *pGetZirconHandleInfo,
zx_handle_t *pZirconHandle);
#endif
#ifdef __cplusplus
}
#endif
#endif // COMMON_VULKAN_FUCHSIA_EXT_H_
...@@ -8145,7 +8145,9 @@ void Context::importMemoryZirconHandle(MemoryObjectID memory, ...@@ -8145,7 +8145,9 @@ void Context::importMemoryZirconHandle(MemoryObjectID memory,
HandleType handleType, HandleType handleType,
GLuint handle) GLuint handle)
{ {
UNREACHABLE(); MemoryObject *memoryObject = getMemoryObject(memory);
ASSERT(memoryObject != nullptr);
ANGLE_CONTEXT_TRY(memoryObject->importZirconHandle(this, size, handleType, handle));
} }
void Context::genSemaphores(GLsizei n, SemaphoreID *semaphores) void Context::genSemaphores(GLsizei n, SemaphoreID *semaphores)
...@@ -8247,7 +8249,9 @@ void Context::importSemaphoreZirconHandle(SemaphoreID semaphore, ...@@ -8247,7 +8249,9 @@ void Context::importSemaphoreZirconHandle(SemaphoreID semaphore,
HandleType handleType, HandleType handleType,
GLuint handle) GLuint handle)
{ {
UNREACHABLE(); Semaphore *semaphoreObject = getSemaphore(semaphore);
ASSERT(semaphoreObject != nullptr);
ANGLE_CONTEXT_TRY(semaphoreObject->importZirconHandle(this, handleType, handle));
} }
void Context::eGLImageTargetTexture2D(TextureType target, GLeglImageOES image) void Context::eGLImageTargetTexture2D(TextureType target, GLeglImageOES image)
......
...@@ -33,4 +33,12 @@ angle::Result MemoryObject::importFd(Context *context, ...@@ -33,4 +33,12 @@ angle::Result MemoryObject::importFd(Context *context,
return mImplementation->importFd(context, size, handleType, fd); return mImplementation->importFd(context, size, handleType, fd);
} }
angle::Result MemoryObject::importZirconHandle(Context *context,
GLuint64 size,
HandleType handleType,
GLuint handle)
{
return mImplementation->importZirconHandle(context, size, handleType, handle);
}
} // namespace gl } // namespace gl
...@@ -35,6 +35,10 @@ class MemoryObject final : public RefCountObject<MemoryObjectID> ...@@ -35,6 +35,10 @@ class MemoryObject final : public RefCountObject<MemoryObjectID>
rx::MemoryObjectImpl *getImplementation() const { return mImplementation.get(); } rx::MemoryObjectImpl *getImplementation() const { return mImplementation.get(); }
angle::Result importFd(Context *context, GLuint64 size, HandleType handleType, GLint fd); angle::Result importFd(Context *context, GLuint64 size, HandleType handleType, GLint fd);
angle::Result importZirconHandle(Context *context,
GLuint64 size,
HandleType handleType,
GLuint handle);
private: private:
std::unique_ptr<rx::MemoryObjectImpl> mImplementation; std::unique_ptr<rx::MemoryObjectImpl> mImplementation;
......
...@@ -30,6 +30,11 @@ angle::Result Semaphore::importFd(Context *context, HandleType handleType, GLint ...@@ -30,6 +30,11 @@ angle::Result Semaphore::importFd(Context *context, HandleType handleType, GLint
return mImplementation->importFd(context, handleType, fd); return mImplementation->importFd(context, handleType, fd);
} }
angle::Result Semaphore::importZirconHandle(Context *context, HandleType handleType, GLuint handle)
{
return mImplementation->importZirconHandle(context, handleType, handle);
}
angle::Result Semaphore::wait(Context *context, angle::Result Semaphore::wait(Context *context,
const BufferBarrierVector &bufferBarriers, const BufferBarrierVector &bufferBarriers,
const TextureBarrierVector &textureBarriers) const TextureBarrierVector &textureBarriers)
......
...@@ -38,6 +38,7 @@ class Semaphore final : public RefCountObject<SemaphoreID> ...@@ -38,6 +38,7 @@ class Semaphore final : public RefCountObject<SemaphoreID>
rx::SemaphoreImpl *getImplementation() const { return mImplementation.get(); } rx::SemaphoreImpl *getImplementation() const { return mImplementation.get(); }
angle::Result importFd(Context *context, HandleType handleType, GLint fd); angle::Result importFd(Context *context, HandleType handleType, GLint fd);
angle::Result importZirconHandle(Context *context, HandleType handleType, GLuint handle);
angle::Result wait(Context *context, angle::Result wait(Context *context,
const BufferBarrierVector &bufferBarriers, const BufferBarrierVector &bufferBarriers,
......
...@@ -32,7 +32,11 @@ class MemoryObjectImpl : angle::NonCopyable ...@@ -32,7 +32,11 @@ class MemoryObjectImpl : angle::NonCopyable
virtual angle::Result importFd(gl::Context *context, virtual angle::Result importFd(gl::Context *context,
GLuint64 size, GLuint64 size,
gl::HandleType handleType, gl::HandleType handleType,
GLint fd) = 0; GLint fd) = 0;
virtual angle::Result importZirconHandle(gl::Context *context,
GLuint64 size,
gl::HandleType handleType,
GLuint handle) = 0;
}; };
} // namespace rx } // namespace rx
......
...@@ -32,6 +32,10 @@ class SemaphoreImpl : angle::NonCopyable ...@@ -32,6 +32,10 @@ class SemaphoreImpl : angle::NonCopyable
virtual angle::Result importFd(gl::Context *context, gl::HandleType handleType, GLint fd) = 0; virtual angle::Result importFd(gl::Context *context, gl::HandleType handleType, GLint fd) = 0;
virtual angle::Result importZirconHandle(gl::Context *context,
gl::HandleType handleType,
GLuint handle) = 0;
virtual angle::Result wait(gl::Context *context, virtual angle::Result wait(gl::Context *context,
const gl::BufferBarrierVector &bufferBarriers, const gl::BufferBarrierVector &bufferBarriers,
const gl::TextureBarrierVector &textureBarriers) = 0; const gl::TextureBarrierVector &textureBarriers) = 0;
......
...@@ -39,6 +39,15 @@ angle::Result MemoryObjectGL::importFd(gl::Context *context, ...@@ -39,6 +39,15 @@ angle::Result MemoryObjectGL::importFd(gl::Context *context,
return angle::Result::Continue; return angle::Result::Continue;
} }
angle::Result MemoryObjectGL::importZirconHandle(gl::Context *context,
GLuint64 size,
gl::HandleType handleType,
GLuint handle)
{
UNREACHABLE();
return angle::Result::Stop;
}
GLuint MemoryObjectGL::getMemoryObjectID() const GLuint MemoryObjectGL::getMemoryObjectID() const
{ {
return mMemoryObject; return mMemoryObject;
......
...@@ -26,6 +26,11 @@ class MemoryObjectGL : public MemoryObjectImpl ...@@ -26,6 +26,11 @@ class MemoryObjectGL : public MemoryObjectImpl
gl::HandleType handleType, gl::HandleType handleType,
GLint fd) override; GLint fd) override;
angle::Result importZirconHandle(gl::Context *context,
GLuint64 size,
gl::HandleType handleType,
GLuint handle) override;
GLuint getMemoryObjectID() const; GLuint getMemoryObjectID() const;
private: private:
......
...@@ -67,6 +67,14 @@ angle::Result SemaphoreGL::importFd(gl::Context *context, gl::HandleType handleT ...@@ -67,6 +67,14 @@ angle::Result SemaphoreGL::importFd(gl::Context *context, gl::HandleType handleT
return angle::Result::Continue; return angle::Result::Continue;
} }
angle::Result SemaphoreGL::importZirconHandle(gl::Context *context,
gl::HandleType handleType,
GLuint handle)
{
UNREACHABLE();
return angle::Result::Stop;
}
angle::Result SemaphoreGL::wait(gl::Context *context, angle::Result SemaphoreGL::wait(gl::Context *context,
const gl::BufferBarrierVector &bufferBarriers, const gl::BufferBarrierVector &bufferBarriers,
const gl::TextureBarrierVector &textureBarriers) const gl::TextureBarrierVector &textureBarriers)
......
...@@ -23,6 +23,10 @@ class SemaphoreGL : public SemaphoreImpl ...@@ -23,6 +23,10 @@ class SemaphoreGL : public SemaphoreImpl
angle::Result importFd(gl::Context *context, gl::HandleType handleType, GLint fd) override; angle::Result importFd(gl::Context *context, gl::HandleType handleType, GLint fd) override;
angle::Result importZirconHandle(gl::Context *context,
gl::HandleType handleType,
GLuint handle) override;
angle::Result wait(gl::Context *context, angle::Result wait(gl::Context *context,
const gl::BufferBarrierVector &bufferBarriers, const gl::BufferBarrierVector &bufferBarriers,
const gl::TextureBarrierVector &textureBarriers) override; const gl::TextureBarrierVector &textureBarriers) override;
......
...@@ -7,12 +7,12 @@ ...@@ -7,12 +7,12 @@
#include "libANGLE/renderer/vulkan/MemoryObjectVk.h" #include "libANGLE/renderer/vulkan/MemoryObjectVk.h"
#include "volk.h"
#include "common/debug.h" #include "common/debug.h"
#include "libANGLE/Context.h" #include "libANGLE/Context.h"
#include "libANGLE/renderer/vulkan/ContextVk.h" #include "libANGLE/renderer/vulkan/ContextVk.h"
#include "libANGLE/renderer/vulkan/RendererVk.h" #include "libANGLE/renderer/vulkan/RendererVk.h"
#include "volk.h"
#include "vulkan/vulkan_fuchsia_ext.h"
#if !defined(ANGLE_PLATFORM_WINDOWS) #if !defined(ANGLE_PLATFORM_WINDOWS)
# include <unistd.h> # include <unistd.h>
...@@ -20,14 +20,17 @@ ...@@ -20,14 +20,17 @@
# include <io.h> # include <io.h>
#endif #endif
#if defined(ANGLE_PLATFORM_FUCHSIA)
# include <zircon/status.h>
# include <zircon/syscalls.h>
#endif
namespace rx namespace rx
{ {
namespace namespace
{ {
constexpr int kInvalidFd = -1;
#if defined(ANGLE_PLATFORM_WINDOWS) #if defined(ANGLE_PLATFORM_WINDOWS)
int close(int fd) int close(int fd)
{ {
...@@ -35,9 +38,45 @@ int close(int fd) ...@@ -35,9 +38,45 @@ int close(int fd)
} }
#endif #endif
void CloseZirconVmo(zx_handle_t handle)
{
#if defined(ANGLE_PLATFORM_FUCHSIA)
zx_handle_close(handle);
#else
UNREACHABLE();
#endif
}
angle::Result DuplicateZirconVmo(ContextVk *contextVk, zx_handle_t handle, zx_handle_t *duplicate)
{
#if defined(ANGLE_PLATFORM_FUCHSIA)
zx_status_t status = zx_handle_duplicate(handle, ZX_RIGHT_SAME_RIGHTS, duplicate);
ANGLE_VK_CHECK(contextVk, status == ZX_OK, VK_ERROR_INVALID_EXTERNAL_HANDLE);
return angle::Result::Continue;
#else
UNREACHABLE();
return angle::Result::Stop;
#endif
}
VkExternalMemoryHandleTypeFlagBits ToVulkanHandleType(gl::HandleType handleType)
{
switch (handleType)
{
case gl::HandleType::OpaqueFd:
return VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT;
case gl::HandleType::ZirconVmo:
return VK_EXTERNAL_MEMORY_HANDLE_TYPE_TEMP_ZIRCON_VMO_BIT_FUCHSIA;
default:
// Not a memory handle type.
UNREACHABLE();
return VK_EXTERNAL_MEMORY_HANDLE_TYPE_FLAG_BITS_MAX_ENUM;
}
}
} // namespace } // namespace
MemoryObjectVk::MemoryObjectVk() : mSize(0), mFd(kInvalidFd) {} MemoryObjectVk::MemoryObjectVk() {}
MemoryObjectVk::~MemoryObjectVk() = default; MemoryObjectVk::~MemoryObjectVk() = default;
...@@ -48,6 +87,12 @@ void MemoryObjectVk::onDestroy(const gl::Context *context) ...@@ -48,6 +87,12 @@ void MemoryObjectVk::onDestroy(const gl::Context *context)
close(mFd); close(mFd);
mFd = kInvalidFd; mFd = kInvalidFd;
} }
if (mZirconHandle != ZX_HANDLE_INVALID)
{
CloseZirconVmo(mZirconHandle);
mZirconHandle = ZX_HANDLE_INVALID;
}
} }
angle::Result MemoryObjectVk::importFd(gl::Context *context, angle::Result MemoryObjectVk::importFd(gl::Context *context,
...@@ -68,11 +113,43 @@ angle::Result MemoryObjectVk::importFd(gl::Context *context, ...@@ -68,11 +113,43 @@ angle::Result MemoryObjectVk::importFd(gl::Context *context,
} }
} }
angle::Result MemoryObjectVk::importZirconHandle(gl::Context *context,
GLuint64 size,
gl::HandleType handleType,
GLuint handle)
{
ContextVk *contextVk = vk::GetImpl(context);
switch (handleType)
{
case gl::HandleType::ZirconVmo:
return importZirconVmo(contextVk, size, handle);
default:
UNREACHABLE();
return angle::Result::Stop;
}
}
angle::Result MemoryObjectVk::importOpaqueFd(ContextVk *contextVk, GLuint64 size, GLint fd) angle::Result MemoryObjectVk::importOpaqueFd(ContextVk *contextVk, GLuint64 size, GLint fd)
{ {
ASSERT(mHandleType == gl::HandleType::InvalidEnum);
ASSERT(mFd == kInvalidFd); ASSERT(mFd == kInvalidFd);
mFd = fd; ASSERT(fd != kInvalidFd);
mSize = size; mHandleType = gl::HandleType::OpaqueFd;
mFd = fd;
mSize = size;
return angle::Result::Continue;
}
angle::Result MemoryObjectVk::importZirconVmo(ContextVk *contextVk, GLuint64 size, GLuint handle)
{
ASSERT(mHandleType == gl::HandleType::InvalidEnum);
ASSERT(mZirconHandle == ZX_HANDLE_INVALID);
ASSERT(handle != ZX_HANDLE_INVALID);
mHandleType = gl::HandleType::ZirconVmo;
mZirconHandle = handle;
mSize = size;
return angle::Result::Continue; return angle::Result::Continue;
} }
...@@ -95,7 +172,7 @@ angle::Result MemoryObjectVk::createImage(ContextVk *contextVk, ...@@ -95,7 +172,7 @@ angle::Result MemoryObjectVk::createImage(ContextVk *contextVk,
VkExternalMemoryImageCreateInfo externalMemoryImageCreateInfo = {}; VkExternalMemoryImageCreateInfo externalMemoryImageCreateInfo = {};
externalMemoryImageCreateInfo.sType = VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO; externalMemoryImageCreateInfo.sType = VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO;
externalMemoryImageCreateInfo.handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT; externalMemoryImageCreateInfo.handleTypes = ToVulkanHandleType(mHandleType);
VkExtent3D vkExtents; VkExtent3D vkExtents;
uint32_t layerCount; uint32_t layerCount;
...@@ -109,11 +186,30 @@ angle::Result MemoryObjectVk::createImage(ContextVk *contextVk, ...@@ -109,11 +186,30 @@ angle::Result MemoryObjectVk::createImage(ContextVk *contextVk,
VkMemoryRequirements externalMemoryRequirements; VkMemoryRequirements externalMemoryRequirements;
image->getImage().getMemoryRequirements(renderer->getDevice(), &externalMemoryRequirements); image->getImage().getMemoryRequirements(renderer->getDevice(), &externalMemoryRequirements);
ASSERT(mFd != -1); void *importMemoryInfo = nullptr;
VkImportMemoryFdInfoKHR importMemoryFdInfo = {}; VkImportMemoryFdInfoKHR importMemoryFdInfo = {};
importMemoryFdInfo.sType = VK_STRUCTURE_TYPE_IMPORT_MEMORY_FD_INFO_KHR; VkImportMemoryZirconHandleInfoFUCHSIA importMemoryZirconHandleInfo = {};
importMemoryFdInfo.handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT; switch (mHandleType)
importMemoryFdInfo.fd = dup(mFd); {
case gl::HandleType::OpaqueFd:
ASSERT(mFd != kInvalidFd);
importMemoryFdInfo.sType = VK_STRUCTURE_TYPE_IMPORT_MEMORY_FD_INFO_KHR;
importMemoryFdInfo.handleType = ToVulkanHandleType(mHandleType);
importMemoryFdInfo.fd = dup(mFd);
importMemoryInfo = &importMemoryFdInfo;
break;
case gl::HandleType::ZirconVmo:
ASSERT(mZirconHandle != ZX_HANDLE_INVALID);
importMemoryZirconHandleInfo.sType =
VK_STRUCTURE_TYPE_TEMP_IMPORT_MEMORY_ZIRCON_HANDLE_INFO_FUCHSIA;
importMemoryZirconHandleInfo.handleType = ToVulkanHandleType(mHandleType);
ANGLE_TRY(
DuplicateZirconVmo(contextVk, mZirconHandle, &importMemoryZirconHandleInfo.handle));
importMemoryInfo = &importMemoryZirconHandleInfo;
break;
default:
UNREACHABLE();
}
// TODO(jmadill, spang): Memory sub-allocation. http://anglebug.com/2162 // TODO(jmadill, spang): Memory sub-allocation. http://anglebug.com/2162
ASSERT(offset == 0); ASSERT(offset == 0);
...@@ -121,7 +217,7 @@ angle::Result MemoryObjectVk::createImage(ContextVk *contextVk, ...@@ -121,7 +217,7 @@ angle::Result MemoryObjectVk::createImage(ContextVk *contextVk,
VkMemoryPropertyFlags flags = 0; VkMemoryPropertyFlags flags = 0;
ANGLE_TRY(image->initExternalMemory(contextVk, renderer->getMemoryProperties(), ANGLE_TRY(image->initExternalMemory(contextVk, renderer->getMemoryProperties(),
externalMemoryRequirements, &importMemoryFdInfo, externalMemoryRequirements, importMemoryInfo,
VK_QUEUE_FAMILY_EXTERNAL, flags)); VK_QUEUE_FAMILY_EXTERNAL, flags));
return angle::Result::Continue; return angle::Result::Continue;
......
...@@ -28,7 +28,12 @@ class MemoryObjectVk : public MemoryObjectImpl ...@@ -28,7 +28,12 @@ class MemoryObjectVk : public MemoryObjectImpl
gl::HandleType handleType, gl::HandleType handleType,
GLint fd) override; GLint fd) override;
angle::Result createImage(ContextVk *contextVk, angle::Result importZirconHandle(gl::Context *context,
GLuint64 size,
gl::HandleType handleType,
GLuint handle) override;
angle::Result createImage(ContextVk *context,
gl::TextureType type, gl::TextureType type,
size_t levels, size_t levels,
GLenum internalFormat, GLenum internalFormat,
...@@ -37,10 +42,15 @@ class MemoryObjectVk : public MemoryObjectImpl ...@@ -37,10 +42,15 @@ class MemoryObjectVk : public MemoryObjectImpl
vk::ImageHelper *image); vk::ImageHelper *image);
private: private:
static constexpr int kInvalidFd = -1;
angle::Result importOpaqueFd(ContextVk *contextVk, GLuint64 size, GLint fd); angle::Result importOpaqueFd(ContextVk *contextVk, GLuint64 size, GLint fd);
angle::Result importZirconVmo(ContextVk *contextVk, GLuint64 size, GLuint handle);
GLuint64 mSize = 0;
gl::HandleType mHandleType = gl::HandleType::InvalidEnum;
int mFd = kInvalidFd;
GLuint64 mSize; zx_handle_t mZirconHandle = ZX_HANDLE_INVALID;
int mFd;
}; };
} // namespace rx } // namespace rx
......
...@@ -1128,12 +1128,6 @@ angle::Result RendererVk::initializeDevice(DisplayVk *displayVk, uint32_t queueF ...@@ -1128,12 +1128,6 @@ angle::Result RendererVk::initializeDevice(DisplayVk *displayVk, uint32_t queueF
enabledDeviceExtensions.push_back(VK_KHR_INCREMENTAL_PRESENT_EXTENSION_NAME); enabledDeviceExtensions.push_back(VK_KHR_INCREMENTAL_PRESENT_EXTENSION_NAME);
} }
if (getFeatures().supportsAndroidHardwareBuffer.enabled ||
getFeatures().supportsExternalMemoryFd.enabled)
{
enabledDeviceExtensions.push_back(VK_KHR_EXTERNAL_MEMORY_EXTENSION_NAME);
}
#if defined(ANGLE_PLATFORM_ANDROID) #if defined(ANGLE_PLATFORM_ANDROID)
if (getFeatures().supportsAndroidHardwareBuffer.enabled) if (getFeatures().supportsAndroidHardwareBuffer.enabled)
{ {
...@@ -1145,12 +1139,25 @@ angle::Result RendererVk::initializeDevice(DisplayVk *displayVk, uint32_t queueF ...@@ -1145,12 +1139,25 @@ angle::Result RendererVk::initializeDevice(DisplayVk *displayVk, uint32_t queueF
ASSERT(!getFeatures().supportsAndroidHardwareBuffer.enabled); ASSERT(!getFeatures().supportsAndroidHardwareBuffer.enabled);
#endif #endif
if (getFeatures().supportsAndroidHardwareBuffer.enabled ||
getFeatures().supportsExternalMemoryFd.enabled ||
getFeatures().supportsExternalMemoryFuchsia.enabled)
{
enabledDeviceExtensions.push_back(VK_KHR_EXTERNAL_MEMORY_EXTENSION_NAME);
}
if (getFeatures().supportsExternalMemoryFd.enabled) if (getFeatures().supportsExternalMemoryFd.enabled)
{ {
enabledDeviceExtensions.push_back(VK_KHR_EXTERNAL_MEMORY_FD_EXTENSION_NAME); enabledDeviceExtensions.push_back(VK_KHR_EXTERNAL_MEMORY_FD_EXTENSION_NAME);
} }
if (getFeatures().supportsExternalSemaphoreFd.enabled) if (getFeatures().supportsExternalMemoryFuchsia.enabled)
{
enabledDeviceExtensions.push_back(VK_FUCHSIA_EXTERNAL_MEMORY_EXTENSION_NAME);
}
if (getFeatures().supportsExternalSemaphoreFd.enabled ||
getFeatures().supportsExternalSemaphoreFuchsia.enabled)
{ {
enabledDeviceExtensions.push_back(VK_KHR_EXTERNAL_SEMAPHORE_EXTENSION_NAME); enabledDeviceExtensions.push_back(VK_KHR_EXTERNAL_SEMAPHORE_EXTENSION_NAME);
} }
...@@ -1160,6 +1167,11 @@ angle::Result RendererVk::initializeDevice(DisplayVk *displayVk, uint32_t queueF ...@@ -1160,6 +1167,11 @@ angle::Result RendererVk::initializeDevice(DisplayVk *displayVk, uint32_t queueF
enabledDeviceExtensions.push_back(VK_KHR_EXTERNAL_SEMAPHORE_FD_EXTENSION_NAME); enabledDeviceExtensions.push_back(VK_KHR_EXTERNAL_SEMAPHORE_FD_EXTENSION_NAME);
} }
if (getFeatures().supportsExternalSemaphoreFuchsia.enabled)
{
enabledDeviceExtensions.push_back(VK_FUCHSIA_EXTERNAL_SEMAPHORE_EXTENSION_NAME);
}
if (getFeatures().supportsShaderStencilExport.enabled) if (getFeatures().supportsShaderStencilExport.enabled)
{ {
enabledDeviceExtensions.push_back(VK_EXT_SHADER_STENCIL_EXPORT_EXTENSION_NAME); enabledDeviceExtensions.push_back(VK_EXT_SHADER_STENCIL_EXPORT_EXTENSION_NAME);
...@@ -1573,10 +1585,18 @@ void RendererVk::initFeatures(DisplayVk *displayVk, const ExtensionNameList &dev ...@@ -1573,10 +1585,18 @@ void RendererVk::initFeatures(DisplayVk *displayVk, const ExtensionNameList &dev
ExtensionFound(VK_KHR_EXTERNAL_MEMORY_FD_EXTENSION_NAME, deviceExtensionNames)); ExtensionFound(VK_KHR_EXTERNAL_MEMORY_FD_EXTENSION_NAME, deviceExtensionNames));
ANGLE_FEATURE_CONDITION( ANGLE_FEATURE_CONDITION(
(&mFeatures), supportsExternalMemoryFuchsia,
ExtensionFound(VK_FUCHSIA_EXTERNAL_MEMORY_EXTENSION_NAME, deviceExtensionNames));
ANGLE_FEATURE_CONDITION(
(&mFeatures), supportsExternalSemaphoreFd, (&mFeatures), supportsExternalSemaphoreFd,
ExtensionFound(VK_KHR_EXTERNAL_SEMAPHORE_FD_EXTENSION_NAME, deviceExtensionNames)); ExtensionFound(VK_KHR_EXTERNAL_SEMAPHORE_FD_EXTENSION_NAME, deviceExtensionNames));
ANGLE_FEATURE_CONDITION( ANGLE_FEATURE_CONDITION(
(&mFeatures), supportsExternalSemaphoreFuchsia,
ExtensionFound(VK_FUCHSIA_EXTERNAL_SEMAPHORE_EXTENSION_NAME, deviceExtensionNames));
ANGLE_FEATURE_CONDITION(
(&mFeatures), supportsShaderStencilExport, (&mFeatures), supportsShaderStencilExport,
ExtensionFound(VK_EXT_SHADER_STENCIL_EXPORT_EXTENSION_NAME, deviceExtensionNames)); ExtensionFound(VK_EXT_SHADER_STENCIL_EXPORT_EXTENSION_NAME, deviceExtensionNames));
......
...@@ -78,6 +78,23 @@ angle::Result SemaphoreVk::importFd(gl::Context *context, gl::HandleType handleT ...@@ -78,6 +78,23 @@ angle::Result SemaphoreVk::importFd(gl::Context *context, gl::HandleType handleT
} }
} }
angle::Result SemaphoreVk::importZirconHandle(gl::Context *context,
gl::HandleType handleType,
GLuint handle)
{
ContextVk *contextVk = vk::GetImpl(context);
switch (handleType)
{
case gl::HandleType::ZirconEvent:
return importZirconEvent(contextVk, handle);
default:
ANGLE_VK_UNREACHABLE(contextVk);
return angle::Result::Stop;
}
}
angle::Result SemaphoreVk::wait(gl::Context *context, angle::Result SemaphoreVk::wait(gl::Context *context,
const gl::BufferBarrierVector &bufferBarriers, const gl::BufferBarrierVector &bufferBarriers,
const gl::TextureBarrierVector &textureBarriers) const gl::TextureBarrierVector &textureBarriers)
...@@ -216,4 +233,35 @@ angle::Result SemaphoreVk::importOpaqueFd(ContextVk *contextVk, GLint fd) ...@@ -216,4 +233,35 @@ angle::Result SemaphoreVk::importOpaqueFd(ContextVk *contextVk, GLint fd)
return angle::Result::Continue; return angle::Result::Continue;
} }
angle::Result SemaphoreVk::importZirconEvent(ContextVk *contextVk, GLuint handle)
{
RendererVk *renderer = contextVk->getRenderer();
if (!mSemaphore.valid())
{
mSemaphore.init(renderer->getDevice());
}
ASSERT(mSemaphore.valid());
VkImportSemaphoreZirconHandleInfoFUCHSIA importSemaphoreZirconHandleInfo = {};
importSemaphoreZirconHandleInfo.sType =
VK_STRUCTURE_TYPE_TEMP_IMPORT_SEMAPHORE_ZIRCON_HANDLE_INFO_FUCHSIA;
importSemaphoreZirconHandleInfo.semaphore = mSemaphore.getHandle();
importSemaphoreZirconHandleInfo.flags = 0;
importSemaphoreZirconHandleInfo.handleType =
VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_TEMP_ZIRCON_EVENT_BIT_FUCHSIA;
importSemaphoreZirconHandleInfo.handle = handle;
// TODO(spang): Add vkImportSemaphoreZirconHandleFUCHSIA to volk.
static PFN_vkImportSemaphoreZirconHandleFUCHSIA vkImportSemaphoreZirconHandleFUCHSIA =
reinterpret_cast<PFN_vkImportSemaphoreZirconHandleFUCHSIA>(
vkGetInstanceProcAddr(renderer->getInstance(), "vkImportSemaphoreZirconHandleFUCHSIA"));
ANGLE_VK_TRY(contextVk, vkImportSemaphoreZirconHandleFUCHSIA(renderer->getDevice(),
&importSemaphoreZirconHandleInfo));
return angle::Result::Continue;
}
} // namespace rx } // namespace rx
...@@ -25,6 +25,10 @@ class SemaphoreVk : public SemaphoreImpl ...@@ -25,6 +25,10 @@ class SemaphoreVk : public SemaphoreImpl
angle::Result importFd(gl::Context *context, gl::HandleType handleType, GLint fd) override; angle::Result importFd(gl::Context *context, gl::HandleType handleType, GLint fd) override;
angle::Result importZirconHandle(gl::Context *context,
gl::HandleType handleType,
GLuint handle) override;
angle::Result wait(gl::Context *context, angle::Result wait(gl::Context *context,
const gl::BufferBarrierVector &bufferBarriers, const gl::BufferBarrierVector &bufferBarriers,
const gl::TextureBarrierVector &textureBarriers) override; const gl::TextureBarrierVector &textureBarriers) override;
...@@ -35,6 +39,7 @@ class SemaphoreVk : public SemaphoreImpl ...@@ -35,6 +39,7 @@ class SemaphoreVk : public SemaphoreImpl
private: private:
angle::Result importOpaqueFd(ContextVk *contextVk, GLint fd); angle::Result importOpaqueFd(ContextVk *contextVk, GLint fd);
angle::Result importZirconEvent(ContextVk *contextVk, GLuint handle);
vk::Semaphore mSemaphore; vk::Semaphore mSemaphore;
}; };
......
...@@ -94,9 +94,13 @@ void RendererVk::ensureCapsInitialized() const ...@@ -94,9 +94,13 @@ void RendererVk::ensureCapsInitialized() const
mNativeExtensions.memoryObject = true; mNativeExtensions.memoryObject = true;
mNativeExtensions.memoryObjectFd = getFeatures().supportsExternalMemoryFd.enabled; mNativeExtensions.memoryObjectFd = getFeatures().supportsExternalMemoryFd.enabled;
mNativeExtensions.memoryObjectFuchsiaANGLE =
getFeatures().supportsExternalMemoryFuchsia.enabled;
mNativeExtensions.semaphore = true; mNativeExtensions.semaphore = true;
mNativeExtensions.semaphoreFd = getFeatures().supportsExternalSemaphoreFd.enabled; mNativeExtensions.semaphoreFd = getFeatures().supportsExternalSemaphoreFd.enabled;
mNativeExtensions.semaphoreFuchsiaANGLE =
getFeatures().supportsExternalSemaphoreFuchsia.enabled;
mNativeExtensions.vertexHalfFloatOES = true; mNativeExtensions.vertexHalfFloatOES = true;
......
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
#include "libANGLE/renderer/serial_utils.h" #include "libANGLE/renderer/serial_utils.h"
#include "libANGLE/renderer/vulkan/SecondaryCommandBuffer.h" #include "libANGLE/renderer/vulkan/SecondaryCommandBuffer.h"
#include "libANGLE/renderer/vulkan/vk_wrapper.h" #include "libANGLE/renderer/vulkan/vk_wrapper.h"
#include "vulkan/vulkan_fuchsia_ext.h"
#define ANGLE_GL_OBJECTS_X(PROC) \ #define ANGLE_GL_OBJECTS_X(PROC) \
PROC(Buffer) \ PROC(Buffer) \
......
...@@ -3589,8 +3589,16 @@ bool ValidateImportMemoryZirconHandleANGLE(const Context *context, ...@@ -3589,8 +3589,16 @@ bool ValidateImportMemoryZirconHandleANGLE(const Context *context,
return false; return false;
} }
UNIMPLEMENTED(); switch (handleType)
return false; {
case HandleType::ZirconVmo:
break;
default:
context->validationError(GL_INVALID_ENUM, kInvalidHandleType);
return false;
}
return true;
} }
bool ValidateDeleteSemaphoresEXT(const Context *context, GLsizei n, const SemaphoreID *semaphores) bool ValidateDeleteSemaphoresEXT(const Context *context, GLsizei n, const SemaphoreID *semaphores)
...@@ -3733,7 +3741,7 @@ bool ValidateImportSemaphoreFdEXT(const Context *context, ...@@ -3733,7 +3741,7 @@ bool ValidateImportSemaphoreFdEXT(const Context *context,
bool ValidateImportSemaphoreZirconHandleANGLE(const Context *context, bool ValidateImportSemaphoreZirconHandleANGLE(const Context *context,
SemaphoreID semaphore, SemaphoreID semaphore,
HandleType handleTypePacked, HandleType handleType,
GLuint handle) GLuint handle)
{ {
if (!context->getExtensions().semaphoreFuchsiaANGLE) if (!context->getExtensions().semaphoreFuchsiaANGLE)
...@@ -3742,8 +3750,16 @@ bool ValidateImportSemaphoreZirconHandleANGLE(const Context *context, ...@@ -3742,8 +3750,16 @@ bool ValidateImportSemaphoreZirconHandleANGLE(const Context *context,
return false; return false;
} }
UNIMPLEMENTED(); switch (handleType)
return false; {
case HandleType::ZirconEvent:
break;
default:
context->validationError(GL_INVALID_ENUM, kInvalidHandleType);
return false;
}
return true;
} }
bool ValidateMapBufferBase(const Context *context, BufferBinding target) bool ValidateMapBufferBase(const Context *context, BufferBinding target)
......
...@@ -175,6 +175,59 @@ TEST_P(VulkanExternalImageTest, ShouldClearOpaqueFdRGBA8) ...@@ -175,6 +175,59 @@ TEST_P(VulkanExternalImageTest, ShouldClearOpaqueFdRGBA8)
vkFreeMemory(helper.getDevice(), deviceMemory, nullptr); vkFreeMemory(helper.getDevice(), deviceMemory, nullptr);
} }
// Test creating and clearing a simple RGBA8 texture in a zircon vmo.
TEST_P(VulkanExternalImageTest, ShouldClearZirconVmoRGBA8)
{
// http://anglebug.com/4229
ANGLE_SKIP_TEST_IF(IsVulkan());
ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_ANGLE_memory_object_fuchsia"));
VulkanExternalHelper helper;
helper.initialize();
VkFormat format = VK_FORMAT_R8G8B8A8_UNORM;
ANGLE_SKIP_TEST_IF(
!helper.canCreateImageZirconVmo(format, VK_IMAGE_TYPE_2D, VK_IMAGE_TILING_OPTIMAL));
VkImage image = VK_NULL_HANDLE;
VkDeviceMemory deviceMemory = VK_NULL_HANDLE;
VkDeviceSize deviceMemorySize = 0;
VkExtent3D extent = {1, 1, 1};
VkResult result =
helper.createImage2DZirconVmo(format, extent, &image, &deviceMemory, &deviceMemorySize);
EXPECT_EQ(result, VK_SUCCESS);
zx_handle_t vmo = ZX_HANDLE_INVALID;
result = helper.exportMemoryZirconVmo(deviceMemory, &vmo);
EXPECT_EQ(result, VK_SUCCESS);
EXPECT_NE(vmo, ZX_HANDLE_INVALID);
{
GLMemoryObject memoryObject;
glImportMemoryZirconHandleANGLE(memoryObject, deviceMemorySize,
GL_HANDLE_TYPE_ZIRCON_VMO_ANGLE, vmo);
GLTexture texture;
glBindTexture(GL_TEXTURE_2D, texture);
glTexStorageMem2DEXT(GL_TEXTURE_2D, 1, GL_RGBA8, 1, 1, memoryObject, 0);
GLFramebuffer framebuffer;
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
glClearColor(0.5f, 0.5f, 0.5f, 0.5f);
glClear(GL_COLOR_BUFFER_BIT);
EXPECT_PIXEL_NEAR(0, 0, 128, 128, 128, 128, 1.0);
}
EXPECT_GL_NO_ERROR();
vkDestroyImage(helper.getDevice(), image, nullptr);
vkFreeMemory(helper.getDevice(), deviceMemory, nullptr);
}
// Use this to select which configurations (e.g. which renderer, which GLES major version) these // Use this to select which configurations (e.g. which renderer, which GLES major version) these
// tests should be run against. // tests should be run against.
ANGLE_INSTANTIATE_TEST_ES2_AND_ES3(VulkanExternalImageTest); ANGLE_INSTANTIATE_TEST_ES2_AND_ES3(VulkanExternalImageTest);
......
...@@ -201,10 +201,9 @@ void VulkanExternalHelper::initialize() ...@@ -201,10 +201,9 @@ void VulkanExternalHelper::initialize()
EnumerateDeviceExtensionProperties(mPhysicalDevice, nullptr); EnumerateDeviceExtensionProperties(mPhysicalDevice, nullptr);
std::vector<const char *> requestedDeviceExtensions = { std::vector<const char *> requestedDeviceExtensions = {
VK_KHR_EXTERNAL_SEMAPHORE_EXTENSION_NAME, VK_KHR_EXTERNAL_SEMAPHORE_EXTENSION_NAME, VK_KHR_EXTERNAL_SEMAPHORE_FD_EXTENSION_NAME,
VK_KHR_EXTERNAL_SEMAPHORE_FD_EXTENSION_NAME, VK_KHR_EXTERNAL_MEMORY_EXTENSION_NAME, VK_KHR_EXTERNAL_MEMORY_FD_EXTENSION_NAME,
VK_KHR_EXTERNAL_MEMORY_EXTENSION_NAME, VK_FUCHSIA_EXTERNAL_MEMORY_EXTENSION_NAME, VK_FUCHSIA_EXTERNAL_SEMAPHORE_EXTENSION_NAME,
VK_KHR_EXTERNAL_MEMORY_FD_EXTENSION_NAME,
}; };
std::vector<const char *> enabledDeviceExtensions; std::vector<const char *> enabledDeviceExtensions;
...@@ -273,6 +272,10 @@ void VulkanExternalHelper::initialize() ...@@ -273,6 +272,10 @@ void VulkanExternalHelper::initialize()
HasExtension(enabledDeviceExtensions, VK_KHR_EXTERNAL_MEMORY_FD_EXTENSION_NAME); HasExtension(enabledDeviceExtensions, VK_KHR_EXTERNAL_MEMORY_FD_EXTENSION_NAME);
mHasExternalSemaphoreFd = mHasExternalSemaphoreFd =
HasExtension(enabledDeviceExtensions, VK_KHR_EXTERNAL_SEMAPHORE_FD_EXTENSION_NAME); HasExtension(enabledDeviceExtensions, VK_KHR_EXTERNAL_SEMAPHORE_FD_EXTENSION_NAME);
mHasExternalMemoryFuchsia =
HasExtension(enabledDeviceExtensions, VK_FUCHSIA_EXTERNAL_MEMORY_EXTENSION_NAME);
mHasExternalSemaphoreFuchsia =
HasExtension(enabledDeviceExtensions, VK_FUCHSIA_EXTERNAL_SEMAPHORE_EXTENSION_NAME);
vkGetPhysicalDeviceImageFormatProperties2 = vkGetPhysicalDeviceImageFormatProperties2 =
reinterpret_cast<PFN_vkGetPhysicalDeviceImageFormatProperties2>( reinterpret_cast<PFN_vkGetPhysicalDeviceImageFormatProperties2>(
...@@ -284,21 +287,20 @@ void VulkanExternalHelper::initialize() ...@@ -284,21 +287,20 @@ void VulkanExternalHelper::initialize()
vkGetPhysicalDeviceExternalSemaphorePropertiesKHR = vkGetPhysicalDeviceExternalSemaphorePropertiesKHR =
reinterpret_cast<PFN_vkGetPhysicalDeviceExternalSemaphorePropertiesKHR>( reinterpret_cast<PFN_vkGetPhysicalDeviceExternalSemaphorePropertiesKHR>(
vkGetInstanceProcAddr(mInstance, "vkGetPhysicalDeviceExternalSemaphorePropertiesKHR")); vkGetInstanceProcAddr(mInstance, "vkGetPhysicalDeviceExternalSemaphorePropertiesKHR"));
vkGetMemoryZirconHandleFUCHSIA = reinterpret_cast<PFN_vkGetMemoryZirconHandleFUCHSIA>(
vkGetInstanceProcAddr(mInstance, "vkGetMemoryZirconHandleFUCHSIA"));
} }
bool VulkanExternalHelper::canCreateImageOpaqueFd(VkFormat format, bool VulkanExternalHelper::canCreateImageExternal(
VkImageType type, VkFormat format,
VkImageTiling tiling) const VkImageType type,
VkImageTiling tiling,
VkExternalMemoryHandleTypeFlagBits handleType) const
{ {
if (!mHasExternalMemoryFd)
{
return false;
}
VkPhysicalDeviceExternalImageFormatInfo externalImageFormatInfo = { VkPhysicalDeviceExternalImageFormatInfo externalImageFormatInfo = {
/* .sType = */ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO, /* .sType = */ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO,
/* .pNext = */ nullptr, /* .pNext = */ nullptr,
/* .handleType = */ VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT, /* .handleType = */ handleType,
}; };
VkPhysicalDeviceImageFormatInfo2 imageFormatInfo = { VkPhysicalDeviceImageFormatInfo2 imageFormatInfo = {
...@@ -347,8 +349,9 @@ bool VulkanExternalHelper::canCreateImageOpaqueFd(VkFormat format, ...@@ -347,8 +349,9 @@ bool VulkanExternalHelper::canCreateImageOpaqueFd(VkFormat format,
return true; return true;
} }
VkResult VulkanExternalHelper::createImage2DOpaqueFd(VkFormat format, VkResult VulkanExternalHelper::createImage2DExternal(VkFormat format,
VkExtent3D extent, VkExtent3D extent,
VkExternalMemoryHandleTypeFlags handleTypes,
VkImage *imageOut, VkImage *imageOut,
VkDeviceMemory *deviceMemoryOut, VkDeviceMemory *deviceMemoryOut,
VkDeviceSize *deviceMemorySizeOut) VkDeviceSize *deviceMemorySizeOut)
...@@ -356,7 +359,7 @@ VkResult VulkanExternalHelper::createImage2DOpaqueFd(VkFormat format, ...@@ -356,7 +359,7 @@ VkResult VulkanExternalHelper::createImage2DOpaqueFd(VkFormat format,
VkExternalMemoryImageCreateInfoKHR externalMemoryImageCreateInfo = { VkExternalMemoryImageCreateInfoKHR externalMemoryImageCreateInfo = {
/* .sType = */ VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO, /* .sType = */ VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO,
/* .pNext = */ nullptr, /* .pNext = */ nullptr,
/* .handleTypes = */ VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT, /* .handleTypes = */ handleTypes,
}; };
VkImageCreateInfo imageCreateInfo = { VkImageCreateInfo imageCreateInfo = {
...@@ -395,9 +398,8 @@ VkResult VulkanExternalHelper::createImage2DOpaqueFd(VkFormat format, ...@@ -395,9 +398,8 @@ VkResult VulkanExternalHelper::createImage2DOpaqueFd(VkFormat format,
VkExportMemoryAllocateInfo exportMemoryAllocateInfo = { VkExportMemoryAllocateInfo exportMemoryAllocateInfo = {
/* .sType = */ VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO, /* .sType = */ VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO,
/* .pNext = */ nullptr, /* .pNext = */ nullptr,
/* .handleTypes = */ VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT, /* .handleTypes = */ handleTypes,
}; };
VkMemoryAllocateInfo memoryAllocateInfo = { VkMemoryAllocateInfo memoryAllocateInfo = {
/* .sType = */ VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, /* .sType = */ VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
/* .pNext = */ &exportMemoryAllocateInfo, /* .pNext = */ &exportMemoryAllocateInfo,
...@@ -429,6 +431,29 @@ VkResult VulkanExternalHelper::createImage2DOpaqueFd(VkFormat format, ...@@ -429,6 +431,29 @@ VkResult VulkanExternalHelper::createImage2DOpaqueFd(VkFormat format,
return VK_SUCCESS; return VK_SUCCESS;
} }
bool VulkanExternalHelper::canCreateImageOpaqueFd(VkFormat format,
VkImageType type,
VkImageTiling tiling) const
{
if (!mHasExternalMemoryFd)
{
return false;
}
return canCreateImageExternal(format, type, tiling,
VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT);
}
VkResult VulkanExternalHelper::createImage2DOpaqueFd(VkFormat format,
VkExtent3D extent,
VkImage *imageOut,
VkDeviceMemory *deviceMemoryOut,
VkDeviceSize *deviceMemorySizeOut)
{
return createImage2DExternal(format, extent, VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT,
imageOut, deviceMemoryOut, deviceMemorySizeOut);
}
VkResult VulkanExternalHelper::exportMemoryOpaqueFd(VkDeviceMemory deviceMemory, int *fd) VkResult VulkanExternalHelper::exportMemoryOpaqueFd(VkDeviceMemory deviceMemory, int *fd)
{ {
VkMemoryGetFdInfoKHR memoryGetFdInfo = { VkMemoryGetFdInfoKHR memoryGetFdInfo = {
...@@ -441,6 +466,42 @@ VkResult VulkanExternalHelper::exportMemoryOpaqueFd(VkDeviceMemory deviceMemory, ...@@ -441,6 +466,42 @@ VkResult VulkanExternalHelper::exportMemoryOpaqueFd(VkDeviceMemory deviceMemory,
return vkGetMemoryFdKHR(mDevice, &memoryGetFdInfo, fd); return vkGetMemoryFdKHR(mDevice, &memoryGetFdInfo, fd);
} }
bool VulkanExternalHelper::canCreateImageZirconVmo(VkFormat format,
VkImageType type,
VkImageTiling tiling) const
{
if (!mHasExternalMemoryFuchsia)
{
return false;
}
return canCreateImageExternal(format, type, tiling,
VK_EXTERNAL_MEMORY_HANDLE_TYPE_TEMP_ZIRCON_VMO_BIT_FUCHSIA);
}
VkResult VulkanExternalHelper::createImage2DZirconVmo(VkFormat format,
VkExtent3D extent,
VkImage *imageOut,
VkDeviceMemory *deviceMemoryOut,
VkDeviceSize *deviceMemorySizeOut)
{
return createImage2DExternal(format, extent,
VK_EXTERNAL_MEMORY_HANDLE_TYPE_TEMP_ZIRCON_VMO_BIT_FUCHSIA,
imageOut, deviceMemoryOut, deviceMemorySizeOut);
}
VkResult VulkanExternalHelper::exportMemoryZirconVmo(VkDeviceMemory deviceMemory, zx_handle_t *vmo)
{
VkMemoryGetZirconHandleInfoFUCHSIA memoryGetZirconHandleInfo = {
/* .sType = */ VK_STRUCTURE_TYPE_TEMP_MEMORY_GET_ZIRCON_HANDLE_INFO_FUCHSIA,
/* .pNext = */ nullptr,
/* .memory = */ deviceMemory,
/* .handleType = */ VK_EXTERNAL_MEMORY_HANDLE_TYPE_TEMP_ZIRCON_VMO_BIT_FUCHSIA,
};
return vkGetMemoryZirconHandleFUCHSIA(mDevice, &memoryGetZirconHandleInfo, vmo);
}
bool VulkanExternalHelper::canCreateSemaphoreOpaqueFd() const bool VulkanExternalHelper::canCreateSemaphoreOpaqueFd() const
{ {
if (!mHasExternalSemaphoreFd || !vkGetPhysicalDeviceExternalSemaphorePropertiesKHR) if (!mHasExternalSemaphoreFd || !vkGetPhysicalDeviceExternalSemaphorePropertiesKHR)
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#define ANGLE_TESTS_TESTUTILS_VULKANEXTERNALHELPER_H_ #define ANGLE_TESTS_TESTUTILS_VULKANEXTERNALHELPER_H_
#include "volk.h" #include "volk.h"
#include "vulkan/vulkan_fuchsia_ext.h"
namespace angle namespace angle
{ {
...@@ -26,6 +27,17 @@ class VulkanExternalHelper ...@@ -26,6 +27,17 @@ class VulkanExternalHelper
VkDevice getDevice() const { return mDevice; } VkDevice getDevice() const { return mDevice; }
VkQueue getGraphicsQueue() const { return mGraphicsQueue; } VkQueue getGraphicsQueue() const { return mGraphicsQueue; }
bool canCreateImageExternal(VkFormat format,
VkImageType type,
VkImageTiling tiling,
VkExternalMemoryHandleTypeFlagBits handleType) const;
VkResult createImage2DExternal(VkFormat format,
VkExtent3D extent,
VkExternalMemoryHandleTypeFlags handleTypes,
VkImage *imageOut,
VkDeviceMemory *deviceMemoryOut,
VkDeviceSize *deviceMemorySizeOut);
// VK_KHR_external_memory_fd // VK_KHR_external_memory_fd
bool canCreateImageOpaqueFd(VkFormat format, VkImageType type, VkImageTiling tiling) const; bool canCreateImageOpaqueFd(VkFormat format, VkImageType type, VkImageTiling tiling) const;
VkResult createImage2DOpaqueFd(VkFormat format, VkResult createImage2DOpaqueFd(VkFormat format,
...@@ -35,11 +47,25 @@ class VulkanExternalHelper ...@@ -35,11 +47,25 @@ class VulkanExternalHelper
VkDeviceSize *deviceMemorySizeOut); VkDeviceSize *deviceMemorySizeOut);
VkResult exportMemoryOpaqueFd(VkDeviceMemory deviceMemory, int *fd); VkResult exportMemoryOpaqueFd(VkDeviceMemory deviceMemory, int *fd);
// VK_FUCHSIA_external_memory
bool canCreateImageZirconVmo(VkFormat format, VkImageType type, VkImageTiling tiling) const;
VkResult createImage2DZirconVmo(VkFormat format,
VkExtent3D extent,
VkImage *imageOut,
VkDeviceMemory *deviceMemoryOut,
VkDeviceSize *deviceMemorySizeOut);
VkResult exportMemoryZirconVmo(VkDeviceMemory deviceMemory, zx_handle_t *vmo);
// VK_KHR_external_semaphore_fd // VK_KHR_external_semaphore_fd
bool canCreateSemaphoreOpaqueFd() const; bool canCreateSemaphoreOpaqueFd() const;
VkResult createSemaphoreOpaqueFd(VkSemaphore *semaphore); VkResult createSemaphoreOpaqueFd(VkSemaphore *semaphore);
VkResult exportSemaphoreOpaqueFd(VkSemaphore semaphore, int *fd); VkResult exportSemaphoreOpaqueFd(VkSemaphore semaphore, int *fd);
// VK_FUCHSIA_external_semaphore
bool canCreateSemaphoreZirconEvent() const;
VkResult createSemaphoreZirconEvent(VkSemaphore *semaphore);
VkResult exportSemaphoreZirconEvent(VkSemaphore semaphore, zx_handle_t *event);
private: private:
VkInstance mInstance = VK_NULL_HANDLE; VkInstance mInstance = VK_NULL_HANDLE;
VkPhysicalDevice mPhysicalDevice = VK_NULL_HANDLE; VkPhysicalDevice mPhysicalDevice = VK_NULL_HANDLE;
...@@ -50,14 +76,17 @@ class VulkanExternalHelper ...@@ -50,14 +76,17 @@ class VulkanExternalHelper
uint32_t mGraphicsQueueFamilyIndex = UINT32_MAX; uint32_t mGraphicsQueueFamilyIndex = UINT32_MAX;
bool mHasExternalMemoryFd = false; bool mHasExternalMemoryFd = false;
bool mHasExternalSemaphoreFd = false; bool mHasExternalMemoryFuchsia = false;
bool mHasExternalSemaphoreFd = false;
bool mHasExternalSemaphoreFuchsia = false;
PFN_vkGetPhysicalDeviceImageFormatProperties2 vkGetPhysicalDeviceImageFormatProperties2 = PFN_vkGetPhysicalDeviceImageFormatProperties2 vkGetPhysicalDeviceImageFormatProperties2 =
nullptr; nullptr;
PFN_vkGetMemoryFdKHR vkGetMemoryFdKHR = nullptr; PFN_vkGetMemoryFdKHR vkGetMemoryFdKHR = nullptr;
PFN_vkGetSemaphoreFdKHR vkGetSemaphoreFdKHR = nullptr; PFN_vkGetSemaphoreFdKHR vkGetSemaphoreFdKHR = nullptr;
PFN_vkGetPhysicalDeviceExternalSemaphorePropertiesKHR PFN_vkGetPhysicalDeviceExternalSemaphorePropertiesKHR
vkGetPhysicalDeviceExternalSemaphorePropertiesKHR = nullptr; vkGetPhysicalDeviceExternalSemaphorePropertiesKHR = nullptr;
PFN_vkGetMemoryZirconHandleFUCHSIA vkGetMemoryZirconHandleFUCHSIA = nullptr;
}; };
} // namespace angle } // namespace angle
......
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