Overte C++ Documentation
GLBackend.h
1 //
2 // GLBackend.h
3 // libraries/gpu/src/gpu
4 //
5 // Created by Sam Gateau on 10/27/2014.
6 // Copyright 2014 High Fidelity, Inc.
7 // Copyright 2024 Overte e.V.
8 //
9 // Distributed under the Apache License, Version 2.0.
10 // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
11 //
12 #ifndef hifi_gpu_gl_GLBackend_h
13 #define hifi_gpu_gl_GLBackend_h
14 
15 #include <assert.h>
16 #include <functional>
17 #include <memory>
18 #include <bitset>
19 #include <queue>
20 #include <utility>
21 #include <list>
22 #include <array>
23 
24 #include <QtCore/QLoggingCategory>
25 
26 #include <gl/Config.h>
27 #include <gl/GLShaders.h>
28 
29 #include <gpu/Forward.h>
30 #include <gpu/Backend.h>
31 
32 #include "GLShared.h"
33 
34 // Different versions for the stereo drawcall
35 // Current preferred is "instanced" which draw the shape twice but instanced and rely on clipping plane to draw left/right side only
36 #if defined(USE_GLES) && !defined(HAVE_EXT_clip_cull_distance)
37 #define GPU_STEREO_TECHNIQUE_DOUBLED_SIMPLE
38 #else
39 //#define GPU_STEREO_TECHNIQUE_DOUBLED_SMARTER
40 #define GPU_STEREO_TECHNIQUE_INSTANCED
41 #endif
42 
43 // Let these be configured by the one define picked above
44 #ifdef GPU_STEREO_TECHNIQUE_DOUBLED_SIMPLE
45 #define GPU_STEREO_DRAWCALL_DOUBLED
46 #endif
47 
48 #ifdef GPU_STEREO_TECHNIQUE_DOUBLED_SMARTER
49 #define GPU_STEREO_DRAWCALL_DOUBLED
50 #define GPU_STEREO_CAMERA_BUFFER
51 #endif
52 
53 #ifdef GPU_STEREO_TECHNIQUE_INSTANCED
54 #define GPU_STEREO_DRAWCALL_INSTANCED
55 #define GPU_STEREO_CAMERA_BUFFER
56 #endif
57 
58 namespace gpu { namespace gl {
59 
60 class GLBackend : public Backend, public std::enable_shared_from_this<GLBackend> {
61  // Context Backend static interface required
62  friend class gpu::Context;
63  static void init();
64  static BackendPointer createBackend();
65 
66 protected:
67  explicit GLBackend(bool syncCache);
68  GLBackend();
69 
70 public:
71  enum VideoCardType {
72  ATI,
73  NVIDIA,
74  MESA,
75  Unknown
76  };
77 
78 #if defined(USE_GLES)
79  // https://www.khronos.org/registry/OpenGL-Refpages/es3/html/glGet.xhtml
80  static const GLint MIN_REQUIRED_TEXTURE_IMAGE_UNITS = 16;
81  static const GLint MIN_REQUIRED_COMBINED_UNIFORM_BLOCKS = 60;
82  static const GLint MIN_REQUIRED_COMBINED_TEXTURE_IMAGE_UNITS = 48;
83  static const GLint MIN_REQUIRED_UNIFORM_BUFFER_BINDINGS = 72;
84  static const GLint MIN_REQUIRED_UNIFORM_LOCATIONS = 1024;
85 #else
86  // https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/glGet.xhtml
87  static const GLint MIN_REQUIRED_TEXTURE_IMAGE_UNITS = 16;
88  static const GLint MIN_REQUIRED_COMBINED_UNIFORM_BLOCKS = 70;
89  static const GLint MIN_REQUIRED_COMBINED_TEXTURE_IMAGE_UNITS = 48;
90  static const GLint MIN_REQUIRED_UNIFORM_BUFFER_BINDINGS = 36;
91  static const GLint MIN_REQUIRED_UNIFORM_LOCATIONS = 1024;
92 #endif
93 
94  static GLint MAX_TEXTURE_IMAGE_UNITS;
95  static GLint MAX_UNIFORM_BUFFER_BINDINGS;
96  static GLint MAX_COMBINED_UNIFORM_BLOCKS;
97  static GLint MAX_COMBINED_TEXTURE_IMAGE_UNITS;
98  static GLint MAX_UNIFORM_BLOCK_SIZE;
99  static GLint UNIFORM_BUFFER_OFFSET_ALIGNMENT;
100  static GLint GPU_MEMORY_INFO_DEDICATED_VIDMEM_NVX;
101  static GLint GPU_MEMORY_INFO_TOTAL_AVAILABLE_MEMORY_NVX;
102  static GLint GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX;
103  static GLint TEXTURE_FREE_MEMORY_ATI;
104 
105 
106  static size_t _totalMemory;
107  static size_t _dedicatedMemory;
108  static VideoCardType _videoCard;
109 
110 
111  static size_t getTotalMemory() { return _totalMemory; }
112  static size_t getDedicatedMemory() { return _dedicatedMemory; }
113 
114  static size_t getAvailableMemory();
115  static bool availableMemoryKnown();
116 
117 
118 
119 
120  virtual ~GLBackend();
121 
122  // Shutdown rendering and persist any required resources
123  void shutdown() override;
124 
125  void updatePresentFrame(const Mat4& correction = Mat4(), bool primary = true) override;
126 
127  void executeFrame(const FramePointer& frame) override;
128  void render(const Batch& batch) final override;
129 
130  // This call synchronize the Full Backend cache with the current GLState
131  // THis is only intended to be used when mixing raw gl calls with the gpu api usage in order to sync
132  // the gpu::Backend state with the true gl state which has probably been messed up by these ugly naked gl calls
133  // Let's try to avoid to do that as much as possible!
134  void syncCache() final override;
135 
136  void syncProgram(const gpu::ShaderPointer& program) override;
137 
138  // This is the ugly "download the pixels to sysmem for taking a snapshot"
139  // Just avoid using it, it's ugly and will break performances
140  virtual void downloadFramebuffer(const FramebufferPointer& srcFramebuffer,
141  const Vec4i& region,
142  QImage& destImage) final override;
143 
144  // this is the maximum numeber of available input buffers
145  size_t getNumInputBuffers() const { return _input._invalidBuffers.size(); }
146 
147  // this is the maximum per shader stage on the low end apple
148  // TODO make it platform dependant at init time
149  static const int MAX_NUM_UNIFORM_BUFFERS = 14;
150  size_t getMaxNumUniformBuffers() const { return MAX_NUM_UNIFORM_BUFFERS; }
151 
152  // this is the maximum per shader stage on the low end apple
153  // TODO make it platform dependant at init time
154  static const int MAX_NUM_RESOURCE_BUFFERS = 16;
155  size_t getMaxNumResourceBuffers() const { return MAX_NUM_RESOURCE_BUFFERS; }
156  static const int MAX_NUM_RESOURCE_TEXTURES = 16;
157  size_t getMaxNumResourceTextures() const { return MAX_NUM_RESOURCE_TEXTURES; }
158 
159  // Texture Tables offers 2 dedicated slot (taken from the ubo slots)
160  static const int MAX_NUM_RESOURCE_TABLE_TEXTURES = 2;
161  size_t getMaxNumResourceTextureTables() const { return MAX_NUM_RESOURCE_TABLE_TEXTURES; }
162 
163  // Draw Stage
164  virtual void do_draw(const Batch& batch, size_t paramOffset) = 0;
165  virtual void do_drawIndexed(const Batch& batch, size_t paramOffset) = 0;
166  virtual void do_drawInstanced(const Batch& batch, size_t paramOffset) = 0;
167  virtual void do_drawIndexedInstanced(const Batch& batch, size_t paramOffset) = 0;
168  virtual void do_multiDrawIndirect(const Batch& batch, size_t paramOffset) = 0;
169  virtual void do_multiDrawIndexedIndirect(const Batch& batch, size_t paramOffset) = 0;
170 
171  // Input Stage
172  virtual void do_setInputFormat(const Batch& batch, size_t paramOffset) final;
173  virtual void do_setInputBuffer(const Batch& batch, size_t paramOffset) final;
174  virtual void do_setIndexBuffer(const Batch& batch, size_t paramOffset) final;
175  virtual void do_setIndirectBuffer(const Batch& batch, size_t paramOffset) final;
176  virtual void do_generateTextureMips(const Batch& batch, size_t paramOffset) final;
177  virtual void do_generateTextureMipsWithPipeline(const Batch& batch, size_t paramOffset) final;
178 
179  // Transform Stage
180  virtual void do_setModelTransform(const Batch& batch, size_t paramOffset) final;
181  virtual void do_setViewTransform(const Batch& batch, size_t paramOffset) final;
182  virtual void do_setProjectionTransform(const Batch& batch, size_t paramOffset) final;
183  virtual void do_setProjectionJitterEnabled(const Batch& batch, size_t paramOffset) final;
184  virtual void do_setProjectionJitterSequence(const Batch& batch, size_t paramOffset) final;
185  virtual void do_setProjectionJitterScale(const Batch& batch, size_t paramOffset) final;
186  virtual void do_setViewportTransform(const Batch& batch, size_t paramOffset) final;
187  virtual void do_setDepthRangeTransform(const Batch& batch, size_t paramOffset) final;
188 
189  virtual void do_saveViewProjectionTransform(const Batch& batch, size_t paramOffset) final;
190  virtual void do_setSavedViewProjectionTransform(const Batch& batch, size_t paramOffset) final;
191  virtual void do_copySavedViewProjectionTransformToBuffer(const Batch& batch, size_t paramOffset) = 0;
192 
193  // Uniform Stage
194  virtual void do_setUniformBuffer(const Batch& batch, size_t paramOffset) final;
195 
196  // Resource Stage
197  virtual void do_setResourceBuffer(const Batch& batch, size_t paramOffset) final;
198  virtual void do_setResourceTexture(const Batch& batch, size_t paramOffset) final;
199  virtual void do_setResourceTextureTable(const Batch& batch, size_t paramOffset);
200  virtual void do_setResourceFramebufferSwapChainTexture(const Batch& batch, size_t paramOffset) final;
201 
202  // Pipeline Stage
203  virtual void do_setPipeline(const Batch& batch, size_t paramOffset) final;
204 
205  // Output stage
206  virtual void do_setFramebuffer(const Batch& batch, size_t paramOffset) final;
207  virtual void do_setFramebufferSwapChain(const Batch& batch, size_t paramOffset) final;
208  virtual void do_clearFramebuffer(const Batch& batch, size_t paramOffset) final;
209  virtual void do_blit(const Batch& batch, size_t paramOffset) = 0;
210 
211  virtual void do_advance(const Batch& batch, size_t paramOffset) final;
212 
213  // Query section
214  virtual void do_beginQuery(const Batch& batch, size_t paramOffset) final;
215  virtual void do_endQuery(const Batch& batch, size_t paramOffset) final;
216  virtual void do_getQuery(const Batch& batch, size_t paramOffset) final;
217 
218  // Reset stages
219  virtual void do_resetStages(const Batch& batch, size_t paramOffset) final;
220 
221  virtual void do_disableContextViewCorrection(const Batch& batch, size_t paramOffset) final;
222  virtual void do_restoreContextViewCorrection(const Batch& batch, size_t paramOffset) final;
223  virtual void do_setContextMirrorViewCorrection(const Batch& batch, size_t paramOffset) final;
224 
225  virtual void do_disableContextStereo(const Batch& batch, size_t paramOffset) final;
226  virtual void do_restoreContextStereo(const Batch& batch, size_t paramOffset) final;
227 
228  virtual void do_runLambda(const Batch& batch, size_t paramOffset) final;
229 
230  virtual void do_startNamedCall(const Batch& batch, size_t paramOffset) final;
231  virtual void do_stopNamedCall(const Batch& batch, size_t paramOffset) final;
232 
233  static const int MAX_NUM_ATTRIBUTES = Stream::NUM_INPUT_SLOTS;
234  // The drawcall Info attribute channel is reserved and is the upper bound for the number of availables Input buffers
235  static const int MAX_NUM_INPUT_BUFFERS = Stream::DRAW_CALL_INFO;
236 
237  virtual void do_pushProfileRange(const Batch& batch, size_t paramOffset) final;
238  virtual void do_popProfileRange(const Batch& batch, size_t paramOffset) final;
239 
240  // TODO: As long as we have gl calls explicitely issued from interface
241  // code, we need to be able to record and batch these calls. THe long
242  // term strategy is to get rid of any GL calls in favor of the HIFI GPU API
243  virtual void do_glUniform1i(const Batch& batch, size_t paramOffset) final;
244  virtual void do_glUniform1f(const Batch& batch, size_t paramOffset) final;
245  virtual void do_glUniform2f(const Batch& batch, size_t paramOffset) final;
246  virtual void do_glUniform3f(const Batch& batch, size_t paramOffset) final;
247  virtual void do_glUniform4f(const Batch& batch, size_t paramOffset) final;
248  virtual void do_glUniform3fv(const Batch& batch, size_t paramOffset) final;
249  virtual void do_glUniform4fv(const Batch& batch, size_t paramOffset) final;
250  virtual void do_glUniform4iv(const Batch& batch, size_t paramOffset) final;
251  virtual void do_glUniformMatrix3fv(const Batch& batch, size_t paramOffset) final;
252  virtual void do_glUniformMatrix4fv(const Batch& batch, size_t paramOffset) final;
253 
254  // The State setters called by the GLState::Commands when a new state is assigned
255  virtual void do_setStateFillMode(int32 mode) final;
256  virtual void do_setStateCullMode(int32 mode) final;
257  virtual void do_setStateFrontFaceClockwise(bool isClockwise) final;
258  virtual void do_setStateDepthClampEnable(bool enable) final;
259  virtual void do_setStateScissorEnable(bool enable) final;
260  virtual void do_setStateMultisampleEnable(bool enable) final;
261  virtual void do_setStateAntialiasedLineEnable(bool enable) final;
262  virtual void do_setStateDepthBias(Vec2 bias) final;
263  virtual void do_setStateDepthTest(State::DepthTest test) final;
264  virtual void do_setStateStencil(State::StencilActivation activation,
265  State::StencilTest frontTest,
266  State::StencilTest backTest) final;
267  virtual void do_setStateAlphaToCoverageEnable(bool enable) final;
268  virtual void do_setStateSampleMask(uint32 mask) final;
269  virtual void do_setStateBlend(State::BlendFunction blendFunction) final;
270  virtual void do_setStateColorWriteMask(uint32 mask) final;
271  virtual void do_setStateBlendFactor(const Batch& batch, size_t paramOffset) final;
272  virtual void do_setStateScissorRect(const Batch& batch, size_t paramOffset) final;
273 
274  virtual GLuint getFramebufferID(const FramebufferPointer& framebuffer) = 0;
275  virtual GLuint getTextureID(const TexturePointer& texture) final;
276  virtual GLuint getBufferID(const Buffer& buffer) = 0;
277  virtual GLuint getBufferIDUnsynced(const Buffer& buffer) = 0;
278  virtual GLuint getQueryID(const QueryPointer& query) = 0;
279 
280  virtual GLFramebuffer* syncGPUObject(const Framebuffer& framebuffer) = 0;
281  virtual GLBuffer* syncGPUObject(const Buffer& buffer) = 0;
282  virtual GLTexture* syncGPUObject(const TexturePointer& texture);
283  virtual GLQuery* syncGPUObject(const Query& query) = 0;
284  //virtual bool isTextureReady(const TexturePointer& texture);
285 
286  virtual void releaseBuffer(GLuint id, Size size) const;
287  virtual void releaseExternalTexture(GLuint id, const Texture::ExternalRecycler& recycler) const;
288  virtual void releaseTexture(GLuint id, Size size) const;
289  virtual void releaseFramebuffer(GLuint id) const;
290  virtual void releaseShader(GLuint id) const;
291  virtual void releaseProgram(GLuint id) const;
292  virtual void releaseQuery(GLuint id) const;
293  virtual void queueLambda(const std::function<void()> lambda) const;
294 
295  bool isTextureManagementSparseEnabled() const override {
296  return (_textureManagement._sparseCapable && Texture::getEnableSparseTextures());
297  }
298 
299 protected:
300  virtual GLint getRealUniformLocation(GLint location) const;
301 
302  virtual void draw(GLenum mode, uint32 numVertices, uint32 startVertex) = 0;
303 
304  void recycle() const override;
305 
306  // FIXME instead of a single flag, create a features struct similar to
307  // https://www.khronos.org/registry/vulkan/specs/1.0/man/html/VkPhysicalDeviceFeatures.html
308  virtual bool supportsBindless() const { return false; }
309 
310  static const size_t INVALID_OFFSET = (size_t)-1;
311  static const uint INVALID_SAVED_CAMERA_SLOT = (uint)-1;
312  bool _inRenderTransferPass { false };
313  int _currentDraw { -1 };
314 
315  struct FrameTrash {
316  GLsync fence = nullptr;
317  std::list<std::pair<GLuint, Size>> buffersTrash;
318  std::list<std::pair<GLuint, Size>> texturesTrash;
319  std::list<std::pair<GLuint, Texture::ExternalRecycler>> externalTexturesTrash;
320  std::list<GLuint> framebuffersTrash;
321  std::list<GLuint> shadersTrash;
322  std::list<GLuint> programsTrash;
323  std::list<GLuint> queriesTrash;
324 
325  void swap(FrameTrash& other) {
326  buffersTrash.swap(other.buffersTrash);
327  texturesTrash.swap(other.texturesTrash);
328  externalTexturesTrash.swap(other.externalTexturesTrash);
329  framebuffersTrash.swap(other.framebuffersTrash);
330  shadersTrash.swap(other.shadersTrash);
331  programsTrash.swap(other.programsTrash);
332  queriesTrash.swap(other.queriesTrash);
333  }
334 
335  void cleanup();
336  };
337 
338  mutable Mutex _trashMutex;
339  mutable FrameTrash _currentFrameTrash;
340  mutable std::list<FrameTrash> _previousFrameTrashes;
341  std::list<std::string> profileRanges;
342  mutable std::list<std::function<void()>> _lambdaQueue;
343 
344  void renderPassTransfer(const Batch& batch);
345  void renderPassDraw(const Batch& batch);
346 
347 #ifdef GPU_STEREO_DRAWCALL_DOUBLED
348  void setupStereoSide(int side);
349 #endif
350 
351  virtual void setResourceTexture(unsigned int slot, const TexturePointer& resourceTexture, const Sampler& sampler);
352  virtual void setFramebuffer(const FramebufferPointer& framebuffer);
353  virtual void initInput() final;
354  virtual void killInput() final;
355  virtual void syncInputStateCache() final;
356  virtual void resetInputStage();
357  virtual void updateInput() = 0;
358 
359  struct InputStageState {
360  bool _invalidFormat { true };
361  bool _lastUpdateStereoState { false };
362  FormatReference _format { GPU_REFERENCE_INIT_VALUE };
363  std::string _formatKey;
364 
365  typedef std::bitset<MAX_NUM_ATTRIBUTES> ActivationCache;
366  ActivationCache _attributeActivation { 0 };
367 
368  typedef std::bitset<MAX_NUM_INPUT_BUFFERS> BuffersState;
369 
370  BuffersState _invalidBuffers { 0 };
371  BuffersState _attribBindingBuffers { 0 };
372 
373  std::array<BufferReference, MAX_NUM_INPUT_BUFFERS> _buffers;
374  std::array<Offset, MAX_NUM_INPUT_BUFFERS> _bufferOffsets;
375  std::array<Offset, MAX_NUM_INPUT_BUFFERS> _bufferStrides;
376  std::array<GLuint, MAX_NUM_INPUT_BUFFERS> _bufferVBOs;
377 
378  BufferReference _indexBuffer;
379  Offset _indexBufferOffset { 0 };
380  Type _indexBufferType { UINT32 };
381 
382  BufferReference _indirectBuffer;
383  Offset _indirectBufferOffset { 0 };
384  Offset _indirectBufferStride { 0 };
385 
386  GLuint _defaultVAO { 0 };
387  } _input;
388 
389  virtual void initTransform() = 0;
390  void killTransform();
391  // Synchronize the state cache of this Backend with the actual real state of the GL Context
392  void syncTransformStateCache();
393  virtual void updateTransform(const Batch& batch) = 0;
394  virtual void resetTransformStage();
395 
396  // Allows for correction of the camera pose to account for changes
397  // between the time when a was recorded and the time(s) when it is
398  // executed
399  // Prev is the previous correction used at previous frame
400  struct PresentFrame {
401  mat4 correction;
402  mat4 correctionInverse;
403 
404  mat4 unflippedCorrection;
405  mat4 flippedCorrection;
406  bool mirrorViewCorrection { false };
407  };
408 
409  struct TransformStageState {
410 #ifdef GPU_STEREO_CAMERA_BUFFER
411  struct Cameras {
412  TransformCamera _cams[2];
413 
414  Cameras(){};
415  Cameras(const TransformCamera& cam) { _cams[0] = cam; };
416  Cameras(const TransformCamera& camL, const TransformCamera& camR) {
417  _cams[0] = camL;
418  _cams[1] = camR;
419  };
420  };
421 
422  using CameraBufferElement = Cameras;
423 #else
424  using CameraBufferElement = TransformCamera;
425 #endif
426  using TransformCameras = std::vector<CameraBufferElement>;
427 
428  struct ViewProjectionState {
429  Transform _view;
430  Transform _correctedView;
431  Transform _previousCorrectedView;
432  Mat4 _projection;
433  Mat4 _previousProjection;
434  bool _viewIsCamera;
435 
436  void copyExceptPrevious(const ViewProjectionState& other) {
437  _view = other._view;
438  _correctedView = other._correctedView;
439  _projection = other._projection;
440  _viewIsCamera = other._viewIsCamera;
441  }
442  };
443 
444  struct SaveTransform {
445  ViewProjectionState _state;
446  size_t _cameraOffset { INVALID_OFFSET };
447  };
448 
449  TransformCamera _camera;
450  TransformCameras _cameras;
451  std::array<SaveTransform, gpu::Batch::MAX_TRANSFORM_SAVE_SLOT_COUNT> _savedTransforms;
452 
453  mutable std::map<std::string, GLvoid*> _drawCallInfoOffsets;
454 
455  GLuint _objectBuffer { 0 };
456  GLuint _cameraBuffer { 0 };
457  GLuint _drawCallInfoBuffer { 0 };
458  GLuint _objectBufferTexture { 0 };
459  size_t _cameraUboSize { 0 };
460  ViewProjectionState _viewProjectionState;
461  uint _currentSavedTransformSlot { INVALID_SAVED_CAMERA_SLOT };
462  bool _skybox { false };
463  PresentFrame _presentFrame;
464  bool _viewCorrectionEnabled { true };
465 
466  struct Jitter {
467  std::vector<Vec2> _offsetSequence;
468  Vec2 _offset { 0.0f };
469  float _scale { 0.f };
470  unsigned int _currentSampleIndex { 0 };
471  bool _isEnabled { false };
472  };
473 
474  Jitter _projectionJitter;
475  Vec4i _viewport { 0, 0, 1, 1 };
476  Vec2 _depthRange { 0.0f, 1.0f };
477  bool _invalidView { false };
478  bool _invalidProj { false };
479  bool _invalidViewport { false };
480 
481  bool _enabledDrawcallInfoBuffer { false };
482 
483  using Pair = std::pair<size_t, size_t>;
484  using List = std::list<Pair>;
485  List _cameraOffsets;
486  mutable List::const_iterator _camerasItr;
487  mutable size_t _currentCameraOffset{ INVALID_OFFSET };
488 
489  void pushCameraBufferElement(const StereoState& stereo, const StereoState& prevStereo, TransformCameras& cameras) const;
490  void preUpdate(size_t commandIndex, const StereoState& stereo, const StereoState& prevStereo);
491  void update(size_t commandIndex, const StereoState& stereo) const;
492  void bindCurrentCamera(int stereoSide) const;
493  } _transform;
494 
495  void preUpdateTransform();
496  virtual void transferTransformState(const Batch& batch) const = 0;
497 
498  struct UniformStageState {
499  struct BufferState {
500  BufferReference buffer{};
501  GLintptr offset{ 0 };
502  GLsizeiptr size{ 0 };
503 
504  BufferState& operator=(const BufferState& other) = delete;
505  void reset() {
506  gpu::reset(buffer);
507  offset = 0;
508  size = 0;
509  }
510  bool compare(const BufferPointer& buffer, GLintptr offset, GLsizeiptr size) {
511  const auto& self = *this;
512  return (self.offset == offset && self.size == size && gpu::compare(self.buffer, buffer));
513  }
514  };
515 
516  // MAX_NUM_UNIFORM_BUFFERS-1 is the max uniform index BATCHES are allowed to set, but
517  // MIN_REQUIRED_UNIFORM_BUFFER_BINDINGS is used here because the backend sets some
518  // internal UBOs for things like camera correction
519  std::array<BufferState, MIN_REQUIRED_UNIFORM_BUFFER_BINDINGS> _buffers;
520  } _uniform;
521 
522  // Helper function that provides common code
523  void bindUniformBuffer(uint32_t slot, const BufferPointer& buffer, GLintptr offset = 0, GLsizeiptr size = 0);
524  void releaseUniformBuffer(uint32_t slot);
525  void resetUniformStage();
526 
527  // update resource cache and do the gl bind/unbind call with the current gpu::Buffer cached at slot s
528  // This is using different gl object depending on the gl version
529  virtual bool bindResourceBuffer(uint32_t slot, const BufferPointer& buffer) = 0;
530  virtual void releaseResourceBuffer(uint32_t slot) = 0;
531 
532  // Helper function that provides common code used by do_setResourceTexture and
533  // do_setResourceTextureTable (in non-bindless mode)
534  void bindResourceTexture(uint32_t slot, const TexturePointer& texture, const Sampler& sampler);
535 
536  // update resource cache and do the gl unbind call with the current gpu::Texture cached at slot s
537  void releaseResourceTexture(uint32_t slot);
538 
539  void resetResourceStage();
540 
541  struct ResourceStageState {
542  struct TextureState {
543  TextureReference _texture {};
544  Sampler _sampler {};
545  GLenum _target;
546  };
547  std::array<BufferReference, MAX_NUM_RESOURCE_BUFFERS> _buffers{};
548  std::array<TextureState, MAX_NUM_RESOURCE_TEXTURES> _textures{};
549  int findEmptyTextureSlot() const;
550  } _resource;
551 
552  size_t _commandIndex{ 0 };
553 
554  // Standard update pipeline check that the current Program and current State or good to go for a
555  void updatePipeline();
556  // Force to reset all the state fields indicated by the 'toBeReset" signature
557  void resetPipelineState(State::Signature toBeReset);
558  // Synchronize the state cache of this Backend with the actual real state of the GL Context
559  void syncPipelineStateCache();
560  void resetPipelineStage();
561 
562  struct PipelineStageState {
563  PipelineReference _pipeline{};
564 
565  GLuint _program{ 0 };
566  GLShader* _programShader { nullptr };
567  bool _invalidProgram { false };
568 
569  State::Data _stateCache { State::DEFAULT };
570  State::Signature _stateSignatureCache { 0 };
571 
572  GLState* _state { nullptr };
573  bool _invalidState { false };
574 
575  PipelineStageState() {}
576  } _pipeline;
577 
578  // Backend dependent compilation of the shader
579  virtual void postLinkProgram(ShaderObject& programObject, const Shader& program) const;
580  virtual GLShader* compileBackendProgram(const Shader& program, const Shader::CompilationHandler& handler);
581  virtual GLShader* compileBackendShader(const Shader& shader, const Shader::CompilationHandler& handler);
582 
583  // For a program, this will return a string containing all the source files (without any
584  // backend headers or defines). For a vertex, fragment or geometry shader, this will
585  // return the fully customized shader with all the version and backend specific
586  // preprocessor directives
587  // The program string returned can be used as a key for a cache of shader binaries
588  // The shader strings can be reliably sent to the low level `compileShader` functions
589  virtual std::string getShaderSource(const Shader& shader, shader::Variant version) final;
590  shader::Variant getShaderVariant() const { return isStereo() ? shader::Variant::Stereo : shader::Variant::Mono; }
591  virtual shader::Dialect getShaderDialect() const = 0;
592 
593  class ElementResource {
594  public:
595  gpu::Element _element;
596  uint16 _resource;
597  ElementResource(Element&& elem, uint16 resource) : _element(elem), _resource(resource) {}
598  };
599  ElementResource getFormatFromGLUniform(GLenum gltype);
600 
601  // Synchronize the state cache of this Backend with the actual real state of the GL Context
602  void syncOutputStateCache();
603  void resetOutputStage();
604 
605  struct OutputStageState {
606  FramebufferReference _framebuffer{};
607  GLuint _drawFBO{ 0 };
608  } _output;
609 
610  void resetQueryStage();
611  struct QueryStageState {
612  uint32_t _rangeQueryDepth{ 0 };
613  } _queryStage;
614 
615  void resetStages();
616 
617  // Stores cached binary versions of the shaders for quicker startup on subsequent runs
618  // Note that shaders in the cache can still fail to load due to hardware or driver
619  // changes that invalidate the cached binary, in which case we fall back on compiling
620  // the source again
621  struct ShaderBinaryCache {
622  std::mutex _mutex;
623  std::vector<GLint> _formats;
624  std::unordered_map<std::string, ::gl::CachedShader> _binaries;
625  } _shaderBinaryCache;
626 
627  virtual void initShaderBinaryCache();
628  virtual void killShaderBinaryCache();
629 
630  struct TextureManagementStageState {
631  bool _sparseCapable{ false };
632  GLTextureTransferEnginePointer _transferEngine;
633  } _textureManagement;
634  virtual void initTextureManagementStage();
635  virtual void killTextureManagementStage();
636 
637  GLuint _mipGenerationFramebufferId{ 0 };
638 
639  typedef void (GLBackend::*CommandCall)(const Batch&, size_t);
640  static CommandCall _commandCalls[Batch::NUM_COMMANDS];
641  friend class GLState;
642  friend class GLTexture;
643  friend class GLShader;
644  friend class GLPipeline;
645 };
646 
647 }} // namespace gpu::gl
648 
649 #endif
Provides the Mat4 scripting interface.
Definition: Mat4.h:44
@ Unknown
Socket type unknown or not set.