• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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