1 // 2 // Copyright 2016 The ANGLE Project Authors. All rights reserved. 3 // Use of this source code is governed by a BSD-style license that can be 4 // found in the LICENSE file. 5 // 6 // SyncVk: 7 // Defines the class interface for SyncVk, implementing SyncImpl. 8 // 9 10 #ifndef LIBANGLE_RENDERER_VULKAN_FENCESYNCVK_H_ 11 #define LIBANGLE_RENDERER_VULKAN_FENCESYNCVK_H_ 12 13 #include "libANGLE/renderer/EGLSyncImpl.h" 14 #include "libANGLE/renderer/SyncImpl.h" 15 #include "libANGLE/renderer/vulkan/ResourceVk.h" 16 17 namespace egl 18 { 19 class AttributeMap; 20 } 21 22 namespace rx 23 { 24 namespace vk 25 { 26 27 // Represents an invalid native fence FD. 28 constexpr int kInvalidFenceFd = EGL_NO_NATIVE_FENCE_FD_ANDROID; 29 30 class ExternalFence final : angle::NonCopyable 31 { 32 public: 33 ExternalFence(); 34 ~ExternalFence(); 35 36 VkResult init(VkDevice device, const VkFenceCreateInfo &createInfo); 37 void init(int fenceFd); 38 getHandle()39 VkFence getHandle() const { return mFence.getHandle(); } 40 VkResult getStatus(VkDevice device) const; 41 VkResult wait(VkDevice device, uint64_t timeout) const; 42 43 void exportFd(VkDevice device, const VkFenceGetFdInfoKHR &fenceGetFdInfo); getFenceFdStatus()44 VkResult getFenceFdStatus() const { return mFenceFdStatus; } getFenceFd()45 int getFenceFd() const { return mFenceFd; } 46 47 private: 48 VkDevice mDevice; 49 Fence mFence; 50 VkResult mFenceFdStatus; 51 int mFenceFd; 52 }; 53 54 using SharedExternalFence = std::shared_ptr<ExternalFence>; 55 56 class SyncHelperInterface : angle::NonCopyable 57 { 58 public: 59 virtual ~SyncHelperInterface() = default; 60 61 virtual void releaseToRenderer(RendererVk *renderer) = 0; 62 63 virtual angle::Result clientWait(Context *context, 64 ContextVk *contextVk, 65 bool flushCommands, 66 uint64_t timeout, 67 VkResult *outResult) = 0; 68 virtual angle::Result serverWait(ContextVk *contextVk) = 0; 69 virtual angle::Result getStatus(Context *context, ContextVk *contextVk, bool *signaledOut) = 0; 70 virtual angle::Result dupNativeFenceFD(Context *context, int *fdOut) const = 0; 71 }; 72 73 // Implementation of fence types - glFenceSync, and EGLSync(EGL_SYNC_FENCE_KHR). 74 // The behaviors of SyncVk and EGLFenceSyncVk as fence syncs are currently 75 // identical for the Vulkan backend, and this class implements both interfaces. 76 class SyncHelper final : public vk::Resource, public SyncHelperInterface 77 { 78 public: 79 SyncHelper(); 80 ~SyncHelper() override; 81 82 angle::Result initialize(ContextVk *contextVk, bool isEGLSyncObject); 83 84 // SyncHelperInterface 85 86 void releaseToRenderer(RendererVk *renderer) override; 87 88 angle::Result clientWait(Context *context, 89 ContextVk *contextVk, 90 bool flushCommands, 91 uint64_t timeout, 92 VkResult *outResult) override; 93 angle::Result serverWait(ContextVk *contextVk) override; 94 angle::Result getStatus(Context *context, ContextVk *contextVk, bool *signaledOut) override; dupNativeFenceFD(Context * context,int * fdOut)95 angle::Result dupNativeFenceFD(Context *context, int *fdOut) const override 96 { 97 return angle::Result::Stop; 98 } 99 100 private: 101 angle::Result submitSyncIfDeferred(ContextVk *contextVk, RenderPassClosureReason reason); 102 }; 103 104 // Implementation of sync types: EGLSync(EGL_SYNC_ANDROID_NATIVE_FENCE_ANDROID). 105 class SyncHelperNativeFence final : public SyncHelperInterface 106 { 107 public: 108 SyncHelperNativeFence(); 109 ~SyncHelperNativeFence() override; 110 111 angle::Result initializeWithFd(ContextVk *contextVk, int inFd); 112 113 // SyncHelperInterface 114 115 void releaseToRenderer(RendererVk *renderer) override; 116 117 angle::Result clientWait(Context *context, 118 ContextVk *contextVk, 119 bool flushCommands, 120 uint64_t timeout, 121 VkResult *outResult) override; 122 angle::Result serverWait(ContextVk *contextVk) override; 123 angle::Result getStatus(Context *context, ContextVk *contextVk, bool *signaledOut) override; 124 angle::Result dupNativeFenceFD(Context *context, int *fdOut) const override; 125 126 private: 127 SharedExternalFence mExternalFence; 128 }; 129 130 } // namespace vk 131 132 // Implementor for glFenceSync. 133 class SyncVk final : public SyncImpl 134 { 135 public: 136 SyncVk(); 137 ~SyncVk() override; 138 139 void onDestroy(const gl::Context *context) override; 140 141 angle::Result set(const gl::Context *context, GLenum condition, GLbitfield flags) override; 142 angle::Result clientWait(const gl::Context *context, 143 GLbitfield flags, 144 GLuint64 timeout, 145 GLenum *outResult) override; 146 angle::Result serverWait(const gl::Context *context, 147 GLbitfield flags, 148 GLuint64 timeout) override; 149 angle::Result getStatus(const gl::Context *context, GLint *outResult) override; 150 151 private: 152 vk::SyncHelper mSyncHelper; 153 }; 154 155 // Implementor for EGLSync. 156 class EGLSyncVk final : public EGLSyncImpl 157 { 158 public: 159 EGLSyncVk(const egl::AttributeMap &attribs); 160 ~EGLSyncVk() override; 161 162 void onDestroy(const egl::Display *display) override; 163 164 egl::Error initialize(const egl::Display *display, 165 const gl::Context *context, 166 EGLenum type) override; 167 egl::Error clientWait(const egl::Display *display, 168 const gl::Context *context, 169 EGLint flags, 170 EGLTime timeout, 171 EGLint *outResult) override; 172 egl::Error serverWait(const egl::Display *display, 173 const gl::Context *context, 174 EGLint flags) override; 175 egl::Error getStatus(const egl::Display *display, EGLint *outStatus) override; 176 177 egl::Error dupNativeFenceFD(const egl::Display *display, EGLint *fdOut) const override; 178 179 private: 180 EGLenum mType; 181 // SyncHelper or SyncHelperNativeFence decided at run-time. 182 vk::SyncHelperInterface *mSyncHelper; 183 EGLint mNativeFenceFD; 184 }; 185 } // namespace rx 186 187 #endif // LIBANGLE_RENDERER_VULKAN_FENCESYNCVK_H_ 188