From 9e0af63441e009ee682f8f4ce12fc05a412b1114 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Thu, 14 Jan 2016 12:35:20 -0800 Subject: [PATCH] Bind model transform as single buffer --- libraries/gpu/src/gpu/GLBackend.cpp | 8 ++--- libraries/gpu/src/gpu/GLBackend.h | 5 +-- libraries/gpu/src/gpu/GLBackendTransform.cpp | 38 +++++++------------- libraries/gpu/src/gpu/Transform.slh | 4 ++- 4 files changed, 20 insertions(+), 35 deletions(-) diff --git a/libraries/gpu/src/gpu/GLBackend.cpp b/libraries/gpu/src/gpu/GLBackend.cpp index bd8439c8be..4664557f2e 100644 --- a/libraries/gpu/src/gpu/GLBackend.cpp +++ b/libraries/gpu/src/gpu/GLBackend.cpp @@ -158,10 +158,9 @@ void GLBackend::renderPassTransfer(Batch& batch) { { // Sync all the buffers PROFILE_RANGE("syncCPUTransform"); - _transform._cameras.resize(0); + _transform._cameras.clear(); _transform._cameraOffsets.clear(); - _transform._objects.resize(0); - _transform._objectOffsets.clear(); + _transform._objects.clear(); for (_commandIndex = 0; _commandIndex < numCommands; ++_commandIndex) { switch (*command) { @@ -196,10 +195,11 @@ void GLBackend::renderPassTransfer(Batch& batch) { PROFILE_RANGE("syncGPUTransform"); _transform.transfer(); } + + } void GLBackend::renderPassDraw(Batch& batch) { - _transform._objectsItr = _transform._objectOffsets.begin(); _transform._camerasItr = _transform._cameraOffsets.begin(); const size_t numCommands = batch.getCommands().size(); const Batch::Commands::value_type* command = batch.getCommands().data(); diff --git a/libraries/gpu/src/gpu/GLBackend.h b/libraries/gpu/src/gpu/GLBackend.h index 86d06b9605..a5bdba9788 100644 --- a/libraries/gpu/src/gpu/GLBackend.h +++ b/libraries/gpu/src/gpu/GLBackend.h @@ -355,10 +355,9 @@ protected: TransformObjects _objects; TransformCameras _cameras; - size_t _cameraUboSize{ 0 }; - size_t _objectUboSize{ 0 }; GLuint _objectBuffer{ 0 }; GLuint _cameraBuffer{ 0 }; + size_t _cameraUboSize{ 0 }; Transform _model; Transform _view; Mat4 _projection; @@ -372,8 +371,6 @@ protected: using Pair = std::pair; using List = std::list; List _cameraOffsets; - List _objectOffsets; - mutable List::const_iterator _objectsItr; mutable List::const_iterator _camerasItr; void preUpdate(size_t commandIndex, const StereoState& stereo); diff --git a/libraries/gpu/src/gpu/GLBackendTransform.cpp b/libraries/gpu/src/gpu/GLBackendTransform.cpp index 9bfd258833..7f7a2b2c4a 100755 --- a/libraries/gpu/src/gpu/GLBackendTransform.cpp +++ b/libraries/gpu/src/gpu/GLBackendTransform.cpp @@ -67,10 +67,6 @@ void GLBackend::initTransform() { while (_transform._cameraUboSize < cameraSize) { _transform._cameraUboSize += _uboAlignment; } - size_t objectSize = sizeof(TransformObject); - while (_transform._objectUboSize < objectSize) { - _transform._objectUboSize += _uboAlignment; - } } void GLBackend::killTransform() { @@ -116,6 +112,8 @@ void GLBackend::TransformStageState::preUpdate(size_t commandIndex, const Stereo // of non-uniform scale. We need to fix that. In the mean time, glm::inverse() works. //_model.getInverseMatrix(_object._modelInverse); _object._modelInverse = glm::inverse(_object._model); + + _objects.push_back(_object); } if (_invalidView || _invalidProj || _invalidViewport) { @@ -131,12 +129,6 @@ void GLBackend::TransformStageState::preUpdate(size_t commandIndex, const Stereo } } - if (_invalidModel) { - size_t offset = _objectUboSize * _objects.size(); - _objectOffsets.push_back(TransformStageState::Pair(commandIndex, offset)); - _objects.push_back(_object); - } - // Flags are clean _invalidView = _invalidProj = _invalidModel = _invalidViewport = false; } @@ -145,42 +137,33 @@ void GLBackend::TransformStageState::transfer() const { // FIXME not thread safe static std::vector bufferData; if (!_cameras.empty()) { - glBindBuffer(GL_UNIFORM_BUFFER, _cameraBuffer); bufferData.resize(_cameraUboSize * _cameras.size()); for (size_t i = 0; i < _cameras.size(); ++i) { memcpy(bufferData.data() + (_cameraUboSize * i), &_cameras[i], sizeof(TransformCamera)); } + glBindBuffer(GL_UNIFORM_BUFFER, _cameraBuffer); glBufferData(GL_UNIFORM_BUFFER, bufferData.size(), bufferData.data(), GL_DYNAMIC_DRAW); } if (!_objects.empty()) { + auto byteSize = _objects.size() * sizeof(TransformObject); + bufferData.resize(byteSize); + memcpy(bufferData.data(), _objects.data(), byteSize); + glBindBuffer(GL_UNIFORM_BUFFER, _objectBuffer); - bufferData.resize(_objectUboSize * _objects.size()); - for (size_t i = 0; i < _objects.size(); ++i) { - memcpy(bufferData.data() + (_objectUboSize * i), &_objects[i], sizeof(TransformObject)); - } glBufferData(GL_UNIFORM_BUFFER, bufferData.size(), bufferData.data(), GL_DYNAMIC_DRAW); } - if (!_cameras.empty() || !_objects.empty()) { + if (!_objects.empty() || !_cameras.empty()) { glBindBuffer(GL_UNIFORM_BUFFER, 0); } + CHECK_GL_ERROR(); } void GLBackend::TransformStageState::update(size_t commandIndex, const StereoState& stereo) const { static const size_t INVALID_OFFSET = (size_t)-1; size_t offset = INVALID_OFFSET; - while ((_objectsItr != _objectOffsets.end()) && (commandIndex >= (*_objectsItr).first)) { - offset = (*_objectsItr).second; - ++_objectsItr; - } - if (offset != INVALID_OFFSET) { - glBindBufferRange(GL_UNIFORM_BUFFER, TRANSFORM_OBJECT_SLOT, - _objectBuffer, offset, sizeof(Backend::TransformObject)); - } - - offset = INVALID_OFFSET; while ((_camerasItr != _cameraOffsets.end()) && (commandIndex >= (*_camerasItr).first)) { offset = (*_camerasItr).second; ++_camerasItr; @@ -194,6 +177,9 @@ void GLBackend::TransformStageState::update(size_t commandIndex, const StereoSta _cameraBuffer, offset, sizeof(Backend::TransformCamera)); } + glBindBufferBase(GL_UNIFORM_BUFFER, TRANSFORM_OBJECT_SLOT, _objectBuffer); + + (void)CHECK_GL_ERROR(); } diff --git a/libraries/gpu/src/gpu/Transform.slh b/libraries/gpu/src/gpu/Transform.slh index 26ea9784be..e7ddc051c5 100644 --- a/libraries/gpu/src/gpu/Transform.slh +++ b/libraries/gpu/src/gpu/Transform.slh @@ -25,8 +25,10 @@ struct TransformCamera { vec4 _viewport; }; +const int MAX_OBJECTS = 512; // NEEDS to match GLBackend::TransformStageState::update's MAX_OBJECT + layout(std140) uniform transformObjectBuffer { - TransformObject _object; + TransformObject _object[MAX_OBJECTS]; }; TransformObject getTransformObject() { return _object;