12 #ifndef hifi_gpu_gl_GLBackend_h
13 #define hifi_gpu_gl_GLBackend_h
24 #include <QtCore/QLoggingCategory>
26 #include <gl/Config.h>
27 #include <gl/GLShaders.h>
29 #include <gpu/Forward.h>
30 #include <gpu/Backend.h>
36 #if defined(USE_GLES) && !defined(HAVE_EXT_clip_cull_distance)
37 #define GPU_STEREO_TECHNIQUE_DOUBLED_SIMPLE
40 #define GPU_STEREO_TECHNIQUE_INSTANCED
44 #ifdef GPU_STEREO_TECHNIQUE_DOUBLED_SIMPLE
45 #define GPU_STEREO_DRAWCALL_DOUBLED
48 #ifdef GPU_STEREO_TECHNIQUE_DOUBLED_SMARTER
49 #define GPU_STEREO_DRAWCALL_DOUBLED
50 #define GPU_STEREO_CAMERA_BUFFER
53 #ifdef GPU_STEREO_TECHNIQUE_INSTANCED
54 #define GPU_STEREO_DRAWCALL_INSTANCED
55 #define GPU_STEREO_CAMERA_BUFFER
58 namespace gpu {
namespace gl {
60 class GLBackend :
public Backend,
public std::enable_shared_from_this<GLBackend> {
62 friend class gpu::Context;
64 static BackendPointer createBackend();
67 explicit GLBackend(
bool syncCache);
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;
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;
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;
106 static size_t _totalMemory;
107 static size_t _dedicatedMemory;
108 static VideoCardType _videoCard;
111 static size_t getTotalMemory() {
return _totalMemory; }
112 static size_t getDedicatedMemory() {
return _dedicatedMemory; }
114 static size_t getAvailableMemory();
115 static bool availableMemoryKnown();
120 virtual ~GLBackend();
123 void shutdown()
override;
125 void updatePresentFrame(
const Mat4& correction =
Mat4(),
bool primary =
true)
override;
127 void executeFrame(
const FramePointer& frame)
override;
128 void render(
const Batch& batch)
final override;
134 void syncCache() final override;
136 void syncProgram(const gpu::ShaderPointer& program) override;
140 virtual
void downloadFramebuffer(const FramebufferPointer& srcFramebuffer,
142 QImage& destImage) final override;
145 size_t getNumInputBuffers()
const {
return _input._invalidBuffers.size(); }
149 static const int MAX_NUM_UNIFORM_BUFFERS = 14;
150 size_t getMaxNumUniformBuffers()
const {
return MAX_NUM_UNIFORM_BUFFERS; }
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; }
160 static const int MAX_NUM_RESOURCE_TABLE_TEXTURES = 2;
161 size_t getMaxNumResourceTextureTables()
const {
return MAX_NUM_RESOURCE_TABLE_TEXTURES; }
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;
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;
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;
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;
194 virtual void do_setUniformBuffer(
const Batch& batch,
size_t paramOffset)
final;
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;
203 virtual void do_setPipeline(
const Batch& batch,
size_t paramOffset)
final;
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;
211 virtual void do_advance(
const Batch& batch,
size_t paramOffset)
final;
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;
219 virtual void do_resetStages(
const Batch& batch,
size_t paramOffset)
final;
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;
225 virtual void do_disableContextStereo(
const Batch& batch,
size_t paramOffset)
final;
226 virtual void do_restoreContextStereo(
const Batch& batch,
size_t paramOffset)
final;
228 virtual void do_runLambda(
const Batch& batch,
size_t paramOffset)
final;
230 virtual void do_startNamedCall(
const Batch& batch,
size_t paramOffset)
final;
231 virtual void do_stopNamedCall(
const Batch& batch,
size_t paramOffset)
final;
233 static const int MAX_NUM_ATTRIBUTES = Stream::NUM_INPUT_SLOTS;
235 static const int MAX_NUM_INPUT_BUFFERS = Stream::DRAW_CALL_INFO;
237 virtual void do_pushProfileRange(
const Batch& batch,
size_t paramOffset)
final;
238 virtual void do_popProfileRange(
const Batch& batch,
size_t paramOffset)
final;
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;
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;
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;
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;
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;
295 bool isTextureManagementSparseEnabled()
const override {
296 return (_textureManagement._sparseCapable && Texture::getEnableSparseTextures());
300 virtual GLint getRealUniformLocation(GLint location)
const;
302 virtual void draw(GLenum mode, uint32 numVertices, uint32 startVertex) = 0;
304 void recycle()
const override;
308 virtual bool supportsBindless()
const {
return false; }
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 };
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;
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);
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;
344 void renderPassTransfer(
const Batch& batch);
345 void renderPassDraw(
const Batch& batch);
347 #ifdef GPU_STEREO_DRAWCALL_DOUBLED
348 void setupStereoSide(
int side);
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;
359 struct InputStageState {
360 bool _invalidFormat {
true };
361 bool _lastUpdateStereoState {
false };
362 FormatReference _format { GPU_REFERENCE_INIT_VALUE };
363 std::string _formatKey;
365 typedef std::bitset<MAX_NUM_ATTRIBUTES> ActivationCache;
366 ActivationCache _attributeActivation { 0 };
368 typedef std::bitset<MAX_NUM_INPUT_BUFFERS> BuffersState;
370 BuffersState _invalidBuffers { 0 };
371 BuffersState _attribBindingBuffers { 0 };
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;
378 BufferReference _indexBuffer;
379 Offset _indexBufferOffset { 0 };
380 Type _indexBufferType { UINT32 };
382 BufferReference _indirectBuffer;
383 Offset _indirectBufferOffset { 0 };
384 Offset _indirectBufferStride { 0 };
386 GLuint _defaultVAO { 0 };
389 virtual void initTransform() = 0;
390 void killTransform();
392 void syncTransformStateCache();
393 virtual void updateTransform(
const Batch& batch) = 0;
394 virtual void resetTransformStage();
400 struct PresentFrame {
402 mat4 correctionInverse;
404 mat4 unflippedCorrection;
405 mat4 flippedCorrection;
406 bool mirrorViewCorrection {
false };
409 struct TransformStageState {
410 #ifdef GPU_STEREO_CAMERA_BUFFER
412 TransformCamera _cams[2];
415 Cameras(
const TransformCamera& cam) { _cams[0] = cam; };
416 Cameras(
const TransformCamera& camL,
const TransformCamera& camR) {
422 using CameraBufferElement = Cameras;
424 using CameraBufferElement = TransformCamera;
426 using TransformCameras = std::vector<CameraBufferElement>;
428 struct ViewProjectionState {
430 Transform _correctedView;
431 Transform _previousCorrectedView;
433 Mat4 _previousProjection;
436 void copyExceptPrevious(
const ViewProjectionState& other) {
438 _correctedView = other._correctedView;
439 _projection = other._projection;
440 _viewIsCamera = other._viewIsCamera;
444 struct SaveTransform {
445 ViewProjectionState _state;
446 size_t _cameraOffset { INVALID_OFFSET };
449 TransformCamera _camera;
450 TransformCameras _cameras;
451 std::array<SaveTransform, gpu::Batch::MAX_TRANSFORM_SAVE_SLOT_COUNT> _savedTransforms;
453 mutable std::map<std::string, GLvoid*> _drawCallInfoOffsets;
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 };
467 std::vector<Vec2> _offsetSequence;
468 Vec2 _offset { 0.0f };
469 float _scale { 0.f };
470 unsigned int _currentSampleIndex { 0 };
471 bool _isEnabled {
false };
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 };
481 bool _enabledDrawcallInfoBuffer {
false };
483 using Pair = std::pair<size_t, size_t>;
484 using List = std::list<Pair>;
486 mutable List::const_iterator _camerasItr;
487 mutable size_t _currentCameraOffset{ INVALID_OFFSET };
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;
495 void preUpdateTransform();
496 virtual void transferTransformState(
const Batch& batch)
const = 0;
498 struct UniformStageState {
500 BufferReference buffer{};
501 GLintptr offset{ 0 };
502 GLsizeiptr size{ 0 };
504 BufferState& operator=(
const BufferState& other) =
delete;
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));
519 std::array<BufferState, MIN_REQUIRED_UNIFORM_BUFFER_BINDINGS> _buffers;
523 void bindUniformBuffer(uint32_t slot,
const BufferPointer& buffer, GLintptr offset = 0, GLsizeiptr size = 0);
524 void releaseUniformBuffer(uint32_t slot);
525 void resetUniformStage();
529 virtual bool bindResourceBuffer(uint32_t slot,
const BufferPointer& buffer) = 0;
530 virtual void releaseResourceBuffer(uint32_t slot) = 0;
534 void bindResourceTexture(uint32_t slot,
const TexturePointer& texture,
const Sampler& sampler);
537 void releaseResourceTexture(uint32_t slot);
539 void resetResourceStage();
541 struct ResourceStageState {
542 struct TextureState {
543 TextureReference _texture {};
547 std::array<BufferReference, MAX_NUM_RESOURCE_BUFFERS> _buffers{};
548 std::array<TextureState, MAX_NUM_RESOURCE_TEXTURES> _textures{};
549 int findEmptyTextureSlot()
const;
552 size_t _commandIndex{ 0 };
555 void updatePipeline();
557 void resetPipelineState(State::Signature toBeReset);
559 void syncPipelineStateCache();
560 void resetPipelineStage();
562 struct PipelineStageState {
563 PipelineReference _pipeline{};
565 GLuint _program{ 0 };
566 GLShader* _programShader {
nullptr };
567 bool _invalidProgram {
false };
569 State::Data _stateCache { State::DEFAULT };
570 State::Signature _stateSignatureCache { 0 };
572 GLState* _state {
nullptr };
573 bool _invalidState {
false };
575 PipelineStageState() {}
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);
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;
593 class ElementResource {
595 gpu::Element _element;
597 ElementResource(Element&& elem, uint16 resource) : _element(elem), _resource(resource) {}
599 ElementResource getFormatFromGLUniform(GLenum gltype);
602 void syncOutputStateCache();
603 void resetOutputStage();
605 struct OutputStageState {
606 FramebufferReference _framebuffer{};
607 GLuint _drawFBO{ 0 };
610 void resetQueryStage();
611 struct QueryStageState {
612 uint32_t _rangeQueryDepth{ 0 };
621 struct ShaderBinaryCache {
623 std::vector<GLint> _formats;
624 std::unordered_map<std::string, ::gl::CachedShader> _binaries;
625 } _shaderBinaryCache;
627 virtual void initShaderBinaryCache();
628 virtual void killShaderBinaryCache();
630 struct TextureManagementStageState {
631 bool _sparseCapable{
false };
632 GLTextureTransferEnginePointer _transferEngine;
633 } _textureManagement;
634 virtual void initTextureManagementStage();
635 virtual void killTextureManagementStage();
637 GLuint _mipGenerationFramebufferId{ 0 };
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;
Provides the Mat4 scripting interface.
Definition: Mat4.h:44
@ Unknown
Socket type unknown or not set.