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 terms set forth in the LICENSE.txt file available at
5 // https://openusd.org/license.
6 //
7 #ifndef PXR_IMAGING_HGI_HGI_H
8 #define PXR_IMAGING_HGI_HGI_H
9 
10 #include "pxr/pxr.h"
11 #include "pxr/base/tf/token.h"
12 #include "pxr/base/tf/type.h"
13 
14 #include "pxr/imaging/hgi/api.h"
16 #include "pxr/imaging/hgi/buffer.h"
27 #include "pxr/imaging/hgi/types.h"
28 
29 #include <atomic>
30 #include <memory>
31 
33 
34 class HgiCapabilities;
36 
37 using HgiUniquePtr = std::unique_ptr<class Hgi>;
38 
39 
40 /// \class Hgi
41 ///
42 /// Hydra Graphics Interface.
43 /// Hgi is used to communicate with one or more physical gpu devices.
44 ///
45 /// Hgi provides API to create/destroy resources that a gpu device owns.
46 /// The lifetime of resources is not managed by Hgi, so it is up to the caller
47 /// to destroy resources and ensure those resources are no longer used.
48 ///
49 /// Commands are recorded in 'HgiCmds' objects and submitted via Hgi.
50 ///
51 /// Thread-safety:
52 ///
53 /// Modern graphics APIs like Metal and Vulkan are designed with multi-threading
54 /// in mind. We want to try and take advantage of this where possible.
55 /// However we also wish to continue to support OpenGL for the time being.
56 ///
57 /// In an application where OpenGL is involved, when we say "main thread" we
58 /// mean the thread on which the gl-context is bound.
59 ///
60 /// Each Hgi backend should at minimum support the following:
61 ///
62 /// * Single threaded Hgi::SubmitCmds on main thread.
63 /// * Single threaded Hgi::Resource Create*** / Destroy*** on main thread.
64 /// * Multi threaded recording of commands in Hgi***Cmds objects.
65 /// * A Hgi***Cmds object should be creatable on the main thread, recorded
66 /// into with one secondary thread (only one thread may use a Cmds object) and
67 /// submitted via the main thread.
68 ///
69 /// Each Hgi backend is additionally encouraged to support:
70 ///
71 /// * Multi threaded support for resource creation and destruction.
72 ///
73 /// We currently do not rely on these additional multi-threading features in
74 /// Hydra / Storm where we still wish to run OpenGL. In Hydra we make sure to
75 /// use the main-thread for resource creation and command submission.
76 /// One day we may wish to switch this to be multi-threaded so new Hgi backends
77 /// are encouraged to support it.
78 ///
79 /// Pseudo code what should minimally be supported:
80 ///
81 /// vector<HgiGraphicsCmds> cmds
82 ///
83 /// for num_threads
84 /// cmds.push_back( Hgi->CreateGraphicsCmds() )
85 ///
86 /// parallel_for i to num_threads
87 /// cmds[i]->SetViewport()
88 /// cmds[i]->Draw()
89 ///
90 /// for i to num_threads
91 /// hgi->SubmitCmds( cmds[i] )
92 ///
93 class Hgi
94 {
95 public:
96  HGI_API
97  Hgi();
98 
99  HGI_API
100  virtual ~Hgi();
101 
102  /// Submit one HgiCmds objects.
103  /// Once the cmds object is submitted it cannot be re-used to record cmds.
104  /// A call to SubmitCmds would usually result in the hgi backend submitting
105  /// the cmd buffers of the cmds object(s) to the device queue.
106  /// Derived classes can override _SubmitCmds to customize submission.
107  /// Thread safety: This call is not thread-safe. Submission must happen on
108  /// the main thread so we can continue to support the OpenGL platform.
109  /// See notes above.
110  HGI_API
111  void SubmitCmds(
112  HgiCmds* cmds,
114 
115  /// *** DEPRECATED *** Please use: CreatePlatformDefaultHgi
116  HGI_API
117  static Hgi* GetPlatformDefaultHgi();
118 
119  /// Helper function to return a Hgi object for the current platform.
120  /// For example on Linux this may return HgiGL while on macOS HgiMetal.
121  /// Caller, usually the application, owns the lifetime of the Hgi object and
122  /// the object is destroyed when the caller drops the unique ptr.
123  /// Thread safety: Not thread safe.
124  HGI_API
126 
127  /// Helper function to return a Hgi object of choice supported by current
128  /// platform and build configuration.
129  /// For example, on macOS, this may allow HgiMetal only.
130  /// If the Hgi device specified is not available on the current platform,
131  /// this function will fail and return nullptr.
132  /// If an empty token is provided, the default Hgi type (see
133  /// CreatePlatformDefaultHgi) will be created.
134  /// Supported TfToken values are OpenGL, Metal, Vulkan, or an empty token;
135  /// if not using an empty token, the caller is expected to use a token from
136  /// HgiTokens.
137  /// Caller, usually the application, owns the lifetime of the Hgi object and
138  /// the object is destroyed when the caller drops the unique ptr.
139  /// Thread safety: Not thread safe.
140  HGI_API
141  static HgiUniquePtr CreateNamedHgi(const TfToken& hgiToken);
142 
143  /// Determine if Hgi instance can run on current hardware.
144  /// Thread safety: This call is thread safe.
145  HGI_API
146  virtual bool IsBackendSupported() const = 0;
147 
148  /// Constructs a temporary Hgi object and calls the object's
149  /// IsBackendSupported() function.
150  /// A token can optionally be provided to specify a specific Hgi backend to
151  /// create. Supported TfToken values are OpenGL, Metal, Vulkan, or an empty
152  /// token; if not using an empty token, the caller is expected to use a
153  /// token from HgiTokens.
154  /// An empty token will check support for creating the platform default Hgi.
155  /// An invalid token will result in this function returning false.
156  /// Thread safety: Not thread safe.
157  HGI_API
158  static bool IsSupported(const TfToken& hgiToken = TfToken());
159 
160  /// Returns a GraphicsCmds object (for temporary use) that is ready to
161  /// record draw commands. GraphicsCmds is a lightweight object that
162  /// should be re-acquired each frame (don't hold onto it after EndEncoding).
163  /// Thread safety: Each Hgi backend must ensure that a Cmds object can be
164  /// created on the main thread, recorded into (exclusively) by one secondary
165  /// thread and be submitted on the main thread. See notes above.
166  HGI_API
168  HgiGraphicsCmdsDesc const& desc) = 0;
169 
170  /// Returns a BlitCmds object (for temporary use) that is ready to execute
171  /// resource copy commands. BlitCmds is a lightweight object that
172  /// should be re-acquired each frame (don't hold onto it after EndEncoding).
173  /// Thread safety: Each Hgi backend must ensure that a Cmds object can be
174  /// created on the main thread, recorded into (exclusively) by one secondary
175  /// thread and be submitted on the main thread. See notes above.
176  HGI_API
177  virtual HgiBlitCmdsUniquePtr CreateBlitCmds() = 0;
178 
179  /// Returns a ComputeCmds object (for temporary use) that is ready to
180  /// record dispatch commands. ComputeCmds is a lightweight object that
181  /// should be re-acquired each frame (don't hold onto it after EndEncoding).
182  /// Thread safety: Each Hgi backend must ensure that a Cmds object can be
183  /// created on the main thread, recorded into (exclusively) by one secondary
184  /// thread and be submitted on the main thread. See notes above.
185  HGI_API
187  HgiComputeCmdsDesc const& desc) = 0;
188 
189  /// Create a texture in rendering backend.
190  /// Thread safety: Creation must happen on main thread. See notes above.
191  HGI_API
192  virtual HgiTextureHandle CreateTexture(HgiTextureDesc const & desc) = 0;
193 
194  /// Destroy a texture in rendering backend.
195  /// Thread safety: Destruction must happen on main thread. See notes above.
196  HGI_API
197  virtual void DestroyTexture(HgiTextureHandle* texHandle) = 0;
198 
199  /// Create a texture view in rendering backend.
200  /// A texture view aliases another texture's data.
201  /// It is the responsibility of the client to ensure that the sourceTexture
202  /// is not destroyed while the texture view is in use.
203  /// Thread safety: Creation must happen on main thread. See notes above.
204  HGI_API
206  HgiTextureViewDesc const & desc) = 0;
207 
208  /// Destroy a texture view in rendering backend.
209  /// This will destroy the view's texture, but not the sourceTexture that
210  /// was aliased by the view. The sourceTexture data remains unchanged.
211  /// Thread safety: Destruction must happen on main thread. See notes above.
212  HGI_API
213  virtual void DestroyTextureView(HgiTextureViewHandle* viewHandle) = 0;
214 
215  /// Create a sampler in rendering backend.
216  /// Thread safety: Creation must happen on main thread. See notes above.
217  HGI_API
218  virtual HgiSamplerHandle CreateSampler(HgiSamplerDesc const & desc) = 0;
219 
220  /// Destroy a sampler in rendering backend.
221  /// Thread safety: Destruction must happen on main thread. See notes above.
222  HGI_API
223  virtual void DestroySampler(HgiSamplerHandle* smpHandle) = 0;
224 
225  /// Create a buffer in rendering backend.
226  /// Thread safety: Creation must happen on main thread. See notes above.
227  HGI_API
228  virtual HgiBufferHandle CreateBuffer(HgiBufferDesc const & desc) = 0;
229 
230  /// Destroy a buffer in rendering backend.
231  /// Thread safety: Destruction must happen on main thread. See notes above.
232  HGI_API
233  virtual void DestroyBuffer(HgiBufferHandle* bufHandle) = 0;
234 
235  /// Create a new shader function.
236  /// Thread safety: Creation must happen on main thread. See notes above.
237  HGI_API
239  HgiShaderFunctionDesc const& desc) = 0;
240 
241  /// Destroy a shader function.
242  /// Thread safety: Destruction must happen on main thread. See notes above.
243  HGI_API
244  virtual void DestroyShaderFunction(
245  HgiShaderFunctionHandle* shaderFunctionHandle) = 0;
246 
247  /// Create a new shader program.
248  /// Thread safety: Creation must happen on main thread. See notes above.
249  HGI_API
251  HgiShaderProgramDesc const& desc) = 0;
252 
253  /// Destroy a shader program.
254  /// Note that this does NOT automatically destroy the shader functions in
255  /// the program since shader functions may be used by more than one program.
256  /// Thread safety: Destruction must happen on main thread. See notes above.
257  HGI_API
258  virtual void DestroyShaderProgram(
259  HgiShaderProgramHandle* shaderProgramHandle) = 0;
260 
261  /// Create a new resource binding object.
262  /// Thread safety: Creation must happen on main thread. See notes above.
263  HGI_API
265  HgiResourceBindingsDesc const& desc) = 0;
266 
267  /// Destroy a resource binding object.
268  /// Thread safety: Destruction must happen on main thread. See notes above.
269  HGI_API
270  virtual void DestroyResourceBindings(
271  HgiResourceBindingsHandle* resHandle) = 0;
272 
273  /// Create a new graphics pipeline state object.
274  /// Thread safety: Creation must happen on main thread. See notes above.
275  HGI_API
277  HgiGraphicsPipelineDesc const& pipeDesc) = 0;
278 
279  /// Destroy a graphics pipeline state object.
280  /// Thread safety: Destruction must happen on main thread. See notes above.
281  HGI_API
282  virtual void DestroyGraphicsPipeline(
283  HgiGraphicsPipelineHandle* pipeHandle) = 0;
284 
285  /// Create a new compute pipeline state object.
286  /// Thread safety: Creation must happen on main thread. See notes above.
287  HGI_API
289  HgiComputePipelineDesc const& pipeDesc) = 0;
290 
291  /// Destroy a compute pipeline state object.
292  /// Thread safety: Destruction must happen on main thread. See notes above.
293  HGI_API
294  virtual void DestroyComputePipeline(HgiComputePipelineHandle* pipeHandle)=0;
295 
296  /// Return the name of the api (e.g. "OpenGL").
297  /// Thread safety: This call is thread safe.
298  HGI_API
299  virtual TfToken const& GetAPIName() const = 0;
300 
301  /// Returns the device-specific capabilities structure.
302  /// Thread safety: This call is thread safe.
303  HGI_API
304  virtual HgiCapabilities const* GetCapabilities() const = 0;
305 
306  /// Returns the device-specific indirect command buffer encoder
307  /// or nullptr if not supported.
308  /// Thread safety: This call is thread safe.
309  HGI_API
311 
312  /// Optionally called by client app at the start of a new rendering frame.
313  /// We can't rely on StartFrame for anything important, because it is up to
314  /// the external client to (optionally) call this and they may never do.
315  /// Hydra doesn't have a clearly defined start or end frame.
316  /// This can be helpful to insert GPU frame debug markers.
317  /// Thread safety: Not thread safe. Should be called on the main thread.
318  HGI_API
319  virtual void StartFrame() = 0;
320 
321  /// Optionally called at the end of a rendering frame.
322  /// Please read the comments in StartFrame.
323  /// Thread safety: Not thread safe. Should be called on the main thread.
324  HGI_API
325  virtual void EndFrame() = 0;
326 
327 protected:
328  // Returns a unique id for handle creation.
329  // Thread safety: Thread-safe atomic increment.
330  HGI_API
331  uint64_t GetUniqueId();
332 
333  // Calls Submit on provided Cmds.
334  // Derived classes can override this function if they need customize the
335  // command submission. The default implementation calls cmds->_Submit().
336  HGI_API
337  virtual bool _SubmitCmds(
339 
340 private:
341  Hgi & operator=(const Hgi&) = delete;
342  Hgi(const Hgi&) = delete;
343 
344  std::atomic<uint64_t> _uniqueIdCounter;
345 };
346 
347 
348 ///
349 /// Hgi factory for plugin system
350 ///
352 public:
353  virtual Hgi* New() const = 0;
354 };
355 
356 template <class T>
357 class HgiFactory : public HgiFactoryBase {
358 public:
359  Hgi* New() const {
360  return new T;
361  }
362 };
363 
364 
366 
367 #endif
virtual HGI_API bool _SubmitCmds(HgiCmds *cmds, HgiSubmitWaitType wait)
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:359
virtual HGI_API HgiCapabilities const * GetCapabilities() const =0
virtual HGI_API void DestroyBuffer(HgiBufferHandle *bufHandle)=0
virtual HGI_API HgiResourceBindingsHandle CreateResourceBindings(HgiResourceBindingsDesc const &desc)=0
HGI_API uint64_t GetUniqueId()
virtual HGI_API void DestroyGraphicsPipeline(HgiGraphicsPipelineHandle *pipeHandle)=0
HGI_API Hgi()
int HgiHandle< class HgiTexture > HgiTextureHandle
virtual HGI_API HgiGraphicsCmdsUniquePtr CreateGraphicsCmds(HgiGraphicsCmdsDesc const &desc)=0
virtual HGI_API HgiComputeCmdsUniquePtr CreateComputeCmds(HgiComputeCmdsDesc const &desc)=0
static HGI_API bool IsSupported(const TfToken &hgiToken=TfToken())
virtual HGI_API void DestroyShaderFunction(HgiShaderFunctionHandle *shaderFunctionHandle)=0
HGI_API void SubmitCmds(HgiCmds *cmds, HgiSubmitWaitType wait=HgiSubmitWaitTypeNoWait)
virtual HGI_API HgiShaderFunctionHandle CreateShaderFunction(HgiShaderFunctionDesc const &desc)=0
Base class of all factory types.
Definition: type.h:56
virtual HGI_API void DestroyTexture(HgiTextureHandle *texHandle)=0
HgiSubmitWaitType
Definition: enums.h:650
virtual HGI_API void EndFrame()=0
Definition: token.h:70
static HGI_API HgiUniquePtr CreateNamedHgi(const TfToken &hgiToken)
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 bool IsBackendSupported() const =0
virtual HGI_API void StartFrame()=0
static HGI_API HgiUniquePtr CreatePlatformDefaultHgi()
virtual HGI_API void DestroyTextureView(HgiTextureViewHandle *viewHandle)=0
std::unique_ptr< class HgiGraphicsCmds > HgiGraphicsCmdsUniquePtr
Definition: effectsShader.h:28
virtual HGI_API HgiTextureViewHandle CreateTextureView(HgiTextureViewDesc const &desc)=0
std::unique_ptr< class HgiComputeCmds > HgiComputeCmdsUniquePtr
Definition: computeCmds.h:19
virtual HGI_API HgiComputePipelineHandle CreateComputePipeline(HgiComputePipelineDesc const &pipeDesc)=0
*tasks wait()
virtual HGI_API HgiGraphicsPipelineHandle CreateGraphicsPipeline(HgiGraphicsPipelineDesc const &pipeDesc)=0
Definition: hgi.h:93
std::unique_ptr< class HgiBlitCmds > HgiBlitCmdsUniquePtr
Definition: blitCmds.h:28
#define HGI_API
Definition: api.h:23
virtual HGI_API HgiTextureHandle CreateTexture(HgiTextureDesc const &desc)=0
PXR_NAMESPACE_CLOSE_SCOPE PXR_NAMESPACE_OPEN_SCOPE
Definition: path.h:1425
virtual HGI_API HgiIndirectCommandEncoder * GetIndirectCommandEncoder() const =0
virtual HGI_API HgiSamplerHandle CreateSampler(HgiSamplerDesc const &desc)=0
#define PXR_NAMESPACE_CLOSE_SCOPE
Definition: pxr.h:74
virtual HGI_API ~Hgi()
virtual HGI_API void DestroyComputePipeline(HgiComputePipelineHandle *pipeHandle)=0
virtual HGI_API TfToken const & GetAPIName() const =0
Definition: cmds.h:27
std::unique_ptr< class Hgi > HgiUniquePtr
Definition: hgi.h:37