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