Commit e20f36f4 by Jeff Vigil Committed by Commit Bot

EGL: Implement EGL_ANDROID_native_fence_sync on vulkan

Check the following - 1. Vulkan ICD supports VK_KHR_external_fence_fd 2. ExternalFenceProperties and ExternalSemaphoreProperties support Android FD. eglCreateSync - if FD was provided import to VkFence, else create VkFence with new FD and then flush and submit VkFence on next vkQueueSubmit. eglGetSyncAttrib - for status call vkGetFenceStatus. eglDupNativeFenceFdANDROID - return FD from vkGetFenceFD call. eglClientWaitSync - call vkWaitForFences. eglWaitSync - dup FD, create VkSemaphore and import FD, then flush() and add VkSemaphore to next vkQueueSubmit as a waiting semaphore. Extended end2end test suite with nativefence test cases. Bug: angleproject:2517 Test: angle_end2end_tests --gtest_filter=EGLSyncTest.AndroidNativeFence_* Change-Id: I8f6a6f4c3d71d83007f662b78377aa015a740035 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2026177 Commit-Queue: Mohan Maiya <m.maiya@samsung.com> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org>
parent 963759a3
...@@ -120,6 +120,16 @@ struct FeaturesVk : FeatureSetBase ...@@ -120,6 +120,16 @@ struct FeaturesVk : FeatureSetBase
"supports_external_memory_fuchsia", FeatureCategory::VulkanFeatures, "supports_external_memory_fuchsia", FeatureCategory::VulkanFeatures,
"VkDevice supports the VK_FUCHSIA_external_memory extension", &members}; "VkDevice supports the VK_FUCHSIA_external_memory extension", &members};
// Whether the VkDevice supports the VK_KHR_external_fence_capabilities extension.
Feature supportsExternalFenceCapabilities = {
"supports_external_fence_capabilities", FeatureCategory::VulkanFeatures,
"VkDevice supports the VK_KHR_external_fence_capabilities extension", &members};
// Whether the VkDevice supports the VK_KHR_external_semaphore_capabilities extension.
Feature supportsExternalSemaphoreCapabilities = {
"supports_external_semaphore_capabilities", FeatureCategory::VulkanFeatures,
"VkDevice supports the VK_KHR_external_semaphore_capabilities 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 = {
...@@ -132,6 +142,19 @@ struct FeaturesVk : FeatureSetBase ...@@ -132,6 +142,19 @@ struct FeaturesVk : FeatureSetBase
"supports_external_semaphore_fuchsia", FeatureCategory::VulkanFeatures, "supports_external_semaphore_fuchsia", FeatureCategory::VulkanFeatures,
"VkDevice supports the VK_FUCHSIA_external_semaphore extension", &members}; "VkDevice supports the VK_FUCHSIA_external_semaphore extension", &members};
// Whether the VkDevice supports the VK_KHR_external_fence_fd extension, on which the
// EGL_ANDROID_native_fence extension can be layered.
Feature supportsExternalFenceFd = {"supports_external_fence_fd",
FeatureCategory::VulkanFeatures,
"VkDevice supports the VK_KHR_external_fence_fd extension",
&members, "http://anglebug.com/2517"};
// Whether the VkDevice can support EGL_ANDROID_native_fence_sync extension.
Feature supportsAndroidNativeFenceSync = {
"supports_android_native_fence_sync", FeatureCategory::VulkanFeatures,
"VkDevice supports the EGL_ANDROID_native_fence_sync extension", &members,
"http://anglebug.com/2517"};
// 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.
......
...@@ -21,9 +21,21 @@ Sync::Sync(rx::EGLImplFactory *factory, EGLenum type, const AttributeMap &attrib ...@@ -21,9 +21,21 @@ Sync::Sync(rx::EGLImplFactory *factory, EGLenum type, const AttributeMap &attrib
: mFence(factory->createSync(attribs)), : mFence(factory->createSync(attribs)),
mLabel(nullptr), mLabel(nullptr),
mType(type), mType(type),
mCondition(EGL_SYNC_PRIOR_COMMANDS_COMPLETE_KHR),
mNativeFenceFD( mNativeFenceFD(
attribs.getAsInt(EGL_SYNC_NATIVE_FENCE_FD_ANDROID, EGL_NO_NATIVE_FENCE_FD_ANDROID)) attribs.getAsInt(EGL_SYNC_NATIVE_FENCE_FD_ANDROID, EGL_NO_NATIVE_FENCE_FD_ANDROID))
{} {
// Per extension spec: Signaling Condition.
// "If the EGL_SYNC_NATIVE_FENCE_FD_ANDROID attribute is not
// EGL_NO_NATIVE_FENCE_FD_ANDROID then the EGL_SYNC_CONDITION_KHR attribute
// is set to EGL_SYNC_NATIVE_FENCE_SIGNALED_ANDROID and the EGL_SYNC_STATUS_KHR
// attribute is set to reflect the signal status of the native fence object.
if ((mType == EGL_SYNC_NATIVE_FENCE_ANDROID) &&
(mNativeFenceFD != EGL_NO_NATIVE_FENCE_FD_ANDROID))
{
mCondition = EGL_SYNC_NATIVE_FENCE_SIGNALED_ANDROID;
}
}
void Sync::onDestroy(const Display *display) void Sync::onDestroy(const Display *display)
{ {
......
...@@ -61,7 +61,7 @@ class Sync final : public angle::RefCountObject<Display, angle::Result>, public ...@@ -61,7 +61,7 @@ class Sync final : public angle::RefCountObject<Display, angle::Result>, public
EGLLabelKHR mLabel; EGLLabelKHR mLabel;
EGLenum mType; EGLenum mType;
static constexpr EGLint mCondition = EGL_SYNC_PRIOR_COMMANDS_COMPLETE_KHR; EGLint mCondition;
EGLint mNativeFenceFD; EGLint mNativeFenceFD;
}; };
......
...@@ -48,7 +48,7 @@ class EGLSyncImpl : angle::NonCopyable ...@@ -48,7 +48,7 @@ class EGLSyncImpl : angle::NonCopyable
EGLint flags) = 0; EGLint flags) = 0;
virtual egl::Error getStatus(const egl::Display *display, EGLint *outStatus) = 0; virtual egl::Error getStatus(const egl::Display *display, EGLint *outStatus) = 0;
virtual egl::Error dupNativeFenceFD(const egl::Display *display, EGLint *result) const = 0; virtual egl::Error dupNativeFenceFD(const egl::Display *display, EGLint *fdOut) const = 0;
}; };
} // namespace rx } // namespace rx
......
...@@ -221,6 +221,11 @@ void DisplayVk::generateExtensions(egl::DisplayExtensions *outExtensions) const ...@@ -221,6 +221,11 @@ void DisplayVk::generateExtensions(egl::DisplayExtensions *outExtensions) const
outExtensions->contextPriority = !getRenderer()->getFeatures().allocateNonZeroMemory.enabled; outExtensions->contextPriority = !getRenderer()->getFeatures().allocateNonZeroMemory.enabled;
outExtensions->noConfigContext = true; outExtensions->noConfigContext = true;
#if defined(ANGLE_PLATFORM_ANDROID)
outExtensions->nativeFenceSyncANDROID =
getRenderer()->getFeatures().supportsAndroidNativeFenceSync.enabled;
#endif // defined(ANGLE_PLATFORM_ANDROID)
#if defined(ANGLE_PLATFORM_GGP) #if defined(ANGLE_PLATFORM_GGP)
outExtensions->ggpStreamDescriptor = true; outExtensions->ggpStreamDescriptor = true;
outExtensions->swapWithFrameToken = true; outExtensions->swapWithFrameToken = true;
......
...@@ -563,6 +563,54 @@ gl::Version LimitVersionTo(const gl::Version &current, const gl::Version &lower) ...@@ -563,6 +563,54 @@ gl::Version LimitVersionTo(const gl::Version &current, const gl::Version &lower)
{ {
return std::min(current, lower); return std::min(current, lower);
} }
ANGLE_MAYBE_UNUSED bool FencePropertiesCompatibleWithAndroid(
const VkExternalFenceProperties &externalFenceProperties)
{
// handleType here is the external fence type -
// we want type compatible with creating and export/dup() Android FD
// Imported handleType that can be exported - need for vkGetFenceFdKHR()
if ((externalFenceProperties.exportFromImportedHandleTypes &
VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT_KHR) == 0)
{
return false;
}
// HandleTypes which can be specified at creating a fence
if ((externalFenceProperties.compatibleHandleTypes &
VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT_KHR) == 0)
{
return false;
}
constexpr VkExternalFenceFeatureFlags kFeatureFlags =
(VK_EXTERNAL_FENCE_FEATURE_IMPORTABLE_BIT_KHR |
VK_EXTERNAL_FENCE_FEATURE_EXPORTABLE_BIT_KHR);
if ((externalFenceProperties.externalFenceFeatures & kFeatureFlags) != kFeatureFlags)
{
return false;
}
return true;
}
ANGLE_MAYBE_UNUSED bool SemaphorePropertiesCompatibleWithAndroid(
const VkExternalSemaphoreProperties &externalSemaphoreProperties)
{
// handleType here is the external semaphore type -
// we want type compatible with importing an Android FD
constexpr VkExternalSemaphoreFeatureFlags kFeatureFlags =
(VK_EXTERNAL_SEMAPHORE_FEATURE_IMPORTABLE_BIT_KHR);
if ((externalSemaphoreProperties.externalSemaphoreFeatures & kFeatureFlags) != kFeatureFlags)
{
return false;
}
return true;
}
} // namespace } // namespace
// RendererVk implementation. // RendererVk implementation.
...@@ -576,6 +624,8 @@ RendererVk::RendererVk() ...@@ -576,6 +624,8 @@ RendererVk::RendererVk()
mDebugUtilsMessenger(VK_NULL_HANDLE), mDebugUtilsMessenger(VK_NULL_HANDLE),
mDebugReportCallback(VK_NULL_HANDLE), mDebugReportCallback(VK_NULL_HANDLE),
mPhysicalDevice(VK_NULL_HANDLE), mPhysicalDevice(VK_NULL_HANDLE),
mExternalFenceProperties{},
mExternalSemaphoreProperties{},
mCurrentQueueFamilyIndex(std::numeric_limits<uint32_t>::max()), mCurrentQueueFamilyIndex(std::numeric_limits<uint32_t>::max()),
mMaxVertexAttribDivisor(1), mMaxVertexAttribDivisor(1),
mMaxVertexAttribStride(0), mMaxVertexAttribStride(0),
...@@ -1044,6 +1094,32 @@ void RendererVk::queryDeviceExtensionFeatures(const ExtensionNameList &deviceExt ...@@ -1044,6 +1094,32 @@ void RendererVk::queryDeviceExtensionFeatures(const ExtensionNameList &deviceExt
vkGetPhysicalDeviceFeatures2KHR(mPhysicalDevice, &deviceFeatures); vkGetPhysicalDeviceFeatures2KHR(mPhysicalDevice, &deviceFeatures);
vkGetPhysicalDeviceProperties2KHR(mPhysicalDevice, &deviceProperties); vkGetPhysicalDeviceProperties2KHR(mPhysicalDevice, &deviceProperties);
// Fence properties
if (mFeatures.supportsExternalFenceCapabilities.enabled)
{
mExternalFenceProperties.sType = VK_STRUCTURE_TYPE_EXTERNAL_FENCE_PROPERTIES;
VkPhysicalDeviceExternalFenceInfo externalFenceInfo = {};
externalFenceInfo.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_FENCE_INFO;
externalFenceInfo.handleType = VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT_KHR;
vkGetPhysicalDeviceExternalFencePropertiesKHR(mPhysicalDevice, &externalFenceInfo,
&mExternalFenceProperties);
}
// Semaphore properties
if (mFeatures.supportsExternalSemaphoreCapabilities.enabled)
{
mExternalSemaphoreProperties.sType = VK_STRUCTURE_TYPE_EXTERNAL_SEMAPHORE_PROPERTIES;
VkPhysicalDeviceExternalSemaphoreInfo externalSemaphoreInfo = {};
externalSemaphoreInfo.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_SEMAPHORE_INFO;
externalSemaphoreInfo.handleType = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT_KHR;
vkGetPhysicalDeviceExternalSemaphorePropertiesKHR(mPhysicalDevice, &externalSemaphoreInfo,
&mExternalSemaphoreProperties);
}
// Clean up pNext chains // Clean up pNext chains
mLineRasterizationFeatures.pNext = nullptr; mLineRasterizationFeatures.pNext = nullptr;
mProvokingVertexFeatures.pNext = nullptr; mProvokingVertexFeatures.pNext = nullptr;
...@@ -1198,11 +1274,26 @@ angle::Result RendererVk::initializeDevice(DisplayVk *displayVk, uint32_t queueF ...@@ -1198,11 +1274,26 @@ angle::Result RendererVk::initializeDevice(DisplayVk *displayVk, uint32_t queueF
enabledDeviceExtensions.push_back(VK_KHR_EXTERNAL_SEMAPHORE_EXTENSION_NAME); enabledDeviceExtensions.push_back(VK_KHR_EXTERNAL_SEMAPHORE_EXTENSION_NAME);
} }
if (getFeatures().supportsExternalSemaphoreCapabilities.enabled)
{
enabledDeviceExtensions.push_back(VK_KHR_EXTERNAL_SEMAPHORE_CAPABILITIES_EXTENSION_NAME);
}
if (getFeatures().supportsExternalFenceCapabilities.enabled)
{
enabledDeviceExtensions.push_back(VK_KHR_EXTERNAL_FENCE_CAPABILITIES_EXTENSION_NAME);
}
if (getFeatures().supportsExternalSemaphoreFd.enabled) if (getFeatures().supportsExternalSemaphoreFd.enabled)
{ {
enabledDeviceExtensions.push_back(VK_KHR_EXTERNAL_SEMAPHORE_FD_EXTENSION_NAME); enabledDeviceExtensions.push_back(VK_KHR_EXTERNAL_SEMAPHORE_FD_EXTENSION_NAME);
} }
if (getFeatures().supportsExternalFenceFd.enabled)
{
enabledDeviceExtensions.push_back(VK_KHR_EXTERNAL_FENCE_FD_EXTENSION_NAME);
}
if (getFeatures().supportsExternalSemaphoreFuchsia.enabled) if (getFeatures().supportsExternalSemaphoreFuchsia.enabled)
{ {
enabledDeviceExtensions.push_back(VK_FUCHSIA_EXTERNAL_SEMAPHORE_EXTENSION_NAME); enabledDeviceExtensions.push_back(VK_FUCHSIA_EXTERNAL_SEMAPHORE_EXTENSION_NAME);
...@@ -1636,6 +1727,14 @@ void RendererVk::initFeatures(DisplayVk *displayVk, const ExtensionNameList &dev ...@@ -1636,6 +1727,14 @@ void RendererVk::initFeatures(DisplayVk *displayVk, const ExtensionNameList &dev
ExtensionFound(VK_FUCHSIA_EXTERNAL_MEMORY_EXTENSION_NAME, deviceExtensionNames)); ExtensionFound(VK_FUCHSIA_EXTERNAL_MEMORY_EXTENSION_NAME, deviceExtensionNames));
ANGLE_FEATURE_CONDITION( ANGLE_FEATURE_CONDITION(
&mFeatures, supportsExternalFenceCapabilities,
ExtensionFound(VK_KHR_EXTERNAL_FENCE_CAPABILITIES_EXTENSION_NAME, deviceExtensionNames));
ANGLE_FEATURE_CONDITION(&mFeatures, supportsExternalSemaphoreCapabilities,
ExtensionFound(VK_KHR_EXTERNAL_SEMAPHORE_CAPABILITIES_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));
...@@ -1644,6 +1743,29 @@ void RendererVk::initFeatures(DisplayVk *displayVk, const ExtensionNameList &dev ...@@ -1644,6 +1743,29 @@ void RendererVk::initFeatures(DisplayVk *displayVk, const ExtensionNameList &dev
ExtensionFound(VK_FUCHSIA_EXTERNAL_SEMAPHORE_EXTENSION_NAME, deviceExtensionNames)); ExtensionFound(VK_FUCHSIA_EXTERNAL_SEMAPHORE_EXTENSION_NAME, deviceExtensionNames));
ANGLE_FEATURE_CONDITION( ANGLE_FEATURE_CONDITION(
&mFeatures, supportsExternalFenceFd,
ExtensionFound(VK_KHR_EXTERNAL_FENCE_FD_EXTENSION_NAME, deviceExtensionNames));
#if defined(ANGLE_PLATFORM_ANDROID)
if (mFeatures.supportsExternalFenceCapabilities.enabled &&
mFeatures.supportsExternalSemaphoreCapabilities.enabled)
{
ANGLE_FEATURE_CONDITION(
&mFeatures, supportsAndroidNativeFenceSync,
(mFeatures.supportsExternalFenceFd.enabled &&
FencePropertiesCompatibleWithAndroid(mExternalFenceProperties) &&
mFeatures.supportsExternalSemaphoreFd.enabled &&
SemaphorePropertiesCompatibleWithAndroid(mExternalSemaphoreProperties)));
}
else
{
ANGLE_FEATURE_CONDITION(&mFeatures, supportsAndroidNativeFenceSync,
(mFeatures.supportsExternalFenceFd.enabled &&
mFeatures.supportsExternalSemaphoreFd.enabled));
}
#endif // defined(ANGLE_PLATFORM_ANDROID)
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));
......
...@@ -287,6 +287,8 @@ class RendererVk : angle::NonCopyable ...@@ -287,6 +287,8 @@ class RendererVk : angle::NonCopyable
VkPhysicalDevice mPhysicalDevice; VkPhysicalDevice mPhysicalDevice;
VkPhysicalDeviceProperties mPhysicalDeviceProperties; VkPhysicalDeviceProperties mPhysicalDeviceProperties;
VkPhysicalDeviceFeatures mPhysicalDeviceFeatures; VkPhysicalDeviceFeatures mPhysicalDeviceFeatures;
VkExternalFenceProperties mExternalFenceProperties;
VkExternalSemaphoreProperties mExternalSemaphoreProperties;
VkPhysicalDeviceLineRasterizationFeaturesEXT mLineRasterizationFeatures; VkPhysicalDeviceLineRasterizationFeaturesEXT mLineRasterizationFeatures;
VkPhysicalDeviceProvokingVertexFeaturesEXT mProvokingVertexFeatures; VkPhysicalDeviceProvokingVertexFeaturesEXT mProvokingVertexFeatures;
VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT mVertexAttributeDivisorFeatures; VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT mVertexAttributeDivisorFeatures;
......
...@@ -23,24 +23,33 @@ namespace rx ...@@ -23,24 +23,33 @@ namespace rx
{ {
namespace vk namespace vk
{ {
// The behaviors of SyncImpl and EGLSyncImpl as fence syncs (only supported type) are currently
// Represents an invalid native fence FD.
constexpr int kInvalidFenceFd = EGL_NO_NATIVE_FENCE_FD_ANDROID;
// Implementation of fence types - glFenceSync, and EGLSync(EGL_SYNC_FENCE_KHR).
// The behaviors of SyncVk and EGLFenceSyncVk as fence syncs are currently
// identical for the Vulkan backend, and this class implements both interfaces. // identical for the Vulkan backend, and this class implements both interfaces.
class SyncHelper : public vk::Resource class SyncHelper : public vk::Resource
{ {
public: public:
SyncHelper(); SyncHelper();
~SyncHelper(); virtual ~SyncHelper();
void releaseToRenderer(RendererVk *renderer); virtual void releaseToRenderer(RendererVk *renderer);
angle::Result initialize(ContextVk *contextVk); virtual angle::Result initialize(ContextVk *contextVk);
angle::Result clientWait(Context *context, virtual angle::Result clientWait(Context *context,
ContextVk *contextVk, ContextVk *contextVk,
bool flushCommands, bool flushCommands,
uint64_t timeout, uint64_t timeout,
VkResult *outResult); VkResult *outResult);
angle::Result serverWait(ContextVk *contextVk); virtual angle::Result serverWait(ContextVk *contextVk);
angle::Result getStatus(Context *context, bool *signaled); virtual angle::Result getStatus(Context *context, bool *signaled) const;
virtual angle::Result dupNativeFenceFD(Context *context, int *fdOut) const
{
return angle::Result::Stop;
}
private: private:
// The vkEvent that's signaled on `init` and can be waited on in `serverWait`, or queried with // The vkEvent that's signaled on `init` and can be waited on in `serverWait`, or queried with
...@@ -50,8 +59,33 @@ class SyncHelper : public vk::Resource ...@@ -50,8 +59,33 @@ class SyncHelper : public vk::Resource
// `clientWait` waits on this fence. // `clientWait` waits on this fence.
Shared<Fence> mFence; Shared<Fence> mFence;
}; };
// Implementation of sync types: EGLSync(EGL_SYNC_ANDROID_NATIVE_FENCE_ANDROID).
class SyncHelperNativeFence : public SyncHelper
{
public:
SyncHelperNativeFence() {}
~SyncHelperNativeFence() override {}
void releaseToRenderer(RendererVk *renderer) override;
angle::Result initializeWithFd(ContextVk *contextVk, int inFd);
angle::Result clientWait(Context *context,
ContextVk *contextVk,
bool flushCommands,
uint64_t timeout,
VkResult *outResult) override;
angle::Result serverWait(ContextVk *contextVk) override;
angle::Result getStatus(Context *context, bool *signaled) const override;
angle::Result dupNativeFenceFD(Context *context, int *fdOut) const override;
private:
vk::Fence mFenceWithFd;
};
} // namespace vk } // namespace vk
// Implementor for glFenceSync.
class SyncVk final : public SyncImpl class SyncVk final : public SyncImpl
{ {
public: public:
...@@ -71,9 +105,10 @@ class SyncVk final : public SyncImpl ...@@ -71,9 +105,10 @@ class SyncVk final : public SyncImpl
angle::Result getStatus(const gl::Context *context, GLint *outResult) override; angle::Result getStatus(const gl::Context *context, GLint *outResult) override;
private: private:
vk::SyncHelper mFenceSync; vk::SyncHelper mSyncHelper;
}; };
// Implementor for EGLSync.
class EGLSyncVk final : public EGLSyncImpl class EGLSyncVk final : public EGLSyncImpl
{ {
public: public:
...@@ -95,10 +130,12 @@ class EGLSyncVk final : public EGLSyncImpl ...@@ -95,10 +130,12 @@ class EGLSyncVk final : public EGLSyncImpl
EGLint flags) override; EGLint flags) override;
egl::Error getStatus(const egl::Display *display, EGLint *outStatus) override; egl::Error getStatus(const egl::Display *display, EGLint *outStatus) override;
egl::Error dupNativeFenceFD(const egl::Display *display, EGLint *result) const override; egl::Error dupNativeFenceFD(const egl::Display *display, EGLint *fdOut) const override;
private: private:
vk::SyncHelper mFenceSync; EGLenum mType;
vk::SyncHelper *mSyncHelper; // SyncHelper or SyncHelperNativeFence decided at run-time.
const egl::AttributeMap &mAttribs;
}; };
} // namespace rx } // namespace rx
......
...@@ -427,6 +427,8 @@ class Semaphore final : public WrappedObject<Semaphore, VkSemaphore> ...@@ -427,6 +427,8 @@ class Semaphore final : public WrappedObject<Semaphore, VkSemaphore>
void destroy(VkDevice device); void destroy(VkDevice device);
VkResult init(VkDevice device); VkResult init(VkDevice device);
VkResult init(VkDevice device, const VkSemaphoreCreateInfo &createInfo);
VkResult importFd(VkDevice device, const VkImportSemaphoreFdInfoKHR &importFdInfo) const;
}; };
class Framebuffer final : public WrappedObject<Framebuffer, VkFramebuffer> class Framebuffer final : public WrappedObject<Framebuffer, VkFramebuffer>
...@@ -600,6 +602,8 @@ class Fence final : public WrappedObject<Fence, VkFence> ...@@ -600,6 +602,8 @@ class Fence final : public WrappedObject<Fence, VkFence>
VkResult reset(VkDevice device); VkResult reset(VkDevice device);
VkResult getStatus(VkDevice device) const; VkResult getStatus(VkDevice device) const;
VkResult wait(VkDevice device, uint64_t timeout) const; VkResult wait(VkDevice device, uint64_t timeout) const;
VkResult importFd(VkDevice device, const VkImportFenceFdInfoKHR &importFenceFdInfo) const;
VkResult exportFd(VkDevice device, const VkFenceGetFdInfoKHR &fenceGetFdInfo, int *outFd) const;
}; };
class QueryPool final : public WrappedObject<QueryPool, VkQueryPool> class QueryPool final : public WrappedObject<QueryPool, VkQueryPool>
...@@ -1263,6 +1267,19 @@ ANGLE_INLINE VkResult Semaphore::init(VkDevice device) ...@@ -1263,6 +1267,19 @@ ANGLE_INLINE VkResult Semaphore::init(VkDevice device)
return vkCreateSemaphore(device, &semaphoreInfo, nullptr, &mHandle); return vkCreateSemaphore(device, &semaphoreInfo, nullptr, &mHandle);
} }
ANGLE_INLINE VkResult Semaphore::init(VkDevice device, const VkSemaphoreCreateInfo &createInfo)
{
ASSERT(valid());
return vkCreateSemaphore(device, &createInfo, nullptr, &mHandle);
}
ANGLE_INLINE VkResult Semaphore::importFd(VkDevice device,
const VkImportSemaphoreFdInfoKHR &importFdInfo) const
{
ASSERT(valid());
return vkImportSemaphoreFdKHR(device, &importFdInfo);
}
// Framebuffer implementation. // Framebuffer implementation.
ANGLE_INLINE void Framebuffer::destroy(VkDevice device) ANGLE_INLINE void Framebuffer::destroy(VkDevice device)
{ {
...@@ -1675,6 +1692,21 @@ ANGLE_INLINE VkResult Fence::wait(VkDevice device, uint64_t timeout) const ...@@ -1675,6 +1692,21 @@ ANGLE_INLINE VkResult Fence::wait(VkDevice device, uint64_t timeout) const
return vkWaitForFences(device, 1, &mHandle, true, timeout); return vkWaitForFences(device, 1, &mHandle, true, timeout);
} }
ANGLE_INLINE VkResult Fence::importFd(VkDevice device,
const VkImportFenceFdInfoKHR &importFenceFdInfo) const
{
ASSERT(valid());
return vkImportFenceFdKHR(device, &importFenceFdInfo);
}
ANGLE_INLINE VkResult Fence::exportFd(VkDevice device,
const VkFenceGetFdInfoKHR &fenceGetFdInfo,
int *fdOut) const
{
ASSERT(valid());
return vkGetFenceFdKHR(device, &fenceGetFdInfo, fdOut);
}
// QueryPool implementation. // QueryPool implementation.
ANGLE_INLINE void QueryPool::destroy(VkDevice device) ANGLE_INLINE void QueryPool::destroy(VkDevice device)
{ {
......
...@@ -4221,12 +4221,6 @@ Error ValidateDupNativeFenceFDANDROID(const Display *display, const Sync *sync) ...@@ -4221,12 +4221,6 @@ Error ValidateDupNativeFenceFDANDROID(const Display *display, const Sync *sync)
ANGLE_TRY(ValidateSync(display, sync)); ANGLE_TRY(ValidateSync(display, sync));
if (sync->getNativeFenceFD() == EGL_NO_NATIVE_FENCE_FD_ANDROID)
{
return EglBadParameter() << "EGL_NATIVE_FENCE_FD_ANDROID attribute of sync is "
"EGL_NO_NATIVE_FENCE_FD_ANDROID";
}
return NoError(); return NoError();
} }
......
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