11 #ifndef hifi_gpu_gl_GLBackend_h
12 #define hifi_gpu_gl_GLBackend_h
23 #include <QtCore/QLoggingCategory>
25 #include <gl/Config.h>
26 #include <gl/GLShaders.h>
28 #include <gpu/Forward.h>
29 #include <gpu/Context.h>
35 #if defined(USE_GLES) && !defined(HAVE_EXT_clip_cull_distance)
36 #define GPU_STEREO_TECHNIQUE_DOUBLED_SIMPLE
39 #define GPU_STEREO_TECHNIQUE_INSTANCED
43 #ifdef GPU_STEREO_TECHNIQUE_DOUBLED_SIMPLE
44 #define GPU_STEREO_DRAWCALL_DOUBLED
47 #ifdef GPU_STEREO_TECHNIQUE_DOUBLED_SMARTER
48 #define GPU_STEREO_DRAWCALL_DOUBLED
49 #define GPU_STEREO_CAMERA_BUFFER
52 #ifdef GPU_STEREO_TECHNIQUE_INSTANCED
53 #define GPU_STEREO_DRAWCALL_INSTANCED
54 #define GPU_STEREO_CAMERA_BUFFER
57 namespace gpu {
namespace gl {
59 class GLBackend :
public Backend,
public std::enable_shared_from_this<GLBackend> {
61 friend class gpu::Context;
63 static BackendPointer createBackend();
66 explicit GLBackend(
bool syncCache);
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;
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;
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;
105 static size_t _totalMemory;
106 static size_t _dedicatedMemory;
107 static VideoCardType _videoCard;
110 static size_t getTotalMemory() {
return _totalMemory; }
111 static size_t getDedicatedMemory() {
return _dedicatedMemory; }
113 static size_t getAvailableMemory();
114 static bool availableMemoryKnown();
119 virtual ~GLBackend();
122 void shutdown()
override;
124 void setCameraCorrection(
const Mat4& correction,
const Mat4& prevRenderView,
bool reset =
false)
override;
125 void render(
const Batch& batch)
final override;
131 void syncCache() final override;
133 void syncProgram(const gpu::ShaderPointer& program) override;
137 virtual
void downloadFramebuffer(const FramebufferPointer& srcFramebuffer,
139 QImage& destImage) final override;
142 size_t getNumInputBuffers()
const {
return _input._invalidBuffers.size(); }
146 static const int MAX_NUM_UNIFORM_BUFFERS = 14;
147 size_t getMaxNumUniformBuffers()
const {
return MAX_NUM_UNIFORM_BUFFERS; }
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; }
157 static const int MAX_NUM_RESOURCE_TABLE_TEXTURES = 2;
158 size_t getMaxNumResourceTextureTables()
const {
return MAX_NUM_RESOURCE_TABLE_TEXTURES; }
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;
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;
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;
185 virtual void do_setUniformBuffer(
const Batch& batch,
size_t paramOffset)
final;
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;
194 virtual void do_setPipeline(
const Batch& batch,
size_t paramOffset)
final;
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;
202 virtual void do_advance(
const Batch& batch,
size_t paramOffset)
final;
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;
210 virtual void do_resetStages(
const Batch& batch,
size_t paramOffset)
final;
212 virtual void do_disableContextViewCorrection(
const Batch& batch,
size_t paramOffset)
final;
213 virtual void do_restoreContextViewCorrection(
const Batch& batch,
size_t paramOffset)
final;
215 virtual void do_disableContextStereo(
const Batch& batch,
size_t paramOffset)
final;
216 virtual void do_restoreContextStereo(
const Batch& batch,
size_t paramOffset)
final;
218 virtual void do_runLambda(
const Batch& batch,
size_t paramOffset)
final;
220 virtual void do_startNamedCall(
const Batch& batch,
size_t paramOffset)
final;
221 virtual void do_stopNamedCall(
const Batch& batch,
size_t paramOffset)
final;
223 static const int MAX_NUM_ATTRIBUTES = Stream::NUM_INPUT_SLOTS;
225 static const int MAX_NUM_INPUT_BUFFERS = Stream::DRAW_CALL_INFO;
227 virtual void do_pushProfileRange(
const Batch& batch,
size_t paramOffset)
final;
228 virtual void do_popProfileRange(
const Batch& batch,
size_t paramOffset)
final;
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;
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;
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;
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;
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;
285 bool isTextureManagementSparseEnabled()
const override {
286 return (_textureManagement._sparseCapable && Texture::getEnableSparseTextures());
290 virtual GLint getRealUniformLocation(GLint location)
const;
292 virtual void draw(GLenum mode, uint32 numVertices, uint32 startVertex) = 0;
294 void recycle()
const override;
298 virtual bool supportsBindless()
const {
return false; }
300 static const size_t INVALID_OFFSET = (size_t)-1;
301 bool _inRenderTransferPass{
false };
302 int _currentDraw{ -1 };
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;
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);
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;
333 void renderPassTransfer(
const Batch& batch);
334 void renderPassDraw(
const Batch& batch);
336 #ifdef GPU_STEREO_DRAWCALL_DOUBLED
337 void setupStereoSide(
int side);
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;
348 struct InputStageState {
349 bool _invalidFormat {
true };
350 bool _lastUpdateStereoState {
false };
351 FormatReference _format { GPU_REFERENCE_INIT_VALUE };
352 std::string _formatKey;
354 typedef std::bitset<MAX_NUM_ATTRIBUTES> ActivationCache;
355 ActivationCache _attributeActivation { 0 };
357 typedef std::bitset<MAX_NUM_INPUT_BUFFERS> BuffersState;
359 BuffersState _invalidBuffers { 0 };
360 BuffersState _attribBindingBuffers { 0 };
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;
367 BufferReference _indexBuffer;
368 Offset _indexBufferOffset { 0 };
369 Type _indexBufferType { UINT32 };
371 BufferReference _indirectBuffer;
372 Offset _indirectBufferOffset { 0 };
373 Offset _indirectBufferStride { 0 };
375 GLuint _defaultVAO { 0 };
378 virtual void initTransform() = 0;
379 void killTransform();
381 void syncTransformStateCache();
382 virtual void updateTransform(
const Batch& batch) = 0;
383 virtual void resetTransformStage();
389 struct CameraCorrection {
391 mat4 correctionInverse;
393 mat4 prevViewInverse;
396 struct TransformStageState {
397 #ifdef GPU_STEREO_CAMERA_BUFFER
399 TransformCamera _cams[2];
402 Cameras(
const TransformCamera& cam) { _cams[0] = cam; };
403 Cameras(
const TransformCamera& camL,
const TransformCamera& camR) {
409 using CameraBufferElement = Cameras;
411 using CameraBufferElement = TransformCamera;
413 using TransformCameras = std::vector<CameraBufferElement>;
415 TransformCamera _camera;
416 TransformCameras _cameras;
418 mutable std::map<std::string, GLvoid*> _drawCallInfoOffsets;
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 };
428 CameraCorrection _correction;
429 bool _viewCorrectionEnabled{
true };
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 };
439 bool _enabledDrawcallInfoBuffer{
false };
441 using Pair = std::pair<size_t, size_t>;
442 using List = std::list<Pair>;
444 mutable List::const_iterator _camerasItr;
445 mutable size_t _currentCameraOffset{ INVALID_OFFSET };
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;
452 virtual void transferTransformState(
const Batch& batch)
const = 0;
454 struct UniformStageState {
456 BufferReference buffer{};
457 GLintptr offset{ 0 };
458 GLsizeiptr size{ 0 };
460 BufferState& operator=(
const BufferState& other) =
delete;
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));
475 std::array<BufferState, MIN_REQUIRED_UNIFORM_BUFFER_BINDINGS> _buffers;
479 void bindUniformBuffer(uint32_t slot,
const BufferPointer& buffer, GLintptr offset = 0, GLsizeiptr size = 0);
480 void releaseUniformBuffer(uint32_t slot);
481 void resetUniformStage();
485 virtual bool bindResourceBuffer(uint32_t slot,
const BufferPointer& buffer) = 0;
486 virtual void releaseResourceBuffer(uint32_t slot) = 0;
490 void bindResourceTexture(uint32_t slot,
const TexturePointer& texture);
493 void releaseResourceTexture(uint32_t slot);
495 void resetResourceStage();
497 struct ResourceStageState {
498 struct TextureState {
499 TextureReference _texture{};
502 std::array<BufferReference, MAX_NUM_RESOURCE_BUFFERS> _buffers{};
503 std::array<TextureState, MAX_NUM_RESOURCE_TEXTURES> _textures{};
504 int findEmptyTextureSlot()
const;
507 size_t _commandIndex{ 0 };
510 void updatePipeline();
512 void resetPipelineState(State::Signature toBeReset);
514 void syncPipelineStateCache();
515 void resetPipelineStage();
517 struct PipelineStageState {
518 PipelineReference _pipeline{};
520 GLuint _program{ 0 };
521 bool _cameraCorrection{
false };
522 GLShader* _programShader{
nullptr };
523 bool _invalidProgram{
false };
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)) };
529 State::Data _stateCache{ State::DEFAULT };
530 State::Signature _stateSignatureCache{ 0 };
532 GLState* _state{
nullptr };
533 bool _invalidState{
false };
535 PipelineStageState() {
536 _cameraCorrectionBuffer.edit<CameraCorrection>() = CameraCorrection();
537 _cameraCorrectionBufferIdentity.edit<CameraCorrection>() = CameraCorrection();
538 _cameraCorrectionBufferIdentity._buffer->flush();
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);
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;
557 class ElementResource {
559 gpu::Element _element;
561 ElementResource(Element&& elem, uint16 resource) : _element(elem), _resource(resource) {}
563 ElementResource getFormatFromGLUniform(GLenum gltype);
566 void syncOutputStateCache();
567 void resetOutputStage();
569 struct OutputStageState {
570 FramebufferReference _framebuffer{};
571 GLuint _drawFBO{ 0 };
574 void resetQueryStage();
575 struct QueryStageState {
576 uint32_t _rangeQueryDepth{ 0 };
585 struct ShaderBinaryCache {
587 std::vector<GLint> _formats;
588 std::unordered_map<std::string, ::gl::CachedShader> _binaries;
589 } _shaderBinaryCache;
591 virtual void initShaderBinaryCache();
592 virtual void killShaderBinaryCache();
594 struct TextureManagementStageState {
595 bool _sparseCapable{
false };
596 GLTextureTransferEnginePointer _transferEngine;
597 } _textureManagement;
598 virtual void initTextureManagementStage();
599 virtual void killTextureManagementStage();
601 GLuint _mipGenerationFramebufferId{ 0 };
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;
Provides the Mat4 scripting interface.
Definition: Mat4.h:44
@ Unknown
Socket type unknown or not set.