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>
31 #include <shared/GlobalAppProperties.h>
37 #if !defined(HAVE_EXT_clip_cull_distance)
38 #define GPU_STEREO_TECHNIQUE_DOUBLED_SIMPLE
41 #define GPU_STEREO_TECHNIQUE_INSTANCED
45 #ifdef GPU_STEREO_TECHNIQUE_DOUBLED_SIMPLE
46 #define GPU_STEREO_DRAWCALL_DOUBLED
49 #ifdef GPU_STEREO_TECHNIQUE_DOUBLED_SMARTER
50 #define GPU_STEREO_DRAWCALL_DOUBLED
51 #define GPU_STEREO_CAMERA_BUFFER
54 #ifdef GPU_STEREO_TECHNIQUE_INSTANCED
55 #define GPU_STEREO_DRAWCALL_INSTANCED
56 #define GPU_STEREO_CAMERA_BUFFER
59 namespace gpu {
namespace gl {
61 class GLBackend :
public Backend,
public std::enable_shared_from_this<GLBackend> {
65 static BackendPointer createBackend();
68 explicit GLBackend(
bool syncCache);
79 static GLint MAX_TEXTURE_IMAGE_UNITS;
80 static GLint MAX_UNIFORM_BUFFER_BINDINGS;
81 static GLint MAX_COMBINED_UNIFORM_BLOCKS;
82 static GLint MAX_COMBINED_TEXTURE_IMAGE_UNITS;
83 static GLint MAX_UNIFORM_BLOCK_SIZE;
84 static GLint UNIFORM_BUFFER_OFFSET_ALIGNMENT;
85 static GLint GPU_MEMORY_INFO_DEDICATED_VIDMEM_NVX;
86 static GLint GPU_MEMORY_INFO_TOTAL_AVAILABLE_MEMORY_NVX;
87 static GLint GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX;
88 static GLint TEXTURE_FREE_MEMORY_ATI;
91 static size_t _totalMemory;
92 static size_t _dedicatedMemory;
93 static VideoCardType _videoCard;
96 static size_t getTotalMemory() {
return _totalMemory; }
97 static size_t getDedicatedMemory() {
return _dedicatedMemory; }
99 static size_t getAvailableMemory();
100 static bool availableMemoryKnown();
105 virtual ~GLBackend();
110 void updatePresentFrame(
const Mat4& correction =
Mat4(),
bool primary =
true)
override;
113 void render(
const Batch& batch)
final override;
119 void syncCache() final override;
121 void syncProgram(const gpu::ShaderPointer& program) override;
127 QImage& destImage) final override;
130 size_t getNumInputBuffers()
const {
return _input._invalidBuffers.size(); }
134 static const int MAX_NUM_UNIFORM_BUFFERS = 14;
135 size_t getMaxNumUniformBuffers()
const {
return MAX_NUM_UNIFORM_BUFFERS; }
139 static const int MAX_NUM_RESOURCE_BUFFERS = 16;
140 size_t getMaxNumResourceBuffers()
const {
return MAX_NUM_RESOURCE_BUFFERS; }
141 static const int MAX_NUM_RESOURCE_TEXTURES = 16;
142 size_t getMaxNumResourceTextures()
const {
return MAX_NUM_RESOURCE_TEXTURES; }
145 static const int MAX_NUM_RESOURCE_TABLE_TEXTURES = 2;
146 size_t getMaxNumResourceTextureTables()
const {
return MAX_NUM_RESOURCE_TABLE_TEXTURES; }
149 virtual void do_draw(
const Batch& batch,
size_t paramOffset) = 0;
150 virtual void do_drawIndexed(
const Batch& batch,
size_t paramOffset) = 0;
151 virtual void do_drawInstanced(
const Batch& batch,
size_t paramOffset) = 0;
152 virtual void do_drawIndexedInstanced(
const Batch& batch,
size_t paramOffset) = 0;
153 virtual void do_multiDrawIndirect(
const Batch& batch,
size_t paramOffset) = 0;
154 virtual void do_multiDrawIndexedIndirect(
const Batch& batch,
size_t paramOffset) = 0;
157 virtual void do_setInputFormat(
const Batch& batch,
size_t paramOffset)
final;
158 virtual void do_setInputBuffer(
const Batch& batch,
size_t paramOffset)
final;
159 virtual void do_setIndexBuffer(
const Batch& batch,
size_t paramOffset)
final;
160 virtual void do_setIndirectBuffer(
const Batch& batch,
size_t paramOffset)
final;
161 virtual void do_generateTextureMips(
const Batch& batch,
size_t paramOffset)
final;
162 virtual void do_generateTextureMipsWithPipeline(
const Batch& batch,
size_t paramOffset)
final;
165 virtual void do_setModelTransform(
const Batch& batch,
size_t paramOffset)
final;
166 virtual void do_setViewTransform(
const Batch& batch,
size_t paramOffset)
final;
167 virtual void do_setProjectionTransform(
const Batch& batch,
size_t paramOffset)
final;
168 virtual void do_setProjectionJitterEnabled(
const Batch& batch,
size_t paramOffset)
final;
169 virtual void do_setProjectionJitterSequence(
const Batch& batch,
size_t paramOffset)
final;
170 virtual void do_setProjectionJitterScale(
const Batch& batch,
size_t paramOffset)
final;
171 virtual void do_setViewportTransform(
const Batch& batch,
size_t paramOffset)
final;
172 virtual void do_setDepthRangeTransform(
const Batch& batch,
size_t paramOffset)
final;
174 virtual void do_saveViewProjectionTransform(
const Batch& batch,
size_t paramOffset)
final;
175 virtual void do_setSavedViewProjectionTransform(
const Batch& batch,
size_t paramOffset)
final;
176 virtual void do_copySavedViewProjectionTransformToBuffer(
const Batch& batch,
size_t paramOffset) = 0;
179 virtual void do_setUniformBuffer(
const Batch& batch,
size_t paramOffset)
final;
182 virtual void do_setResourceBuffer(
const Batch& batch,
size_t paramOffset)
final;
183 virtual void do_setResourceTexture(
const Batch& batch,
size_t paramOffset)
final;
184 virtual void do_setResourceTextureTable(
const Batch& batch,
size_t paramOffset);
185 virtual void do_setResourceFramebufferSwapChainTexture(
const Batch& batch,
size_t paramOffset)
final;
188 virtual void do_setPipeline(
const Batch& batch,
size_t paramOffset)
final;
191 virtual void do_setFramebuffer(
const Batch& batch,
size_t paramOffset)
final;
192 virtual void do_setFramebufferSwapChain(
const Batch& batch,
size_t paramOffset)
final;
193 virtual void do_clearFramebuffer(
const Batch& batch,
size_t paramOffset)
final;
194 virtual void do_blit(
const Batch& batch,
size_t paramOffset) = 0;
196 virtual void do_advance(
const Batch& batch,
size_t paramOffset)
final;
199 virtual void do_beginQuery(
const Batch& batch,
size_t paramOffset)
final;
200 virtual void do_endQuery(
const Batch& batch,
size_t paramOffset)
final;
201 virtual void do_getQuery(
const Batch& batch,
size_t paramOffset)
final;
204 virtual void do_resetStages(
const Batch& batch,
size_t paramOffset)
final;
206 virtual void do_disableContextViewCorrection(
const Batch& batch,
size_t paramOffset)
final;
207 virtual void do_restoreContextViewCorrection(
const Batch& batch,
size_t paramOffset)
final;
208 virtual void do_setContextMirrorViewCorrection(
const Batch& batch,
size_t paramOffset)
final;
210 virtual void do_disableContextStereo(
const Batch& batch,
size_t paramOffset)
final;
211 virtual void do_restoreContextStereo(
const Batch& batch,
size_t paramOffset)
final;
213 virtual void do_runLambda(
const Batch& batch,
size_t paramOffset)
final;
215 virtual void do_startNamedCall(
const Batch& batch,
size_t paramOffset)
final;
216 virtual void do_stopNamedCall(
const Batch& batch,
size_t paramOffset)
final;
218 static const int MAX_NUM_ATTRIBUTES = Stream::NUM_INPUT_SLOTS;
220 static const int MAX_NUM_INPUT_BUFFERS = Stream::DRAW_CALL_INFO;
222 virtual void do_pushProfileRange(
const Batch& batch,
size_t paramOffset)
final;
223 virtual void do_popProfileRange(
const Batch& batch,
size_t paramOffset)
final;
228 virtual void do_glUniform1i(
const Batch& batch,
size_t paramOffset)
final;
229 virtual void do_glUniform1f(
const Batch& batch,
size_t paramOffset)
final;
230 virtual void do_glUniform2f(
const Batch& batch,
size_t paramOffset)
final;
231 virtual void do_glUniform3f(
const Batch& batch,
size_t paramOffset)
final;
232 virtual void do_glUniform4f(
const Batch& batch,
size_t paramOffset)
final;
233 virtual void do_glUniform3fv(
const Batch& batch,
size_t paramOffset)
final;
234 virtual void do_glUniform4fv(
const Batch& batch,
size_t paramOffset)
final;
235 virtual void do_glUniform4iv(
const Batch& batch,
size_t paramOffset)
final;
236 virtual void do_glUniformMatrix3fv(
const Batch& batch,
size_t paramOffset)
final;
237 virtual void do_glUniformMatrix4fv(
const Batch& batch,
size_t paramOffset)
final;
240 virtual void do_setStateFillMode(int32 mode)
final;
241 virtual void do_setStateCullMode(int32 mode)
final;
242 virtual void do_setStateFrontFaceClockwise(
bool isClockwise)
final;
243 virtual void do_setStateDepthClampEnable(
bool enable)
final;
244 virtual void do_setStateScissorEnable(
bool enable)
final;
245 virtual void do_setStateMultisampleEnable(
bool enable)
final;
246 virtual void do_setStateAntialiasedLineEnable(
bool enable)
final;
247 virtual void do_setStateDepthBias(Vec2 bias)
final;
248 virtual void do_setStateDepthTest(State::DepthTest test)
final;
249 virtual void do_setStateStencil(State::StencilActivation activation,
250 State::StencilTest frontTest,
251 State::StencilTest backTest)
final;
252 virtual void do_setStateAlphaToCoverageEnable(
bool enable)
final;
253 virtual void do_setStateSampleMask(uint32 mask)
final;
254 virtual void do_setStateBlend(State::BlendFunction blendFunction)
final;
255 virtual void do_setStateColorWriteMask(uint32 mask)
final;
256 virtual void do_setStateBlendFactor(
const Batch& batch,
size_t paramOffset)
final;
257 virtual void do_setStateScissorRect(
const Batch& batch,
size_t paramOffset)
final;
259 virtual GLuint getFramebufferID(
const FramebufferPointer& framebuffer) = 0;
260 virtual GLuint getTextureID(
const TexturePointer& texture)
final;
261 virtual GLuint getBufferID(
const Buffer& buffer) = 0;
262 virtual GLuint getBufferIDUnsynced(
const Buffer& buffer) = 0;
263 virtual GLuint getQueryID(
const QueryPointer& query) = 0;
265 virtual GLFramebuffer* syncGPUObject(
const Framebuffer& framebuffer) = 0;
266 virtual GLBuffer* syncGPUObject(
const Buffer& buffer) = 0;
267 virtual GLTexture* syncGPUObject(
const TexturePointer& texture);
268 virtual GLQuery* syncGPUObject(
const Query& query) = 0;
271 virtual void releaseBuffer(GLuint
id, Size size)
const;
272 virtual void releaseExternalTexture(GLuint
id,
const Texture::ExternalRecycler& recycler)
const;
273 virtual void releaseTexture(GLuint
id, Size size)
const;
274 virtual void releaseFramebuffer(GLuint
id)
const;
275 virtual void releaseShader(GLuint
id)
const;
276 virtual void releaseProgram(GLuint
id)
const;
277 virtual void releaseQuery(GLuint
id)
const;
278 virtual void queueLambda(
const std::function<
void()> lambda)
const;
280 bool isTextureManagementSparseEnabled()
const override {
281 return (_textureManagement._sparseCapable && Texture::getEnableSparseTextures());
285 virtual GLint getRealUniformLocation(GLint location)
const;
287 virtual void draw(GLenum mode, uint32 numVertices, uint32 startVertex) = 0;
293 virtual bool supportsBindless()
const {
return false; }
295 static const size_t INVALID_OFFSET = (size_t)-1;
296 static const uint INVALID_SAVED_CAMERA_SLOT = (uint)-1;
297 bool _inRenderTransferPass {
false };
298 int _currentDraw { -1 };
301 GLsync fence =
nullptr;
302 std::list<std::pair<GLuint, Size>> buffersTrash;
303 std::list<std::pair<GLuint, Size>> texturesTrash;
304 std::list<std::pair<GLuint, Texture::ExternalRecycler>> externalTexturesTrash;
305 std::list<GLuint> framebuffersTrash;
306 std::list<GLuint> shadersTrash;
307 std::list<GLuint> programsTrash;
308 std::list<GLuint> queriesTrash;
310 void swap(FrameTrash& other) {
311 buffersTrash.swap(other.buffersTrash);
312 texturesTrash.swap(other.texturesTrash);
313 externalTexturesTrash.swap(other.externalTexturesTrash);
314 framebuffersTrash.swap(other.framebuffersTrash);
315 shadersTrash.swap(other.shadersTrash);
316 programsTrash.swap(other.programsTrash);
317 queriesTrash.swap(other.queriesTrash);
323 mutable Mutex _trashMutex;
324 mutable FrameTrash _currentFrameTrash;
325 mutable std::list<FrameTrash> _previousFrameTrashes;
326 std::list<std::string> profileRanges;
327 mutable std::list<std::function<void()>> _lambdaQueue;
329 void renderPassTransfer(
const Batch& batch);
330 void renderPassDraw(
const Batch& batch);
332 #ifdef GPU_STEREO_DRAWCALL_DOUBLED
333 void setupStereoSide(
int side);
336 virtual void setResourceTexture(
unsigned int slot,
const TexturePointer& resourceTexture,
const Sampler& sampler);
337 virtual void setFramebuffer(
const FramebufferPointer& framebuffer);
338 virtual void initInput() final;
339 virtual
void killInput() final;
340 virtual
void syncInputStateCache() final;
341 virtual
void resetInputStage();
342 virtual
void updateInput() = 0;
344 struct InputStageState {
345 bool _invalidFormat {
true };
346 bool _lastUpdateStereoState {
false };
347 FormatReference _format { GPU_REFERENCE_INIT_VALUE };
348 std::string _formatKey;
350 typedef std::bitset<MAX_NUM_ATTRIBUTES> ActivationCache;
351 ActivationCache _attributeActivation { 0 };
353 typedef std::bitset<MAX_NUM_INPUT_BUFFERS> BuffersState;
355 BuffersState _invalidBuffers { 0 };
356 BuffersState _attribBindingBuffers { 0 };
358 std::array<BufferReference, MAX_NUM_INPUT_BUFFERS> _buffers;
359 std::array<Offset, MAX_NUM_INPUT_BUFFERS> _bufferOffsets;
360 std::array<Offset, MAX_NUM_INPUT_BUFFERS> _bufferStrides;
361 std::array<GLuint, MAX_NUM_INPUT_BUFFERS> _bufferVBOs;
363 BufferReference _indexBuffer;
364 Offset _indexBufferOffset { 0 };
365 Type _indexBufferType { UINT32 };
367 BufferReference _indirectBuffer;
368 Offset _indirectBufferOffset { 0 };
369 Offset _indirectBufferStride { 0 };
371 GLuint _defaultVAO { 0 };
374 virtual void initTransform() = 0;
375 void killTransform();
377 void syncTransformStateCache();
378 virtual void updateTransform(
const Batch& batch) = 0;
379 virtual void resetTransformStage();
385 struct PresentFrame {
387 mat4 correctionInverse;
389 mat4 unflippedCorrection;
390 mat4 flippedCorrection;
391 bool mirrorViewCorrection {
false };
394 struct TransformStageState {
395 #ifdef GPU_STEREO_CAMERA_BUFFER
397 TransformCamera _cams[2];
400 Cameras(
const TransformCamera& cam) { _cams[0] = cam; };
401 Cameras(
const TransformCamera& camL,
const TransformCamera& camR) {
407 using CameraBufferElement = Cameras;
409 using CameraBufferElement = TransformCamera;
411 using TransformCameras = std::vector<CameraBufferElement>;
413 struct ViewProjectionState {
415 Transform _correctedView;
416 Transform _previousCorrectedView;
418 Mat4 _previousProjection;
421 void copyExceptPrevious(
const ViewProjectionState& other) {
423 _correctedView = other._correctedView;
424 _projection = other._projection;
425 _viewIsCamera = other._viewIsCamera;
429 struct SaveTransform {
430 ViewProjectionState _state;
431 size_t _cameraOffset { INVALID_OFFSET };
434 TransformCamera _camera;
435 TransformCameras _cameras;
436 std::array<SaveTransform, gpu::Batch::MAX_TRANSFORM_SAVE_SLOT_COUNT> _savedTransforms;
438 mutable std::map<std::string, GLvoid*> _drawCallInfoOffsets;
440 GLuint _objectBuffer { 0 };
441 GLuint _cameraBuffer { 0 };
442 GLuint _drawCallInfoBuffer { 0 };
443 GLuint _objectBufferTexture { 0 };
444 size_t _cameraUboSize { 0 };
445 ViewProjectionState _viewProjectionState;
446 uint _currentSavedTransformSlot { INVALID_SAVED_CAMERA_SLOT };
447 bool _skybox {
false };
448 PresentFrame _presentFrame;
449 bool _viewCorrectionEnabled {
true };
452 std::vector<Vec2> _offsetSequence;
453 Vec2 _offset { 0.0f };
454 float _scale { 0.f };
455 unsigned int _currentSampleIndex { 0 };
456 bool _isEnabled {
false };
459 Jitter _projectionJitter;
460 Vec4i _viewport { 0, 0, 1, 1 };
461 Vec2 _depthRange { 0.0f, 1.0f };
462 bool _invalidView {
false };
463 bool _invalidProj {
false };
464 bool _invalidViewport {
false };
466 bool _enabledDrawcallInfoBuffer {
false };
468 using Pair = std::pair<size_t, size_t>;
469 using List = std::list<Pair>;
471 mutable List::const_iterator _camerasItr;
472 mutable size_t _currentCameraOffset{ INVALID_OFFSET };
474 void pushCameraBufferElement(
const StereoState& stereo,
const StereoState& prevStereo, TransformCameras& cameras)
const;
475 void preUpdate(
size_t commandIndex,
const StereoState& stereo,
const StereoState& prevStereo);
476 void update(
size_t commandIndex,
const StereoState& stereo)
const;
477 void bindCurrentCamera(
int stereoSide)
const;
480 void preUpdateTransform();
481 virtual void transferTransformState(
const Batch& batch)
const = 0;
483 struct UniformStageState {
484 UniformStageState() {
488 size_t minRequiredUniformBufferBindings = 0;
489 auto backendApi = hifi::properties::getGraphicsAPI();
490 if (backendApi == hifi::properties::GraphicsAPI::GLES32) {
492 minRequiredUniformBufferBindings = 72;
495 minRequiredUniformBufferBindings = 36;
497 _buffers.resize(minRequiredUniformBufferBindings);
501 BufferReference buffer{};
502 GLintptr offset{ 0 };
503 GLsizeiptr size{ 0 };
505 BufferState& operator=(
const BufferState& other) =
delete;
511 bool compare(
const BufferPointer& buffer, GLintptr offset, GLsizeiptr size) {
512 const auto&
self = *
this;
513 return (
self.offset == offset &&
self.size == size && gpu::compare(
self.buffer, buffer));
517 std::vector<BufferState> _buffers;
521 void bindUniformBuffer(uint32_t slot,
const BufferPointer& buffer, GLintptr offset = 0, GLsizeiptr size = 0);
522 void releaseUniformBuffer(uint32_t slot);
523 void resetUniformStage();
527 virtual bool bindResourceBuffer(uint32_t slot,
const BufferPointer& buffer) = 0;
528 virtual void releaseResourceBuffer(uint32_t slot) = 0;
532 void bindResourceTexture(uint32_t slot,
const TexturePointer& texture,
const Sampler& sampler);
535 void releaseResourceTexture(uint32_t slot);
537 void resetResourceStage();
539 struct ResourceStageState {
540 struct TextureState {
541 TextureReference _texture {};
545 std::array<BufferReference, MAX_NUM_RESOURCE_BUFFERS> _buffers{};
546 std::array<TextureState, MAX_NUM_RESOURCE_TEXTURES> _textures{};
547 int findEmptyTextureSlot()
const;
550 size_t _commandIndex{ 0 };
553 void updatePipeline();
557 void syncPipelineStateCache();
558 void resetPipelineStage();
560 struct PipelineStageState {
561 PipelineReference _pipeline{};
563 GLuint _program{ 0 };
564 GLShader* _programShader {
nullptr };
565 bool _invalidProgram {
false };
570 GLState* _state {
nullptr };
571 bool _invalidState {
false };
573 PipelineStageState() {}
577 virtual void postLinkProgram(ShaderObject& programObject,
const Shader& program)
const;
578 virtual GLShader* compileBackendProgram(
const Shader& program,
const Shader::CompilationHandler& handler);
579 virtual GLShader* compileBackendShader(
const Shader& shader,
const Shader::CompilationHandler& handler);
587 virtual std::string getShaderSource(
const Shader& shader, shader::Variant version)
final;
588 shader::Variant getShaderVariant()
const {
return isStereo() ? shader::Variant::Stereo : shader::Variant::Mono; }
589 virtual shader::Dialect getShaderDialect()
const = 0;
591 class ElementResource {
595 ElementResource(Element&& elem, uint16 resource) : _element(elem), _resource(resource) {}
597 ElementResource getFormatFromGLUniform(GLenum gltype);
600 void syncOutputStateCache();
601 void resetOutputStage();
603 struct OutputStageState {
604 FramebufferReference _framebuffer{};
605 GLuint _drawFBO{ 0 };
608 void resetQueryStage();
609 struct QueryStageState {
610 uint32_t _rangeQueryDepth{ 0 };
619 struct ShaderBinaryCache {
621 std::vector<GLint> _formats;
622 std::unordered_map<std::string, ::gl::CachedShader> _binaries;
623 } _shaderBinaryCache;
625 virtual void initShaderBinaryCache();
626 virtual void killShaderBinaryCache();
628 struct TextureManagementStageState {
629 bool _sparseCapable{
false };
630 GLTextureTransferEnginePointer _transferEngine;
631 } _textureManagement;
632 virtual void initTextureManagementStage();
633 virtual void killTextureManagementStage();
635 GLuint _mipGenerationFramebufferId{ 0 };
637 typedef void (GLBackend::*CommandCall)(
const Batch&, size_t);
638 static CommandCall _commandCalls[Batch::NUM_COMMANDS];
639 friend class GLState;
640 friend class GLTexture;
641 friend class GLShader;
642 friend class GLPipeline;
Provides the Mat4 scripting interface.
Definition: Mat4.h:44
Definition: gpu/src/gpu/Context.h:29
static void init()
Creates graphics-API specific Backend object.
Definition: gpu/src/gpu/Context.h:42
void downloadFramebuffer(const FramebufferPointer &srcFramebuffer, const Vec4i ®ion, QImage &destImage)
Writes a region of a given framebuffer to a QImage.
Definition: gpu/src/gpu/Context.cpp:191
void recycle() const
Definition: gpu/src/gpu/Context.cpp:121
void executeFrame(const FramePointer &frame) const
Definition: gpu/src/gpu/Context.cpp:131
void shutdown()
Definition: gpu/src/gpu/Context.cpp:62
static const Data DEFAULT
The unique default values for all the fields.
Definition: State.h:477
std::bitset< NUM_FIELDS > Signature
Definition: State.h:664
@ Unknown
Socket type unknown or not set.