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/vk_resource.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 using MapVkResultToApiType = std::function<void(VkResult, angle::Result, void *)>; 56 57 class SyncHelperInterface : angle::NonCopyable 58 { 59 public: 60 virtual ~SyncHelperInterface() = default; 61 62 virtual void releaseToRenderer(Renderer *renderer) = 0; 63 64 virtual angle::Result clientWait(ErrorContext *context, 65 ContextVk *contextVk, 66 bool flushCommands, 67 uint64_t timeout, 68 MapVkResultToApiType mappingFunction, 69 void *outResult) = 0; 70 virtual angle::Result serverWait(ContextVk *contextVk) = 0; 71 virtual angle::Result getStatus(ErrorContext *context, 72 ContextVk *contextVk, 73 bool *signaledOut) = 0; 74 virtual angle::Result dupNativeFenceFD(ErrorContext *context, int *fdOut) const = 0; 75 }; 76 77 // Implementation of fence types - glFenceSync, and EGLSync(EGL_SYNC_FENCE_KHR). 78 // The behaviors of SyncVk and EGLFenceSyncVk as fence syncs are currently 79 // identical for the Vulkan backend, and this class implements both interfaces. 80 class SyncHelper final : public vk::Resource, public SyncHelperInterface 81 { 82 public: 83 SyncHelper(); 84 ~SyncHelper() override; 85 86 angle::Result initialize(ContextVk *contextVk, SyncFenceScope scope); 87 88 // SyncHelperInterface 89 90 void releaseToRenderer(Renderer *renderer) override; 91 92 angle::Result clientWait(ErrorContext *context, 93 ContextVk *contextVk, 94 bool flushCommands, 95 uint64_t timeout, 96 MapVkResultToApiType mappingFunction, 97 void *resultOut) override; 98 angle::Result serverWait(ContextVk *contextVk) override; 99 angle::Result getStatus(ErrorContext *context, 100 ContextVk *contextVk, 101 bool *signaledOut) override; dupNativeFenceFD(ErrorContext * context,int * fdOut)102 angle::Result dupNativeFenceFD(ErrorContext *context, int *fdOut) const override 103 { 104 return angle::Result::Stop; 105 } 106 107 // Used by FenceNVVk. Equivalent of clientWait with infinite timeout, flushCommands == true, 108 // and throw-away return value. 109 angle::Result finish(ContextVk *contextVk); 110 111 private: 112 angle::Result submitSyncIfDeferred(ContextVk *contextVk, RenderPassClosureReason reason); 113 angle::Result prepareForClientWait(ErrorContext *context, 114 ContextVk *contextVk, 115 bool flushCommands, 116 uint64_t timeout, 117 VkResult *resultOut); 118 }; 119 120 // Implementation of sync types: EGLSync(EGL_SYNC_ANDROID_NATIVE_FENCE_ANDROID). 121 class SyncHelperNativeFence final : public SyncHelperInterface 122 { 123 public: 124 SyncHelperNativeFence(); 125 ~SyncHelperNativeFence() override; 126 127 angle::Result initializeWithFd(ContextVk *contextVk, int inFd); 128 129 // SyncHelperInterface 130 131 void releaseToRenderer(Renderer *renderer) override; 132 133 angle::Result clientWait(ErrorContext *context, 134 ContextVk *contextVk, 135 bool flushCommands, 136 uint64_t timeout, 137 MapVkResultToApiType mappingFunction, 138 void *resultOut) override; 139 angle::Result serverWait(ContextVk *contextVk) override; 140 angle::Result getStatus(ErrorContext *context, 141 ContextVk *contextVk, 142 bool *signaledOut) override; 143 angle::Result dupNativeFenceFD(ErrorContext *context, int *fdOut) const override; 144 145 private: 146 angle::Result prepareForClientWait(ErrorContext *context, 147 ContextVk *contextVk, 148 bool flushCommands, 149 uint64_t timeout, 150 VkResult *resultOut); 151 152 SharedExternalFence mExternalFence; 153 }; 154 155 } // namespace vk 156 157 // Implementor for glFenceSync. 158 class SyncVk final : public SyncImpl 159 { 160 public: 161 SyncVk(); 162 ~SyncVk() override; 163 164 void onDestroy(const gl::Context *context) override; 165 166 angle::Result set(const gl::Context *context, GLenum condition, GLbitfield flags) override; 167 angle::Result clientWait(const gl::Context *context, 168 GLbitfield flags, 169 GLuint64 timeout, 170 GLenum *outResult) override; 171 angle::Result serverWait(const gl::Context *context, 172 GLbitfield flags, 173 GLuint64 timeout) override; 174 angle::Result getStatus(const gl::Context *context, GLint *outResult) override; 175 176 private: 177 vk::SyncHelper mSyncHelper; 178 }; 179 180 // Implementor for EGLSync. 181 class EGLSyncVk final : public EGLSyncImpl 182 { 183 public: 184 EGLSyncVk(); 185 ~EGLSyncVk() override; 186 187 void onDestroy(const egl::Display *display) override; 188 189 egl::Error initialize(const egl::Display *display, 190 const gl::Context *context, 191 EGLenum type, 192 const egl::AttributeMap &attribs) override; 193 egl::Error clientWait(const egl::Display *display, 194 const gl::Context *context, 195 EGLint flags, 196 EGLTime timeout, 197 EGLint *outResult) override; 198 egl::Error serverWait(const egl::Display *display, 199 const gl::Context *context, 200 EGLint flags) override; 201 egl::Error getStatus(const egl::Display *display, EGLint *outStatus) override; 202 203 egl::Error dupNativeFenceFD(const egl::Display *display, EGLint *fdOut) const override; 204 205 private: 206 // SyncHelper or SyncHelperNativeFence decided at run-time. 207 std::unique_ptr<vk::SyncHelperInterface> mSyncHelper; 208 }; 209 } // namespace rx 210 211 #endif // LIBANGLE_RENDERER_VULKAN_FENCESYNCVK_H_ 212