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