Overte C++ Documentation
GL45Backend.h
1 //
2 // GL45Backend.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 #pragma once
13 #ifndef hifi_gpu_45_GL45Backend_h
14 #define hifi_gpu_45_GL45Backend_h
15 
16 #include <gpu/gl/GLBackend.h>
17 #include <gpu/gl/GLTexture.h>
18 
19 #include <thread>
20 #include <gpu/TextureTable.h>
21 
22 #define INCREMENTAL_TRANSFER 0
23 #define GPU_SSBO_TRANSFORM_OBJECT 1
24 #define GPU_BINDLESS_TEXTURES 0
25 
26 namespace gpu { namespace gl45 {
27 
28 using namespace gpu::gl;
29 using TextureWeakPointer = std::weak_ptr<Texture>;
30 
31 class GL45Backend : public GLBackend {
32  using Parent = GLBackend;
33  // Context Backend static interface required
34  friend class Context;
35 
36 public:
37  static const GLint RESOURCE_TRANSFER_TEX_UNIT { 32 };
38  static GLint MAX_COMBINED_SHADER_STORAGE_BLOCKS;
39  static GLint MAX_UNIFORM_LOCATIONS;
40 #if GPU_BINDLESS_TEXTURES
41  virtual bool supportsBindless() const override { return true; }
42 #endif
43 
44  explicit GL45Backend(bool syncCache);
45  GL45Backend();
46  virtual ~GL45Backend() {
47  // call resetStages here rather than in ~GLBackend dtor because it will call releaseResourceBuffer
48  // which is pure virtual from GLBackend's dtor.
49  resetStages();
50  }
51 
52  static const std::string GL45_VERSION;
53  const std::string& getVersion() const override { return GL45_VERSION; }
54 
55  bool supportedTextureFormat(const gpu::Element& format) const override;
56 
57  class GL45Texture : public GLTexture {
58  using Parent = GLTexture;
59  friend class GL45Backend;
60  static GLuint allocate(const Texture& texture);
61 
62  protected:
63  GL45Texture(const std::weak_ptr<GLBackend>& backend, const Texture& texture);
64  void generateMips() const override;
65  Size copyMipFaceLinesFromTexture(uint16_t mip, uint8_t face, const uvec3& size, uint32_t yOffset, GLenum internalFormat, GLenum format, GLenum type, Size sourceSize, const void* sourcePointer) const override;
66  void syncSampler(const Sampler& sampler) const override;
67 
68 #if GPU_BINDLESS_TEXTURES
69  bool isBindless() const {
70  return _bindless.operator bool();
71  }
72 
73  struct Bindless {
74  uint64_t handle{ 0 };
75  uint32_t minMip{ 0 };
76  uint32_t sampler{ 0 };
77 
78  bool operator==(const Bindless& other) const {
79  return handle == other.handle && minMip == other.minMip && sampler == other.sampler;
80  }
81 
82  bool operator!=(const Bindless& other) const {
83  return !(*this == other);
84  }
85 
86  operator bool() const {
87  return handle != 0;
88  }
89  };
90 
91  virtual const Bindless& getBindless() const;
92  void releaseBindless() const;
93  void recreateBindless() const;
94 
95  private:
96  mutable Bindless _bindless;
97 #endif
98 
99  static Sampler getInvalidSampler();
100 
101  // This stores the texture handle (64 bits) in xy, the min mip available in z, and the sampler ID in w
102  mutable Sampler _cachedSampler { getInvalidSampler() };
103  };
104 
105 #if GPU_BINDLESS_TEXTURES
106  class GL45TextureTable : public GLObject<TextureTable> {
107  static GLuint allocate();
108  using Parent = GLObject<TextureTable>;
109 
110  public:
111  using BindlessArray = std::array<GL45Texture::Bindless, TextureTable::COUNT>;
112 
113  GL45TextureTable(const std::weak_ptr<GLBackend>& backend, const TextureTable& texture);
114  ~GL45TextureTable();
115 
116  void update(const BindlessArray& newHandles);
117 
118  // FIXME instead of making a buffer for each table, there should be a global buffer of all materials
119  // and we should store an offset into that buffer
120  BindlessArray _handles;
121  };
122 #endif
123 
124  //
125  // Textures that have fixed allocation sizes and cannot be managed at runtime
126  //
127 
128  class GL45FixedAllocationTexture : public GL45Texture {
129  using Parent = GL45Texture;
130  friend class GL45Backend;
131 
132  public:
133  GL45FixedAllocationTexture(const std::weak_ptr<GLBackend>& backend, const Texture& texture);
134  ~GL45FixedAllocationTexture();
135 
136  protected:
137  Size size() const override { return _size; }
138 
139  void allocateStorage() const;
140  void syncSampler(const Sampler& sampler) const override;
141  const Size _size{ 0 };
142  };
143 
144  class GL45AttachmentTexture : public GL45FixedAllocationTexture {
145  using Parent = GL45FixedAllocationTexture;
146  friend class GL45Backend;
147 
148  protected:
149  GL45AttachmentTexture(const std::weak_ptr<GLBackend>& backend, const Texture& texture);
150  ~GL45AttachmentTexture();
151  };
152 
153  class GL45StrictResourceTexture : public GL45FixedAllocationTexture {
154  using Parent = GL45FixedAllocationTexture;
155  friend class GL45Backend;
156 
157  protected:
158  GL45StrictResourceTexture(const std::weak_ptr<GLBackend>& backend, const Texture& texture);
159  ~GL45StrictResourceTexture();
160  };
161 
162  //
163  // Textures that can be managed at runtime to increase or decrease their memory load
164  //
165 
166  class GL45VariableAllocationTexture : public GL45Texture, public GLVariableAllocationSupport {
167  using Parent = GL45Texture;
168  friend class GL45Backend;
169  using PromoteLambda = std::function<void()>;
170 
171  protected:
172  GL45VariableAllocationTexture(const std::weak_ptr<GLBackend>& backend, const Texture& texture);
173  ~GL45VariableAllocationTexture();
174 
175  Size size() const override { return _size; }
176 
177  Size copyMipFaceLinesFromTexture(uint16_t mip, uint8_t face, const uvec3& size, uint32_t yOffset, GLenum internalFormat, GLenum format, GLenum type, Size sourceSize, const void* sourcePointer) const override;
178  void copyTextureMipsInGPUMem(GLuint srcId, GLuint destId, uint16_t srcMipOffset, uint16_t destMipOffset, uint16_t populatedMips) override;
179 
180 #if GPU_BINDLESS_TEXTURES
181  virtual const Bindless& getBindless() const override;
182 #endif
183  };
184 
185  class GL45ResourceTexture : public GL45VariableAllocationTexture {
186  using Parent = GL45VariableAllocationTexture;
187  friend class GL45Backend;
188 
189  protected:
190  GL45ResourceTexture(const std::weak_ptr<GLBackend>& backend, const Texture& texture);
191 
192  void syncSampler(const Sampler& sampler) const override;
193  size_t promote() override;
194  size_t demote() override;
195  void populateTransferQueue(TransferQueue& pendingTransfers) override;
196 
197  void allocateStorage(uint16 mip);
198  Size copyMipsFromTexture();
199  };
200 
201 #if 0
202  class GL45SparseResourceTexture : public GL45VariableAllocationTexture {
203  using Parent = GL45VariableAllocationTexture;
204  friend class GL45Backend;
205  using TextureTypeFormat = std::pair<GLenum, GLenum>;
206  using PageDimensions = std::vector<uvec3>;
207  using PageDimensionsMap = std::map<TextureTypeFormat, PageDimensions>;
208  static PageDimensionsMap pageDimensionsByFormat;
209  static Mutex pageDimensionsMutex;
210 
211  static bool isSparseEligible(const Texture& texture);
212  static PageDimensions getPageDimensionsForFormat(const TextureTypeFormat& typeFormat);
213  static PageDimensions getPageDimensionsForFormat(GLenum type, GLenum format);
214  static const uint32_t DEFAULT_PAGE_DIMENSION = 128;
215  static const uint32_t DEFAULT_MAX_SPARSE_LEVEL = 0xFFFF;
216 
217  protected:
218  GL45SparseResourceTexture(const std::weak_ptr<GLBackend>& backend, const Texture& texture);
219  ~GL45SparseResourceTexture();
220  uint32 size() const override { return _allocatedPages * _pageBytes; }
221  void promote() override;
222  void demote() override;
223 
224  private:
225  uvec3 getPageCounts(const uvec3& dimensions) const;
226  uint32_t getPageCount(const uvec3& dimensions) const;
227 
228  uint32_t _allocatedPages { 0 };
229  uint32_t _pageBytes { 0 };
230  uvec3 _pageDimensions { DEFAULT_PAGE_DIMENSION };
231  GLuint _maxSparseLevel { DEFAULT_MAX_SPARSE_LEVEL };
232  };
233 #endif
234 
235 protected:
236 
237  void draw(GLenum mode, uint32 numVertices, uint32 startVertex) override;
238  void recycle() const override;
239 
240  GLuint getFramebufferID(const FramebufferPointer& framebuffer) override;
241  GLFramebuffer* syncGPUObject(const Framebuffer& framebuffer) override;
242 
243  GLuint getBufferID(const Buffer& buffer) override;
244  GLuint getBufferIDUnsynced(const Buffer& buffer) override;
245  GLBuffer* syncGPUObject(const Buffer& buffer) override;
246 
247  GLTexture* syncGPUObject(const TexturePointer& texture) override;
248 
249  GLuint getQueryID(const QueryPointer& query) override;
250  GLQuery* syncGPUObject(const Query& query) override;
251 
252  // Draw Stage
253  void do_draw(const Batch& batch, size_t paramOffset) override;
254  void do_drawIndexed(const Batch& batch, size_t paramOffset) override;
255  void do_drawInstanced(const Batch& batch, size_t paramOffset) override;
256  void do_drawIndexedInstanced(const Batch& batch, size_t paramOffset) override;
257  void do_multiDrawIndirect(const Batch& batch, size_t paramOffset) override;
258  void do_multiDrawIndexedIndirect(const Batch& batch, size_t paramOffset) override;
259 
260  // Input Stage
261  void resetInputStage() override;
262  void updateInput() override;
263 
264  // Synchronize the state cache of this Backend with the actual real state of the GL Context
265  void transferTransformState(const Batch& batch) const override;
266  void initTransform() override;
267  void updateTransform(const Batch& batch) override;
268 
269  // Resource Stage
270  bool bindResourceBuffer(uint32_t slot, const BufferPointer& buffer) override;
271  void releaseResourceBuffer(uint32_t slot) override;
272 
273  void do_copySavedViewProjectionTransformToBuffer(const Batch& batch, size_t paramOffset) override;
274 
275  // Output stage
276  void do_blit(const Batch& batch, size_t paramOffset) override;
277 
278  // Shader Stage
279  shader::Dialect getShaderDialect() const override;
280 
281  // Texture Management Stage
282  void initTextureManagementStage() override;
283 
284 #if GPU_BINDLESS_TEXTURES
285  GL45TextureTable* syncGPUObject(const TextureTablePointer& textureTable);
286  // Resource stage
287  void do_setResourceTextureTable(const Batch& batch, size_t paramOffset) override;
288 #endif
289 };
290 
291 }} // namespace gpu::gl45
292 
293 Q_DECLARE_LOGGING_CATEGORY(gpugl45logging)
294 
295 #endif