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(
125  HgiCmds* cmds,
127 
128  /// *** DEPRECATED *** Please use: CreatePlatformDefaultHgi
129  HGI_API
130  static Hgi* GetPlatformDefaultHgi();
131 
132  /// Helper function to return a Hgi object for the current platform.
133  /// For example on Linux this may return HgiGL while on macOS HgiMetal.
134  /// Caller, usually the application, owns the lifetime of the Hgi object and
135  /// the object is destroyed when the caller drops the unique ptr.
136  /// Thread safety: Not thread safe.
137  HGI_API
139 
140  /// Returns a GraphicsCmds object (for temporary use) that is ready to
141  /// record draw commands. GraphicsCmds is a lightweight object that
142  /// should be re-acquired each frame (don't hold onto it after EndEncoding).
143  /// Thread safety: Each Hgi backend must ensure that a Cmds object can be
144  /// created on the main thread, recorded into (exclusively) by one secondary
145  /// thread and be submitted on the main thread. See notes above.
146  HGI_API
148  HgiGraphicsCmdsDesc const& desc) = 0;
149 
150  /// Returns a BlitCmds object (for temporary use) that is ready to execute
151  /// resource copy commands. BlitCmds is a lightweight object that
152  /// should be re-acquired each frame (don't hold onto it after EndEncoding).
153  /// Thread safety: Each Hgi backend must ensure that a Cmds object can be
154  /// created on the main thread, recorded into (exclusively) by one secondary
155  /// thread and be submitted on the main thread. See notes above.
156  HGI_API
157  virtual HgiBlitCmdsUniquePtr CreateBlitCmds() = 0;
158 
159  /// Returns a ComputeCmds object (for temporary use) that is ready to
160  /// record dispatch commands. ComputeCmds is a lightweight object that
161  /// should be re-acquired each frame (don't hold onto it after EndEncoding).
162  /// Thread safety: Each Hgi backend must ensure that a Cmds object can be
163  /// created on the main thread, recorded into (exclusively) by one secondary
164  /// thread and be submitted on the main thread. See notes above.
165  HGI_API
167 
168  /// Create a texture in rendering backend.
169  /// Thread safety: Creation must happen on main thread. See notes above.
170  HGI_API
171  virtual HgiTextureHandle CreateTexture(HgiTextureDesc const & desc) = 0;
172 
173  /// Destroy a texture in rendering backend.
174  /// Thread safety: Destruction must happen on main thread. See notes above.
175  HGI_API
176  virtual void DestroyTexture(HgiTextureHandle* texHandle) = 0;
177 
178  /// Create a texture view in rendering backend.
179  /// A texture view aliases another texture's data.
180  /// It is the responsibility of the client to ensure that the sourceTexture
181  /// is not destroyed while the texture view is in use.
182  /// Thread safety: Creation must happen on main thread. See notes above.
183  HGI_API
185  HgiTextureViewDesc const & desc) = 0;
186 
187  /// Destroy a texture view in rendering backend.
188  /// This will destroy the view's texture, but not the sourceTexture that
189  /// was aliased by the view. The sourceTexture data remains unchanged.
190  /// Thread safety: Destruction must happen on main thread. See notes above.
191  HGI_API
192  virtual void DestroyTextureView(HgiTextureViewHandle* viewHandle) = 0;
193 
194  /// Create a sampler in rendering backend.
195  /// Thread safety: Creation must happen on main thread. See notes above.
196  HGI_API
197  virtual HgiSamplerHandle CreateSampler(HgiSamplerDesc const & desc) = 0;
198 
199  /// Destroy a sampler in rendering backend.
200  /// Thread safety: Destruction must happen on main thread. See notes above.
201  HGI_API
202  virtual void DestroySampler(HgiSamplerHandle* smpHandle) = 0;
203 
204  /// Create a buffer in rendering backend.
205  /// Thread safety: Creation must happen on main thread. See notes above.
206  HGI_API
207  virtual HgiBufferHandle CreateBuffer(HgiBufferDesc const & desc) = 0;
208 
209  /// Destroy a buffer in rendering backend.
210  /// Thread safety: Destruction must happen on main thread. See notes above.
211  HGI_API
212  virtual void DestroyBuffer(HgiBufferHandle* bufHandle) = 0;
213 
214  /// Create a new shader function.
215  /// Thread safety: Creation must happen on main thread. See notes above.
216  HGI_API
218  HgiShaderFunctionDesc const& desc) = 0;
219 
220  /// Destroy a shader function.
221  /// Thread safety: Destruction must happen on main thread. See notes above.
222  HGI_API
223  virtual void DestroyShaderFunction(
224  HgiShaderFunctionHandle* shaderFunctionHandle) = 0;
225 
226  /// Create a new shader program.
227  /// Thread safety: Creation must happen on main thread. See notes above.
228  HGI_API
230  HgiShaderProgramDesc const& desc) = 0;
231 
232  /// Destroy a shader program.
233  /// Note that this does NOT automatically destroy the shader functions in
234  /// the program since shader functions may be used by more than one program.
235  /// Thread safety: Destruction must happen on main thread. See notes above.
236  HGI_API
237  virtual void DestroyShaderProgram(
238  HgiShaderProgramHandle* shaderProgramHandle) = 0;
239 
240  /// Create a new resource binding object.
241  /// Thread safety: Creation must happen on main thread. See notes above.
242  HGI_API
244  HgiResourceBindingsDesc const& desc) = 0;
245 
246  /// Destroy a resource binding object.
247  /// Thread safety: Destruction must happen on main thread. See notes above.
248  HGI_API
249  virtual void DestroyResourceBindings(
250  HgiResourceBindingsHandle* resHandle) = 0;
251 
252  /// Create a new graphics pipeline state object.
253  /// Thread safety: Creation must happen on main thread. See notes above.
254  HGI_API
256  HgiGraphicsPipelineDesc const& pipeDesc) = 0;
257 
258  /// Destroy a graphics pipeline state object.
259  /// Thread safety: Destruction must happen on main thread. See notes above.
260  HGI_API
261  virtual void DestroyGraphicsPipeline(
262  HgiGraphicsPipelineHandle* pipeHandle) = 0;
263 
264  /// Create a new compute pipeline state object.
265  /// Thread safety: Creation must happen on main thread. See notes above.
266  HGI_API
268  HgiComputePipelineDesc const& pipeDesc) = 0;
269 
270  /// Destroy a compute pipeline state object.
271  /// Thread safety: Destruction must happen on main thread. See notes above.
272  HGI_API
273  virtual void DestroyComputePipeline(HgiComputePipelineHandle* pipeHandle)=0;
274 
275  /// Return the name of the api (e.g. "OpenGL").
276  /// Thread safety: This call is thread safe.
277  HGI_API
278  virtual TfToken const& GetAPIName() const = 0;
279 
280  /// Optionally called by client app at the start of a new rendering frame.
281  /// We can't rely on StartFrame for anything important, because it is up to
282  /// the external client to (optionally) call this and they may never do.
283  /// Hydra doesn't have a clearly defined start or end frame.
284  /// This can be helpful to insert GPU frame debug markers.
285  /// Thread safety: Not thread safe. Should be called on the main thread.
286  HGI_API
287  virtual void StartFrame() = 0;
288 
289  /// Optionally called at the end of a rendering frame.
290  /// Please read the comments in StartFrame.
291  /// Thread safety: Not thread safe. Should be called on the main thread.
292  HGI_API
293  virtual void EndFrame() = 0;
294 
295 protected:
296  // Returns a unique id for handle creation.
297  // Thread safety: Thread-safe atomic increment.
298  HGI_API
299  uint64_t GetUniqueId();
300 
301  // Calls Submit on provided Cmds.
302  // Derived classes can override this function if they need customize the
303  // command submission. The default implementation calls cmds->_Submit().
304  HGI_API
305  virtual bool _SubmitCmds(
307 
308 private:
309  Hgi & operator=(const Hgi&) = delete;
310  Hgi(const Hgi&) = delete;
311 
312  std::atomic<uint64_t> _uniqueIdCounter;
313 };
314 
315 
316 ///
317 /// Hgi factory for plugin system
318 ///
320 public:
321  virtual Hgi* New() const = 0;
322 };
323 
324 template <class T>
325 class HgiFactory : public HgiFactoryBase {
326 public:
327  Hgi* New() const {
328  return new T;
329  }
330 };
331 
332 
334 
335 #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:327
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 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:516
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()
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:106
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:1375
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:44
std::unique_ptr< class Hgi > HgiUniquePtr
Definition: hgi.h:50