Hash :
e20f36f4
Author :
Date :
2020-04-21T15:45:44
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: Jamie Madill <jmadill@chromium.org>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142
//
// Copyright 2016 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.
//
// SyncVk:
// Defines the class interface for SyncVk, implementing SyncImpl.
//
#ifndef LIBANGLE_RENDERER_VULKAN_FENCESYNCVK_H_
#define LIBANGLE_RENDERER_VULKAN_FENCESYNCVK_H_
#include "libANGLE/renderer/EGLSyncImpl.h"
#include "libANGLE/renderer/SyncImpl.h"
#include "libANGLE/renderer/vulkan/ResourceVk.h"
namespace egl
{
class AttributeMap;
}
namespace rx
{
namespace vk
{
// 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.
class SyncHelper : public vk::Resource
{
public:
SyncHelper();
virtual ~SyncHelper();
virtual void releaseToRenderer(RendererVk *renderer);
virtual angle::Result initialize(ContextVk *contextVk);
virtual angle::Result clientWait(Context *context,
ContextVk *contextVk,
bool flushCommands,
uint64_t timeout,
VkResult *outResult);
virtual angle::Result serverWait(ContextVk *contextVk);
virtual angle::Result getStatus(Context *context, bool *signaled) const;
virtual angle::Result dupNativeFenceFD(Context *context, int *fdOut) const
{
return angle::Result::Stop;
}
private:
// The vkEvent that's signaled on `init` and can be waited on in `serverWait`, or queried with
// `getStatus`.
Event mEvent;
// The fence is signaled once the CB including the `init` signal is executed.
// `clientWait` waits on this fence.
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
// Implementor for glFenceSync.
class SyncVk final : public SyncImpl
{
public:
SyncVk();
~SyncVk() override;
void onDestroy(const gl::Context *context) override;
angle::Result set(const gl::Context *context, GLenum condition, GLbitfield flags) override;
angle::Result clientWait(const gl::Context *context,
GLbitfield flags,
GLuint64 timeout,
GLenum *outResult) override;
angle::Result serverWait(const gl::Context *context,
GLbitfield flags,
GLuint64 timeout) override;
angle::Result getStatus(const gl::Context *context, GLint *outResult) override;
private:
vk::SyncHelper mSyncHelper;
};
// Implementor for EGLSync.
class EGLSyncVk final : public EGLSyncImpl
{
public:
EGLSyncVk(const egl::AttributeMap &attribs);
~EGLSyncVk() override;
void onDestroy(const egl::Display *display) override;
egl::Error initialize(const egl::Display *display,
const gl::Context *context,
EGLenum type) override;
egl::Error clientWait(const egl::Display *display,
const gl::Context *context,
EGLint flags,
EGLTime timeout,
EGLint *outResult) override;
egl::Error serverWait(const egl::Display *display,
const gl::Context *context,
EGLint flags) override;
egl::Error getStatus(const egl::Display *display, EGLint *outStatus) override;
egl::Error dupNativeFenceFD(const egl::Display *display, EGLint *fdOut) const override;
private:
EGLenum mType;
vk::SyncHelper *mSyncHelper; // SyncHelper or SyncHelperNativeFence decided at run-time.
const egl::AttributeMap &mAttribs;
};
} // namespace rx
#endif // LIBANGLE_RENDERER_VULKAN_FENCESYNCVK_H_