Commit fda994c6 by David 'Digit' Turner Committed by David Turner

[vulkan] Implement external semaphore support for Fuchsia

This corresponds to the VK_FUCHSIA_external_semaphore extension which uses a Zircon event object to communicate across processes. Bug: b/140421726 Change-Id: I47b235d4ff7d787491738422bda6fdf853803ab7 Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/35969 Kokoro-Presubmit: kokoro <noreply+kokoro@google.com> Reviewed-by: 's avatarBen Clayton <bclayton@google.com> Tested-by: 's avatarDavid Turner <digit@google.com>
parent c47ee16c
......@@ -92,6 +92,10 @@ swiftshader_source_set("swiftshader_libvulkan_headers") {
sources += [
"VkSemaphoreExternalLinux.hpp",
]
} else if (is_fuchsia) {
sources += [
"VkSemaphoreExternalFuchsia.hpp",
]
} else {
sources += [
"VkSemaphoreExternalNone.hpp",
......
......@@ -88,4 +88,8 @@ constexpr int SUBPIXEL_PRECISION_MASK = 0xFFFFFFFF >> (32 - SUBPIXEL_PRECISION_B
#define SWIFTSHADER_EXTERNAL_SEMAPHORE_LINUX_MEMFD 1
#endif
#if VK_USE_PLATFORM_FUCHSIA
#define SWIFTSHADER_EXTERNAL_SEMAPHORE_ZIRCON_EVENT 1
#endif
#endif // VK_CONFIG_HPP_
......@@ -346,6 +346,17 @@ static const std::vector<std::pair<const char*, std::unordered_map<std::string,
}
},
#endif
#if SWIFTSHADER_EXTERNAL_SEMAPHORE_ZIRCON_EVENT
// VK_FUCHSIA_external_semaphore
{
VK_FUCHSIA_EXTERNAL_SEMAPHORE_EXTENSION_NAME,
{
MAKE_VULKAN_DEVICE_ENTRY(vkGetSemaphoreZirconHandleFUCHSIA),
MAKE_VULKAN_DEVICE_ENTRY(vkImportSemaphoreZirconHandleFUCHSIA),
}
},
#endif
};
#undef MAKE_VULKAN_DEVICE_ENTRY
......
......@@ -381,6 +381,15 @@ void PhysicalDevice::getProperties(const VkPhysicalDeviceExternalSemaphoreInfo*
return;
}
#endif
#if SWIFTSHADER_EXTERNAL_SEMAPHORE_ZIRCON_EVENT
if (pExternalSemaphoreInfo->handleType == VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_TEMP_ZIRCON_EVENT_BIT_FUCHSIA)
{
pExternalSemaphoreProperties->compatibleHandleTypes = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_TEMP_ZIRCON_EVENT_BIT_FUCHSIA;
pExternalSemaphoreProperties->exportFromImportedHandleTypes = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_TEMP_ZIRCON_EVENT_BIT_FUCHSIA;
pExternalSemaphoreProperties->externalSemaphoreFeatures = VK_EXTERNAL_SEMAPHORE_FEATURE_EXPORTABLE_BIT | VK_EXTERNAL_SEMAPHORE_FEATURE_IMPORTABLE_BIT;
return;
}
#endif
pExternalSemaphoreProperties->compatibleHandleTypes = 0;
pExternalSemaphoreProperties->exportFromImportedHandleTypes = 0;
pExternalSemaphoreProperties->externalSemaphoreFeatures = 0;
......
......@@ -18,6 +18,8 @@
#if SWIFTSHADER_EXTERNAL_SEMAPHORE_LINUX_MEMFD
#include "VkSemaphoreExternalLinux.hpp"
#elif SWIFTSHADER_EXTERNAL_SEMAPHORE_ZIRCON_EVENT
#include "VkSemaphoreExternalFuchsia.hpp"
#else
#include "VkSemaphoreExternalNone.hpp"
#endif
......@@ -226,4 +228,30 @@ VkResult Semaphore::exportFd(int* pFd) const
}
#endif // SWIFTSHADER_EXTERNAL_SEMAPHORE_LINUX_MEMFD
#if SWIFTSHADER_EXTERNAL_SEMAPHORE_ZIRCON_EVENT
VkResult Semaphore::importHandle(zx_handle_t handle, bool temporaryImport)
{
std::unique_lock<std::mutex> lock(impl->mutex);
if (!impl->external)
{
impl->allocateExternalNoInit();
}
// NOTE: Imports are just moving a handle so cannot fail.
impl->external->importHandle(handle);
impl->temporaryImport = temporaryImport;
return VK_SUCCESS;
}
VkResult Semaphore::exportHandle(zx_handle_t *pHandle) const
{
std::unique_lock<std::mutex> lock(impl->mutex);
if (!impl->external)
{
TRACE("Cannot export non-external semaphore");
return VK_ERROR_INVALID_EXTERNAL_HANDLE;
}
return impl->external->exportHandle(pHandle);
}
#endif // SWIFTSHADER_EXTERNAL_SEMAPHORE_ZIRCON_EVENT
} // namespace vk
......@@ -18,6 +18,10 @@
#include "VkConfig.h"
#include "VkObject.hpp"
#if SWIFTSHADER_EXTERNAL_SEMAPHORE_ZIRCON_EVENT
#include <zircon/types.h>
#endif
namespace vk
{
......@@ -44,6 +48,11 @@ public:
VkResult exportFd(int* pFd) const;
#endif
#if SWIFTSHADER_EXTERNAL_SEMAPHORE_ZIRCON_EVENT
VkResult importHandle(zx_handle_t handle, bool temporaryImport);
VkResult exportHandle(zx_handle_t *pHandle) const;
#endif
private:
class External;
class Impl;
......
// Copyright 2019 The SwiftShader Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef VK_SEMAPHORE_EXTERNAL_FUCHSIA_H_
#define VK_SEMAPHORE_EXTERNAL_FUCHSIA_H_
#include "VkDebug.hpp"
#include <zircon/syscalls.h>
// An external semaphore implementation for the Zircon kernel using a simple
// Zircon event handle. This matches
// VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_TEMP_ZIRCON_EVENT_BIT_FUCHSIA
// which is not official yet but used by Fuchsia at the moment.
namespace vk
{
class Semaphore::External {
public:
// The type of external semaphore handle types supported by this implementation.
static const VkExternalSemaphoreHandleTypeFlags kExternalSemaphoreHandleType =
VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_TEMP_ZIRCON_EVENT_BIT_FUCHSIA;
// Default constructor. Note that one should call either init() or
// importFd() before any call to wait() or signal().
External() = default;
~External()
{
zx_handle_close(handle);
}
void init()
{
zx_status_t status = zx_event_create(0, &handle);
if (status != ZX_OK)
{
ABORT("zx_event_create() returned %d", status);
}
}
void importHandle(zx_handle_t new_handle)
{
zx_handle_close(handle);
handle = new_handle;
}
VkResult exportHandle(zx_handle_t* pHandle) const
{
zx_handle_t new_handle = ZX_HANDLE_INVALID;
zx_status_t status = zx_handle_duplicate(handle, ZX_RIGHT_SAME_RIGHTS, &new_handle);
if (status != ZX_OK)
{
TRACE("zx_handle_duplicate() returned %d", status);
return VK_ERROR_INVALID_EXTERNAL_HANDLE;
}
*pHandle = new_handle;
return VK_SUCCESS;
}
void wait()
{
zx_signals_t observed = 0;
zx_status_t status = zx_object_wait_one(
handle, ZX_EVENT_SIGNALED, ZX_TIME_INFINITE, &observed);
if (status != ZX_OK)
{
ABORT("zx_object_wait_one() returned %d", status);
}
if (observed != ZX_EVENT_SIGNALED)
{
ABORT("zx_object_wait_one() returned observed %x (%x expected)", observed, ZX_EVENT_SIGNALED);
}
// Need to unsignal the event now, as required by the Vulkan spec.
status = zx_object_signal(handle, ZX_EVENT_SIGNALED, 0);
if (status != ZX_OK)
{
ABORT("zx_object_signal() returned %d", status);
}
}
bool tryWait()
{
zx_signals_t observed = 0;
zx_status_t status = zx_object_wait_one(
handle, ZX_EVENT_SIGNALED, zx_clock_get_monotonic(), &observed);
if (status != ZX_OK)
{
ABORT("zx_object_wait_one() returned %d", status);
}
if (observed != ZX_EVENT_SIGNALED)
{
return false;
}
// Need to unsignal the event now, as required by the Vulkan spec.
status = zx_object_signal(handle, ZX_EVENT_SIGNALED, 0);
if (status != ZX_OK)
{
ABORT("zx_object_signal() returned %d", status);
}
return true;
}
void signal()
{
zx_status_t status = zx_object_signal(handle, 0, ZX_EVENT_SIGNALED);
if (status != ZX_OK)
{
ABORT("zx_object_signal() returned %d", status);
}
}
private:
zx_handle_t handle = ZX_HANDLE_INVALID;
};
} // namespace vk
#endif // VK_SEMAPHORE_EXTERNAL_FUCHSIA_H_
......@@ -233,6 +233,9 @@ static const VkExtensionProperties deviceExtensionProperties[] =
#if SWIFTSHADER_EXTERNAL_SEMAPHORE_LINUX_MEMFD
{ VK_KHR_EXTERNAL_SEMAPHORE_FD_EXTENSION_NAME, VK_KHR_EXTERNAL_SEMAPHORE_FD_SPEC_VERSION },
#endif
#if SWIFTSHADER_EXTERNAL_SEMAPHORE_ZIRCON_EVENT
{ VK_FUCHSIA_EXTERNAL_SEMAPHORE_EXTENSION_NAME, VK_FUCHSIA_EXTERNAL_SEMAPHORE_SPEC_VERSION },
#endif
{ VK_EXT_PROVOKING_VERTEX_EXTENSION_NAME, VK_EXT_PROVOKING_VERTEX_SPEC_VERSION },
};
......@@ -1022,6 +1025,42 @@ VKAPI_ATTR VkResult VKAPI_CALL vkImportSemaphoreFdKHR(VkDevice device, const VkI
}
#endif // SWIFTSHADER_EXTERNAL_SEMAPHORE_LINUX_MEMFD
#if SWIFTSHADER_EXTERNAL_SEMAPHORE_ZIRCON_EVENT
VKAPI_ATTR VkResult VKAPI_CALL vkImportSemaphoreZirconHandleFUCHSIA(
VkDevice device,
const VkImportSemaphoreZirconHandleInfoFUCHSIA* pImportSemaphoreZirconHandleInfo)
{
TRACE("(VkDevice device = %p, const VkImportSemaphoreZirconHandleInfoFUCHSIA* pImportSemaphoreZirconHandleInfo = %p)",
device, pImportSemaphoreZirconHandleInfo);
if (pImportSemaphoreZirconHandleInfo->handleType != VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_TEMP_ZIRCON_EVENT_BIT_FUCHSIA)
{
UNIMPLEMENTED("pImportSemaphoreZirconHandleInfo->handleType");
}
bool temporaryImport = (pImportSemaphoreZirconHandleInfo->flags & VK_SEMAPHORE_IMPORT_TEMPORARY_BIT) != 0;
return vk::Cast(pImportSemaphoreZirconHandleInfo->semaphore)->importHandle(
pImportSemaphoreZirconHandleInfo->handle,
temporaryImport);
}
VKAPI_ATTR VkResult VKAPI_CALL vkGetSemaphoreZirconHandleFUCHSIA(
VkDevice device,
const VkSemaphoreGetZirconHandleInfoFUCHSIA* pGetZirconHandleInfo,
zx_handle_t* pZirconHandle)
{
TRACE("(VkDevice device = %p, const VkSemaphoreGetZirconHandleInfoFUCHSIA* pGetZirconHandleInfo = %p, zx_handle_t* pZirconHandle = %p)",
device, static_cast<const void*>(pGetZirconHandleInfo), static_cast<void*>(pZirconHandle));
if (pGetZirconHandleInfo->handleType != VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_TEMP_ZIRCON_EVENT_BIT_FUCHSIA)
{
UNIMPLEMENTED("pGetZirconHandleInfo->handleType");
}
return vk::Cast(pGetZirconHandleInfo->semaphore)->exportHandle(pZirconHandle);
}
#endif // SWIFTSHADER_EXTERNAL_SEMAPHORE_ZIRCON_EVENT
VKAPI_ATTR VkResult VKAPI_CALL vkCreateEvent(VkDevice device, const VkEventCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkEvent* pEvent)
{
TRACE("(VkDevice device = %p, const VkEventCreateInfo* pCreateInfo = %p, const VkAllocationCallbacks* pAllocator = %p, VkEvent* pEvent = %p)",
......
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