• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* Copyright 2019 The TensorFlow Authors. All Rights Reserved.
2 
3 Licensed under the Apache License, Version 2.0 (the "License");
4 you may not use this file except in compliance with the License.
5 You may obtain a copy of the License at
6 
7     http://www.apache.org/licenses/LICENSE-2.0
8 
9 Unless required by applicable law or agreed to in writing, software
10 distributed under the License is distributed on an "AS IS" BASIS,
11 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 See the License for the specific language governing permissions and
13 limitations under the License.
14 ==============================================================================*/
15 
16 #ifndef TENSORFLOW_LITE_DELEGATES_GPU_CL_GL_INTEROP_H_
17 #define TENSORFLOW_LITE_DELEGATES_GPU_CL_GL_INTEROP_H_
18 
19 #include <vector>
20 
21 #include <EGL/egl.h>
22 #include <EGL/eglext.h>
23 #include "tensorflow/lite/delegates/gpu/cl/cl_context.h"
24 #include "tensorflow/lite/delegates/gpu/cl/cl_device.h"
25 #include "tensorflow/lite/delegates/gpu/cl/cl_event.h"
26 #include "tensorflow/lite/delegates/gpu/cl/cl_memory.h"
27 #include "tensorflow/lite/delegates/gpu/cl/egl_sync.h"
28 #include "tensorflow/lite/delegates/gpu/cl/environment.h"
29 #include "tensorflow/lite/delegates/gpu/cl/opencl_wrapper.h"
30 #include "tensorflow/lite/delegates/gpu/common/access_type.h"
31 #include "tensorflow/lite/delegates/gpu/common/status.h"
32 #include "tensorflow/lite/delegates/gpu/gl/portable_gl31.h"
33 
34 namespace tflite {
35 namespace gpu {
36 namespace cl {
37 
38 // Creates an EglSync from OpenCL event. Source event does not need to outlive
39 // returned sync and could be safely destroyed.
40 //
41 // Depends on EGL 1.5.
42 Status CreateEglSyncFromClEvent(cl_event event, EGLDisplay display,
43                                 EglSync* sync);
44 
45 // Returns true if 'CreateEglSyncFromClEvent' is supported.
46 bool IsEglSyncFromClEventSupported();
47 
48 // Creates CL event from EGL sync.
49 // Created event could only be comsumed by AcquiredGlObject::Acquire call as
50 // a 'wait_event'.
51 Status CreateClEventFromEglSync(cl_context context, const EglSync& egl_sync,
52                                 CLEvent* event);
53 
54 // Returns true if 'CreateClEventFromEglSync' is supported.
55 bool IsClEventFromEglSyncSupported(const CLDevice& device);
56 
57 // Creates new CL memory object from OpenGL buffer.
58 Status CreateClMemoryFromGlBuffer(GLuint gl_ssbo_id, AccessType access_type,
59                                   CLContext* context, CLMemory* memory);
60 
61 // Creates new CL memory object from OpenGL texture.
62 Status CreateClMemoryFromGlTexture(GLenum texture_target, GLuint texture_id,
63                                    AccessType access_type, CLContext* context,
64                                    CLMemory* memory);
65 
66 // Returns true if GL objects could be shared with OpenCL context.
67 bool IsGlSharingSupported(const CLDevice& device);
68 
69 // RAII-wrapper for GL objects acquired into CL context.
70 class AcquiredGlObjects {
71  public:
72   static bool IsSupported(const CLDevice& device);
73 
AcquiredGlObjects()74   AcquiredGlObjects() : AcquiredGlObjects({}, nullptr) {}
75 
76   // Quitely releases OpenGL objects. It is recommended to call Release()
77   // explicitly to properly handle potential errors.
78   ~AcquiredGlObjects();
79 
80   // Acquires memory from the OpenGL context. Memory must be created by either
81   // CreateClMemoryFromGlBuffer or CreateClMemoryFromGlTexture calls.
82   // If 'acquire_event' is not nullptr, it will be signared once acquisition is
83   // complete.
84   static Status Acquire(const std::vector<cl_mem>& memory,
85                         cl_command_queue queue,
86                         const std::vector<cl_event>& wait_events,
87                         CLEvent* acquire_event /* optional */,
88                         AcquiredGlObjects* objects);
89 
90   // Releases OpenCL memory back to OpenGL context. If 'release_event' is not
91   // nullptr, it will be signalled once release is complete.
92   Status Release(const std::vector<cl_event>& wait_events,
93                  CLEvent* release_event /* optional */);
94 
95  private:
AcquiredGlObjects(const std::vector<cl_mem> & memory,cl_command_queue queue)96   AcquiredGlObjects(const std::vector<cl_mem>& memory, cl_command_queue queue)
97       : memory_(memory), queue_(queue) {}
98 
99   std::vector<cl_mem> memory_;
100   cl_command_queue queue_;
101 };
102 
103 // Incapsulates all complicated GL-CL synchronization. It manages life time of
104 // all appropriate events to ensure fast synchronization whenever possible.
105 class GlInteropFabric {
106  public:
107   GlInteropFabric(EGLDisplay egl_display, Environment* environment);
108 
109   // Ensures proper GL->CL synchronization is in place before
110   // GL objects that are mapped to CL objects are used.
111   Status Start();
112 
113   // Puts appropriate CL->GL synchronization after all work is complete.
114   Status Finish();
115 
116   // Registers memory to be used from GL context. Such CL memory object must
117   // be created with CreateClMemoryFromGlBuffer or CreateClMemoryFromGlTexture
118   // call.
119   void RegisterMemory(cl_mem memory);
120 
121   // Unregisters memory registered with RegisterMemory call.
122   void UnregisterMemory(cl_mem memory);
123 
124  private:
is_enabled()125   bool is_enabled() const { return egl_display_ && !memory_.empty(); }
126 
127   bool is_egl_sync_supported_;
128   bool is_egl_to_cl_mapping_supported_;
129   bool is_cl_to_egl_mapping_supported_;
130 
131   const EGLDisplay egl_display_;
132   cl_context context_;
133   cl_command_queue queue_;
134   CLEvent inbound_event_;
135   CLEvent outbound_event_;
136   std::vector<cl_mem> memory_;
137   AcquiredGlObjects gl_objects_;  // transient during Start/Finish calls.
138 };
139 
140 }  // namespace cl
141 }  // namespace gpu
142 }  // namespace tflite
143 
144 #endif  // TENSORFLOW_LITE_DELEGATES_GPU_CL_GL_INTEROP_H_
145