HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
hgi.h
Go to the documentation of this file.
1 //
2 // Copyright 2019 Pixar
3 //
4 // Licensed under the Apache License, Version 2.0 (the "Apache License")
5 // with the following modification; you may not use this file except in
6 // compliance with the Apache License and the following modification to it:
7 // Section 6. Trademarks. is deleted and replaced with:
8 //
9 // 6. Trademarks. This License does not grant permission to use the trade
10 // names, trademarks, service marks, or product names of the Licensor
11 // and its affiliates, except as required to comply with Section 4(c) of
12 // the License and to reproduce the content of the NOTICE file.
13 //
14 // You may obtain a copy of the Apache License at
15 //
16 // http://www.apache.org/licenses/LICENSE-2.0
17 //
18 // Unless required by applicable law or agreed to in writing, software
19 // distributed under the Apache License with the above modification is
20 // distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
21 // KIND, either express or implied. See the Apache License for the specific
22 // language governing permissions and limitations under the Apache License.
23 //
24 #ifndef PXR_IMAGING_HGI_HGI_H
25 #define PXR_IMAGING_HGI_HGI_H
26 
27 #include "pxr/pxr.h"
28 #include "pxr/base/tf/token.h"
29 #include "pxr/base/tf/type.h"
30 
31 #include "pxr/imaging/hgi/api.h"
33 #include "pxr/imaging/hgi/buffer.h"
43 #include "pxr/imaging/hgi/types.h"
44 
45 #include <atomic>
46 #include <memory>
47 
49 
50 using HgiUniquePtr = std::unique_ptr<class Hgi>;
51 
52 
53 /// \class Hgi
54 ///
55 /// Hydra Graphics Interface.
56 /// Hgi is used to communicate with one or more physical gpu devices.
57 ///
58 /// Hgi provides API to create/destroy resources that a gpu device owns.
59 /// The lifetime of resources is not managed by Hgi, so it is up to the caller
60 /// to destroy resources and ensure those resources are no longer used.
61 ///
62 /// Commands are recorded in 'HgiCmds' objects and submitted via Hgi.
63 ///
64 /// Thread-safety:
65 ///
66 /// Modern graphics APIs like Metal and Vulkan are designed with multi-threading
67 /// in mind. We want to try and take advantage of this where possible.
68 /// However we also wish to continue to support OpenGL for the time being.
69 ///
70 /// In an application where OpenGL is involved, when we say "main thread" we
71 /// mean the thread on which the gl-context is bound.
72 ///
73 /// Each Hgi backend should at minimum support the following:
74 ///
75 /// * Single threaded Hgi::SubmitCmds on main thread.
76 /// * Single threaded Hgi::Resource Create*** / Destroy*** on main thread.
77 /// * Multi threaded recording of commands in Hgi***Cmds objects.
78 /// * A Hgi***Cmds object should be creatable on the main thread, recorded
79 /// into with one secondary thread (only one thread may use a Cmds object) and
80 /// submitted via the main thread.
81 ///
82 /// Each Hgi backend is additionally encouraged to support:
83 ///
84 /// * Multi threaded support for resource creation and destruction.
85 ///
86 /// We currently do not rely on these additional multi-threading features in
87 /// Hydra / Storm where we still wish to run OpenGL. In Hydra we make sure to
88 /// use the main-thread for resource creation and command submission.
89 /// One day we may wish to switch this to be multi-threaded so new Hgi backends
90 /// are encouraged to support it.
91 ///
92 /// Pseudo code what should minimally be supported:
93 ///
94 /// vector<HgiGraphicsCmds> cmds
95 ///
96 /// for num_threads
97 /// cmds.push_back( Hgi->CreateGraphicsCmds() )
98 ///
99 /// parallel_for i to num_threads
100 /// cmds[i]->SetViewport()
101 /// cmds[i]->Draw()
102 ///
103 /// for i to num_threads
104 /// hgi->SubmitCmds( cmds[i] )
105 ///
106 class Hgi
107 {
108 public:
109  HGI_API
110  Hgi();
111 
112  HGI_API
113  virtual ~Hgi();
114 
115  /// Submit one HgiCmds objects.
116  /// Once the cmds object is submitted it cannot be re-used to record cmds.
117  /// A call to SubmitCmds would usually result in the hgi backend submitting
118  /// the cmd buffers of the cmds object(s) to the device queue.
119  /// Derived classes can override _SubmitCmds to customize submission.
120  /// Thread safety: This call is not thread-safe. Submission must happen on
121  /// the main thread so we can continue to support the OpenGL platform.
122  /// See notes above.
123  HGI_API
124  void SubmitCmds(HgiCmds* cmds);
125 
126  /// *** DEPRECATED *** Please use: CreatePlatformDefaultHgi
127  HGI_API
128  static Hgi* GetPlatformDefaultHgi();
129 
130  /// Helper function to return a Hgi object for the current platform.
131  /// For example on Linux this may return HgiGL while on macOS HgiMetal.
132  /// Caller, usually the application, owns the lifetime of the Hgi object and
133  /// the object is destroyed when the caller drops the unique ptr.
134  /// Thread safety: Not thread safe.
135  HGI_API
137 
138  /// Returns a GraphicsCmds object (for temporary use) that is ready to
139  /// record draw commands. GraphicsCmds is a lightweight object that
140  /// should be re-acquired each frame (don't hold onto it after EndEncoding).
141  /// Thread safety: Each Hgi backend must ensure that a Cmds object can be
142  /// created on the main thread, recorded into (exclusively) by one secondary
143  /// thread and be submitted on the main thread. See notes above.
144  HGI_API
146  HgiGraphicsCmdsDesc const& desc) = 0;
147 
148  /// Returns a BlitCmds object (for temporary use) that is ready to execute
149  /// resource copy commands. BlitCmds is a lightweight object that
150  /// should be re-acquired each frame (don't hold onto it after EndEncoding).
151  /// Thread safety: Each Hgi backend must ensure that a Cmds object can be
152  /// created on the main thread, recorded into (exclusively) by one secondary
153  /// thread and be submitted on the main thread. See notes above.
154  HGI_API
155  virtual HgiBlitCmdsUniquePtr CreateBlitCmds() = 0;
156 
157  /// Returns a ComputeCmds object (for temporary use) that is ready to
158  /// record dispatch commands. ComputeCmds is a lightweight object that
159  /// should be re-acquired each frame (don't hold onto it after EndEncoding).
160  /// Thread safety: Each Hgi backend must ensure that a Cmds object can be
161  /// created on the main thread, recorded into (exclusively) by one secondary
162  /// thread and be submitted on the main thread. See notes above.
163  HGI_API
165 
166  /// Create a texture in rendering backend.
167  /// Thread safety: Creation must happen on main thread. See notes above.
168  HGI_API
169  virtual HgiTextureHandle CreateTexture(HgiTextureDesc const & desc) = 0;
170 
171  /// Destroy a texture in rendering backend.
172  /// Thread safety: Destruction must happen on main thread. See notes above.
173  HGI_API
174  virtual void DestroyTexture(HgiTextureHandle* texHandle) = 0;
175 
176  /// Create a sampler in rendering backend.
177  /// Thread safety: Creation must happen on main thread. See notes above.
178  HGI_API
179  virtual HgiSamplerHandle CreateSampler(HgiSamplerDesc const & desc) = 0;
180 
181  /// Destroy a sampler in rendering backend.
182  /// Thread safety: Destruction must happen on main thread. See notes above.
183  HGI_API
184  virtual void DestroySampler(HgiSamplerHandle* smpHandle) = 0;
185 
186  /// Create a buffer in rendering backend.
187  /// Thread safety: Creation must happen on main thread. See notes above.
188  HGI_API
189  virtual HgiBufferHandle CreateBuffer(HgiBufferDesc const & desc) = 0;
190 
191  /// Destroy a buffer in rendering backend.
192  /// Thread safety: Destruction must happen on main thread. See notes above.
193  HGI_API
194  virtual void DestroyBuffer(HgiBufferHandle* bufHandle) = 0;
195 
196  /// Create a new shader function.
197  /// Thread safety: Creation must happen on main thread. See notes above.
198  HGI_API
200  HgiShaderFunctionDesc const& desc) = 0;
201 
202  /// Destroy a shader function.
203  /// Thread safety: Destruction must happen on main thread. See notes above.
204  HGI_API
205  virtual void DestroyShaderFunction(
206  HgiShaderFunctionHandle* shaderFunctionHandle) = 0;
207 
208  /// Create a new shader program.
209  /// Thread safety: Creation must happen on main thread. See notes above.
210  HGI_API
212  HgiShaderProgramDesc const& desc) = 0;
213 
214  /// Destroy a shader program.
215  /// Note that this does NOT automatically destroy the shader functions in
216  /// the program since shader functions may be used by more than one program.
217  /// Thread safety: Destruction must happen on main thread. See notes above.
218  HGI_API
219  virtual void DestroyShaderProgram(
220  HgiShaderProgramHandle* shaderProgramHandle) = 0;
221 
222  /// Create a new resource binding object.
223  /// Thread safety: Creation must happen on main thread. See notes above.
224  HGI_API
226  HgiResourceBindingsDesc const& desc) = 0;
227 
228  /// Destroy a resource binding object.
229  /// Thread safety: Destruction must happen on main thread. See notes above.
230  HGI_API
231  virtual void DestroyResourceBindings(
232  HgiResourceBindingsHandle* resHandle) = 0;
233 
234  /// Create a new graphics pipeline state object.
235  /// Thread safety: Creation must happen on main thread. See notes above.
236  HGI_API
238  HgiGraphicsPipelineDesc const& pipeDesc) = 0;
239 
240  /// Destroy a graphics pipeline state object.
241  /// Thread safety: Destruction must happen on main thread. See notes above.
242  HGI_API
243  virtual void DestroyGraphicsPipeline(
244  HgiGraphicsPipelineHandle* pipeHandle) = 0;
245 
246  /// Create a new compute pipeline state object.
247  /// Thread safety: Creation must happen on main thread. See notes above.
248  HGI_API
250  HgiComputePipelineDesc const& pipeDesc) = 0;
251 
252  /// Destroy a compute pipeline state object.
253  /// Thread safety: Destruction must happen on main thread. See notes above.
254  HGI_API
255  virtual void DestroyComputePipeline(HgiComputePipelineHandle* pipeHandle)=0;
256 
257  /// Return the name of the api (e.g. "OpenGL").
258  /// Thread safety: This call is thread safe.
259  HGI_API
260  virtual TfToken const& GetAPIName() const = 0;
261 
262  /// Optionally called by client app at the start of a new rendering frame.
263  /// We can't rely on StartFrame for anything important, because it is up to
264  /// the external client to (optionally) call this and they may never do.
265  /// Hydra doesn't have a clearly defined start or end frame.
266  /// This can be helpful to insert GPU frame debug markers.
267  /// Thread safety: Not thread safe. Should be called on the main thread.
268  HGI_API
269  virtual void StartFrame() = 0;
270 
271  /// Optionally called at the end of a rendering frame.
272  /// Please read the comments in StartFrame.
273  /// Thread safety: Not thread safe. Should be called on the main thread.
274  HGI_API
275  virtual void EndFrame() = 0;
276 
277 protected:
278  // Returns a unique id for handle creation.
279  // Thread safety: Thread-safe atomic increment.
280  HGI_API
281  uint64_t GetUniqueId();
282 
283  // Calls Submit on provided Cmds.
284  // Derived classes can override this function if they need customize the
285  // command submission. The default implementation calls cmds->_Submit().
286  HGI_API
287  virtual bool _SubmitCmds(HgiCmds* cmds);
288 
289 private:
290  Hgi & operator=(const Hgi&) = delete;
291  Hgi(const Hgi&) = delete;
292 
293  std::atomic<uint64_t> _uniqueIdCounter;
294 };
295 
296 
297 ///
298 /// Hgi factory for plugin system
299 ///
301 public:
302  virtual Hgi* New() const = 0;
303 };
304 
305 template <class T>
306 class HgiFactory : public HgiFactoryBase {
307 public:
308  Hgi* New() const {
309  return new T;
310  }
311 };
312 
313 
315 
316 #endif
HGI_API void SubmitCmds(HgiCmds *cmds)
static HGI_API Hgi * GetPlatformDefaultHgi()
*** DEPRECATED *** Please use: CreatePlatformDefaultHgi
virtual HGI_API HgiShaderProgramHandle CreateShaderProgram(HgiShaderProgramDesc const &desc)=0
virtual HGI_API void DestroySampler(HgiSamplerHandle *smpHandle)=0
Hgi * New() const
Definition: hgi.h:308
virtual HGI_API void DestroyBuffer(HgiBufferHandle *bufHandle)=0
virtual HGI_API HgiResourceBindingsHandle CreateResourceBindings(HgiResourceBindingsDesc const &desc)=0
virtual HGI_API bool _SubmitCmds(HgiCmds *cmds)
HGI_API uint64_t GetUniqueId()
virtual HGI_API void DestroyGraphicsPipeline(HgiGraphicsPipelineHandle *pipeHandle)=0
HGI_API Hgi()
virtual HGI_API HgiGraphicsCmdsUniquePtr CreateGraphicsCmds(HgiGraphicsCmdsDesc const &desc)=0
virtual HGI_API void DestroyShaderFunction(HgiShaderFunctionHandle *shaderFunctionHandle)=0
virtual HGI_API HgiShaderFunctionHandle CreateShaderFunction(HgiShaderFunctionDesc const &desc)=0
Base class of all factory types.
Definition: type.h:73
virtual HGI_API void DestroyTexture(HgiTextureHandle *texHandle)=0
virtual HGI_API void EndFrame()=0
Definition: token.h:87
virtual HGI_API void DestroyResourceBindings(HgiResourceBindingsHandle *resHandle)=0
virtual HGI_API void DestroyShaderProgram(HgiShaderProgramHandle *shaderProgramHandle)=0
virtual Hgi * New() const =0
virtual HGI_API HgiBlitCmdsUniquePtr CreateBlitCmds()=0
virtual HGI_API HgiBufferHandle CreateBuffer(HgiBufferDesc const &desc)=0
virtual HGI_API void StartFrame()=0
static HGI_API HgiUniquePtr CreatePlatformDefaultHgi()
std::unique_ptr< class HgiComputeCmds > HgiComputeCmdsUniquePtr
Definition: computeCmds.h:36
virtual HGI_API HgiComputePipelineHandle CreateComputePipeline(HgiComputePipelineDesc const &pipeDesc)=0
virtual HGI_API HgiGraphicsPipelineHandle CreateGraphicsPipeline(HgiGraphicsPipelineDesc const &pipeDesc)=0
Definition: hgi.h:106
std::unique_ptr< class HgiBlitCmds > HgiBlitCmdsUniquePtr
Definition: blitCmds.h:40
#define HGI_API
Definition: api.h:40
virtual HGI_API HgiTextureHandle CreateTexture(HgiTextureDesc const &desc)=0
PXR_NAMESPACE_CLOSE_SCOPE PXR_NAMESPACE_OPEN_SCOPE
Definition: path.h:1346
virtual HGI_API HgiSamplerHandle CreateSampler(HgiSamplerDesc const &desc)=0
#define PXR_NAMESPACE_CLOSE_SCOPE
Definition: pxr.h:91
std::unique_ptr< class HgiGraphicsCmds > HgiGraphicsCmdsUniquePtr
Definition: graphicsCmds.h:38
virtual HGI_API ~Hgi()
virtual HGI_API HgiComputeCmdsUniquePtr CreateComputeCmds()=0
virtual HGI_API void DestroyComputePipeline(HgiComputePipelineHandle *pipeHandle)=0
virtual HGI_API TfToken const & GetAPIName() const =0
Definition: cmds.h:43
std::unique_ptr< class Hgi > HgiUniquePtr
Definition: hgi.h:50