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