diff --git a/libraries/gpu/src/gpu/Batch.h b/libraries/gpu/src/gpu/Batch.h index 51e384ee61..f6cddc1c5b 100644 --- a/libraries/gpu/src/gpu/Batch.h +++ b/libraries/gpu/src/gpu/Batch.h @@ -52,8 +52,8 @@ public: DrawCallInfo(Index idx) : index(idx) {} - Index index{0}; - uint16_t unused{0}; // Reserved space for later + Index index { 0 }; + uint16_t unused { 0 }; // Reserved space for later }; // Make sure DrawCallInfo has no extra padding @@ -68,6 +68,7 @@ public: BufferPointers buffers; Function function; DrawCallInfoBuffer drawCallInfos; + size_t numVertices; size_t count() const { return drawCallInfos.size(); } diff --git a/libraries/gpu/src/gpu/GLBackend.h b/libraries/gpu/src/gpu/GLBackend.h index f9a7f8626a..d30e4e69a6 100644 --- a/libraries/gpu/src/gpu/GLBackend.h +++ b/libraries/gpu/src/gpu/GLBackend.h @@ -329,16 +329,19 @@ protected: TransformCamera _camera; TransformCameras _cameras; - GLuint _objectBuffer{ 0 }; - GLuint _cameraBuffer{ 0 }; - size_t _cameraUboSize{ 0 }; + mutable std::map _drawCallInfoOffsets; + + GLuint _objectBuffer { 0 }; + GLuint _cameraBuffer { 0 }; + GLuint _drawCallInfoBuffer { 0 }; + size_t _cameraUboSize { 0 }; Transform _view; Mat4 _projection; - Vec4i _viewport{ 0, 0, 1, 1 }; - Vec2 _depthRange{ 0.0f, 1.0f }; - bool _invalidView{false}; - bool _invalidProj{false}; - bool _invalidViewport{ false }; + Vec4i _viewport { 0, 0, 1, 1 }; + Vec2 _depthRange { 0.0f, 1.0f }; + bool _invalidView { false }; + bool _invalidProj { false }; + bool _invalidViewport { false }; using Pair = std::pair; using List = std::list; diff --git a/libraries/gpu/src/gpu/GLBackendTransform.cpp b/libraries/gpu/src/gpu/GLBackendTransform.cpp index dd4f4837e0..e4a07948c5 100755 --- a/libraries/gpu/src/gpu/GLBackendTransform.cpp +++ b/libraries/gpu/src/gpu/GLBackendTransform.cpp @@ -61,6 +61,7 @@ void GLBackend::do_setDepthRangeTransform(Batch& batch, size_t paramOffset) { void GLBackend::initTransform() { glGenBuffers(1, &_transform._objectBuffer); glGenBuffers(1, &_transform._cameraBuffer); + glGenBuffers(1, &_transform._drawCallInfoBuffer); size_t cameraSize = sizeof(TransformCamera); while (_transform._cameraUboSize < cameraSize) { _transform._cameraUboSize += _uboAlignment; @@ -70,6 +71,7 @@ void GLBackend::initTransform() { void GLBackend::killTransform() { glDeleteBuffers(1, &_transform._objectBuffer); glDeleteBuffers(1, &_transform._cameraBuffer); + glDeleteBuffers(1, &_transform._drawCallInfoBuffer); } void GLBackend::syncTransformStateCache() { @@ -140,6 +142,21 @@ void GLBackend::TransformStageState::transfer(const Batch& batch) const { glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0); } + if (!batch._namedData.empty()) { + bufferData.clear(); + for (auto& data : batch._namedData) { + auto currentSize = bufferData.size(); + auto bytesToCopy = data.second.drawCallInfos.size() * sizeof(Batch::DrawCallInfo); + bufferData.resize(currentSize + bytesToCopy); + memcpy(bufferData.data() + currentSize, data.second.drawCallInfos.data(), bytesToCopy); + _drawCallInfoOffsets[data.first] = (GLvoid*)currentSize; + } + + glBindBuffer(GL_ARRAY_BUFFER, _drawCallInfoBuffer); + glBufferData(GL_ARRAY_BUFFER, bufferData.size(), bufferData.data(), GL_DYNAMIC_DRAW); + glBindBuffer(GL_ARRAY_BUFFER, 0); + } + CHECK_GL_ERROR(); } @@ -169,12 +186,21 @@ void GLBackend::updateTransform(const Batch& batch) { auto& drawCallInfoBuffer = batch.getDrawCallInfoBuffer(); if (batch._currentNamedCall.empty()) { - glDisableVertexAttribArray(gpu::Stream::DRAW_CALL_INFO); auto& drawCallInfo = drawCallInfoBuffer[_currentDraw]; - glVertexAttribI2i(gpu::Stream::DRAW_CALL_INFO, (GLint)drawCallInfo.index, (GLint)drawCallInfo.unused); + glDisableVertexAttribArray(gpu::Stream::DRAW_CALL_INFO); // Make sure attrib array is disabled + glVertexAttribI2i(gpu::Stream::DRAW_CALL_INFO, drawCallInfo.index, drawCallInfo.unused); } else { - glEnableVertexAttribArray(gpu::Stream::DRAW_CALL_INFO); - glVertexAttribIPointer(gpu::Stream::DRAW_CALL_INFO, 2, GL_SHORT, 4, drawCallInfoBuffer.data()); + if (false) { + auto& drawCallInfo = drawCallInfoBuffer[0]; + glDisableVertexAttribArray(gpu::Stream::DRAW_CALL_INFO); // Make sure attrib array is disabled + glVertexAttribI2i(gpu::Stream::DRAW_CALL_INFO, drawCallInfo.index, drawCallInfo.unused); + } else { + glEnableVertexAttribArray(gpu::Stream::DRAW_CALL_INFO); // Make sure attrib array is enabled + glBindBuffer(GL_ARRAY_BUFFER, _transform._drawCallInfoBuffer); + glVertexAttribIPointer(gpu::Stream::DRAW_CALL_INFO, 2, GL_UNSIGNED_SHORT, 0, + _transform._drawCallInfoOffsets[batch._currentNamedCall]); + glVertexAttribDivisor(gpu::Stream::DRAW_CALL_INFO, 100000); + } } }