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